diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 5f35c9fea0a..313ef054829 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -238,7 +238,8 @@ for mir::StatementKind<'gcx> { place.hash_stable(hcx, hasher); rvalue.hash_stable(hcx, hasher); } - mir::StatementKind::ReadForMatch(ref place) => { + mir::StatementKind::FakeRead(ref cause, ref place) => { + cause.hash_stable(hcx, hasher); place.hash_stable(hcx, hasher); } mir::StatementKind::SetDiscriminant { ref place, variant_index } => { @@ -271,6 +272,8 @@ for mir::StatementKind<'gcx> { } } +impl_stable_hash_for!(enum mir::FakeReadCause { ForMatch, ForLet }); + impl<'a, 'gcx, T> HashStable> for mir::ValidationOperand<'gcx, T> where T: HashStable> diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 3450eec8082..8e9c1ad23c8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1613,8 +1613,10 @@ pub enum StatementKind<'tcx> { Assign(Place<'tcx>, Rvalue<'tcx>), /// This represents all the reading that a pattern match may do - /// (e.g. inspecting constants and discriminant values). - ReadForMatch(Place<'tcx>), + /// (e.g. inspecting constants and discriminant values), and the + /// kind of pattern it comes from. This is in order to adapt potential + /// error messages to these specific patterns. + FakeRead(FakeReadCause, Place<'tcx>), /// Write the discriminant for a variant to the enum Place. SetDiscriminant { @@ -1662,6 +1664,13 @@ pub enum StatementKind<'tcx> { Nop, } +/// The `FakeReadCause` describes the type of pattern why a `FakeRead` statement exists. +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum FakeReadCause { + ForMatch, + ForLet, +} + /// The `ValidationOp` describes what happens with each of the operands of a /// `Validate` statement. #[derive(Copy, Clone, RustcEncodable, RustcDecodable, PartialEq, Eq)] @@ -1718,7 +1727,7 @@ impl<'tcx> Debug for Statement<'tcx> { use self::StatementKind::*; match self.kind { Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv), - ReadForMatch(ref place) => write!(fmt, "ReadForMatch({:?})", place), + FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place), // (reuse lifetime rendering policy from ppaux.) EndRegion(ref ce) => write!(fmt, "EndRegion({})", ty::ReScope(*ce)), Validate(ref op, ref places) => write!(fmt, "Validate({:?}, {:?})", op, places), @@ -2585,6 +2594,7 @@ CloneTypeFoldableAndLiftImpls! { Mutability, SourceInfo, UpvarDecl, + FakeReadCause, ValidationOp, SourceScope, SourceScopeData, @@ -2651,7 +2661,7 @@ BraceStructTypeFoldableImpl! { EnumTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> { (StatementKind::Assign)(a, b), - (StatementKind::ReadForMatch)(place), + (StatementKind::FakeRead)(cause, place), (StatementKind::SetDiscriminant) { place, variant_index }, (StatementKind::StorageLive)(a), (StatementKind::StorageDead)(a), diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 0beb5ac0a3c..91c83ecb2e2 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -354,7 +354,7 @@ macro_rules! make_mir_visitor { ref $($mutability)* rvalue) => { self.visit_assign(block, place, rvalue, location); } - StatementKind::ReadForMatch(ref $($mutability)* place) => { + StatementKind::FakeRead(_, ref $($mutability)* place) => { self.visit_place(place, PlaceContext::Inspect, location); diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e4d633c3f2c..1fdbf687be8 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1330,7 +1330,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, disable_nll_user_type_assert: bool = (false, parse_bool, [UNTRACKED], "disable user provided type assertion in NLL"), nll_dont_emit_read_for_match: bool = (false, parse_bool, [UNTRACKED], - "in match codegen, do not include ReadForMatch statements (used by mir-borrowck)"), + "in match codegen, do not include FakeRead statements (used by mir-borrowck)"), dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED], "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting)."), polonius: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 03c0b680acf..aaa0b9fe513 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1478,7 +1478,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.emit_read_for_match() } - /// If true, make MIR codegen for `match` emit ReadForMatch + /// If true, make MIR codegen for `match` emit FakeRead /// statements (which simulate the maximal effect of executing the /// patterns in a match arm). pub fn emit_read_for_match(&self) -> bool { diff --git a/src/librustc_codegen_llvm/mir/statement.rs b/src/librustc_codegen_llvm/mir/statement.rs index 0cb8f99efc3..b4eb7615f98 100644 --- a/src/librustc_codegen_llvm/mir/statement.rs +++ b/src/librustc_codegen_llvm/mir/statement.rs @@ -89,7 +89,7 @@ impl FunctionCx<'a, 'll, 'tcx> { asm::codegen_inline_asm(&bx, asm, outputs, input_vals); bx } - mir::StatementKind::ReadForMatch(_) | + mir::StatementKind::FakeRead(..) | mir::StatementKind::EndRegion(_) | mir::StatementKind::Validate(..) | mir::StatementKind::AscribeUserType(..) | diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 521e7ade00e..478a2326be3 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -478,9 +478,9 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx flow_state, ); } - StatementKind::ReadForMatch(ref place) => { + StatementKind::FakeRead(_, ref place) => { self.access_place( - ContextKind::ReadForMatch.new(location), + ContextKind::FakeRead.new(location), (place, span), (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), LocalMutationIsAllowed::No, @@ -2206,7 +2206,7 @@ enum ContextKind { CallDest, Assert, Yield, - ReadForMatch, + FakeRead, StorageDead, } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 71345f22e44..0b7fededa97 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -93,9 +93,9 @@ impl<'cg, 'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cg, 'cx, 'tc JustWrite ); } - StatementKind::ReadForMatch(ref place) => { + StatementKind::FakeRead(_, ref place) => { self.access_place( - ContextKind::ReadForMatch.new(location), + ContextKind::FakeRead.new(location), place, (Deep, Read(ReadKind::Borrow(BorrowKind::Shared))), LocalMutationIsAllowed::No, diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index de96539ec30..1f12e9c747f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -995,7 +995,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ); } } - StatementKind::ReadForMatch(_) + StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::InlineAsm { .. } diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 5c72679800c..49c1308329f 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -157,7 +157,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { *pre_binding_block, Statement { source_info: pattern_source_info, - kind: StatementKind::ReadForMatch(borrow_temp.clone()), + kind: StatementKind::FakeRead(FakeReadCause::ForMatch, borrow_temp.clone()), }, ); } @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block, Statement { source_info, - kind: StatementKind::ReadForMatch(place.clone()), + kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()), }, ); @@ -336,7 +336,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block, Statement { source_info, - kind: StatementKind::ReadForMatch(place.clone()), + kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()), }, ); diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 010ffafc4bd..ed2f780baf1 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -336,7 +336,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { } } - mir::StatementKind::ReadForMatch(..) | + mir::StatementKind::FakeRead(..) | mir::StatementKind::SetDiscriminant { .. } | mir::StatementKind::StorageLive(..) | mir::StatementKind::Validate(..) | diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 5451d27082d..63adcb5132a 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -281,7 +281,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { } self.gather_rvalue(rval); } - StatementKind::ReadForMatch(ref place) => { + StatementKind::FakeRead(_, ref place) => { self.create_move_path(place); } StatementKind::InlineAsm { ref outputs, ref inputs, ref asm } => { diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 5bdaf6ba729..5db7e0b5eb5 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -150,9 +150,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { self.deallocate_local(old_val)?; } - // No dynamic semantics attached to `ReadForMatch`; MIR + // No dynamic semantics attached to `FakeRead`; MIR // interpreter is solely intended for borrowck'ed code. - ReadForMatch(..) => {} + FakeRead(..) => {} // Validity checks. Validate(op, ref places) => { diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 6fbc2f85c08..286de52bec5 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_info = statement.source_info; match statement.kind { StatementKind::Assign(..) | - StatementKind::ReadForMatch(..) | + StatementKind::FakeRead(..) | StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(..) | StatementKind::StorageDead(..) | diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index bc9cc7274d5..a997bd37c50 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1090,7 +1090,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { StatementKind::Assign(ref place, ref rvalue) => { this.visit_assign(bb, place, rvalue, location); } - StatementKind::ReadForMatch(..) | + StatementKind::FakeRead(..) | StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index f7e44dde186..541b3c0607d 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -216,7 +216,7 @@ fn check_statement( check_rvalue(tcx, mir, rval, span) } - StatementKind::ReadForMatch(_) => Err((span, "match in const fn is unstable".into())), + StatementKind::FakeRead(..) => Err((span, "match in const fn is unstable".into())), // just an assignment StatementKind::SetDiscriminant { .. } => Ok(()), diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 9cdd94a7be7..298e38228d3 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -49,7 +49,7 @@ impl RemoveNoopLandingPads { ) -> bool { for stmt in &mir[bb].statements { match stmt.kind { - StatementKind::ReadForMatch(_) | + StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::EndRegion(_) | diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 3c898eedebc..487a18f6620 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -157,7 +157,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir::StatementKind::Assign(ref place, ref rvalue) => { (place, rvalue) } - mir::StatementKind::ReadForMatch(_) | + mir::StatementKind::FakeRead(..) | mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageDead(_) | mir::StatementKind::InlineAsm { .. } | diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 0120b5bc532..0b9b20d3c45 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -82,7 +82,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { self.record("Statement", statement); self.record(match statement.kind { StatementKind::Assign(..) => "StatementKind::Assign", - StatementKind::ReadForMatch(..) => "StatementKind::ReadForMatch", + StatementKind::FakeRead(..) => "StatementKind::FakeRead", StatementKind::EndRegion(..) => "StatementKind::EndRegion", StatementKind::Validate(..) => "StatementKind::Validate", StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant",