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
This commit is contained in:
commit
b2e36e6c2d
14 changed files with 128 additions and 35 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
49
src/librustc_error_codes/error_codes/E0696.md
Normal file
49
src/librustc_error_codes/error_codes/E0696.md
Normal file
|
|
@ -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!
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 { .. } => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
6
src/test/ui/consts/inline_asm.rs
Normal file
6
src/test/ui/consts/inline_asm.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#![feature(llvm_asm)]
|
||||
|
||||
const _: () = unsafe { llvm_asm!("nop") };
|
||||
//~^ ERROR contains unimplemented expression type
|
||||
|
||||
fn main() {}
|
||||
11
src/test/ui/consts/inline_asm.stderr
Normal file
11
src/test/ui/consts/inline_asm.stderr
Normal file
|
|
@ -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`.
|
||||
|
|
@ -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!
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue