From 41d5a77ee8fc8dc62a8264b992dfd97dae3be59d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 18 Apr 2020 13:56:38 +0200 Subject: [PATCH 01/10] Miri: mplace_access_checked: offer option to force different alignment on place --- src/librustc_mir/interpret/place.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 0fd930090d56a..24e6833c2b437 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -333,7 +333,7 @@ where let val = self.read_immediate(src)?; trace!("deref to {} on {:?}", val.layout.ty, *val); let place = self.ref_to_mplace(val)?; - self.mplace_access_checked(place) + self.mplace_access_checked(place, None) } /// Check if the given place is good for memory access with the given @@ -361,12 +361,14 @@ where pub fn mplace_access_checked( &self, mut place: MPlaceTy<'tcx, M::PointerTag>, + force_align: Option, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let (size, align) = self .size_and_align_of_mplace(place)? .unwrap_or((place.layout.size, place.layout.align.abi)); assert!(place.mplace.align <= align, "dynamic alignment less strict than static one?"); - place.mplace.align = align; // maximally strict checking + // Check (stricter) dynamic alignment, unless forced otherwise. + place.mplace.align = force_align.unwrap_or(align); // When dereferencing a pointer, it must be non-NULL, aligned, and live. if let Some(ptr) = self.check_mplace_access(place, Some(size))? { place.mplace.ptr = ptr.into(); From 65a985e81e05bef484589fbb45dcee8e8048cda5 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:03:35 -0700 Subject: [PATCH 02/10] Check for `llvm_asm` in a const context --- src/librustc_mir/transform/check_consts/ops.rs | 4 ++++ src/librustc_mir/transform/check_consts/validation.rs | 5 ++++- src/test/ui/consts/inline_asm.rs | 6 ++++++ src/test/ui/consts/inline_asm.stderr | 9 +++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/inline_asm.rs create mode 100644 src/test/ui/consts/inline_asm.stderr diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index b5e62aa20130b..c4b94b70938d3 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -147,6 +147,10 @@ impl NonConstOp for IfOrMatch { } } +#[derive(Debug)] +pub struct InlineAsm; +impl NonConstOp for InlineAsm {} + #[derive(Debug)] pub struct LiveDrop; impl NonConstOp for LiveDrop { diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index cee98e9b299c1..19df6e39e4c24 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -481,11 +481,14 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { self.check_op(ops::IfOrMatch); } + StatementKind::LlvmInlineAsm { .. } => { + self.check_op(ops::InlineAsm); + } + // FIXME(eddyb) should these really do nothing? StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) - | StatementKind::LlvmInlineAsm { .. } | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) | StatementKind::Nop => {} diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs new file mode 100644 index 0000000000000..c2ab97e54f0c8 --- /dev/null +++ b/src/test/ui/consts/inline_asm.rs @@ -0,0 +1,6 @@ +#![feature(llvm_asm)] + +const _: () = unsafe { llvm_asm!("nop") }; +//~^ ERROR contains unimplemented expression type + +fn main() {} diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr new file mode 100644 index 0000000000000..68a78d6175f6b --- /dev/null +++ b/src/test/ui/consts/inline_asm.stderr @@ -0,0 +1,9 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/inline_asm.rs:3:1 + | +LL | const _: () = unsafe { llvm_asm!("nop") }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0019`. From e59000265252667c66ed93c85ff21713ac4d172a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:05:59 -0700 Subject: [PATCH 03/10] Exhaustively match on `StatementKind` during const checking --- src/librustc_mir/transform/check_consts/validation.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 19df6e39e4c24..67110a3aed46d 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -478,15 +478,20 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } => { self.super_statement(statement, location); } - StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _) => { + + StatementKind::FakeRead( + FakeReadCause::ForMatchedPlace + | FakeReadCause::ForMatchGuard + | FakeReadCause::ForGuardBinding, + _, + ) => { self.check_op(ops::IfOrMatch); } StatementKind::LlvmInlineAsm { .. } => { self.check_op(ops::InlineAsm); } - // FIXME(eddyb) should these really do nothing? - StatementKind::FakeRead(..) + StatementKind::FakeRead(FakeReadCause::ForLet | FakeReadCause::ForIndex, _) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag { .. } From d24e39bb910e671e1eab27df0aef37985f58df2a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:06:33 -0700 Subject: [PATCH 04/10] Exhaustively match on `TerminatorKind` during const checking --- .../transform/check_consts/validation.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 67110a3aed46d..d2d5e95a1de99 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -580,7 +580,17 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - _ => {} + TerminatorKind::Abort + | TerminatorKind::Assert { .. } + | TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::GeneratorDrop + | TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Return + | TerminatorKind::SwitchInt { .. } + | TerminatorKind::Unreachable + | TerminatorKind::Yield { .. } => {} } } } From e5b58b089ed94a91581a44d0b6d670f18517ff34 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 16:20:06 -0700 Subject: [PATCH 05/10] Note that some terminators should cause an error --- src/librustc_mir/transform/check_consts/validation.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index d2d5e95a1de99..b1cc7edc77432 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -580,6 +580,8 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } + // FIXME: Some of these are only caught by `min_const_fn`, but should error here + // instead. TerminatorKind::Abort | TerminatorKind::Assert { .. } | TerminatorKind::FalseEdges { .. } From 79543397d70c15991dfc56fb4f89988326d4fcf3 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Sun, 19 Apr 2020 17:53:17 -0700 Subject: [PATCH 06/10] Bless new miri_unleashed test --- src/test/ui/consts/miri_unleashed/inline_asm.rs | 2 +- src/test/ui/consts/miri_unleashed/inline_asm.stderr | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs index f56131025627b..f5be75431bae7 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.rs +++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs @@ -6,7 +6,7 @@ fn main() {} // Make sure we catch executing inline assembly. -static TEST_BAD: () = { +static TEST_BAD: () = { //~ WARN: skipping const checks unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } //~^ ERROR could not evaluate static initializer //~| NOTE in this expansion of llvm_asm! diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.stderr b/src/test/ui/consts/miri_unleashed/inline_asm.stderr index 3cbdd326c8233..ef11c5b1d1ab8 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr +++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr @@ -1,3 +1,14 @@ +warning: skipping const checks + --> $DIR/inline_asm.rs:9:1 + | +LL | / static TEST_BAD: () = { +LL | | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } +LL | | +LL | | +LL | | +LL | | }; + | |__^ + error[E0080]: could not evaluate static initializer --> $DIR/inline_asm.rs:10:14 | @@ -6,6 +17,6 @@ LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0080`. From e5b68bc7193889a5df85ea4ffba84ce20c1f0471 Mon Sep 17 00:00:00 2001 From: pankajchaudhary5 Date: Tue, 21 Apr 2020 09:24:16 +0530 Subject: [PATCH 07/10] Added proper explanation error code E0696 --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0696.md | 49 +++++++++++++++++++ .../label/label_break_value_continue.stderr | 3 +- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0696.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 225ede851b4d9..422e8dfcbff8e 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -386,6 +386,7 @@ E0691: include_str!("./error_codes/E0691.md"), E0692: include_str!("./error_codes/E0692.md"), E0693: include_str!("./error_codes/E0693.md"), E0695: include_str!("./error_codes/E0695.md"), +E0696: include_str!("./error_codes/E0696.md"), E0697: include_str!("./error_codes/E0697.md"), E0698: include_str!("./error_codes/E0698.md"), E0699: include_str!("./error_codes/E0699.md"), @@ -602,7 +603,6 @@ E0751: include_str!("./error_codes/E0751.md"), E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders // E0694, // an unknown tool name found in scoped attributes - E0696, // `continue` pointing to a labeled block // E0702, // replaced with a generic attribute input check // E0707, // multiple elided lifetimes used in arguments of `async fn` // E0709, // multiple different lifetimes used in arguments of `async fn` diff --git a/src/librustc_error_codes/error_codes/E0696.md b/src/librustc_error_codes/error_codes/E0696.md new file mode 100644 index 0000000000000..fc32d1cc5f798 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0696.md @@ -0,0 +1,49 @@ +A function is using `continue` keyword incorrectly. + +Erroneous code example: + +```compile_fail,E0696 +fn continue_simple() { + 'b: { + continue; // error! + } +} +fn continue_labeled() { + 'b: { + continue 'b; // error! + } +} +fn continue_crossing() { + loop { + 'b: { + continue; // error! + } + } +} +``` + +Here we have used the `continue` keyword incorrectly. As we +have seen above that `continue` pointing to a labeled block. + +To fix this we have to use the labeled block properly. +For example: + +``` +fn continue_simple() { + 'b: loop { + continue ; // ok! + } +} +fn continue_labeled() { + 'b: loop { + continue 'b; // ok! + } +} +fn continue_crossing() { + loop { + 'b: loop { + continue; // ok! + } + } +} +``` diff --git a/src/test/ui/label/label_break_value_continue.stderr b/src/test/ui/label/label_break_value_continue.stderr index c5f79ed6333ee..9b8693dc584c4 100644 --- a/src/test/ui/label/label_break_value_continue.stderr +++ b/src/test/ui/label/label_break_value_continue.stderr @@ -21,4 +21,5 @@ LL | continue; error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0695`. +Some errors have detailed explanations: E0695, E0696. +For more information about an error, try `rustc --explain E0695`. From 152c06569b6d785cea2d408c3ebd93aaee09772d Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 21 Apr 2020 09:24:41 -0700 Subject: [PATCH 08/10] Assign correct span to new illegal ops --- .../transform/check_consts/validation.rs | 2 ++ src/test/ui/consts/inline_asm.stderr | 6 ++++-- src/test/ui/consts/miri_unleashed/inline_asm.rs | 4 +++- src/test/ui/consts/miri_unleashed/inline_asm.stderr | 13 +++++-------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index b1cc7edc77432..231b3be89826b 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -485,9 +485,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { | FakeReadCause::ForGuardBinding, _, ) => { + self.super_statement(statement, location); self.check_op(ops::IfOrMatch); } StatementKind::LlvmInlineAsm { .. } => { + self.super_statement(statement, location); self.check_op(ops::InlineAsm); } diff --git a/src/test/ui/consts/inline_asm.stderr b/src/test/ui/consts/inline_asm.stderr index 68a78d6175f6b..0a064c8136651 100644 --- a/src/test/ui/consts/inline_asm.stderr +++ b/src/test/ui/consts/inline_asm.stderr @@ -1,8 +1,10 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/inline_asm.rs:3:1 + --> $DIR/inline_asm.rs:3:24 | LL | const _: () = unsafe { llvm_asm!("nop") }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs index f5be75431bae7..ddc4767b83aa1 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.rs +++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs @@ -6,9 +6,11 @@ fn main() {} // Make sure we catch executing inline assembly. -static TEST_BAD: () = { //~ WARN: skipping const checks +static TEST_BAD: () = { unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } //~^ ERROR could not evaluate static initializer //~| NOTE in this expansion of llvm_asm! //~| NOTE inline assembly is not supported + //~| WARN skipping const checks + //~| NOTE in this expansion of llvm_asm! }; diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.stderr b/src/test/ui/consts/miri_unleashed/inline_asm.stderr index ef11c5b1d1ab8..444a0172621e2 100644 --- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr +++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr @@ -1,13 +1,10 @@ warning: skipping const checks - --> $DIR/inline_asm.rs:9:1 + --> $DIR/inline_asm.rs:10:14 + | +LL | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -LL | / static TEST_BAD: () = { -LL | | unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); } -LL | | -LL | | -LL | | -LL | | }; - | |__^ + = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: could not evaluate static initializer --> $DIR/inline_asm.rs:10:14 From 15ecfe65a8f3aa54ab2af11993de7602c9431082 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 21 Apr 2020 17:11:00 -0300 Subject: [PATCH 09/10] visit_place_base is just visit_local --- src/librustc_codegen_ssa/mir/analyze.rs | 2 +- src/librustc_middle/mir/visit.rs | 18 ++---------------- src/librustc_mir/monomorphize/collector.rs | 2 +- .../transform/check_consts/validation.rs | 9 ++++----- src/librustc_mir/transform/generator.rs | 4 ++-- 5 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 71b9ff26140f9..5ce60b8b3d406 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -204,7 +204,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { }; } - self.visit_place_base(&place_ref.local, context, location); + self.visit_local(&place_ref.local, context, location); self.visit_projection(place_ref.local, place_ref.projection, context, location); } } diff --git a/src/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs index efc12138d3487..6335246053608 100644 --- a/src/librustc_middle/mir/visit.rs +++ b/src/librustc_middle/mir/visit.rs @@ -163,13 +163,6 @@ macro_rules! make_mir_visitor { self.super_place(place, context, location); } - fn visit_place_base(&mut self, - local: & $($mutability)? Local, - context: PlaceContext, - location: Location) { - self.super_place_base(local, context, location); - } - visit_place_fns!($($mutability)?); fn visit_constant(&mut self, @@ -710,13 +703,6 @@ macro_rules! make_mir_visitor { ); } - fn super_place_base(&mut self, - local: & $($mutability)? Local, - context: PlaceContext, - location: Location) { - self.visit_local(local, context, location); - } - fn super_local_decl(&mut self, local: Local, local_decl: & $($mutability)? LocalDecl<'tcx>) { @@ -847,7 +833,7 @@ macro_rules! visit_place_fns { context: PlaceContext, location: Location, ) { - self.visit_place_base(&mut place.local, context, location); + self.visit_local(&mut place.local, context, location); if let Some(new_projection) = self.process_projection(&place.projection, location) { place.projection = self.tcx().intern_place_elems(&new_projection); @@ -936,7 +922,7 @@ macro_rules! visit_place_fns { }; } - self.visit_place_base(&place.local, context, location); + self.visit_local(&place.local, context, location); self.visit_projection(place.local, &place.projection, context, location); } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index ea648ebf34ec2..5c94257c31aa4 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -648,7 +648,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_terminator_kind(kind, location); } - fn visit_place_base( + fn visit_local( &mut self, _place_local: &Local, _context: mir::visit::PlaceContext, diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index cee98e9b299c1..282f37e8fc5cf 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -276,7 +276,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { PlaceContext::MutatingUse(MutatingUseContext::Borrow) } }; - self.visit_place_base(&place.local, ctx, location); + self.visit_local(&place.local, ctx, location); self.visit_projection(place.local, reborrowed_proj, ctx, location); return; } @@ -289,7 +289,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf), }; - self.visit_place_base(&place.local, ctx, location); + self.visit_local(&place.local, ctx, location); self.visit_projection(place.local, reborrowed_proj, ctx, location); return; } @@ -386,14 +386,13 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - fn visit_place_base(&mut self, place_local: &Local, context: PlaceContext, location: Location) { + fn visit_local(&mut self, place_local: &Local, context: PlaceContext, location: Location) { trace!( - "visit_place_base: place_local={:?} context={:?} location={:?}", + "visit_local: place_local={:?} context={:?} location={:?}", place_local, context, location, ); - self.super_place_base(place_local, context, location); } fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 4492895104526..257b6b4a5cfae 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -115,7 +115,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { self.tcx, ); } else { - self.visit_place_base(&mut place.local, context, location); + self.visit_local(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { @@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { self.tcx, ); } else { - self.visit_place_base(&mut place.local, context, location); + self.visit_local(&mut place.local, context, location); for elem in place.projection.iter() { if let PlaceElem::Index(local) = elem { From 5449e0f10f84bdf964c5d38e03f11ae2190e94d1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 22 Apr 2020 12:58:17 +0200 Subject: [PATCH 10/10] comment explaining force_align usage --- src/librustc_mir/interpret/place.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 24e6833c2b437..ddfd6ae0b8a28 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -358,6 +358,9 @@ where /// Return the "access-checked" version of this `MPlace`, where for non-ZST /// this is definitely a `Pointer`. + /// + /// `force_align` must only be used when correct alignment does not matter, + /// like in Stacked Borrows. pub fn mplace_access_checked( &self, mut place: MPlaceTy<'tcx, M::PointerTag>,