Skip to content

Commit

Permalink
Merge pull request #13 from Eh2406/minimal-versions
Browse files Browse the repository at this point in the history
inline the code from unreachable and void
  • Loading branch information
Amanieu authored Aug 15, 2018
2 parents c3fe9ef + f8ca900 commit c1c1ac3
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
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
}
}
}

0 comments on commit c1c1ac3

Please sign in to comment.