Skip to content

Commit 2bd7a97

Browse files
committed
Auto merge of #154668 - jhpratt:rollup-ePnl7Di, r=jhpratt
Rollup of 4 pull requests Successful merges: - #154356 ( Add integer truncation and extension methods) - #154641 (build_helper: fix yarn locking, add check, and bump lockfile) - #154647 (change `c_double` to `f32` on `avr` targets) - #154655 (Fix associated type bound suggestion span issue)
2 parents 3ebe60c + 7f794c3 commit 2bd7a97

16 files changed

Lines changed: 538 additions & 118 deletions

compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
105105
if !sp.contains(p_span) {
106106
diag.span_label(p_span, format!("{expected}this type parameter"));
107107
}
108-
let parent = p_def_id.as_local().and_then(|id| {
108+
let param_def_id = match *proj.self_ty().kind() {
109+
ty::Param(param) => {
110+
tcx.generics_of(body_owner_def_id).type_param(param, tcx).def_id
111+
}
112+
_ => p_def_id,
113+
};
114+
let parent = param_def_id.as_local().and_then(|id| {
109115
let local_id = tcx.local_def_id_to_hir_id(id);
110116
let generics = tcx.parent_hir_node(local_id).generics()?;
111117
Some((id, generics))

library/core/src/ffi/c_double.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Equivalent to C's `double` type.
22

3-
This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
3+
This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`]; some 16-bit systems use [`f32`], for example. Esoteric systems could use something entirely different from the IEEE-754 standard.
44

55
[IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
66
[`float`]: c_float

library/core/src/ffi/primitives.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,27 @@ macro_rules! type_alias {
1515
}
1616
}
1717

18-
type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(all()))] }
18+
// `#[doc(cfg(true))]` is used to prevent rustdoc from displaying a "Available on ..." box.
19+
// The implementation of these constants is target-specific, but every target does define them.
20+
21+
type_alias! { "c_char.md", c_char = c_char_definition::c_char; #[doc(cfg(true))] }
1922

2023
type_alias! { "c_schar.md", c_schar = i8; }
2124
type_alias! { "c_uchar.md", c_uchar = u8; }
2225
type_alias! { "c_short.md", c_short = i16; }
2326
type_alias! { "c_ushort.md", c_ushort = u16; }
2427

25-
type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(all()))] }
26-
type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(all()))] }
28+
type_alias! { "c_int.md", c_int = c_int_definition::c_int; #[doc(cfg(true))] }
29+
type_alias! { "c_uint.md", c_uint = c_int_definition::c_uint; #[doc(cfg(true))] }
2730

28-
type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(all()))] }
29-
type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(all()))] }
31+
type_alias! { "c_long.md", c_long = c_long_definition::c_long; #[doc(cfg(true))] }
32+
type_alias! { "c_ulong.md", c_ulong = c_long_definition::c_ulong; #[doc(cfg(true))] }
3033

3134
type_alias! { "c_longlong.md", c_longlong = i64; }
3235
type_alias! { "c_ulonglong.md", c_ulonglong = u64; }
3336

3437
type_alias! { "c_float.md", c_float = f32; }
35-
type_alias! { "c_double.md", c_double = f64; }
38+
type_alias! { "c_double.md", c_double= c_double_definition::c_double; #[doc(cfg(true))] }
3639

3740
mod c_char_definition {
3841
crate::cfg_select! {
@@ -183,3 +186,18 @@ mod c_int_definition {
183186
}
184187
}
185188
}
189+
190+
mod c_double_definition {
191+
crate::cfg_select! {
192+
target_arch = "avr" => {
193+
// avr:
194+
// Per https://gcc.gnu.org/wiki/avr-gcc#Type_Layout. The table says `4,8` because
195+
// in C the width of `double` can be changed with the `-mdouble=32/64` setting. But
196+
// 32-bits is the default for the rust avr target.
197+
pub(super) type c_double = f32;
198+
}
199+
_ => {
200+
pub(super) type c_double = f64;
201+
}
202+
}
203+
}

library/core/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
#![feature(offset_of_enum)]
111111
#![feature(panic_internals)]
112112
#![feature(pattern_type_macro)]
113+
#![feature(sealed)]
113114
#![feature(ub_checks)]
114115
// tidy-alphabetical-end
115116
//
@@ -216,6 +217,14 @@ pub mod from {
216217
pub use crate::macros::builtin::From;
217218
}
218219

220+
mod sealed {
221+
/// This trait being unreachable from outside the crate
222+
/// prevents outside implementations of our extension traits.
223+
/// This allows adding more trait methods in the future.
224+
#[unstable(feature = "sealed", issue = "none")]
225+
pub trait Sealed {}
226+
}
227+
219228
// We don't export this through #[macro_export] for now, to avoid breakage.
220229
#[unstable(feature = "autodiff", issue = "124509")]
221230
/// Unstable module containing the unstable `autodiff` macro.

library/core/src/num/int_macros.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3944,5 +3944,89 @@ macro_rules! int_impl {
39443944
self
39453945
}
39463946
}
3947+
3948+
/// Truncate an integer to an integer of the same size or smaller, preserving the least
3949+
/// significant bits.
3950+
///
3951+
/// # Examples
3952+
///
3953+
/// ```
3954+
/// #![feature(integer_extend_truncate)]
3955+
#[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".truncate());")]
3956+
#[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").truncate());")]
3957+
/// assert_eq!(120i8, 376i32.truncate());
3958+
/// ```
3959+
#[must_use = "this returns the truncated value and does not modify the original"]
3960+
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
3961+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
3962+
#[inline]
3963+
pub const fn truncate<Target>(self) -> Target
3964+
where Self: [const] traits::TruncateTarget<Target>
3965+
{
3966+
traits::TruncateTarget::internal_truncate(self)
3967+
}
3968+
3969+
/// Truncate an integer to an integer of the same size or smaller, saturating at numeric bounds
3970+
/// instead of truncating.
3971+
///
3972+
/// # Examples
3973+
///
3974+
/// ```
3975+
/// #![feature(integer_extend_truncate)]
3976+
#[doc = concat!("assert_eq!(120i8, 120", stringify!($SelfT), ".saturating_truncate());")]
3977+
#[doc = concat!("assert_eq!(-120i8, (-120", stringify!($SelfT), ").saturating_truncate());")]
3978+
/// assert_eq!(127i8, 376i32.saturating_truncate());
3979+
/// assert_eq!(-128i8, (-1000i32).saturating_truncate());
3980+
/// ```
3981+
#[must_use = "this returns the truncated value and does not modify the original"]
3982+
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
3983+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
3984+
#[inline]
3985+
pub const fn saturating_truncate<Target>(self) -> Target
3986+
where Self: [const] traits::TruncateTarget<Target>
3987+
{
3988+
traits::TruncateTarget::internal_saturating_truncate(self)
3989+
}
3990+
3991+
/// Truncate an integer to an integer of the same size or smaller, returning `None` if the value
3992+
/// is outside the bounds of the smaller type.
3993+
///
3994+
/// # Examples
3995+
///
3996+
/// ```
3997+
/// #![feature(integer_extend_truncate)]
3998+
#[doc = concat!("assert_eq!(Some(120i8), 120", stringify!($SelfT), ".checked_truncate());")]
3999+
#[doc = concat!("assert_eq!(Some(-120i8), (-120", stringify!($SelfT), ").checked_truncate());")]
4000+
/// assert_eq!(None, 376i32.checked_truncate::<i8>());
4001+
/// assert_eq!(None, (-1000i32).checked_truncate::<i8>());
4002+
/// ```
4003+
#[must_use = "this returns the truncated value and does not modify the original"]
4004+
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
4005+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
4006+
#[inline]
4007+
pub const fn checked_truncate<Target>(self) -> Option<Target>
4008+
where Self: [const] traits::TruncateTarget<Target>
4009+
{
4010+
traits::TruncateTarget::internal_checked_truncate(self)
4011+
}
4012+
4013+
/// Extend to an integer of the same size or larger, preserving its value.
4014+
///
4015+
/// # Examples
4016+
///
4017+
/// ```
4018+
/// #![feature(integer_extend_truncate)]
4019+
#[doc = concat!("assert_eq!(120i128, 120i8.extend());")]
4020+
#[doc = concat!("assert_eq!(-120i128, (-120i8).extend());")]
4021+
/// ```
4022+
#[must_use = "this returns the extended value and does not modify the original"]
4023+
#[unstable(feature = "integer_extend_truncate", issue = "154330")]
4024+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
4025+
#[inline]
4026+
pub const fn extend<Target>(self) -> Target
4027+
where Self: [const] traits::ExtendTarget<Target>
4028+
{
4029+
traits::ExtendTarget::internal_extend(self)
4030+
}
39474031
}
39484032
}

