mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Introduce a no-op PlaceMention statement for let _ =
.
This commit is contained in:
parent
be758ef5ab
commit
4462bb54e3
@ -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(..)
|
||||
|
@ -73,7 +73,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
|
||||
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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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"),
|
||||
|
@ -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 => {}
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(..)
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -325,6 +325,15 @@ pub enum StatementKind<'tcx> {
|
||||
/// Only `RetagKind::Default` and `RetagKind::FnEntry` are permitted.
|
||||
Retag(RetagKind, Box<Place<'tcx>>),
|
||||
|
||||
/// This statement exists to preserve a trace of a scrutinee matched against a wildcard
|
||||
/// binding. This is especially useful for `let _ = PLACE;` bindings that desugar to a single
|
||||
/// `PlaceMention(PLACE)`.
|
||||
///
|
||||
/// When executed at runtime this is a nop.
|
||||
///
|
||||
/// Disallowed after drop elaboration.
|
||||
PlaceMention(Box<Place<'tcx>>),
|
||||
|
||||
/// Encodes a user's type ascription. These need to be preserved
|
||||
/// intact so that NLL can respect them. For example:
|
||||
/// ```ignore (illustrative)
|
||||
|
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -329,6 +329,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||
}
|
||||
StatementKind::Retag { .. }
|
||||
| StatementKind::AscribeUserType(..)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::Coverage(..)
|
||||
| StatementKind::Intrinsic(..)
|
||||
| StatementKind::ConstEvalCounter
|
||||
|
@ -86,6 +86,7 @@ pub trait ValueAnalysis<'tcx> {
|
||||
StatementKind::ConstEvalCounter
|
||||
| StatementKind::Nop
|
||||
| StatementKind::FakeRead(..)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::Coverage(..)
|
||||
| StatementKind::AscribeUserType(..) => (),
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
_ => (),
|
||||
|
@ -832,6 +832,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
|
||||
| StatementKind::SetDiscriminant { .. }
|
||||
| StatementKind::Deinit(..)
|
||||
| StatementKind::Retag(_, _)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::AscribeUserType(_, _) => {
|
||||
Some(statement.source_info.span)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -581,6 +581,7 @@ impl WriteInfo {
|
||||
| StatementKind::ConstEvalCounter
|
||||
| StatementKind::Nop
|
||||
| StatementKind::Coverage(_)
|
||||
| StatementKind::PlaceMention(_)
|
||||
| StatementKind::StorageLive(_)
|
||||
| StatementKind::StorageDead(_) => (),
|
||||
StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => {
|
||||
|
@ -1647,6 +1647,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
|
||||
| StatementKind::StorageDead(_)
|
||||
| StatementKind::Retag(..)
|
||||
| StatementKind::AscribeUserType(..)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::Coverage(..)
|
||||
| StatementKind::Intrinsic(..)
|
||||
| StatementKind::ConstEvalCounter
|
||||
|
@ -33,6 +33,7 @@ impl RemoveNoopLandingPads {
|
||||
StatementKind::FakeRead(..)
|
||||
| StatementKind::StorageLive(_)
|
||||
| StatementKind::StorageDead(_)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::AscribeUserType(..)
|
||||
| StatementKind::Coverage(..)
|
||||
| StatementKind::ConstEvalCounter
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -241,6 +241,7 @@ fn check_statement<'tcx>(
|
||||
| StatementKind::StorageDead(_)
|
||||
| StatementKind::Retag { .. }
|
||||
| StatementKind::AscribeUserType(..)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::Coverage(..)
|
||||
| StatementKind::ConstEvalCounter
|
||||
| StatementKind::Nop => Ok(()),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user