From 87025449f223f40e85bb1547cc49dbbc0accba68 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Wed, 15 Jun 2022 17:28:08 +0800 Subject: [PATCH] try out local var id in thir mirroring --- compiler/rustc_middle/src/thir.rs | 29 ++++++----- .../src/build/expr/as_place.rs | 46 ++++++++++++----- .../src/build/expr/as_rvalue.rs | 25 +++++++--- .../rustc_mir_build/src/build/expr/into.rs | 8 +-- .../rustc_mir_build/src/build/matches/mod.rs | 50 ++++++++++++------- .../src/build/matches/simplify.rs | 28 ++++++++--- .../rustc_mir_build/src/build/matches/test.rs | 5 +- .../rustc_mir_build/src/build/matches/util.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 6 ++- compiler/rustc_mir_build/src/thir/cx/expr.rs | 13 +++-- compiler/rustc_mir_build/src/thir/cx/mod.rs | 2 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 22 ++++++-- 12 files changed, 160 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 120d09ee35382..ad19d03f3e452 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -8,6 +8,7 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html +use hir::HirId; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir as hir; use rustc_hir::def::CtorKind; @@ -90,10 +91,16 @@ macro_rules! thir_with_elements { } } +#[derive(HashStable, Debug, Clone)] +pub enum LocalVarInfo { + Hir(HirId), +} + thir_with_elements! { arms: ArmId => Arm<'tcx>, exprs: ExprId => Expr<'tcx>, stmts: StmtId => Stmt<'tcx>, + local_vars: LocalVarId => LocalVarInfo, } #[derive(Copy, Clone, Debug, HashStable)] @@ -191,19 +198,15 @@ pub enum StmtKind<'tcx> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(Expr<'_>, 104); -#[derive( - Clone, - Debug, - Copy, - PartialEq, - Eq, - Hash, - HashStable, - TyEncodable, - TyDecodable, - TypeFoldable -)] -pub struct LocalVarId(pub hir::HirId); +newtype_index! { + /// A THIR-specific index into a registry of variables, + /// either directly derived from HIR IDs of local variables or + /// variables generated while building THIR + #[derive(HashStable)] + pub struct LocalVarId { + DEBUG_FORMAT = "LocalVarId({})" + } +} /// A THIR expression. #[derive(Clone, Debug, HashStable)] diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index e77f5931dd65d..42d9ced0fa843 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -4,6 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::HirId; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; @@ -15,7 +16,7 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance}; use rustc_span::Span; use rustc_target::abi::VariantIdx; -use rustc_index::vec::Idx; +use rustc_index::vec::{Idx, IndexVec}; use std::iter; @@ -150,12 +151,12 @@ fn is_ancestor_or_same_capture( /// `ty::MinCaptureList` of the root variable `var_hir_id`. fn compute_capture_idx<'tcx>( closure_min_captures: &ty::RootVariableMinCaptureList<'tcx>, - var_hir_id: LocalVarId, + var_hir_id: HirId, root_var_idx: usize, ) -> usize { let mut res = 0; for (var_id, capture_list) in closure_min_captures { - if *var_id == var_hir_id.0 { + if *var_id == var_hir_id { res += root_var_idx; break; } else { @@ -175,12 +176,12 @@ fn compute_capture_idx<'tcx>( /// Returns None, when the ancestor is not found. fn find_capture_matching_projections<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, - var_hir_id: LocalVarId, + var_hir_id: HirId, closure_def_id: DefId, projections: &[PlaceElem<'tcx>], ) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> { let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?; - let root_variable_min_captures = closure_min_captures.get(&var_hir_id.0)?; + let root_variable_min_captures = closure_min_captures.get(&var_hir_id)?; let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections); @@ -205,6 +206,7 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>( from_builder: PlaceBuilder<'tcx>, tcx: TyCtxt<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &IndexVec, ) -> Result, PlaceBuilder<'tcx>> { match from_builder.base { PlaceBase::Local(_) => Ok(from_builder), @@ -216,6 +218,9 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>( } ty::ClosureKind::FnOnce => {} } + let var_hir_id = match &local_var_defs[var_hir_id] { + LocalVarInfo::Hir(id) => *id, + }; let Some((capture_index, capture)) = find_capture_matching_projections( @@ -319,11 +324,16 @@ impl<'tcx> PlaceBuilder<'tcx> { self, tcx: TyCtxt<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &IndexVec, ) -> Place<'tcx> { if let PlaceBase::Local(local) = self.base { Place { local, projection: tcx.intern_place_elems(&self.projection) } } else { - self.expect_upvars_resolved(tcx, typeck_results).into_place(tcx, typeck_results) + self.expect_upvars_resolved(tcx, typeck_results, local_var_defs).into_place( + tcx, + typeck_results, + local_var_defs, + ) } } @@ -331,8 +341,9 @@ impl<'tcx> PlaceBuilder<'tcx> { self, tcx: TyCtxt<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &IndexVec, ) -> PlaceBuilder<'tcx> { - to_upvars_resolved_place_builder(self, tcx, typeck_results).unwrap() + to_upvars_resolved_place_builder(self, tcx, typeck_results, local_var_defs).unwrap() } /// Attempts to resolve the `PlaceBuilder`. @@ -350,8 +361,9 @@ impl<'tcx> PlaceBuilder<'tcx> { self, tcx: TyCtxt<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &IndexVec, ) -> Result, PlaceBuilder<'tcx>> { - to_upvars_resolved_place_builder(self, tcx, typeck_results) + to_upvars_resolved_place_builder(self, tcx, typeck_results, local_var_defs) } pub(crate) fn base(&self) -> PlaceBase { @@ -411,7 +423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_place_builder(block, expr)); - block.and(place_builder.into_place(self.tcx, self.typeck_results)) + block.and(place_builder.into_place(self.tcx, self.typeck_results, &self.thir.local_vars)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -435,7 +447,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr)); - block.and(place_builder.into_place(self.tcx, self.typeck_results)) + block.and(place_builder.into_place(self.tcx, self.typeck_results, &self.thir.local_vars)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -530,7 +542,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { inferred_ty: expr.ty, }); - let place = place_builder.clone().into_place(this.tcx, this.typeck_results); + let place = place_builder.clone().into_place( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ); this.cfg.push( block, Statement { @@ -681,7 +697,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if is_outermost_index { self.read_fake_borrows(block, fake_borrow_temps, source_info) } else { - base_place = base_place.expect_upvars_resolved(self.tcx, self.typeck_results); + base_place = base_place.expect_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ); self.add_fake_borrows_of_base( &base_place, block, @@ -713,7 +733,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, len, - Rvalue::Len(slice.into_place(self.tcx, self.typeck_results)), + Rvalue::Len(slice.into_place(self.tcx, self.typeck_results, &self.thir.local_vars)), ); // lt = idx < len self.cfg.push_assign( diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 8e87ecd27d285..cc77f434bc2e9 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -300,11 +300,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let place_builder = unpack!(block = this.as_place_builder(block, &this.thir[*thir_place])); - if let Ok(place_builder_resolved) = - place_builder.try_upvars_resolved(this.tcx, this.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); + if let Ok(place_builder_resolved) = place_builder.try_upvars_resolved( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ) { + let mir_place = place_builder_resolved.into_place( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ); this.cfg.push_fake_read( block, this.source_info(this.tcx.hir().span(*hir_id)), @@ -594,8 +599,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // by the parent itself. The mutability of the current capture // is same as that of the capture in the parent closure. PlaceBase::Upvar { .. } => { - let enclosing_upvars_resolved = - arg_place_builder.clone().into_place(this.tcx, this.typeck_results); + let enclosing_upvars_resolved = arg_place_builder.clone().into_place( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ); match enclosing_upvars_resolved.as_ref() { PlaceRef { @@ -632,7 +640,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false }, }; - let arg_place = arg_place_builder.into_place(this.tcx, this.typeck_results); + let arg_place = + arg_place_builder.into_place(this.tcx, this.typeck_results, &this.thir.local_vars); this.cfg.push_assign( block, diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index ccbb518e72d08..c8575820f5f02 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -354,9 +354,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None => { let place_builder = place_builder.clone(); this.consume_by_copy_or_move( - place_builder - .field(n, *ty) - .into_place(this.tcx, this.typeck_results), + place_builder.field(n, *ty).into_place( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ), ) } }) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index dc1860cb11297..cbaa3e161f936 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -215,10 +215,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause_matched_place = FakeReadCause::ForMatchedPlace(None); let source_info = self.source_info(scrutinee_span); - if let Ok(scrutinee_builder) = - scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, self.typeck_results) - { - let scrutinee_place = scrutinee_builder.into_place(self.tcx, self.typeck_results); + if let Ok(scrutinee_builder) = scrutinee_place_builder.clone().try_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ) { + let scrutinee_place = + scrutinee_builder.into_place(self.tcx, self.typeck_results, &self.thir.local_vars); self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place); } @@ -345,10 +348,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scrutinee_place: Place<'tcx>; if let Ok(scrutinee_builder) = scrutinee_place_builder .clone() - .try_upvars_resolved(this.tcx, this.typeck_results) + .try_upvars_resolved(this.tcx, this.typeck_results, &this.thir.local_vars) { - scrutinee_place = - scrutinee_builder.into_place(this.tcx, this.typeck_results); + scrutinee_place = scrutinee_builder.into_place( + this.tcx, + this.typeck_results, + &this.thir.local_vars, + ); opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span)); } let scope = this.declare_bindings( @@ -617,10 +623,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // let (v1, v2) = foo; // }; // ``` - if let Ok(match_pair_resolved) = - initializer.clone().try_upvars_resolved(self.tcx, self.typeck_results) - { - let place = match_pair_resolved.into_place(self.tcx, self.typeck_results); + if let Ok(match_pair_resolved) = initializer.clone().try_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ) { + let place = match_pair_resolved.into_place( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ); *match_place = Some(place); } } @@ -712,6 +724,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { for_guard: ForGuard, ) { let local_id = self.var_local_id(var, for_guard); + // @dingxiangfei2009: We need HirId here to schedule a drop if let Some(region_scope) = self.region_scope_tree.var_scope(var.0.local_id) { self.schedule_drop(span, region_scope, local_id, DropKind::Value); } @@ -1600,9 +1613,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Insert a Shallow borrow of any places that is switched on. if let Some(fb) = fake_borrows && let Ok(match_place_resolved) = - match_place.clone().try_upvars_resolved(self.tcx, self.typeck_results) + match_place.clone().try_upvars_resolved(self.tcx, self.typeck_results, &self.thir.local_vars) { - let resolved_place = match_place_resolved.into_place(self.tcx, self.typeck_results); + let resolved_place = match_place_resolved.into_place(self.tcx, self.typeck_results, &self.thir.local_vars); fb.insert(resolved_place); } @@ -1788,10 +1801,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); let mut opt_expr_place: Option<(Option<&Place<'tcx>>, Span)> = None; let expr_place: Place<'tcx>; - if let Ok(expr_builder) = - expr_place_builder.try_upvars_resolved(self.tcx, self.typeck_results) - { - expr_place = expr_builder.into_place(self.tcx, self.typeck_results); + if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ) { + expr_place = + expr_builder.into_place(self.tcx, self.typeck_results, &self.thir.local_vars); opt_expr_place = Some((Some(&expr_place), expr_span)); } let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index b4a0c965d6b73..65c6b2865d4c1 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -155,12 +155,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ascription: thir::Ascription { ref annotation, variance }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the - if let Ok(place_resolved) = - match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results) - { + if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ) { candidate.ascriptions.push(Ascription { annotation: annotation.clone(), - source: place_resolved.into_place(self.tcx, self.typeck_results), + source: place_resolved.into_place( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ), variance, }); } @@ -184,12 +190,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ref subpattern, is_primary: _, } => { - if let Ok(place_resolved) = - match_pair.place.clone().try_upvars_resolved(self.tcx, self.typeck_results) - { + if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ) { candidate.bindings.push(Binding { span: match_pair.pattern.span, - source: place_resolved.into_place(self.tcx, self.typeck_results), + source: place_resolved.into_place( + self.tcx, + self.typeck_results, + &self.thir.local_vars, + ), var_id: var, binding_mode: mode, }); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 3774a39503521..6ac36f8ee2a17 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -155,9 +155,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let place: Place<'tcx>; if let Ok(test_place_builder) = - place_builder.try_upvars_resolved(self.tcx, self.typeck_results) + place_builder.try_upvars_resolved(self.tcx, self.typeck_results, &self.thir.local_vars) { - place = test_place_builder.into_place(self.tcx, self.typeck_results); + place = + test_place_builder.into_place(self.tcx, self.typeck_results, &self.thir.local_vars); } else { return; } diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 9a1e98d3bb18d..da0cce8b1e6b8 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -32,10 +32,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) { let tcx = self.tcx; let (min_length, exact_size) = if let Ok(place_resolved) = - place.clone().try_upvars_resolved(tcx, self.typeck_results) + place.clone().try_upvars_resolved(tcx, self.typeck_results, &self.thir.local_vars) { match place_resolved - .into_place(tcx, self.typeck_results) + .into_place(tcx, self.typeck_results, &self.thir.local_vars) .ty(&self.local_decls, tcx) .ty .kind() diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 793066e43c3c7..6f88aa0753d07 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -17,7 +17,9 @@ use rustc_middle::middle::region; use rustc_middle::mir::interpret::Allocation; use rustc_middle::mir::interpret::{ConstValue, LitToConstError, LitToConstInput, Scalar}; use rustc_middle::mir::*; -use rustc_middle::thir::{BindingMode, Expr, ExprId, LintLevel, LocalVarId, PatKind, Thir}; +use rustc_middle::thir::{ + BindingMode, Expr, ExprId, LintLevel, LocalVarId, LocalVarInfo, PatKind, Thir, +}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeckResults}; use rustc_span::symbol::sym; @@ -447,6 +449,8 @@ struct Builder<'a, 'tcx> { /// Maps `HirId`s of variable bindings to the `Local`s created for them. /// (A match binding can have two locals; the 2nd is for the arm's guard.) var_indices: FxHashMap, + // @dingxiangfei2009: Since we are mirroring defs from function arguments while building MIR, we need to track the fresh LocalVarId as well (?) + local_var_defs: IndexVec, local_decls: IndexVec>, canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>, upvar_mutbls: Vec, diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index fb2f5861c6f03..3810512bcb92b 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -903,12 +903,15 @@ impl<'tcx> Cx<'tcx> { ); if is_upvar { - ExprKind::UpvarRef { - closure_def_id: self.body_owner, - var_hir_id: LocalVarId(var_hir_id), - } + let var_hir_id = todo!( + "look up the correct LocalVarId from the given HirId, subject to HirId rewriting by THIR mirroring, especially for let-else" + ); + ExprKind::UpvarRef { closure_def_id: self.body_owner, var_hir_id } } else { - ExprKind::VarRef { id: LocalVarId(var_hir_id) } + let id = todo!( + "look up the correct LocalVarId from the given HirId, subject to HirId rewriting by THIR mirroring, especially for let-else" + ); + ExprKind::VarRef { id } } } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index d853a5e9ee797..e7c4ae9822cab 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -104,7 +104,7 @@ impl<'tcx> Cx<'tcx> { Node::Pat(p) | Node::Binding(p) => p, node => bug!("pattern became {:?}", node), }; - pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p) + pat_from_hir(self.tcx, self.param_env, self.typeck_results, &mut self.thir.local_vars, p) } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 417cf0f89c412..8cbeaf06d51da 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -14,12 +14,14 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; -use rustc_index::vec::Idx; +use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::interpret::{get_slice_bytes, ConstValue}; use rustc_middle::mir::interpret::{ErrorHandled, LitToConstError, LitToConstInput}; use rustc_middle::mir::{self, UserTypeProjection}; use rustc_middle::mir::{BorrowKind, Field, Mutability}; -use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange}; +use rustc_middle::thir::{ + Ascription, BindingMode, FieldPat, LocalVarId, LocalVarInfo, Pat, PatKind, PatRange, +}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::{self, AdtDef, ConstKind, DefIdTree, Region, Ty, TyCtxt, UserType}; @@ -40,6 +42,7 @@ pub(crate) struct PatCtxt<'a, 'tcx> { pub(crate) param_env: ty::ParamEnv<'tcx>, pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>, pub(crate) errors: Vec, + pub(crate) local_var_defs: &'a mut IndexVec, include_lint_checks: bool, } @@ -47,9 +50,10 @@ pub(crate) fn pat_from_hir<'a, 'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &'a mut IndexVec, pat: &'tcx hir::Pat<'tcx>, ) -> Pat<'tcx> { - let mut pcx = PatCtxt::new(tcx, param_env, typeck_results); + let mut pcx = PatCtxt::new(tcx, param_env, typeck_results, local_var_defs); let result = pcx.lower_pattern(pat); if !pcx.errors.is_empty() { let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors); @@ -64,8 +68,16 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + local_var_defs: &'a mut IndexVec, ) -> Self { - PatCtxt { tcx, param_env, typeck_results, errors: vec![], include_lint_checks: false } + PatCtxt { + tcx, + param_env, + typeck_results, + local_var_defs, + errors: vec![], + include_lint_checks: false, + } } pub(crate) fn include_lint_checks(&mut self) -> &mut Self { @@ -288,7 +300,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { mutability, mode, name: ident.name, - var: LocalVarId(id), + var: self.local_var_defs.push(LocalVarInfo::Hir(id)), // assigning a new LocalVarId here ty: var_ty, subpattern: self.lower_opt_pattern(sub), is_primary: id == pat.hir_id,