Skip to content

Commit 9ae6ced

Browse files
committed
Auto merge of #67560 - Centril:rollup-fzdpu9c, r=Centril
Rollup of 8 pull requests Successful merges: - #67233 (Add PartialEq and Eq to Cursor) - #67466 (Require const stability attributes on intrinsics to be able to use them in constant contexts) - #67507 (Remove mem::uninitalized from tests) - #67527 (Results show too much) - #67536 (Move `{hir::lowering -> hir}::is_range_literal`) - #67538 (Improve diagnostics for invalid assignment) - #67546 (Fix ICE in mir interpretation) - #67559 (Document that calling Drop, even after it panics, is UB) Failed merges: r? @ghost
2 parents a916ac2 + 68a9a2d commit 9ae6ced

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+619
-369
lines changed

src/libcore/intrinsics.rs

+43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
//! Compiler intrinsics.
22
//!
33
//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
4+
//! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
5+
//!
6+
//! # Const intrinsics
7+
//!
8+
//! Note: any changes to the constness of intrinsics should be discussed with the language team.
9+
//! This includes changes in the stability of the constness.
10+
//!
11+
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
12+
//! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
13+
//! `librustc_mir/interpret/intrinsics.rs` and add a
14+
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
15+
//!
16+
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
17+
//! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
18+
//! without T-lang consulation, because it bakes a feature into the language that cannot be
19+
//! replicated in user code without compiler support.
420
//!
521
//! # Volatiles
622
//!
@@ -671,14 +687,17 @@ extern "rust-intrinsic" {
671687
///
672688
/// The stabilized version of this intrinsic is
673689
/// [`std::mem::size_of`](../../std/mem/fn.size_of.html).
690+
#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
674691
pub fn size_of<T>() -> usize;
675692

676693
/// Moves a value to an uninitialized memory location.
677694
///
678695
/// Drop glue is not run on the destination.
679696
pub fn move_val_init<T>(dst: *mut T, src: T);
680697

698+
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
681699
pub fn min_align_of<T>() -> usize;
700+
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "0")]
682701
pub fn pref_align_of<T>() -> usize;
683702

