diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
commit | d1b2d29528b7794b41e66fc2136e395a02f8529b (patch) | |
tree | a4a17504b260206dec3cf55b2dca82929a348ac2 /compiler/rustc_mir_build/src/build | |
parent | Releasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip |
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_build/src/build')
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, |