Skip to content

Add type hint struct #10388

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

Closed
wants to merge 4 commits into from
Closed
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
27 changes: 14 additions & 13 deletions src/libstd/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ use libc::c_int;
use num::{Zero, One, strconv};
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
use num;
use prelude::*;
use to_str;
use util::ForType;
use prelude::*;

pub use cmath::c_float_targ_consts::*;

Expand Down Expand Up @@ -584,13 +585,13 @@ impl Bounded for f32 {

impl Primitive for f32 {
#[inline]
fn bits(_: Option<f32>) -> uint { 32 }
fn bits(_: ForType<f32>) -> uint { 32 }

#[inline]
fn bytes(_: Option<f32>) -> uint { Primitive::bits(Some(0f32)) / 8 }
fn bytes(_: ForType<f32>) -> uint { Primitive::bits(ForType::<f32>) / 8 }

#[inline]
fn is_signed(_: Option<f32>) -> bool { true }
fn is_signed(_: ForType<f32>) -> bool { true }
}

impl Float for f32 {
Expand Down Expand Up @@ -647,25 +648,25 @@ impl Float for f32 {
}

#[inline]
fn mantissa_digits(_: Option<f32>) -> uint { 24 }
fn mantissa_digits(_: ForType<f32>) -> uint { 24 }

#[inline]
fn digits(_: Option<f32>) -> uint { 6 }
fn digits(_: ForType<f32>) -> uint { 6 }

#[inline]
fn epsilon() -> f32 { 1.19209290e-07 }

#[inline]
fn min_exp(_: Option<f32>) -> int { -125 }
fn min_exp(_: ForType<f32>) -> int { -125 }

#[inline]
fn max_exp(_: Option<f32>) -> int { 128 }
fn max_exp(_: ForType<f32>) -> int { 128 }

#[inline]
fn min_10_exp(_: Option<f32>) -> int { -37 }
fn min_10_exp(_: ForType<f32>) -> int { -37 }

#[inline]
fn max_10_exp(_: Option<f32>) -> int { 38 }
fn max_10_exp(_: ForType<f32>) -> int { 38 }

/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
#[inline]
Expand Down Expand Up @@ -927,6 +928,7 @@ mod tests {
use num::*;
use num;
use mem;
use util::ForType;

#[test]
fn test_num() {
Expand Down Expand Up @@ -1195,9 +1197,8 @@ mod tests {

#[test]
fn test_primitive() {
let none: Option<f32> = None;
assert_eq!(Primitive::bits(none), mem::size_of::<f32>() * 8);
assert_eq!(Primitive::bytes(none), mem::size_of::<f32>());
assert_eq!(Primitive::bits(ForType::<f32>), mem::size_of::<f32>() * 8);
assert_eq!(Primitive::bytes(ForType::<f32>), mem::size_of::<f32>());
}

#[test]
Expand Down
27 changes: 14 additions & 13 deletions src/libstd/num/f64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ use libc::c_int;
use num::{Zero, One, strconv};
use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
use num;
use prelude::*;
use to_str;
use util::ForType;
use prelude::*;

pub use cmath::c_double_targ_consts::*;
pub use cmp::{min, max};
Expand Down Expand Up @@ -632,13 +633,13 @@ impl Bounded for f64 {

impl Primitive for f64 {
#[inline]
fn bits(_: Option<f64>) -> uint { 64 }
fn bits(_: ForType<f64>) -> uint { 64 }

#[inline]
fn bytes(_: Option<f64>) -> uint { Primitive::bits(Some(0f64)) / 8 }
fn bytes(_: ForType<f64>) -> uint { Primitive::bits(ForType::<f64>) / 8 }

#[inline]
fn is_signed(_: Option<f64>) -> bool { true }
fn is_signed(_: ForType<f64>) -> bool { true }
}

impl Float for f64 {
Expand Down Expand Up @@ -695,25 +696,25 @@ impl Float for f64 {
}

#[inline]
fn mantissa_digits(_: Option<f64>) -> uint { 53 }
fn mantissa_digits(_: ForType<f64>) -> uint { 53 }

#[inline]
fn digits(_: Option<f64>) -> uint { 15 }
fn digits(_: ForType<f64>) -> uint { 15 }

#[inline]
fn epsilon() -> f64 { 2.2204460492503131e-16 }

#[inline]
fn min_exp(_: Option<f64>) -> int { -1021 }
fn min_exp(_: ForType<f64>) -> int { -1021 }

#[inline]
fn max_exp(_: Option<f64>) -> int { 1024 }
fn max_exp(_: ForType<f64>) -> int { 1024 }

#[inline]
fn min_10_exp(_: Option<f64>) -> int { -307 }
fn min_10_exp(_: ForType<f64>) -> int { -307 }

#[inline]
fn max_10_exp(_: Option<f64>) -> int { 308 }
fn max_10_exp(_: ForType<f64>) -> int { 308 }

/// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
#[inline]
Expand Down Expand Up @@ -975,6 +976,7 @@ mod tests {
use num::*;
use num;
use mem;
use util::ForType;

#[test]
fn test_num() {
Expand Down Expand Up @@ -1246,9 +1248,8 @@ mod tests {

#[test]
fn test_primitive() {
let none: Option<f64> = None;
assert_eq!(Primitive::bits(none), mem::size_of::<f64>() * 8);
assert_eq!(Primitive::bytes(none), mem::size_of::<f64>());
assert_eq!(Primitive::bits(ForType::<f64>), mem::size_of::<f64>() * 8);
assert_eq!(Primitive::bytes(ForType::<f64>), mem::size_of::<f64>());
}

#[test]
Expand Down
15 changes: 8 additions & 7 deletions src/libstd/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ macro_rules! int_module (($T:ty, $bits:expr) => (mod generated {
use default::Default;
use num::{ToStrRadix, FromStrRadix};
use num::{CheckedDiv, Zero, One, strconv};
use prelude::*;
use str;
use util::ForType;
use prelude::*;

pub use cmp::{min, max};

Expand Down Expand Up @@ -377,13 +378,13 @@ impl Int for $T {}

impl Primitive for $T {
#[inline]
fn bits(_: Option<$T>) -> uint { bits }
fn bits(_: ForType<$T>) -> uint { bits }

#[inline]
fn bytes(_: Option<$T>) -> uint { bits / 8 }
fn bytes(_: ForType<$T>) -> uint { bits / 8 }

#[inline]
fn is_signed(_: Option<$T>) -> bool { true }
fn is_signed(_: ForType<$T>) -> bool { true }
}

// String conversion functions and impl str -> num
Expand Down Expand Up @@ -458,6 +459,7 @@ mod tests {
use i32;
use num;
use mem;
use util::ForType;

#[test]
fn test_num() {
Expand Down Expand Up @@ -653,9 +655,8 @@ mod tests {

#[test]
fn test_primitive() {
let none: Option<$T> = None;
assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8);
assert_eq!(Primitive::bytes(none), mem::size_of::<$T>());
assert_eq!(Primitive::bits(ForType::<$T>), mem::size_of::<$T>() * 8);
assert_eq!(Primitive::bytes(ForType::<$T>), mem::size_of::<$T>());
}

#[test]
Expand Down
29 changes: 15 additions & 14 deletions src/libstd/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use cmp::{Eq, ApproxEq, Ord};
use ops::{Add, Sub, Mul, Div, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::{Option, Some, None};
use util::ForType;

pub mod strconv;

Expand Down Expand Up @@ -343,10 +344,10 @@ pub trait Primitive: Clone
+ Div<Self,Self>
+ Rem<Self,Self> {
// FIXME (#5527): These should be associated constants
// FIXME (#8888): Removing `unused_self` requires #8888 to be fixed.
fn bits(unused_self: Option<Self>) -> uint;
fn bytes(unused_self: Option<Self>) -> uint;
fn is_signed(unused_self: Option<Self>) -> bool;
// FIXME (#8888): `ForType` should be a language feature. See also: #6894
fn bits(_: ForType<Self>) -> uint;
fn bytes(_: ForType<Self>) -> uint;
fn is_signed(_: ForType<Self>) -> bool;
}

/// A collection of traits relevant to primitive signed and unsigned integers
Expand Down Expand Up @@ -387,14 +388,14 @@ pub trait Float: Real
fn is_normal(&self) -> bool;
fn classify(&self) -> FPCategory;

// FIXME (#8888): Removing `unused_self` requires #8888 to be fixed.
fn mantissa_digits(unused_self: Option<Self>) -> uint;
fn digits(unused_self: Option<Self>) -> uint;
// FIXME (#8888): `ForType` should be a language feature. See also: #6894
fn mantissa_digits(_: ForType<Self>) -> uint;
fn digits(_: ForType<Self>) -> uint;
fn epsilon() -> Self;
fn min_exp(unused_self: Option<Self>) -> int;
fn max_exp(unused_self: Option<Self>) -> int;
fn min_10_exp(unused_self: Option<Self>) -> int;
fn max_10_exp(unused_self: Option<Self>) -> int;
fn min_exp(_: ForType<Self>) -> int;
fn max_exp(_: ForType<Self>) -> int;
fn min_10_exp(_: ForType<Self>) -> int;
fn max_10_exp(_: ForType<Self>) -> int;

fn ldexp(x: Self, exp: int) -> Self;
fn frexp(&self) -> (Self, int);
Expand Down Expand Up @@ -490,7 +491,7 @@ pub trait ToPrimitive {
macro_rules! impl_to_primitive_int_to_int(
($SrcT:ty, $DstT:ty) => (
{
if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
if Primitive::bits(ForType::<$SrcT>) <= Primitive::bits(ForType::<$DstT>) {
Some(*self as $DstT)
} else {
let n = *self as i64;
Expand Down Expand Up @@ -575,7 +576,7 @@ macro_rules! impl_to_primitive_uint_to_int(
macro_rules! impl_to_primitive_uint_to_uint(
($SrcT:ty, $DstT:ty) => (
{
if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
if Primitive::bits(ForType::<$SrcT>) <= Primitive::bits(ForType::<$DstT>) {
Some(*self as $DstT)
} else {
let zero: $SrcT = Zero::zero();
Expand Down Expand Up @@ -631,7 +632,7 @@ impl_to_primitive_uint!(u64)

macro_rules! impl_to_primitive_float_to_float(
($SrcT:ty, $DstT:ty) => (
if Primitive::bits(None::<$SrcT>) <= Primitive::bits(None::<$DstT>) {
if Primitive::bits(ForType::<$SrcT>) <= Primitive::bits(ForType::<$DstT>) {
Some(*self as $DstT)
} else {
let n = *self as f64;
Expand Down
15 changes: 8 additions & 7 deletions src/libstd/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ use default::Default;
use num::BitCount;
use num::{ToStrRadix, FromStrRadix};
use num::{CheckedDiv, Zero, One, strconv};
use prelude::*;
use str;
use util::ForType;
use prelude::*;

pub use cmp::{min, max};

Expand Down Expand Up @@ -302,13 +303,13 @@ impl ToStrRadix for $T {

impl Primitive for $T {
#[inline]
fn bits(_: Option<$T>) -> uint { bits }
fn bits(_: ForType<$T>) -> uint { bits }

#[inline]
fn bytes(_: Option<$T>) -> uint { bits / 8 }
fn bytes(_: ForType<$T>) -> uint { bits / 8 }

#[inline]
fn is_signed(_: Option<$T>) -> bool { false }
fn is_signed(_: ForType<$T>) -> bool { false }
}

impl BitCount for $T {
Expand Down Expand Up @@ -339,6 +340,7 @@ mod tests {
use num;
use mem;
use u16;
use util::ForType;

#[test]
fn test_num() {
Expand Down Expand Up @@ -430,9 +432,8 @@ mod tests {

#[test]
fn test_primitive() {
let none: Option<$T> = None;
assert_eq!(Primitive::bits(none), mem::size_of::<$T>() * 8);
assert_eq!(Primitive::bytes(none), mem::size_of::<$T>());
assert_eq!(Primitive::bits(ForType::<$T>), mem::size_of::<$T>() * 8);
assert_eq!(Primitive::bytes(ForType::<$T>), mem::size_of::<$T>());
}

#[test]
Expand Down
43 changes: 35 additions & 8 deletions src/libstd/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@ pub fn id<T>(x: T) -> T { x }
#[inline]
pub fn ignore<T>(_x: T) { }

/**
* Swap the values at two mutable locations of the same type, without
* deinitialising or copying either one.
*/
/// Swap the values at two mutable locations of the same type, without
/// deinitialising or copying either one.
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
unsafe {
Expand All @@ -47,10 +45,8 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
}
}

/**
* Replace the value at a mutable location with a new one, returning the old
* value, without deinitialising or copying either one.
*/
/// Replace the value at a mutable location with a new one, returning the old
/// value, without deinitialising or copying either one.
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
swap(dest, &mut src);
Expand Down Expand Up @@ -84,6 +80,24 @@ impl Void {
}
}

/// A zero-sized type hint useful for accessing static methods that don't
/// mention `Self`.
///
/// # Example
///
/// ~~~rust
/// trait A {
/// fn a(_: ForType<Self>) -> uint;
/// }
///
/// impl A for int {
/// fn a(_: ForType<int>) -> uint { 6 }
/// }
///
/// assert_eq!(A::a(ForType::<int>), 6);
/// ~~~
// FIXME (#8888): This should really be part of the language. See also: #6894
pub struct ForType<T>;

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -155,6 +169,19 @@ mod tests {

unsafe { assert_eq!(did_run, true); }
}

#[test]
fn type_hint() {
trait A {
fn a(_: ForType<Self>) -> uint;
}

impl A for int {
fn a(_: ForType<int33>) -> uint { 6 }
}

assert_eq!(A::a(ForType::<int>), 6);
}
}

/// Completely miscellaneous language-construct benchmarks.
Expand Down