From be758ef5ab570b7685c9a5eecacab65911da9e6f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 18 Oct 2022 18:41:14 +0000 Subject: [PATCH 1/9] Add ui test. --- tests/ui/binding/issue-53114-safety-checks.rs | 14 ++++ .../binding/issue-53114-safety-checks.stderr | 64 +++++++++++++++++-- tests/ui/borrowck/let_underscore_temporary.rs | 27 ++++++++ .../ui/unsafe/unsafe-fn-deref-ptr.mir.stderr | 12 +++- tests/ui/unsafe/unsafe-fn-deref-ptr.rs | 2 + .../ui/unsafe/unsafe-fn-deref-ptr.thir.stderr | 20 +++++- 6 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 tests/ui/borrowck/let_underscore_temporary.rs diff --git a/tests/ui/binding/issue-53114-safety-checks.rs b/tests/ui/binding/issue-53114-safety-checks.rs index e234db516c7da..e646dfba3e027 100644 --- a/tests/ui/binding/issue-53114-safety-checks.rs +++ b/tests/ui/binding/issue-53114-safety-checks.rs @@ -30,6 +30,20 @@ fn let_wild_gets_unsafe_field() { let (_,) = (&u2.a,); //~ ERROR [E0133] } +fn let_ascribe_gets_unsafe_field() { + let u1 = U { a: I(0) }; + let u2 = U { a: I(1) }; + let p = P { a: &2, b: &3 }; + let _: _ = &p.b; //~ ERROR reference to packed field + let _: _ = u1.a; //~ ERROR [E0133] + let _: _ = &u2.a; //~ ERROR [E0133] + + // variation on above with `_` in substructure + let (_,): _ = (&p.b,); //~ ERROR reference to packed field + let (_,): _ = (u1.a,); //~ ERROR [E0133] + let (_,): _ = (&u2.a,); //~ ERROR [E0133] +} + fn match_unsafe_field_to_wild() { let u1 = U { a: I(0) }; let u2 = U { a: I(1) }; diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index 5c9d787724778..0760e04490ca9 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -17,7 +17,25 @@ LL | let (_,) = (&p.b,); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:37:11 + --> $DIR/issue-53114-safety-checks.rs:37:16 + | +LL | let _: _ = &p.b; + | ^^^^ + | + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:42:20 + | +LL | let (_,): _ = (&p.b,); + | ^^^^ + | + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/issue-53114-safety-checks.rs:51:11 | LL | match &p.b { _ => { } } | ^^^^ @@ -26,7 +44,7 @@ LL | match &p.b { _ => { } } = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:42:12 + --> $DIR/issue-53114-safety-checks.rs:56:12 | LL | match (&p.b,) { (_,) => { } } | ^^^^ @@ -59,7 +77,39 @@ LL | let (_,) = (&u2.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:38:11 + --> $DIR/issue-53114-safety-checks.rs:38:12 + | +LL | let _: _ = u1.a; + | ^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:39:16 + | +LL | let _: _ = &u2.a; + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:43:20 + | +LL | let (_,): _ = (u1.a,); + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:44:20 + | +LL | let (_,): _ = (&u2.a,); + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:52:11 | LL | match u1.a { _ => { } } | ^^^^ access to union field @@ -67,7 +117,7 @@ LL | match u1.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:39:11 + --> $DIR/issue-53114-safety-checks.rs:53:11 | LL | match &u2.a { _ => { } } | ^^^^^ access to union field @@ -75,7 +125,7 @@ LL | match &u2.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:43:12 + --> $DIR/issue-53114-safety-checks.rs:57:12 | LL | match (u1.a,) { (_,) => { } } | ^^^^ access to union field @@ -83,14 +133,14 @@ LL | match (u1.a,) { (_,) => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:44:12 + --> $DIR/issue-53114-safety-checks.rs:58:12 | LL | match (&u2.a,) { (_,) => { } } | ^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 11 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0133, E0793. For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs new file mode 100644 index 0000000000000..37b5c5d9d7ac5 --- /dev/null +++ b/tests/ui/borrowck/let_underscore_temporary.rs @@ -0,0 +1,27 @@ +// check-pass + +fn let_underscore(string: &Option<&str>, mut num: Option) { + let _ = if let Some(s) = *string { s.len() } else { 0 }; + let _ = if let Some(s) = &num { s } else { &0 }; + let _ = if let Some(s) = &mut num { + *s += 1; + s + } else { + &mut 0 + }; + let _ = if let Some(ref s) = num { s } else { &0 }; + let _ = if let Some(mut s) = num { + s += 1; + s + } else { + 0 + }; + let _ = if let Some(ref mut s) = num { + *s += 1; + s + } else { + &mut 0 + }; +} + +fn main() {} diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr index a26149924458c..62b8710a733d7 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr @@ -1,11 +1,19 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:5:12 + --> $DIR/unsafe-fn-deref-ptr.rs:6:12 + | +LL | let _: u8 = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:7:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs index dc989535bd650..72c881061c489 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -2,6 +2,8 @@ // [thir]compile-flags: -Z thir-unsafeck fn f(p: *const u8) -> u8 { + let _ = *p; //[thir]~ ERROR dereference of raw pointer is unsafe + let _: u8 = *p; //~ ERROR dereference of raw pointer is unsafe return *p; //~ ERROR dereference of raw pointer is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr index a26149924458c..24313352a41e0 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr @@ -1,11 +1,27 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:5:12 + --> $DIR/unsafe-fn-deref-ptr.rs:5:13 + | +LL | let _ = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:6:17 + | +LL | let _: u8 = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:7:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`. From 4462bb54e3bbff7eecae1816836f306fcc309e05 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 6 Sep 2022 18:41:01 +0200 Subject: [PATCH 2/9] Introduce a no-op PlaceMention statement for `let _ =`. --- compiler/rustc_borrowck/src/dataflow.rs | 1 + compiler/rustc_borrowck/src/def_use.rs | 2 +- compiler/rustc_borrowck/src/invalidation.rs | 2 + compiler/rustc_borrowck/src/lib.rs | 2 + compiler/rustc_borrowck/src/type_check/mod.rs | 5 ++- compiler/rustc_codegen_cranelift/src/base.rs | 1 + .../rustc_codegen_cranelift/src/constant.rs | 1 + .../rustc_codegen_ssa/src/mir/statement.rs | 1 + .../rustc_const_eval/src/interpret/step.rs | 2 +- .../src/transform/check_consts/check.rs | 1 + .../src/transform/validate.rs | 8 ++++ compiler/rustc_middle/src/mir/mod.rs | 3 ++ compiler/rustc_middle/src/mir/spanview.rs | 1 + compiler/rustc_middle/src/mir/syntax.rs | 9 +++++ compiler/rustc_middle/src/mir/visit.rs | 9 +++++ compiler/rustc_mir_build/src/build/cfg.rs | 11 ++++++ .../rustc_mir_build/src/build/matches/mod.rs | 7 ++++ .../rustc_mir_dataflow/src/impls/liveness.rs | 1 + .../src/impls/storage_liveness.rs | 1 + .../src/move_paths/builder.rs | 1 + .../rustc_mir_dataflow/src/value_analysis.rs | 1 + .../rustc_mir_transform/src/check_unsafety.rs | 1 + .../src/cleanup_post_borrowck.rs | 1 + .../rustc_mir_transform/src/coverage/spans.rs | 1 + .../src/dead_store_elimination.rs | 4 +- compiler/rustc_mir_transform/src/dest_prop.rs | 1 + compiler/rustc_mir_transform/src/generator.rs | 1 + .../src/remove_noop_landing_pads.rs | 1 + .../src/separate_const_switch.rs | 2 + compiler/rustc_mir_transform/src/simplify.rs | 1 + .../clippy_utils/src/qualify_min_const_fn.rs | 1 + ...se_edges.full_tested_match.built.after.mir | 1 + ...e_edges.full_tested_match2.built.after.mir | 1 + .../match_false_edges.main.built.after.mir | 1 + ...e_out.move_out_by_subslice.built.after.mir | 1 + ...move_out.move_out_from_end.built.after.mir | 1 + .../mir-opt/issue_72181.main.built.after.mir | 2 + tests/mir-opt/issue_91633.bar.built.after.mir | 1 + tests/mir-opt/issue_91633.hey.built.after.mir | 1 + tests/ui/binding/issue-53114-safety-checks.rs | 3 +- .../binding/issue-53114-safety-checks.stderr | 38 +++++++++++++------ .../ui/unsafe/unsafe-fn-deref-ptr.mir.stderr | 20 +++++++++- tests/ui/unsafe/unsafe-fn-deref-ptr.rs | 3 +- .../ui/unsafe/unsafe-fn-deref-ptr.thir.stderr | 2 +- 44 files changed, 139 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index d2574aa58c289..0762987e22961 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -390,6 +390,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> { | mir::StatementKind::Deinit(..) | mir::StatementKind::StorageLive(..) | mir::StatementKind::Retag { .. } + | mir::StatementKind::PlaceMention(..) | mir::StatementKind::AscribeUserType(..) | mir::StatementKind::Coverage(..) | mir::StatementKind::Intrinsic(..) diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 8e62a0198be46..c67411c47843d 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -73,7 +73,7 @@ pub fn categorize(context: PlaceContext) -> Option { Some(DefUse::Drop), // Debug info is neither def nor use. - PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, + PlaceContext::NonUse(NonUseContext::PlaceMention | NonUseContext::VarDebugInfo) => None, PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => { bug!("These statements are not allowed in this MIR phase") diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 1006a047cce09..a71c416328611 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -79,6 +79,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } // Only relevant for mir typeck StatementKind::AscribeUserType(..) + // Only relevant for unsafeck + | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) // Does not actually affect borrowck diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 92acd7555095e..f84a4691d32ab 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -690,6 +690,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } // Only relevant for mir typeck StatementKind::AscribeUserType(..) + // Only relevant for unsafeck + | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) // These do not actually affect borrowck diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d85e058bb208f..3919c4793a06f 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -772,7 +772,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match context { PlaceContext::MutatingUse(_) => ty::Invariant, - PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, + PlaceContext::NonUse(StorageDead | StorageLive | PlaceMention | VarDebugInfo) => { + ty::Invariant + } PlaceContext::NonMutatingUse( Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf | Projection, @@ -1282,6 +1284,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | StatementKind::Retag { .. } | StatementKind::Coverage(..) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(..) | StatementKind::Nop => {} StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index cb0e272cedaba..230256ba5aa84 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -819,6 +819,7 @@ fn codegen_stmt<'tcx>( | StatementKind::Nop | StatementKind::FakeRead(..) | StatementKind::Retag { .. } + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) => {} StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 1930db72ead44..efdf9f6d5bc02 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -529,6 +529,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter | StatementKind::Nop => {} diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 60fbceb344d88..41f585f7fccc1 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -92,6 +92,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | mir::StatementKind::Retag { .. } | mir::StatementKind::AscribeUserType(..) | mir::StatementKind::ConstEvalCounter + | mir::StatementKind::PlaceMention(..) | mir::StatementKind::Nop => {} } } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 6863435e50878..9a366364e769e 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -114,7 +114,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, // Statements we do not track. - AscribeUserType(..) => {} + PlaceMention(..) | AscribeUserType(..) => {} // Currently, Miri discards Coverage statements. Coverage statements are only injected // via an optional compile time MIR pass and have no side effects. Since Coverage diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 656baa784d777..081d9dc8700a4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -690,6 +690,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag { .. } + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 8ecd8f639ddd4..49b1e6d967c70 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -679,6 +679,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + StatementKind::PlaceMention(..) => { + if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { + self.fail( + location, + "`PlaceMention` should have been removed after drop lowering phase", + ); + } + } StatementKind::AscribeUserType(..) => { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 6e6bb8ce95e53..5215e3db798a2 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -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) } diff --git a/compiler/rustc_middle/src/mir/spanview.rs b/compiler/rustc_middle/src/mir/spanview.rs index e52610faf5af7..1a23f9dadd4f4 100644 --- a/compiler/rustc_middle/src/mir/spanview.rs +++ b/compiler/rustc_middle/src/mir/spanview.rs @@ -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", diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 58c060db66003..22046f288c186 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -325,6 +325,15 @@ pub enum StatementKind<'tcx> { /// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted. Retag(RetagKind, Box>), + /// 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>), + /// Encodes a user's type ascription. These need to be preserved /// intact so that NLL can respect them. For example: /// ```ignore (illustrative) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 14b18618aa8d8..cbeacf21c19f0 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -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)] diff --git a/compiler/rustc_mir_build/src/build/cfg.rs b/compiler/rustc_mir_build/src/build/cfg.rs index d7b4b1f731a67..4f1623b4c6a7c 100644 --- a/compiler/rustc_mir_build/src/build/cfg.rs +++ b/compiler/rustc_mir_build/src/build/cfg.rs @@ -90,6 +90,17 @@ impl<'tcx> CFG<'tcx> { self.push(block, stmt); } + pub(crate) fn push_place_mention( + &mut self, + block: BasicBlock, + source_info: SourceInfo, + place: Place<'tcx>, + ) { + let kind = StatementKind::PlaceMention(Box::new(place)); + let stmt = Statement { source_info, kind }; + self.push(block, stmt); + } + pub(crate) fn terminate( &mut self, block: BasicBlock, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index de2851a1af9fd..32892e0ae119c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -556,6 +556,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => { let place_builder = unpack!(block = self.as_place_builder(block, initializer)); + + if let Some(place) = place_builder.try_to_place(self) { + let source_info = self.source_info(initializer.span); + self.cfg.push_place_mention(block, source_info, place); + } + self.place_into_pattern(block, &irrefutable_pat, place_builder, true) } } @@ -576,6 +582,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { false, &mut [&mut candidate], ); + // For matches and function arguments, the place that is being matched // can be set when creating the variables. But the place for // let PATTERN = ... might not even exist until we do the assignment. diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 633a5674f1f96..bc67aa476f1af 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -263,6 +263,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { | StatementKind::StorageDead(_) | StatementKind::Retag(..) | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs index 60fd5169054d3..99988b29e8a57 100644 --- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs @@ -139,6 +139,7 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc // Nothing to do for these. Match exhaustively so this fails to compile when new // variants are added. StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::FakeRead(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index fa62960eee0ff..d9ceac1154f4a 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -329,6 +329,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index b1474a770c59d..7f560d6119428 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -86,6 +86,7 @@ pub trait ValueAnalysis<'tcx> { StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::FakeRead(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::AscribeUserType(..) => (), } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index c61947c566d7c..2d7771ce61c56 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -101,6 +101,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { | StatementKind::StorageDead(..) | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index d435d3ee69b76..0923824db4888 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -24,6 +24,7 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) | StatementKind::FakeRead(..) => statement.make_nop(), _ => (), diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index d9f68f5d93acc..2f1202586594a 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -832,6 +832,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option | StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) | StatementKind::Retag(_, _) + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(_, _) => { Some(statement.source_info.span) } diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 9dbfb089dc665..18c407b42d373 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -56,7 +56,9 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS | StatementKind::ConstEvalCounter | StatementKind::Nop => (), - StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { + StatementKind::FakeRead(_) + | StatementKind::PlaceMention(_) + | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase!", &statement.kind) } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 3823b6201c347..b56cf3a73be04 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -581,6 +581,7 @@ impl WriteInfo { | StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::Coverage(_) + | StatementKind::PlaceMention(_) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => (), StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 129f366bcd0b0..b7f1cdfc7f219 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1647,6 +1647,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { | StatementKind::StorageDead(_) | StatementKind::Retag(..) | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 6c067f4529929..e962819b69177 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -33,6 +33,7 @@ impl RemoveNoopLandingPads { StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) | StatementKind::Coverage(..) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index c3f5b881ab8b2..d76ab95faba96 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -245,6 +245,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData< | StatementKind::StorageLive(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(_) | StatementKind::StorageDead(_) | StatementKind::Intrinsic(_) @@ -315,6 +316,7 @@ fn find_determining_place<'tcx>( | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(_) | StatementKind::Intrinsic(_) | StatementKind::ConstEvalCounter diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 9ef55c558c60b..929d229dcdf8d 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -525,6 +525,7 @@ impl<'tcx> Visitor<'tcx> for UsedLocals { | StatementKind::Retag(..) | StatementKind::Coverage(..) | StatementKind::FakeRead(..) + | StatementKind::PlaceMention(..) | StatementKind::AscribeUserType(..) => { self.super_statement(statement, location); } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index c00800291dbd3..24403e8b6f347 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -241,6 +241,7 @@ fn check_statement<'tcx>( | StatementKind::StorageDead(_) | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::ConstEvalCounter | StatementKind::Nop => Ok(()), diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir index cb36bc64da695..0e6de839df3b2 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir @@ -100,6 +100,7 @@ fn full_tested_match() -> () { } bb11: { + PlaceMention(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:28: +6:2 diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir index 7f8755faac6cf..37e6b1cd4b446 100644 --- a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir @@ -100,6 +100,7 @@ fn full_tested_match2() -> () { } bb11: { + PlaceMention(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +5:6 StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+5:6: +5:7 _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:29: +6:2 diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir index e8b93f4371ecb..7b8983138d2eb 100644 --- a/tests/mir-opt/building/match_false_edges.main.built.after.mir +++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir @@ -162,6 +162,7 @@ fn main() -> () { } bb19: { + PlaceMention(_1); // scope 0 at $DIR/match_false_edges.rs:+1:13: +6:6 StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7 StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:+6:6: +6:7 _0 = const (); // scope 0 at $DIR/match_false_edges.rs:+0:11: +7:2 diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir index 234cd08397739..d80a77fefe508 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir @@ -77,6 +77,7 @@ fn move_out_by_subslice() -> () { bb6: { StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + PlaceMention(_1); // scope 1 at $DIR/uniform_array_move_out.rs:+2:21: +2:22 StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 _12 = move _1[0..2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:10: +2:12 _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:27: +3:2 diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir index 24a189498d347..5f5c18c9f0c38 100644 --- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir +++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir @@ -77,6 +77,7 @@ fn move_out_from_end() -> () { bb6: { StorageDead(_2); // scope 0 at $DIR/uniform_array_move_out.rs:+1:26: +1:27 FakeRead(ForLet(None), _1); // scope 0 at $DIR/uniform_array_move_out.rs:+1:9: +1:10 + PlaceMention(_1); // scope 1 at $DIR/uniform_array_move_out.rs:+2:20: +2:21 StorageLive(_12); // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 _12 = move _1[1 of 2]; // scope 1 at $DIR/uniform_array_move_out.rs:+2:14: +2:16 _0 = const (); // scope 0 at $DIR/uniform_array_move_out.rs:+0:24: +3:2 diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir index e8683692770d1..724e55e17fb3e 100644 --- a/tests/mir-opt/issue_72181.main.built.after.mir +++ b/tests/mir-opt/issue_72181.main.built.after.mir @@ -29,6 +29,7 @@ fn main() -> () { } bb1: { + PlaceMention(_1); // scope 0 at $DIR/issue_72181.rs:+1:13: +1:34 StorageDead(_1); // scope 0 at $DIR/issue_72181.rs:+1:34: +1:35 StorageLive(_2); // scope 1 at $DIR/issue_72181.rs:+3:9: +3:10 StorageLive(_3); // scope 1 at $DIR/issue_72181.rs:+3:14: +3:27 @@ -49,6 +50,7 @@ fn main() -> () { bb2: { _5 = (_2[_6].0: u64); // scope 4 at $DIR/issue_72181.rs:+4:22: +4:28 + PlaceMention(_5); // scope 2 at $DIR/issue_72181.rs:+4:13: +4:30 StorageDead(_6); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31 StorageDead(_5); // scope 2 at $DIR/issue_72181.rs:+4:30: +4:31 _0 = const (); // scope 0 at $DIR/issue_72181.rs:+0:11: +5:2 diff --git a/tests/mir-opt/issue_91633.bar.built.after.mir b/tests/mir-opt/issue_91633.bar.built.after.mir index c3fb90e84024e..760e5a8f90a8f 100644 --- a/tests/mir-opt/issue_91633.bar.built.after.mir +++ b/tests/mir-opt/issue_91633.bar.built.after.mir @@ -20,6 +20,7 @@ fn bar(_1: Box<[T]>) -> () { bb1: { StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+4:18: +4:19 + PlaceMention((*_2)); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:19 StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 drop(_1) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 diff --git a/tests/mir-opt/issue_91633.hey.built.after.mir b/tests/mir-opt/issue_91633.hey.built.after.mir index ccb06dd5983f4..19f0c133e2e53 100644 --- a/tests/mir-opt/issue_91633.hey.built.after.mir +++ b/tests/mir-opt/issue_91633.hey.built.after.mir @@ -23,6 +23,7 @@ fn hey(_1: &[T]) -> () { bb1: { StorageDead(_4); // scope 0 at $DIR/issue_91633.rs:+4:19: +4:20 _2 = &(*_3); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 + PlaceMention(_2); // scope 0 at $DIR/issue_91633.rs:+4:14: +4:20 StorageDead(_2); // scope 0 at $DIR/issue_91633.rs:+4:20: +4:21 _0 = const (); // scope 0 at $DIR/issue_91633.rs:+3:2: +5:3 StorageDead(_3); // scope 0 at $DIR/issue_91633.rs:+5:2: +5:3 diff --git a/tests/ui/binding/issue-53114-safety-checks.rs b/tests/ui/binding/issue-53114-safety-checks.rs index e646dfba3e027..0bffab327821a 100644 --- a/tests/ui/binding/issue-53114-safety-checks.rs +++ b/tests/ui/binding/issue-53114-safety-checks.rs @@ -21,7 +21,7 @@ fn let_wild_gets_unsafe_field() { let u2 = U { a: I(1) }; let p = P { a: &2, b: &3 }; let _ = &p.b; //~ ERROR reference to packed field - let _ = u1.a; // #53114: should eventually signal error as well + let _ = u1.a; //~ ERROR [E0133] let _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure @@ -36,6 +36,7 @@ fn let_ascribe_gets_unsafe_field() { let p = P { a: &2, b: &3 }; let _: _ = &p.b; //~ ERROR reference to packed field let _: _ = u1.a; //~ ERROR [E0133] + //~^ ERROR [E0133] let _: _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index 0760e04490ca9..67902ac7b541e 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -26,7 +26,7 @@ LL | let _: _ = &p.b; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:42:20 + --> $DIR/issue-53114-safety-checks.rs:43:20 | LL | let (_,): _ = (&p.b,); | ^^^^ @@ -35,7 +35,7 @@ LL | let (_,): _ = (&p.b,); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:51:11 + --> $DIR/issue-53114-safety-checks.rs:52:11 | LL | match &p.b { _ => { } } | ^^^^ @@ -44,7 +44,7 @@ LL | match &p.b { _ => { } } = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:56:12 + --> $DIR/issue-53114-safety-checks.rs:57:12 | LL | match (&p.b,) { (_,) => { } } | ^^^^ @@ -52,6 +52,14 @@ LL | match (&p.b,) { (_,) => { } } = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:24:13 + | +LL | let _ = u1.a; + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:25:13 | @@ -76,6 +84,14 @@ LL | let (_,) = (&u2.a,); | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/issue-53114-safety-checks.rs:38:16 + | +LL | let _: _ = u1.a; + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + error[E0133]: access to union field is unsafe and requires unsafe function or block --> $DIR/issue-53114-safety-checks.rs:38:12 | @@ -85,7 +101,7 @@ LL | let _: _ = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:39:16 + --> $DIR/issue-53114-safety-checks.rs:40:16 | LL | let _: _ = &u2.a; | ^^^^^ access to union field @@ -93,7 +109,7 @@ LL | let _: _ = &u2.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:43:20 + --> $DIR/issue-53114-safety-checks.rs:44:20 | LL | let (_,): _ = (u1.a,); | ^^^^ access to union field @@ -101,7 +117,7 @@ LL | let (_,): _ = (u1.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:44:20 + --> $DIR/issue-53114-safety-checks.rs:45:20 | LL | let (_,): _ = (&u2.a,); | ^^^^^ access to union field @@ -109,7 +125,7 @@ LL | let (_,): _ = (&u2.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:52:11 + --> $DIR/issue-53114-safety-checks.rs:53:11 | LL | match u1.a { _ => { } } | ^^^^ access to union field @@ -117,7 +133,7 @@ LL | match u1.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:53:11 + --> $DIR/issue-53114-safety-checks.rs:54:11 | LL | match &u2.a { _ => { } } | ^^^^^ access to union field @@ -125,7 +141,7 @@ LL | match &u2.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:57:12 + --> $DIR/issue-53114-safety-checks.rs:58:12 | LL | match (u1.a,) { (_,) => { } } | ^^^^ access to union field @@ -133,14 +149,14 @@ LL | match (u1.a,) { (_,) => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:58:12 + --> $DIR/issue-53114-safety-checks.rs:59:12 | LL | match (&u2.a,) { (_,) => { } } | ^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 17 previous errors +error: aborting due to 19 previous errors Some errors have detailed explanations: E0133, E0793. For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr index 62b8710a733d7..ba89ad97275d7 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr @@ -1,3 +1,19 @@ +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:5:13 + | +LL | let _ = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:6:17 + | +LL | let _: u8 = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block --> $DIR/unsafe-fn-deref-ptr.rs:6:12 | @@ -7,13 +23,13 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:7:12 + --> $DIR/unsafe-fn-deref-ptr.rs:8:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs index 72c881061c489..e5c16f044b0b2 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -2,8 +2,9 @@ // [thir]compile-flags: -Z thir-unsafeck fn f(p: *const u8) -> u8 { - let _ = *p; //[thir]~ ERROR dereference of raw pointer is unsafe + let _ = *p; //~ ERROR dereference of raw pointer is unsafe let _: u8 = *p; //~ ERROR dereference of raw pointer is unsafe + //[mir]~^ ERROR dereference of raw pointer is unsafe return *p; //~ ERROR dereference of raw pointer is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr index 24313352a41e0..f42a3f0603718 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr @@ -15,7 +15,7 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:7:12 + --> $DIR/unsafe-fn-deref-ptr.rs:8:12 | LL | return *p; | ^^ dereference of raw pointer From e107194b669a9464ff26d59f13ff1499b2a7dc67 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 26 Nov 2022 13:16:47 +0000 Subject: [PATCH 3/9] Ignore AscribeUserType in unsafeck to avoid duplicate diagnostics. --- .../rustc_mir_transform/src/check_unsafety.rs | 4 ++- tests/ui/binding/issue-53114-safety-checks.rs | 1 - .../binding/issue-53114-safety-checks.stderr | 30 +++++++------------ .../ui/unsafe/unsafe-fn-deref-ptr.mir.stderr | 12 ++------ tests/ui/unsafe/unsafe-fn-deref-ptr.rs | 1 - .../ui/unsafe/unsafe-fn-deref-ptr.thir.stderr | 2 +- 6 files changed, 17 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 2d7771ce61c56..61f5586d736a1 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -100,7 +100,6 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) | StatementKind::Retag { .. } - | StatementKind::AscribeUserType(..) | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::Intrinsic(..) @@ -108,6 +107,9 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { | StatementKind::Nop => { // safe (at least as emitted during MIR construction) } + // `AscribeUserType` just exists to help MIR borrowck. It has no semantics, and + // everything is already reported by `PlaceMention`. + StatementKind::AscribeUserType(..) => return, } self.super_statement(statement, location); } diff --git a/tests/ui/binding/issue-53114-safety-checks.rs b/tests/ui/binding/issue-53114-safety-checks.rs index 0bffab327821a..f4be2b482a7e6 100644 --- a/tests/ui/binding/issue-53114-safety-checks.rs +++ b/tests/ui/binding/issue-53114-safety-checks.rs @@ -36,7 +36,6 @@ fn let_ascribe_gets_unsafe_field() { let p = P { a: &2, b: &3 }; let _: _ = &p.b; //~ ERROR reference to packed field let _: _ = u1.a; //~ ERROR [E0133] - //~^ ERROR [E0133] let _: _ = &u2.a; //~ ERROR [E0133] // variation on above with `_` in substructure diff --git a/tests/ui/binding/issue-53114-safety-checks.stderr b/tests/ui/binding/issue-53114-safety-checks.stderr index 67902ac7b541e..41318d0a38a17 100644 --- a/tests/ui/binding/issue-53114-safety-checks.stderr +++ b/tests/ui/binding/issue-53114-safety-checks.stderr @@ -26,7 +26,7 @@ LL | let _: _ = &p.b; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:43:20 + --> $DIR/issue-53114-safety-checks.rs:42:20 | LL | let (_,): _ = (&p.b,); | ^^^^ @@ -35,7 +35,7 @@ LL | let (_,): _ = (&p.b,); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:52:11 + --> $DIR/issue-53114-safety-checks.rs:51:11 | LL | match &p.b { _ => { } } | ^^^^ @@ -44,7 +44,7 @@ LL | match &p.b { _ => { } } = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/issue-53114-safety-checks.rs:57:12 + --> $DIR/issue-53114-safety-checks.rs:56:12 | LL | match (&p.b,) { (_,) => { } } | ^^^^ @@ -93,15 +93,7 @@ LL | let _: _ = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:38:12 - | -LL | let _: _ = u1.a; - | ^ access to union field - | - = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior - -error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:40:16 + --> $DIR/issue-53114-safety-checks.rs:39:16 | LL | let _: _ = &u2.a; | ^^^^^ access to union field @@ -109,7 +101,7 @@ LL | let _: _ = &u2.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:44:20 + --> $DIR/issue-53114-safety-checks.rs:43:20 | LL | let (_,): _ = (u1.a,); | ^^^^ access to union field @@ -117,7 +109,7 @@ LL | let (_,): _ = (u1.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:45:20 + --> $DIR/issue-53114-safety-checks.rs:44:20 | LL | let (_,): _ = (&u2.a,); | ^^^^^ access to union field @@ -125,7 +117,7 @@ LL | let (_,): _ = (&u2.a,); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:53:11 + --> $DIR/issue-53114-safety-checks.rs:52:11 | LL | match u1.a { _ => { } } | ^^^^ access to union field @@ -133,7 +125,7 @@ LL | match u1.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:54:11 + --> $DIR/issue-53114-safety-checks.rs:53:11 | LL | match &u2.a { _ => { } } | ^^^^^ access to union field @@ -141,7 +133,7 @@ LL | match &u2.a { _ => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:58:12 + --> $DIR/issue-53114-safety-checks.rs:57:12 | LL | match (u1.a,) { (_,) => { } } | ^^^^ access to union field @@ -149,14 +141,14 @@ LL | match (u1.a,) { (_,) => { } } = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-53114-safety-checks.rs:59:12 + --> $DIR/issue-53114-safety-checks.rs:58:12 | LL | match (&u2.a,) { (_,) => { } } | ^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 19 previous errors +error: aborting due to 18 previous errors Some errors have detailed explanations: E0133, E0793. For more information about an error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr index ba89ad97275d7..24313352a41e0 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr @@ -15,21 +15,13 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:6:12 - | -LL | let _: u8 = *p; - | ^^ dereference of raw pointer - | - = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior - -error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:8:12 + --> $DIR/unsafe-fn-deref-ptr.rs:7:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs index e5c16f044b0b2..ef8221d05cdb2 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -4,7 +4,6 @@ fn f(p: *const u8) -> u8 { let _ = *p; //~ ERROR dereference of raw pointer is unsafe let _: u8 = *p; //~ ERROR dereference of raw pointer is unsafe - //[mir]~^ ERROR dereference of raw pointer is unsafe return *p; //~ ERROR dereference of raw pointer is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr index f42a3f0603718..24313352a41e0 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr @@ -15,7 +15,7 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:8:12 + --> $DIR/unsafe-fn-deref-ptr.rs:7:12 | LL | return *p; | ^^ dereference of raw pointer From a5ef6bac28af997ff4027aa6deef8b6a250eff7e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 26 Nov 2022 13:34:39 +0000 Subject: [PATCH 4/9] Also test destructuring assignment. --- tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr | 12 ++++++++++-- tests/ui/unsafe/unsafe-fn-deref-ptr.rs | 1 + tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr | 12 ++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr index 24313352a41e0..7f1e7c8902f5d 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.mir.stderr @@ -15,13 +15,21 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:7:12 + --> $DIR/unsafe-fn-deref-ptr.rs:7:9 + | +LL | _ = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:8:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs index ef8221d05cdb2..4b7c6bf698543 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.rs +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.rs @@ -4,6 +4,7 @@ fn f(p: *const u8) -> u8 { let _ = *p; //~ ERROR dereference of raw pointer is unsafe let _: u8 = *p; //~ ERROR dereference of raw pointer is unsafe + _ = *p; //~ ERROR dereference of raw pointer is unsafe return *p; //~ ERROR dereference of raw pointer is unsafe } diff --git a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr index 24313352a41e0..7f1e7c8902f5d 100644 --- a/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr +++ b/tests/ui/unsafe/unsafe-fn-deref-ptr.thir.stderr @@ -15,13 +15,21 @@ LL | let _: u8 = *p; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/unsafe-fn-deref-ptr.rs:7:12 + --> $DIR/unsafe-fn-deref-ptr.rs:7:9 + | +LL | _ = *p; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/unsafe-fn-deref-ptr.rs:8:12 | LL | return *p; | ^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0133`. From b34a8a294d63aa830e0cb76351390d7df0abb40a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Jan 2023 10:20:51 +0000 Subject: [PATCH 5/9] Pacify tidy. --- compiler/rustc_middle/src/mir/syntax.rs | 4 ++-- compiler/rustc_mir_transform/src/check_unsafety.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 22046f288c186..9312e27df378a 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -325,8 +325,8 @@ pub enum StatementKind<'tcx> { /// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted. Retag(RetagKind, Box>), - /// 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 + /// 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. diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 61f5586d736a1..a8ec568eb0d76 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -107,8 +107,8 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { | StatementKind::Nop => { // safe (at least as emitted during MIR construction) } - // `AscribeUserType` just exists to help MIR borrowck. It has no semantics, and - // everything is already reported by `PlaceMention`. + // `AscribeUserType` just exists to help MIR borrowck. + // It has no semantics, and everything is already reported by `PlaceMention`. StatementKind::AscribeUserType(..) => return, } self.super_statement(statement, location); From 45f2a1af3b9a9a489e78085135e28fc432b68b8a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Mar 2023 14:39:05 +0000 Subject: [PATCH 6/9] Document borrowck behaviour. --- compiler/rustc_borrowck/src/def_use.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index c67411c47843d..9e9f0b4b4ad0a 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -72,8 +72,10 @@ pub fn categorize(context: PlaceContext) -> Option { PlaceContext::MutatingUse(MutatingUseContext::Drop) => Some(DefUse::Drop), + // This statement exists to help unsafeck. It does not require the place to be live. + PlaceContext::NonUse(NonUseContext::PlaceMention) => None, // Debug info is neither def nor use. - PlaceContext::NonUse(NonUseContext::PlaceMention | NonUseContext::VarDebugInfo) => None, + PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => { bug!("These statements are not allowed in this MIR phase") From 09dc10c9c2d7a905f3fe966b32d442f2c27128e4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Mar 2023 14:39:19 +0000 Subject: [PATCH 7/9] Bug on PlaceMention in dest-prop. --- compiler/rustc_mir_transform/src/dest_prop.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index b56cf3a73be04..7344ec793ea6a 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -581,10 +581,11 @@ impl WriteInfo { | StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::Coverage(_) - | StatementKind::PlaceMention(_) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => (), - StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { + StatementKind::FakeRead(_) + | StatementKind::AscribeUserType(_, _) + | StatementKind::PlaceMention(_) => { bug!("{:?} not found in this MIR phase", statement) } } From 2eccd52157071599a2659feb4b92e47e0eddb992 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Mar 2023 14:39:39 +0000 Subject: [PATCH 8/9] Test `let _ =` for const_mut_refs. --- .../ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs | 3 +++ .../min_const_fn/min_const_fn_unsafe_bad.stderr | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs index a6e1788bb7f07..df20ff446cda2 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs +++ b/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs @@ -7,4 +7,7 @@ const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x } //~^ dereferencing raw mutable pointers in constant functions +const unsafe fn bad_const_unsafe_deref_raw_underscore(x: *mut usize) { let _ = *x; } +//~^ dereferencing raw mutable pointers in constant functions + fn main() {} diff --git a/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr b/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr index 820b6433f36c5..e68376e7b87f9 100644 --- a/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr +++ b/tests/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr @@ -25,6 +25,15 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error[E0658]: dereferencing raw mutable pointers in constant functions is unstable + --> $DIR/min_const_fn_unsafe_bad.rs:10:80 + | +LL | const unsafe fn bad_const_unsafe_deref_raw_underscore(x: *mut usize) { let _ = *x; } + | ^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0658`. From 684de0418f94622ec8d2a6e7b77ca3f5213790c5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 9 Mar 2023 17:51:38 +0000 Subject: [PATCH 9/9] Update coverage info. --- .../coverage-reports/expected_show_coverage.continue.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-make/coverage-reports/expected_show_coverage.continue.txt b/tests/run-make/coverage-reports/expected_show_coverage.continue.txt index 1c64ead9f2674..bf42924b19118 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.continue.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.continue.txt @@ -65,6 +65,6 @@ 65| | } 66| 0| x = 3; 67| | } - 68| | let _ = x; + 68| 1| let _ = x; 69| 1|}