library/core/src/num/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ mod error;
4646
mod float_parse;
4747
mod nonzero;
4848
mod saturating;
49+
mod traits;
4950
mod wrapping;
5051

5152
/// 100% perma-unstable
@@ -1795,3 +1796,12 @@ macro_rules! from_str_int_impl {
17951796

17961797
from_str_int_impl! { signed isize i8 i16 i32 i64 i128 }
17971798
from_str_int_impl! { unsigned usize u8 u16 u32 u64 u128 }
1799+
1800+
macro_rules! impl_sealed {
1801+
($($t:ty)*) => {$(
1802+
/// Allows extension traits within `core`.
1803+
#[unstable(feature = "sealed", issue = "none")]
1804+
impl crate::sealed::Sealed for $t {}
1805+
)*}
1806+
}
1807+
impl_sealed! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }

library/core/src/num/traits.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/// Definitions of traits for numeric types
2+
// Implementation based on `num_conv` by jhpratt, under (MIT OR Apache-2.0).
3+
4+
/// Trait for types that this type can be truncated to
5+
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
6+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
7+
pub const trait TruncateTarget<Target>: crate::sealed::Sealed {
8+
#[doc(hidden)]
9+
fn internal_truncate(self) -> Target;
10+
11+
#[doc(hidden)]
12+
fn internal_saturating_truncate(self) -> Target;
13+
14+
#[doc(hidden)]
15+
fn internal_checked_truncate(self) -> Option<Target>;
16+
}
17+
18+
/// Trait for types that this type can be truncated to
19+
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
20+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
21+
pub const trait ExtendTarget<Target>: crate::sealed::Sealed {
22+
#[doc(hidden)]
23+
fn internal_extend(self) -> Target;
24+
}
25+
26+
macro_rules! impl_truncate {
27+
($($from:ty => $($to:ty),+;)*) => {$($(
28+
const _: () = assert!(
29+
size_of::<$from>() >= size_of::<$to>(),
30+
concat!(
31+
"cannot truncate ",
32+
stringify!($from),
33+
" to ",
34+
stringify!($to),
35+
" because ",
36+
stringify!($from),
37+
" is smaller than ",
38+
stringify!($to)
39+
)
40+
);
41+
42+
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
43+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
44+
impl const TruncateTarget<$to> for $from {
45+
#[inline]
46+
fn internal_truncate(self) -> $to {
47+
self as _
48+
}
49+
50+
#[inline]
51+
fn internal_saturating_truncate(self) -> $to {
52+
if self > <$to>::MAX as Self {
53+
<$to>::MAX
54+
} else if self < <$to>::MIN as Self {
55+
<$to>::MIN
56+
} else {
57+
self as _
58+
}
59+
}
60+
61+
#[inline]
62+
fn internal_checked_truncate(self) -> Option<$to> {
63+
if self > <$to>::MAX as Self || self < <$to>::MIN as Self {
64+
None
65+
} else {
66+
Some(self as _)
67+
}
68+
}
69+
}
70+
)+)*};
71+
}
72+
73+
macro_rules! impl_extend {
74+
($($from:ty => $($to:ty),+;)*) => {$($(
75+
const _: () = assert!(
76+
size_of::<$from>() <= size_of::<$to>(),
77+
concat!(
78+
"cannot extend ",
79+
stringify!($from),
80+
" to ",
81+
stringify!($to),
82+
" because ",
83+
stringify!($from),
84+
" is larger than ",
85+
stringify!($to)
86+
)
87+
);
88+
89+
#[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")]
90+
#[rustc_const_unstable(feature = "integer_truncate_extend", issue = "154330")]
91+
impl const ExtendTarget<$to> for $from {
92+
fn internal_extend(self) -> $to {
93+
self as _
94+
}
95+
}
96+
)+)*};
97+
}
98+
99+
impl_truncate! {
100+
u8 => u8;
101+
u16 => u16, u8;
102+
u32 => u32, u16, u8;
103+
u64 => u64, u32, u16, u8;
104+
u128 => u128, u64, u32, u16, u8;
105+
usize => usize, u16, u8;
106+
107+
i8 => i8;
108+
i16 => i16, i8;
109+
i32 => i32, i16, i8;
110+
i64 => i64, i32, i16, i8;
111+
i128 => i128, i64, i32, i16, i8;
112+
isize => isize, i16, i8;
113+
}
114+
115+
impl_extend! {
116+
u8 => u8, u16, u32, u64, u128, usize;
117+
u16 => u16, u32, u64, u128, usize;
118+
u32 => u32, u64, u128;
119+
u64 => u64, u128;
120+
u128 => u128;
121+
usize => usize;
122+
123+
i8 => i8, i16, i32, i64, i128, isize;
124+
i16 => i16, i32, i64, i128, isize;
125+
i32 => i32, i64, i128;
126+
i64 => i64, i128;
127+
i128 => i128;
128+
isize => isize;
129+
}

0 commit comments

Comments
 (0)