Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inline the code from unreachable and void #13

Merged
merged 3 commits into from
Aug 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ rust:
- nightly
- beta
- stable
- 1.9.0
- 1.21.0

before_script:
- |
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ keywords = ["thread_local", "concurrent", "thread"]
travis-ci = { repository = "Amanieu/thread_local-rs" }

[dependencies]
unreachable = "1.0"
lazy_static = "1.0"
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@
#![warn(missing_docs)]

extern crate unreachable;
#[macro_use]
extern crate lazy_static;

mod thread_id;
mod unreachable;

use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use std::sync::Mutex;
Expand Down Expand Up @@ -158,7 +158,7 @@ fn hash(id: usize, bits: usize) -> usize {
#[cfg(target_pointer_width = "64")]
#[inline]
fn hash(id: usize, bits: usize) -> usize {
id.wrapping_mul(0x9E3779B97F4A7C15) >> (64 - bits)
id.wrapping_mul(0x9E37_79B9_7F4A_7C15) >> (64 - bits)
}

impl<T: ?Sized + Send> ThreadLocal<T> {
Expand Down
74 changes: 74 additions & 0 deletions src/unreachable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2017 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! # unreachable
//! inlined from https://github.com/reem/rust-unreachable/
//!
//! An unreachable code optimization hint in stable rust, and some useful
//! extension traits for `Option` and `Result`.
//!
/// Hint to the optimizer that any code path which calls this function is
/// statically unreachable and can be removed.
///
/// Calling this function in reachable code invokes undefined behavior. Be
/// very, very sure this is what you want; often, a simple `panic!` is more
/// suitable.
#[inline]
pub unsafe fn unreachable() -> ! {
/// The empty type for cases which can't occur.
enum Void { }
let x: &Void = ::std::mem::transmute(1usize);
match *x {}
}

/// An extension trait for `Option<T>` providing unchecked unwrapping methods.
pub trait UncheckedOptionExt<T> {
/// Get the value out of this Option without checking for None.
unsafe fn unchecked_unwrap(self) -> T;

/// Assert that this Option is a None to the optimizer.
unsafe fn unchecked_unwrap_none(self);
}

/// An extension trait for `Result<T, E>` providing unchecked unwrapping methods.
pub trait UncheckedResultExt<T, E> {
/// Get the value out of this Result without checking for Err.
unsafe fn unchecked_unwrap_ok(self) -> T;

/// Get the error out of this Result without checking for Ok.
unsafe fn unchecked_unwrap_err(self) -> E;
}

impl<T> UncheckedOptionExt<T> for Option<T> {
unsafe fn unchecked_unwrap(self) -> T {
match self {
Some(x) => x,
None => unreachable()
}
}

unsafe fn unchecked_unwrap_none(self) {
if self.is_some() { unreachable() }
}
}

impl<T, E> UncheckedResultExt<T, E> for Result<T, E> {
unsafe fn unchecked_unwrap_ok(self) -> T {
match self {
Ok(x) => x,
Err(_) => unreachable()
}
}

unsafe fn unchecked_unwrap_err(self) -> E {
match self {
Ok(_) => unreachable(),
Err(e) => e
}
}
}