summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/build
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/build')
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs31
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs21
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs16
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs18
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs45
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs73
11 files changed, 143 insertions, 102 deletions
diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs
index 803207d9d..60c4a0416 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse.rs
@@ -74,7 +74,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
kind @ StmtKind::Let { pattern, .. } => {
return Err(ParseError {
span: pattern.span,
- item_description: format!("{:?}", kind),
+ item_description: format!("{kind:?}"),
expected: "expression".to_string(),
});
}
@@ -241,9 +241,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
});
}
- let Some(trailing) = block.expr else {
- return Err(self.expr_error(expr_id, "terminator"))
- };
+ let Some(trailing) = block.expr else { return Err(self.expr_error(expr_id, "terminator")) };
let span = self.thir[trailing].span;
let terminator = self.parse_terminator(trailing)?;
data.terminator = Some(Terminator {
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 4cb9d7bab..26662f5de 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -61,11 +61,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
})
},
@call("mir_call", args) => {
- let destination = self.parse_place(args[0])?;
- let target = self.parse_block(args[1])?;
- self.parse_call(args[2], destination, target)
+ self.parse_call(args)
},
- ExprKind::Match { scrutinee, arms } => {
+ ExprKind::Match { scrutinee, arms, .. } => {
let discr = self.parse_operand(*scrutinee)?;
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
},
@@ -78,7 +76,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
span,
item_description: "no arms".to_string(),
expected: "at least one arm".to_string(),
- })
+ });
};
let otherwise = &self.thir[*otherwise];
@@ -87,7 +85,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
span: otherwise.span,
item_description: format!("{:?}", otherwise.pattern.kind),
expected: "wildcard pattern".to_string(),
- })
+ });
};
let otherwise = self.parse_block(otherwise.body)?;
@@ -100,7 +98,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
span: arm.pattern.span,
item_description: format!("{:?}", arm.pattern.kind),
expected: "constant pattern".to_string(),
- })
+ });
};
values.push(value.eval_bits(self.tcx, self.param_env, arm.pattern.ty));
targets.push(self.parse_block(arm.body)?);
@@ -109,13 +107,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
Ok(SwitchTargets::new(values.into_iter().zip(targets), otherwise))
}
- fn parse_call(
- &self,
- expr_id: ExprId,
- destination: Place<'tcx>,
- target: BasicBlock,
- ) -> PResult<TerminatorKind<'tcx>> {
- parse_by_kind!(self, expr_id, _, "function call",
+ fn parse_call(&self, args: &[ExprId]) -> PResult<TerminatorKind<'tcx>> {
+ let (destination, call) = parse_by_kind!(self, args[0], _, "function call",
+ ExprKind::Assign { lhs, rhs } => (*lhs, *rhs),
+ );
+ let destination = self.parse_place(destination)?;
+ let target = self.parse_block(args[1])?;
+
+ parse_by_kind!(self, call, _, "function call",
ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
let fun = self.parse_operand(*fun)?;
let args = args
@@ -192,12 +191,12 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fields.iter().map(|e| self.parse_operand(*e)).collect::<Result<_, _>>()?
))
},
- ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => {
+ ExprKind::Adt(box AdtExpr{ adt_def, variant_index, args, fields, .. }) => {
let is_union = adt_def.is_union();
let active_field_index = is_union.then(|| fields[0].name);
Ok(Rvalue::Aggregate(
- Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)),
+ Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, args, None, active_field_index)),
fields.iter().map(|f| self.parse_operand(f.expr)).collect::<Result<_, _>>()?
))
},
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 3fe751ae0..aaa37446e 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -75,10 +75,10 @@ pub fn as_constant_inner<'tcx>(
Constant { span, user_ty, literal }
}
- ExprKind::NamedConst { def_id, substs, ref user_ty } => {
+ ExprKind::NamedConst { def_id, args, ref user_ty } => {
let user_ty = user_ty.as_ref().and_then(push_cuta);
- let uneval = mir::UnevaluatedConst::new(def_id, substs);
+ let uneval = mir::UnevaluatedConst::new(def_id, args);
let literal = ConstantKind::Unevaluated(uneval, ty);
Constant { user_ty, span, literal }
@@ -89,8 +89,8 @@ pub fn as_constant_inner<'tcx>(
Constant { user_ty: None, span, literal }
}
- ExprKind::ConstBlock { did: def_id, substs } => {
- let uneval = mir::UnevaluatedConst::new(def_id, substs);
+ ExprKind::ConstBlock { did: def_id, args } => {
+ let uneval = mir::UnevaluatedConst::new(def_id, args);
let literal = ConstantKind::Unevaluated(uneval, ty);
Constant { user_ty: None, span, literal }
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 60acd279f..2e7ef265a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -175,11 +175,8 @@ fn to_upvars_resolved_place_builder<'tcx>(
projection: &[PlaceElem<'tcx>],
) -> Option<PlaceBuilder<'tcx>> {
let Some((capture_index, capture)) =
- find_capture_matching_projections(
- &cx.upvars,
- var_hir_id,
- &projection,
- ) else {
+ find_capture_matching_projections(&cx.upvars, var_hir_id, &projection)
+ else {
let closure_span = cx.tcx.def_span(closure_def_id);
if !enable_precise_capture(closure_span) {
bug!(
@@ -189,10 +186,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
projection
)
} else {
- debug!(
- "No associated capture found for {:?}[{:#?}]",
- var_hir_id, projection,
- );
+ debug!("No associated capture found for {:?}[{:#?}]", var_hir_id, projection,);
}
return None;
};
@@ -242,6 +236,9 @@ fn strip_prefix<'a, 'tcx>(
}
assert_matches!(iter.next(), Some(ProjectionElem::Field(..)));
}
+ HirProjectionKind::OpaqueCast => {
+ assert_matches!(iter.next(), Some(ProjectionElem::OpaqueCast(..)));
+ }
HirProjectionKind::Index | HirProjectionKind::Subslice => {
bug!("unexpected projection kind: {:?}", projection);
}
@@ -736,5 +733,5 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Precise capture is enabled if user is using Rust Edition 2021 or higher.
fn enable_precise_capture(closure_span: Span) -> bool {
- closure_span.rust_2021()
+ closure_span.at_least_rust_2021()
}
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 32ffb990b..3220a184d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -16,7 +16,7 @@ use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::cast::{mir_cast_kind, CastTy};
use rustc_middle::ty::layout::IntegerExt;
-use rustc_middle::ty::{self, Ty, UpvarSubsts};
+use rustc_middle::ty::{self, Ty, UpvarArgs};
use rustc_span::Span;
impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -382,7 +382,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Closure(box ClosureExpr {
closure_id,
- substs,
+ args,
ref upvars,
movability,
ref fake_reads,
@@ -470,19 +470,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
.collect();
- let result = match substs {
- UpvarSubsts::Generator(substs) => {
+ let result = match args {
+ UpvarArgs::Generator(args) => {
// We implicitly set the discriminant to 0. See
// librustc_mir/transform/deaggregator.rs for details.
let movability = movability.unwrap();
- Box::new(AggregateKind::Generator(
- closure_id.to_def_id(),
- substs,
- movability,
- ))
+ Box::new(AggregateKind::Generator(closure_id.to_def_id(), args, movability))
}
- UpvarSubsts::Closure(substs) => {
- Box::new(AggregateKind::Closure(closure_id.to_def_id(), substs))
+ UpvarArgs::Closure(args) => {
+ Box::new(AggregateKind::Closure(closure_id.to_def_id(), args))
}
};
block.and(Rvalue::Aggregate(result, operands))
@@ -778,8 +774,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Not in a closure
debug_assert!(
local == ty::CAPTURE_STRUCT_LOCAL,
- "Expected local to be Local(1), found {:?}",
- local
+ "Expected local to be Local(1), found {local:?}"
);
// Not in a closure
debug_assert!(
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index e30fdcbbe..a5c86e31a 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -47,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Block { block: ast_block } => {
this.ast_block(destination, block, ast_block, source_info)
}
- ExprKind::Match { scrutinee, ref arms } => {
+ ExprKind::Match { scrutinee, ref arms, .. } => {
this.match_expr(destination, expr_span, block, &this.thir[scrutinee], arms)
}
ExprKind::If { cond, then, else_opt, if_then_scope } => {
@@ -317,7 +317,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
ExprKind::Adt(box AdtExpr {
adt_def,
variant_index,
- substs,
+ args,
ref user_ty,
ref fields,
ref base,
@@ -382,7 +382,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let adt = Box::new(AggregateKind::Adt(
adt_def.did(),
variant_index,
- substs,
+ args,
user_ty,
active_field_index,
));
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 10770213c..3c4507407 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -607,9 +607,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// };
// ```
if let Some(place) = initializer.try_to_place(self) {
- let LocalInfo::User(BindingForm::Var(
- VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
- )) = **self.local_decls[local].local_info.as_mut().assert_crate_local() else {
+ let LocalInfo::User(BindingForm::Var(VarBindingForm {
+ opt_match_place: Some((ref mut match_place, _)),
+ ..
+ })) = **self.local_decls[local].local_info.as_mut().assert_crate_local()
+ else {
bug!("Let binding to non-user variable.")
};
*match_place = Some(place);
@@ -804,7 +806,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- PatKind::Variant { adt_def, substs: _, variant_index, ref subpatterns } => {
+ PatKind::Variant { adt_def, args: _, variant_index, ref subpatterns } => {
for subpattern in subpatterns {
let subpattern_user_ty =
pattern_user_ty.clone().variant(adt_def, variant_index, subpattern.field);
@@ -1625,9 +1627,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// at least the first candidate ought to be tested
assert!(
total_candidate_count > candidates.len(),
- "{}, {:#?}",
- total_candidate_count,
- candidates
+ "{total_candidate_count}, {candidates:#?}"
);
debug!("tested_candidates: {}", total_candidate_count - candidates.len());
debug!("untested_candidates: {}", candidates.len());
@@ -2242,7 +2242,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
- references: 0,
value: VarDebugInfoContents::Place(for_arm_body.into()),
argument_index: None,
});
@@ -2262,7 +2261,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info: debug_source_info,
- references: 0,
value: VarDebugInfoContents::Place(ref_for_guard.into()),
argument_index: None,
});
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index f6b1955fd..17ac1f4e0 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -259,13 +259,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
+ PatKind::Variant { adt_def, args, variant_index, ref subpatterns } => {
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
i == variant_index || {
self.tcx.features().exhaustive_patterns
&& !v
.inhabited_predicate(self.tcx, adt_def)
- .subst(self.tcx, substs)
+ .instantiate(self.tcx, args)
.apply_ignore_module(self.tcx, self.param_env)
}
}) && (adt_def.did().is_local()
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index e6806177d..484e84909 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -30,7 +30,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
/// It is a bug to call this with a not-fully-simplified pattern.
pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
match match_pair.pattern.kind {
- PatKind::Variant { adt_def, substs: _, variant_index: _, subpatterns: _ } => Test {
+ PatKind::Variant { adt_def, args: _, variant_index: _, subpatterns: _ } => Test {
span: match_pair.pattern.span,
kind: TestKind::Switch {
adt_def,
@@ -88,7 +88,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
switch_ty: Ty<'tcx>,
options: &mut FxIndexMap<ConstantKind<'tcx>, u128>,
) -> bool {
- let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
+ let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place)
+ else {
return false;
};
@@ -126,7 +127,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &Candidate<'pat, 'tcx>,
variants: &mut BitSet<VariantIdx>,
) -> bool {
- let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place) else {
+ let Some(match_pair) = candidate.match_pairs.iter().find(|mp| mp.place == *test_place)
+ else {
return false;
};
@@ -173,16 +175,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
debug_assert_ne!(
target_blocks[idx.index()],
otherwise_block,
- "no candidates for tested discriminant: {:?}",
- discr,
+ "no candidates for tested discriminant: {discr:?}",
);
Some((discr.val, target_blocks[idx.index()]))
} else {
debug_assert_eq!(
target_blocks[idx.index()],
otherwise_block,
- "found candidates for untested discriminant: {:?}",
- discr,
+ "found candidates for untested discriminant: {discr:?}",
);
None
}
@@ -865,7 +865,7 @@ fn trait_method<'tcx>(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
method_name: Symbol,
- substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+ args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
) -> ConstantKind<'tcx> {
// The unhygienic comparison here is acceptable because this is only
// used on known traits.
@@ -875,7 +875,7 @@ fn trait_method<'tcx>(
.find(|item| item.kind == ty::AssocKind::Fn)
.expect("trait method not found");
- let method_ty = Ty::new_fn_def(tcx, item.def_id, substs);
+ let method_ty = Ty::new_fn_def(tcx, item.def_id, args);
ConstantKind::zero_sized(method_ty)
}
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index d828e71c7..2a23a69b5 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -10,6 +10,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{GeneratorKind, Node};
+use rustc_index::bit_set::GrowableBitSet;
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
@@ -93,8 +94,7 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
|| body.basic_blocks.has_free_regions()
|| body.var_debug_info.has_free_regions()
|| body.yield_ty().has_free_regions()),
- "Unexpected free regions in MIR: {:?}",
- body,
+ "Unexpected free regions in MIR: {body:?}",
);
body
@@ -215,6 +215,14 @@ struct Builder<'a, 'tcx> {
unit_temp: Option<Place<'tcx>>,
var_debug_info: Vec<VarDebugInfo<'tcx>>,
+
+ // A cache for `maybe_lint_level_roots_bounded`. That function is called
+ // repeatedly, and each time it effectively traces a path through a tree
+ // structure from a node towards the root, doing an attribute check on each
+ // node along the way. This cache records which nodes trace all the way to
+ // the root (most of them do) and saves us from retracing many sub-paths
+ // many times, and rechecking many nodes.
+ lint_level_roots_cache: GrowableBitSet<hir::ItemLocalId>,
}
type CaptureMap<'tcx> = SortedIndexMultiMap<usize, hir::HirId, Capture<'tcx>>;
@@ -473,7 +481,7 @@ fn construct_fn<'tcx>(
let (yield_ty, return_ty) = if generator_kind.is_some() {
let gen_ty = arguments[thir::UPVAR_ENV_PARAM].ty;
let gen_sig = match gen_ty.kind() {
- ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
+ ty::Generator(_, gen_args, ..) => gen_args.as_generator().sig(),
_ => {
span_bug!(span, "generator w/o generator type: {:?}", gen_ty)
}
@@ -562,7 +570,7 @@ fn construct_const<'a, 'tcx>(
// Figure out what primary body this item has.
let (span, const_ty_span) = match tcx.hir().get(hir_id) {
Node::Item(hir::Item {
- kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _),
+ kind: hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _, _),
span,
..
})
@@ -618,11 +626,9 @@ fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Bo
let num_params = match body_owner_kind {
hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(),
hir::BodyOwnerKind::Closure => {
- let ty = tcx.type_of(def).subst_identity();
+ let ty = tcx.type_of(def).instantiate_identity();
match ty.kind() {
- ty::Closure(_, substs) => {
- 1 + substs.as_closure().sig().inputs().skip_binder().len()
- }
+ ty::Closure(_, args) => 1 + args.as_closure().sig().inputs().skip_binder().len(),
ty::Generator(..) => 2,
_ => bug!("expected closure or generator, found {ty:?}"),
}
@@ -725,6 +731,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
var_indices: Default::default(),
unit_temp: None,
var_debug_info: vec![],
+ lint_level_roots_cache: GrowableBitSet::new_empty(),
};
assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
@@ -768,9 +775,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
closure_ty = *ty;
}
- let upvar_substs = match closure_ty.kind() {
- ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
- ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
+ let upvar_args = match closure_ty.kind() {
+ ty::Closure(_, args) => ty::UpvarArgs::Closure(args),
+ ty::Generator(_, args, _) => ty::UpvarArgs::Generator(args),
_ => return,
};
@@ -779,7 +786,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// with the closure's DefId. Here, we run through that vec of UpvarIds for
// the given closure and use the necessary information to create upvar
// debuginfo and to fill `self.upvars`.
- let capture_tys = upvar_substs.upvar_tys();
+ let capture_tys = upvar_args.upvar_tys();
let tcx = self.tcx;
self.upvars = tcx
@@ -813,7 +820,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
};
self.var_debug_info.push(VarDebugInfo {
name,
- references: 0,
source_info: SourceInfo::outermost(captured_place.var_ident.span),
value: VarDebugInfoContents::Place(use_place),
argument_index: None,
@@ -844,7 +850,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info.push(VarDebugInfo {
name,
source_info,
- references: 0,
value: VarDebugInfoContents::Place(arg_local.into()),
argument_index: Some(argument_index as u16 + 1),
});
@@ -969,9 +974,9 @@ pub(crate) fn parse_float_into_scalar(
match float_ty {
ty::FloatTy::F32 => {
let Ok(rust_f) = num.parse::<f32>() else { return None };
- let mut f = num.parse::<Single>().unwrap_or_else(|e| {
- panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
- });
+ let mut f = num
+ .parse::<Single>()
+ .unwrap_or_else(|e| panic!("apfloat::ieee::Single failed to parse `{num}`: {e:?}"));
assert!(
u128::from(rust_f.to_bits()) == f.to_bits(),
@@ -992,9 +997,9 @@ pub(crate) fn parse_float_into_scalar(
}
ty::FloatTy::F64 => {
let Ok(rust_f) = num.parse::<f64>() else { return None };
- let mut f = num.parse::<Double>().unwrap_or_else(|e| {
- panic!("apfloat::ieee::Double failed to parse `{}`: {:?}", num, e)
- });
+ let mut f = num
+ .parse::<Double>()
+ .unwrap_or_else(|e| panic!("apfloat::ieee::Double failed to parse `{num}`: {e:?}"));
assert!(
u128::from(rust_f.to_bits()) == f.to_bits(),
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 72374102c..a96288a11 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -90,8 +90,8 @@ use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::middle::region;
use rustc_middle::mir::*;
use rustc_middle::thir::{Expr, LintLevel};
-
use rustc_middle::ty::Ty;
+use rustc_session::lint::Level;
use rustc_span::{Span, DUMMY_SP};
#[derive(Debug)]
@@ -760,20 +760,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
) {
let (current_root, parent_root) =
if self.tcx.sess.opts.unstable_opts.maximal_hir_to_mir_coverage {
- // Some consumers of rustc need to map MIR locations back to HIR nodes. Currently the
- // the only part of rustc that tracks MIR -> HIR is the `SourceScopeLocalData::lint_root`
- // field that tracks lint levels for MIR locations. Normally the number of source scopes
- // is limited to the set of nodes with lint annotations. The -Zmaximal-hir-to-mir-coverage
- // flag changes this behavior to maximize the number of source scopes, increasing the
- // granularity of the MIR->HIR mapping.
+ // Some consumers of rustc need to map MIR locations back to HIR nodes. Currently
+ // the the only part of rustc that tracks MIR -> HIR is the
+ // `SourceScopeLocalData::lint_root` field that tracks lint levels for MIR
+ // locations. Normally the number of source scopes is limited to the set of nodes
+ // with lint annotations. The -Zmaximal-hir-to-mir-coverage flag changes this
+ // behavior to maximize the number of source scopes, increasing the granularity of
+ // the MIR->HIR mapping.
(current_id, parent_id)
} else {
- // Use `maybe_lint_level_root_bounded` with `self.hir_id` as a bound
- // to avoid adding Hir dependencies on our parents.
- // We estimate the true lint roots here to avoid creating a lot of source scopes.
+ // Use `maybe_lint_level_root_bounded` to avoid adding Hir dependencies on our
+ // parents. We estimate the true lint roots here to avoid creating a lot of source
+ // scopes.
(
- self.tcx.maybe_lint_level_root_bounded(current_id, self.hir_id),
- self.tcx.maybe_lint_level_root_bounded(parent_id, self.hir_id),
+ self.maybe_lint_level_root_bounded(current_id),
+ if parent_id == self.hir_id {
+ parent_id // this is very common
+ } else {
+ self.maybe_lint_level_root_bounded(parent_id)
+ },
)
};
@@ -783,6 +788,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
+ /// Walks upwards from `orig_id` to find a node which might change lint levels with attributes.
+ /// It stops at `self.hir_id` and just returns it if reached.
+ fn maybe_lint_level_root_bounded(&mut self, orig_id: HirId) -> HirId {
+ // This assertion lets us just store `ItemLocalId` in the cache, rather
+ // than the full `HirId`.
+ assert_eq!(orig_id.owner, self.hir_id.owner);
+
+ let mut id = orig_id;
+ let hir = self.tcx.hir();
+ loop {
+ if id == self.hir_id {
+ // This is a moderately common case, mostly hit for previously unseen nodes.
+ break;
+ }
+
+ if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) {
+ // This is a rare case. It's for a node path that doesn't reach the root due to an
+ // intervening lint level attribute. This result doesn't get cached.
+ return id;
+ }
+
+ let next = hir.parent_id(id);
+ if next == id {
+ bug!("lint traversal reached the root of the crate");
+ }
+ id = next;
+
+ // This lookup is just an optimization; it can be removed without affecting
+ // functionality. It might seem strange to see this at the end of this loop, but the
+ // `orig_id` passed in to this function is almost always previously unseen, for which a
+ // lookup will be a miss. So we only do lookups for nodes up the parent chain, where
+ // cache lookups have a very high hit rate.
+ if self.lint_level_roots_cache.contains(id.local_id) {
+ break;
+ }
+ }
+
+ // `orig_id` traced to `self_id`; record this fact. If `orig_id` is a leaf node it will
+ // rarely (never?) subsequently be searched for, but it's hard to know if that is the case.
+ // The performance wins from the cache all come from caching non-leaf nodes.
+ self.lint_level_roots_cache.insert(orig_id.local_id);
+ self.hir_id
+ }
+
/// Creates a new source scope, nested in the current one.
pub(crate) fn new_source_scope(
&mut self,