684703
/// The size of the referenced value in bytes.
@@ -689,18 +708,21 @@ extern "rust-intrinsic" {
689708
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
690709

691710
/// Gets a static string slice containing the name of a type.
711+
#[rustc_const_unstable(feature = "const_type_name", issue = "0")]
692712
pub fn type_name<T: ?Sized>() -> &'static str;
693713

694714
/// Gets an identifier which is globally unique to the specified type. This
695715
/// function will return the same value for a type regardless of whichever
696716
/// crate it is invoked in.
717+
#[rustc_const_unstable(feature = "const_type_id", issue = "0")]
697718
pub fn type_id<T: ?Sized + 'static>() -> u64;
698719

699720
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
700721
/// This will statically either panic, or do nothing.
701722
pub fn panic_if_uninhabited<T>();
702723

703724
/// Gets a reference to a static `Location` indicating where it was called.
725+
#[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
704726
pub fn caller_location() -> &'static crate::panic::Location<'static>;
705727

706728
/// Creates a value initialized to zero.
@@ -957,6 +979,7 @@ extern "rust-intrinsic" {
957979
///
958980
/// The stabilized version of this intrinsic is
959981
/// [`std::mem::needs_drop`](../../std/mem/fn.needs_drop.html).
982+
#[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
960983
pub fn needs_drop<T>() -> bool;
961984

962985
/// Calculates the offset from a pointer.
@@ -1154,6 +1177,7 @@ extern "rust-intrinsic" {
11541177
pub fn float_to_int_approx_unchecked<Float, Int>(value: Float) -> Int;
11551178

11561179
/// Returns the number of bits set in an integer type `T`
1180+
#[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
11571181
pub fn ctpop<T>(x: T) -> T;
11581182

11591183
/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
@@ -1181,6 +1205,7 @@ extern "rust-intrinsic" {
11811205
/// let num_leading = ctlz(x);
11821206
/// assert_eq!(num_leading, 16);
11831207
/// ```
1208+
#[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
11841209
pub fn ctlz<T>(x: T) -> T;
11851210

11861211
/// Like `ctlz`, but extra-unsafe as it returns `undef` when
@@ -1197,6 +1222,7 @@ extern "rust-intrinsic" {
11971222
/// let num_leading = unsafe { ctlz_nonzero(x) };
11981223
/// assert_eq!(num_leading, 3);
11991224
/// ```
1225+
#[rustc_const_unstable(feature = "constctlz", issue = "0")]
12001226
pub fn ctlz_nonzero<T>(x: T) -> T;
12011227

12021228
/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
@@ -1224,6 +1250,7 @@ extern "rust-intrinsic" {
12241250
/// let num_trailing = cttz(x);
12251251
/// assert_eq!(num_trailing, 16);
12261252
/// ```
1253+
#[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
12271254
pub fn cttz<T>(x: T) -> T;
12281255

12291256
/// Like `cttz`, but extra-unsafe as it returns `undef` when
@@ -1240,30 +1267,36 @@ extern "rust-intrinsic" {
12401267
/// let num_trailing = unsafe { cttz_nonzero(x) };
12411268
/// assert_eq!(num_trailing, 3);
12421269
/// ```
1270+
#[rustc_const_unstable(feature = "const_cttz", issue = "0")]
12431271
pub fn cttz_nonzero<T>(x: T) -> T;
12441272

12451273
/// Reverses the bytes in an integer type `T`.
1274+
#[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
12461275
pub fn bswap<T>(x: T) -> T;
12471276

12481277
/// Reverses the bits in an integer type `T`.
1278+
#[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
12491279
pub fn bitreverse<T>(x: T) -> T;
12501280

12511281
/// Performs checked integer addition.
12521282
/// The stabilized versions of this intrinsic are available on the integer
12531283
/// primitives via the `overflowing_add` method. For example,
12541284
/// [`std::u32::overflowing_add`](../../std/primitive.u32.html#method.overflowing_add)
1285+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12551286
pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
12561287

12571288
/// Performs checked integer subtraction
12581289
/// The stabilized versions of this intrinsic are available on the integer
12591290
/// primitives via the `overflowing_sub` method. For example,
12601291
/// [`std::u32::overflowing_sub`](../../std/primitive.u32.html#method.overflowing_sub)
1292+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12611293
pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool);
12621294

12631295
/// Performs checked integer multiplication
12641296
/// The stabilized versions of this intrinsic are available on the integer
12651297
/// primitives via the `overflowing_mul` method. For example,
12661298
/// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
1299+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12671300
pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);
12681301

12691302
/// Performs an exact division, resulting in undefined behavior where
@@ -1279,9 +1312,11 @@ extern "rust-intrinsic" {
12791312

12801313
/// Performs an unchecked left shift, resulting in undefined behavior when
12811314
/// y < 0 or y >= N, where N is the width of T in bits.
1315+
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
12821316
pub fn unchecked_shl<T>(x: T, y: T) -> T;
12831317
/// Performs an unchecked right shift, resulting in undefined behavior when
12841318
/// y < 0 or y >= N, where N is the width of T in bits.
1319+
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
12851320
pub fn unchecked_shr<T>(x: T, y: T) -> T;
12861321

12871322
/// Returns the result of an unchecked addition, resulting in
@@ -1300,39 +1335,46 @@ extern "rust-intrinsic" {
13001335
/// The stabilized versions of this intrinsic are available on the integer
13011336
/// primitives via the `rotate_left` method. For example,
13021337
/// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
1338+
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
13031339
pub fn rotate_left<T>(x: T, y: T) -> T;
13041340

13051341
/// Performs rotate right.
13061342
/// The stabilized versions of this intrinsic are available on the integer
13071343
/// primitives via the `rotate_right` method. For example,
13081344
/// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
1345+
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
13091346
pub fn rotate_right<T>(x: T, y: T) -> T;
13101347

13111348
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
13121349
/// The stabilized versions of this intrinsic are available on the integer
13131350
/// primitives via the `wrapping_add` method. For example,
13141351
/// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
1352+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13151353
pub fn wrapping_add<T>(a: T, b: T) -> T;
13161354
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
13171355
/// The stabilized versions of this intrinsic are available on the integer
13181356
/// primitives via the `wrapping_sub` method. For example,
13191357
/// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
1358+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13201359
pub fn wrapping_sub<T>(a: T, b: T) -> T;
13211360
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
13221361
/// The stabilized versions of this intrinsic are available on the integer
13231362
/// primitives via the `wrapping_mul` method. For example,
13241363
/// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
1364+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13251365
pub fn wrapping_mul<T>(a: T, b: T) -> T;
13261366

13271367
/// Computes `a + b`, while saturating at numeric bounds.
13281368
/// The stabilized versions of this intrinsic are available on the integer
13291369
/// primitives via the `saturating_add` method. For example,
13301370
/// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
1371+
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
13311372
pub fn saturating_add<T>(a: T, b: T) -> T;
13321373
/// Computes `a - b`, while saturating at numeric bounds.
13331374
/// The stabilized versions of this intrinsic are available on the integer
13341375
/// primitives via the `saturating_sub` method. For example,
13351376
/// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
1377+
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
13361378
pub fn saturating_sub<T>(a: T, b: T) -> T;
13371379

13381380
/// Returns the value of the discriminant for the variant in 'v',
@@ -1354,6 +1396,7 @@ extern "rust-intrinsic" {
13541396
pub fn nontemporal_store<T>(ptr: *mut T, val: T);
13551397

13561398
/// See documentation of `<*const T>::offset_from` for details.
1399+
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "0")]
13571400
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
13581401

13591402
/// Internal hook used by Miri to implement unwinding.

src/libcore/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@
127127
#![feature(maybe_uninit_slice)]
128128
#![feature(external_doc)]
129129
#![feature(associated_type_bounds)]
130+
#![feature(const_type_id)]
131+
#![feature(const_caller_location)]
130132

131133
#[prelude_import]
132134
#[allow(unused)]

src/libcore/macros/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// the `caller_location` intrinsic, but once `#[track_caller]` is implemented,
66
// `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
77
core_intrinsics,
8+
const_caller_location,
89
)]
910
#[stable(feature = "core", since = "1.6.0")]
1011
macro_rules! panic {

src/libcore/ops/drop.rs

+6
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,15 @@ pub trait Drop {
9999
/// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
100100
/// in a `drop` implementation will likely abort.
101101
///
102+
/// Note that even if this panics, the value is considered to be dropped;
103+
/// you must not cause `drop` to be called again. This is normally automatically
104+
/// handled by the compiler, but when using unsafe code, can sometimes occur
105+
/// unintentionally, particularly when using [`std::ptr::drop_in_place`].
106+
///
102107
/// [E0040]: ../../error-index.html#E0040
103108
/// [`panic!`]: ../macro.panic.html
104109
/// [`std::mem::drop`]: ../../std/mem/fn.drop.html
110+
/// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html
105111
#[stable(feature = "rust1", since = "1.0.0")]
106112
fn drop(&mut self);
107113
}

src/librustc/hir/intravisit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1043,9 +1043,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
10431043
walk_list!(visitor, visit_label, opt_label);
10441044
visitor.visit_block(block);
10451045
}
1046-
ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => {
1047-
visitor.visit_expr(right_hand_expression);
1048-
visitor.visit_expr(left_hand_expression)
1046+
ExprKind::Assign(ref lhs, ref rhs, _) => {
1047+
visitor.visit_expr(rhs);
1048+
visitor.visit_expr(lhs)
10491049
}
10501050
ExprKind::AssignOp(_, ref left_expression, ref right_expression) => {
10511051
visitor.visit_expr(right_expression);

src/librustc/hir/lowering.rs

-62
Original file line numberDiff line numberDiff line change
@@ -3437,65 +3437,3 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body<'hir>>) -> Vec<hir::BodyId>
34373437
body_ids.sort_by_key(|b| bodies[b].value.span);
34383438
body_ids
34393439
}
3440-
3441-
/// Checks if the specified expression is a built-in range literal.
3442-
/// (See: `LoweringContext::lower_expr()`).
3443-
pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
3444-
use hir::{Path, QPath, ExprKind, TyKind};
3445-
3446-
// Returns whether the given path represents a (desugared) range,
3447-
// either in std or core, i.e. has either a `::std::ops::Range` or
3448-
// `::core::ops::Range` prefix.
3449-
fn is_range_path(path: &Path) -> bool {
3450-
let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.to_string()).collect();
3451-
let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
3452-
3453-
// "{{root}}" is the equivalent of `::` prefix in `Path`.
3454-
if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
3455-
(*std_core == "std" || *std_core == "core") && range.starts_with("Range")
3456-
} else {
3457-
false
3458-
}
3459-
};
3460-
3461-
// Check whether a span corresponding to a range expression is a
3462-
// range literal, rather than an explicit struct or `new()` call.
3463-
fn is_lit(sess: &Session, span: &Span) -> bool {
3464-
let source_map = sess.source_map();
3465-
let end_point = source_map.end_point(*span);
3466-
3467-
if let Ok(end_string) = source_map.span_to_snippet(end_point) {
3468-
!(end_string.ends_with("}") || end_string.ends_with(")"))
3469-
} else {
3470-
false
3471-
}
3472-
};
3473-
3474-
match expr.kind {
3475-
// All built-in range literals but `..=` and `..` desugar to `Struct`s.
3476-
ExprKind::Struct(ref qpath, _, _) => {
3477-
if let QPath::Resolved(None, ref path) = **qpath {
3478-
return is_range_path(&path) && is_lit(sess, &expr.span);
3479-
}
3480-
}
3481-
3482-
// `..` desugars to its struct path.
3483-
ExprKind::Path(QPath::Resolved(None, ref path)) => {
3484-
return is_range_path(&path) && is_lit(sess, &expr.span);
3485-
}
3486-
3487-
// `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
3488-
ExprKind::Call(ref func, _) => {
3489-
if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.kind {
3490-
if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.kind {
3491-
let new_call = segment.ident.name == sym::new;
3492-
return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
3493-
}
3494-
}
3495-
}
3496-
3497-
_ => {}
3498-
}
3499-
3500-
false
3501-
}

src/librustc/hir/lowering/expr.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ impl LoweringContext<'_, '_> {
122122
self.lower_block(blk, opt_label.is_some()),
123123
self.lower_label(opt_label),
124124
),
125-
ExprKind::Assign(ref el, ref er) => {
126-
hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)))
125+
ExprKind::Assign(ref el, ref er, span) => {
126+
hir::ExprKind::Assign(P(self.lower_expr(el)), P(self.lower_expr(er)), span)
127127
}
128128
ExprKind::AssignOp(op, ref el, ref er) => hir::ExprKind::AssignOp(
129129
self.lower_binop(op),
@@ -994,8 +994,11 @@ impl LoweringContext<'_, '_> {
994994
let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
995995
let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
996996
let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
997-
let assign =
998-
P(self.expr(pat.span, hir::ExprKind::Assign(next_expr, val_expr), ThinVec::new()));
997+
let assign = P(self.expr(
998+
pat.span,
999+
hir::ExprKind::Assign(next_expr, val_expr, pat.span),
1000+
ThinVec::new(),
1001+
));
9991002
let some_pat = self.pat_some(pat.span, val_pat);
10001003
self.arm(some_pat, assign)
10011004
};

0 commit comments

Comments
 (0)