1
Fork 0

Auto merge of #102256 - cjgillot:let-under, r=lcnr

Introduce a no-op `PlaceMention` statement for `let _ =`.

Fixes https://github.com/rust-lang/rust/issues/54003
Fixes https://github.com/rust-lang/rust/issues/80059
Split from https://github.com/rust-lang/rust/pull/101500

This PR introduces a new `PlaceMention` statement dedicated to matches that neither introduce bindings nor ascribe types.  Without this, all traces of the match would vanish from MIR, making it impossible to diagnose unsafety or use in #101500.

This allows to mark `let _ = <unsafe union access or dereference>` as requiring an unsafe block.
Nominating for lang team, as this introduces an extra error.
This commit is contained in:
bors 2023-03-10 11:55:59 +00:00
commit d5833423a0
48 changed files with 271 additions and 19 deletions

View file

@ -1453,6 +1453,9 @@ impl Debug for Statement<'_> {
write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
}
Deinit(ref place) => write!(fmt, "Deinit({:?})", place),
PlaceMention(ref place) => {
write!(fmt, "PlaceMention({:?})", place)
}
AscribeUserType(box (ref place, ref c_ty), ref variance) => {
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
}

View file

@ -247,6 +247,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
StorageLive(..) => "StorageLive",
StorageDead(..) => "StorageDead",
Retag(..) => "Retag",
PlaceMention(..) => "PlaceMention",
AscribeUserType(..) => "AscribeUserType",
Coverage(..) => "Coverage",
Intrinsic(..) => "Intrinsic",

View file

@ -325,6 +325,15 @@ pub enum StatementKind<'tcx> {
/// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
Retag(RetagKind, Box<Place<'tcx>>),
/// This statement exists to preserve a trace of a scrutinee matched against a wildcard binding.
/// This is especially useful for `let _ = PLACE;` bindings that desugar to a single
/// `PlaceMention(PLACE)`.
///
/// When executed at runtime this is a nop.
///
/// Disallowed after drop elaboration.
PlaceMention(Box<Place<'tcx>>),
/// Encodes a user's type ascription. These need to be preserved
/// intact so that NLL can respect them. For example:
/// ```ignore (illustrative)

View file

@ -405,6 +405,13 @@ macro_rules! make_mir_visitor {
StatementKind::Retag(kind, place) => {
self.visit_retag($(& $mutability)? *kind, place, location);
}
StatementKind::PlaceMention(place) => {
self.visit_place(
place,
PlaceContext::NonUse(NonUseContext::PlaceMention),
location
);
}
StatementKind::AscribeUserType(
box (place, user_ty),
variance
@ -1288,6 +1295,8 @@ pub enum NonUseContext {
AscribeUserTy,
/// The data of a user variable, for debug info.
VarDebugInfo,
/// PlaceMention statement.
PlaceMention,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]