about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-22 17:52:21 +0000
committerbors <bors@rust-lang.org>2020-04-22 17:52:21 +0000
commitb2e36e6c2d229126b59e892c9147fbb68115d292 (patch)
tree19503bd32ce13ba6ec09ad004898782b0bc0d0dd
parent82e90d64266b8a4b53935d629786e69610b33f25 (diff)
parent238e8228d4f78425231113b8a8368abd0d01e9a7 (diff)
downloadrust-b2e36e6c2d229126b59e892c9147fbb68115d292.tar.gz
rust-b2e36e6c2d229126b59e892c9147fbb68115d292.zip
Auto merge of #71431 - Dylan-DPC:rollup-rvm6tfy, r=Dylan-DPC
Rollup of 4 pull requests

Successful merges:

 - #71280 (Miri: mplace_access_checked: offer option to force different alignment on place)
 - #71336 (Exhaustively match on `{Statement,Terminator}Kind` during const checking)
 - #71370 (Added detailed error code explanation for issue E0696 in Rust compiler.)
 - #71401 (visit_place_base is just visit_local)

Failed merges:

r? @ghost
-rw-r--r--src/librustc_codegen_ssa/mir/analyze.rs2
-rw-r--r--src/librustc_error_codes/error_codes.rs2
-rw-r--r--src/librustc_error_codes/error_codes/E0696.md49
-rw-r--r--src/librustc_middle/mir/visit.rs18
-rw-r--r--src/librustc_mir/interpret/place.rs9
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_mir/transform/check_consts/ops.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/validation.rs41
-rw-r--r--src/librustc_mir/transform/generator.rs4
-rw-r--r--src/test/ui/consts/inline_asm.rs6
-rw-r--r--src/test/ui/consts/inline_asm.stderr11
-rw-r--r--src/test/ui/consts/miri_unleashed/inline_asm.rs2
-rw-r--r--src/test/ui/consts/miri_unleashed/inline_asm.stderr10
-rw-r--r--src/test/ui/label/label_break_value_continue.stderr3
14 files changed, 128 insertions, 35 deletions
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index 71b9ff26140..5ce60b8b3d4 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -204,7 +204,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> 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_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs
index 9f4b5fd85fd..bf4a6c52ab8 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"),
@@ -604,7 +605,6 @@ E0753: include_str!("./error_codes/E0753.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 00000000000..fc32d1cc5f7
--- /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/librustc_middle/mir/visit.rs b/src/librustc_middle/mir/visit.rs
index efc12138d34..63352460536 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/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index af3a9da2f6c..348958ee6c5 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
@@ -358,15 +358,20 @@ 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>,
+        force_align: Option<Align>,
     ) -> 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();
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 7e63d8637be..129dfe98e5e 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/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs
index b5e62aa2013..c4b94b70938 100644
--- a/src/librustc_mir/transform/check_consts/ops.rs
+++ b/src/librustc_mir/transform/check_consts/ops.rs
@@ -148,6 +148,10 @@ impl NonConstOp for IfOrMatch {
 }
 
 #[derive(Debug)]
+pub struct InlineAsm;
+impl NonConstOp for InlineAsm {}
+
+#[derive(Debug)]
 pub struct LiveDrop;
 impl NonConstOp for LiveDrop {
     fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index c51136cdaba..1a0f875191b 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) {
@@ -478,14 +477,24 @@ 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.super_statement(statement, location);
                 self.check_op(ops::IfOrMatch);
             }
-            // FIXME(eddyb) should these really do nothing?
-            StatementKind::FakeRead(..)
+            StatementKind::LlvmInlineAsm { .. } => {
+                self.super_statement(statement, location);
+                self.check_op(ops::InlineAsm);
+            }
+
+            StatementKind::FakeRead(FakeReadCause::ForLet | FakeReadCause::ForIndex, _)
             | StatementKind::StorageLive(_)
             | StatementKind::StorageDead(_)
-            | StatementKind::LlvmInlineAsm { .. }
             | StatementKind::Retag { .. }
             | StatementKind::AscribeUserType(..)
             | StatementKind::Nop => {}
@@ -572,7 +581,19 @@ 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 { .. }
+            | TerminatorKind::FalseUnwind { .. }
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::Goto { .. }
+            | TerminatorKind::Resume
+            | TerminatorKind::Return
+            | TerminatorKind::SwitchInt { .. }
+            | TerminatorKind::Unreachable
+            | TerminatorKind::Yield { .. } => {}
         }
     }
 }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 44928951045..257b6b4a5cf 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 {
diff --git a/src/test/ui/consts/inline_asm.rs b/src/test/ui/consts/inline_asm.rs
new file mode 100644
index 00000000000..c2ab97e54f0
--- /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 00000000000..0a064c81366
--- /dev/null
+++ b/src/test/ui/consts/inline_asm.stderr
@@ -0,0 +1,11 @@
+error[E0019]: constant contains unimplemented expression type
+  --> $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
+
+For more information about this error, try `rustc --explain E0019`.
diff --git a/src/test/ui/consts/miri_unleashed/inline_asm.rs b/src/test/ui/consts/miri_unleashed/inline_asm.rs
index f5613102562..ddc4767b83a 100644
--- a/src/test/ui/consts/miri_unleashed/inline_asm.rs
+++ b/src/test/ui/consts/miri_unleashed/inline_asm.rs
@@ -11,4 +11,6 @@ static TEST_BAD: () = {
     //~^ 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 3cbdd326c82..444a0172621 100644
--- a/src/test/ui/consts/miri_unleashed/inline_asm.stderr
+++ b/src/test/ui/consts/miri_unleashed/inline_asm.stderr
@@ -1,3 +1,11 @@
+warning: skipping const checks
+  --> $DIR/inline_asm.rs:10:14
+   |
+LL |     unsafe { llvm_asm!("xor %eax, %eax" ::: "eax"); }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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
    |
@@ -6,6 +14,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`.
diff --git a/src/test/ui/label/label_break_value_continue.stderr b/src/test/ui/label/label_break_value_continue.stderr
index c5f79ed6333..9b8693dc584 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`.