summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src')
-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
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs129
-rw-r--r--compiler/rustc_mir_build/src/errors.rs59
-rw-r--r--compiler/rustc_mir_build/src/lib.rs2
-rw-r--r--compiler/rustc_mir_build/src/lints.rs139
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs106
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/mod.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs41
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs17
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs64
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs40
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs20
-rw-r--r--compiler/rustc_mir_build/src/thir/util.rs2
24 files changed, 546 insertions, 338 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,
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 6b2b140fa..192bd4a83 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -91,7 +91,12 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
kind.emit_unsafe_op_in_unsafe_fn_lint(self.tcx, self.hir_context, span);
}
SafetyContext::Safe => {
- kind.emit_requires_unsafe_err(self.tcx, span, unsafe_op_in_unsafe_fn_allowed);
+ kind.emit_requires_unsafe_err(
+ self.tcx,
+ span,
+ self.hir_context,
+ unsafe_op_in_unsafe_fn_allowed,
+ );
}
}
}
@@ -383,7 +388,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
ExprKind::Adt(box AdtExpr {
adt_def,
variant_index: _,
- substs: _,
+ args: _,
user_ty: _,
fields: _,
base: _,
@@ -393,14 +398,14 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
},
ExprKind::Closure(box ClosureExpr {
closure_id,
- substs: _,
+ args: _,
upvars: _,
movability: _,
fake_reads: _,
}) => {
self.visit_inner_body(closure_id);
}
- ExprKind::ConstBlock { did, substs: _ } => {
+ ExprKind::ConstBlock { did, args: _ } => {
let def_id = did.expect_local();
self.visit_inner_body(def_id);
}
@@ -602,98 +607,164 @@ impl UnsafeOpKind {
&self,
tcx: TyCtxt<'_>,
span: Span,
+ hir_context: hir::HirId,
unsafe_op_in_unsafe_fn_allowed: bool,
) {
+ let note_non_inherited = tcx.hir().parent_iter(hir_context).find(|(id, node)| {
+ if let hir::Node::Expr(block) = node
+ && let hir::ExprKind::Block(block, _) = block.kind
+ && let hir::BlockCheckMode::UnsafeBlock(_) = block.rules
+ {
+ true
+ }
+ else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
+ && sig.header.is_unsafe()
+ {
+ true
+ } else {
+ false
+ }
+ });
+ let unsafe_not_inherited_note = if let Some((id, _)) = note_non_inherited {
+ let span = tcx.hir().span(id);
+ let span = tcx.sess.source_map().guess_head_span(span);
+ Some(UnsafeNotInheritedNote { span })
+ } else {
+ None
+ };
+
match self {
CallToUnsafeFunction(Some(did)) if unsafe_op_in_unsafe_fn_allowed => {
tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span,
+ unsafe_not_inherited_note,
function: &tcx.def_path_str(*did),
});
}
CallToUnsafeFunction(Some(did)) => {
tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe {
span,
+ unsafe_not_inherited_note,
function: &tcx.def_path_str(*did),
});
}
CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => {
tcx.sess.emit_err(
- CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span },
+ CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ },
);
}
CallToUnsafeFunction(None) => {
- tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span });
+ tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless {
+ span,
+ unsafe_not_inherited_note,
+ });
}
UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
UseOfInlineAssembly => {
- tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe { span });
+ tcx.sess.emit_err(UseOfInlineAssemblyRequiresUnsafe {
+ span,
+ unsafe_not_inherited_note,
+ });
}
InitializingTypeWith if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
InitializingTypeWith => {
- tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe { span });
+ tcx.sess.emit_err(InitializingTypeWithRequiresUnsafe {
+ span,
+ unsafe_not_inherited_note,
+ });
}
UseOfMutableStatic if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
UseOfMutableStatic => {
- tcx.sess.emit_err(UseOfMutableStaticRequiresUnsafe { span });
+ tcx.sess
+ .emit_err(UseOfMutableStaticRequiresUnsafe { span, unsafe_not_inherited_note });
}
UseOfExternStatic if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
UseOfExternStatic => {
- tcx.sess.emit_err(UseOfExternStaticRequiresUnsafe { span });
+ tcx.sess
+ .emit_err(UseOfExternStaticRequiresUnsafe { span, unsafe_not_inherited_note });
}
DerefOfRawPointer if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
DerefOfRawPointer => {
- tcx.sess.emit_err(DerefOfRawPointerRequiresUnsafe { span });
+ tcx.sess
+ .emit_err(DerefOfRawPointerRequiresUnsafe { span, unsafe_not_inherited_note });
}
AccessToUnionField if unsafe_op_in_unsafe_fn_allowed => {
- tcx.sess
- .emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span });
+ tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ });
}
AccessToUnionField => {
- tcx.sess.emit_err(AccessToUnionFieldRequiresUnsafe { span });
+ tcx.sess
+ .emit_err(AccessToUnionFieldRequiresUnsafe { span, unsafe_not_inherited_note });
}
MutationOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => {
tcx.sess.emit_err(
MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span,
+ unsafe_not_inherited_note,
},
);
}
MutationOfLayoutConstrainedField => {
- tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe { span });
+ tcx.sess.emit_err(MutationOfLayoutConstrainedFieldRequiresUnsafe {
+ span,
+ unsafe_not_inherited_note,
+ });
}
BorrowOfLayoutConstrainedField if unsafe_op_in_unsafe_fn_allowed => {
tcx.sess.emit_err(
- BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span },
+ BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
+ span,
+ unsafe_not_inherited_note,
+ },
);
}
BorrowOfLayoutConstrainedField => {
- tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe { span });
+ tcx.sess.emit_err(BorrowOfLayoutConstrainedFieldRequiresUnsafe {
+ span,
+ unsafe_not_inherited_note,
+ });
}
CallToFunctionWith(did) if unsafe_op_in_unsafe_fn_allowed => {
tcx.sess.emit_err(CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
span,
+ unsafe_not_inherited_note,
function: &tcx.def_path_str(*did),
});
}
CallToFunctionWith(did) => {
tcx.sess.emit_err(CallToFunctionWithRequiresUnsafe {
span,
+ unsafe_not_inherited_note,
function: &tcx.def_path_str(*did),
});
}
@@ -712,9 +783,7 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
return;
}
- let Ok((thir, expr)) = tcx.thir_body(def) else {
- return
- };
+ let Ok((thir, expr)) = tcx.thir_body(def) else { return };
let thir = &thir.borrow();
// If `thir` is empty, a type error occurred, skip this body.
if thir.exprs.is_empty() {
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index df00cc75c..3ff3387a7 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -119,6 +119,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
#[label]
pub span: Span,
pub function: &'a str,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -128,6 +130,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -138,6 +142,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
#[label]
pub span: Span,
pub function: &'a str,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -150,6 +156,8 @@ pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -159,6 +167,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -168,6 +178,8 @@ pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -177,6 +189,8 @@ pub struct InitializingTypeWithRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -189,6 +203,8 @@ pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -198,6 +214,8 @@ pub struct UseOfMutableStaticRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -207,6 +225,8 @@ pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -216,6 +236,8 @@ pub struct UseOfExternStaticRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -225,6 +247,8 @@ pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -234,6 +258,8 @@ pub struct DerefOfRawPointerRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -243,6 +269,8 @@ pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -252,6 +280,8 @@ pub struct AccessToUnionFieldRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -261,6 +291,8 @@ pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -270,6 +302,8 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -282,6 +316,8 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllow
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -291,6 +327,8 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -303,6 +341,8 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed
#[primary_span]
#[label]
pub span: Span,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -313,6 +353,8 @@ pub struct CallToFunctionWithRequiresUnsafe<'a> {
#[label]
pub span: Span,
pub function: &'a str,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
}
#[derive(Diagnostic)]
@@ -323,6 +365,15 @@ pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
#[label]
pub span: Span,
pub function: &'a str,
+ #[subdiagnostic]
+ pub unsafe_not_inherited_note: Option<UnsafeNotInheritedNote>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(mir_build_unsafe_not_inherited)]
+pub struct UnsafeNotInheritedNote {
+ #[primary_span]
+ pub span: Span,
}
#[derive(LintDiagnostic)]
@@ -403,17 +454,13 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
if self.span.eq_ctxt(self.expr_span) {
// Get the span for the empty match body `{}`.
let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) {
- (format!("\n{}", snippet), " ")
+ (format!("\n{snippet}"), " ")
} else {
(" ".to_string(), "")
};
suggestion = Some((
self.span.shrink_to_hi().with_hi(self.expr_span.hi()),
- format!(
- " {{{indentation}{more}_ => todo!(),{indentation}}}",
- indentation = indentation,
- more = more,
- ),
+ format!(" {{{indentation}{more}_ => todo!(),{indentation}}}",),
));
}
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index 4fdc3178c..099fefbf0 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -19,7 +19,7 @@ extern crate rustc_middle;
mod build;
mod check_unsafety;
mod errors;
-mod lints;
+pub mod lints;
pub mod thir;
use rustc_middle::query::Providers;
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 8e41957af..7fb73b5c7 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -3,27 +3,43 @@ use rustc_data_structures::graph::iterate::{
NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
};
use rustc_hir::def::DefKind;
-use rustc_middle::mir::{self, BasicBlock, BasicBlocks, Body, Operand, TerminatorKind};
-use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
-use rustc_middle::ty::{self, Instance, TyCtxt};
+use rustc_middle::mir::{self, BasicBlock, BasicBlocks, Body, Terminator, TerminatorKind};
+use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::ty::{GenericArg, GenericArgs};
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
use rustc_span::Span;
use std::ops::ControlFlow;
pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+ check_call_recursion(tcx, body);
+}
+
+fn check_call_recursion<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let def_id = body.source.def_id().expect_local();
if let DefKind::Fn | DefKind::AssocFn = tcx.def_kind(def_id) {
- // If this is trait/impl method, extract the trait's substs.
- let trait_substs = match tcx.trait_of_item(def_id.to_def_id()) {
+ // If this is trait/impl method, extract the trait's args.
+ let trait_args = match tcx.trait_of_item(def_id.to_def_id()) {
Some(trait_def_id) => {
- let trait_substs_count = tcx.generics_of(trait_def_id).count();
- &InternalSubsts::identity_for_item(tcx, def_id)[..trait_substs_count]
+ let trait_args_count = tcx.generics_of(trait_def_id).count();
+ &GenericArgs::identity_for_item(tcx, def_id)[..trait_args_count]
}
_ => &[],
};
- let mut vis = Search { tcx, body, reachable_recursive_calls: vec![], trait_substs };
+ check_recursion(tcx, body, CallRecursion { trait_args })
+ }
+}
+
+fn check_recursion<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ body: &Body<'tcx>,
+ classifier: impl TerminatorClassifier<'tcx>,
+) {
+ let def_id = body.source.def_id().expect_local();
+
+ if let DefKind::Fn | DefKind::AssocFn = tcx.def_kind(def_id) {
+ let mut vis = Search { tcx, body, classifier, reachable_recursive_calls: vec![] };
if let Some(NonRecursive) =
TriColorDepthFirstSearch::new(&body.basic_blocks).run_from_start(&mut vis)
{
@@ -46,20 +62,66 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
}
}
+/// Requires drop elaboration to have been performed first.
+pub fn check_drop_recursion<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+ let def_id = body.source.def_id().expect_local();
+
+ // First check if `body` is an `fn drop()` of `Drop`
+ if let DefKind::AssocFn = tcx.def_kind(def_id) &&
+ let Some(trait_ref) = tcx.impl_of_method(def_id.to_def_id()).and_then(|def_id| tcx.impl_trait_ref(def_id)) &&
+ let Some(drop_trait) = tcx.lang_items().drop_trait() && drop_trait == trait_ref.instantiate_identity().def_id {
+
+ // It was. Now figure out for what type `Drop` is implemented and then
+ // check for recursion.
+ if let ty::Ref(_, dropped_ty, _) = tcx.liberate_late_bound_regions(
+ def_id.to_def_id(),
+ tcx.fn_sig(def_id).instantiate_identity().input(0),
+ ).kind() {
+ check_recursion(tcx, body, RecursiveDrop { drop_for: *dropped_ty });
+ }
+ }
+}
+
+trait TerminatorClassifier<'tcx> {
+ fn is_recursive_terminator(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ body: &Body<'tcx>,
+ terminator: &Terminator<'tcx>,
+ ) -> bool;
+}
+
struct NonRecursive;
-struct Search<'mir, 'tcx> {
+struct Search<'mir, 'tcx, C: TerminatorClassifier<'tcx>> {
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
- trait_substs: &'tcx [GenericArg<'tcx>],
+ classifier: C,
reachable_recursive_calls: Vec<Span>,
}
-impl<'mir, 'tcx> Search<'mir, 'tcx> {
+struct CallRecursion<'tcx> {
+ trait_args: &'tcx [GenericArg<'tcx>],
+}
+
+struct RecursiveDrop<'tcx> {
+ /// The type that `Drop` is implemented for.
+ drop_for: Ty<'tcx>,
+}
+
+impl<'tcx> TerminatorClassifier<'tcx> for CallRecursion<'tcx> {
/// Returns `true` if `func` refers to the function we are searching in.
- fn is_recursive_call(&self, func: &Operand<'tcx>, args: &[Operand<'tcx>]) -> bool {
- let Search { tcx, body, trait_substs, .. } = *self;
+ fn is_recursive_terminator(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ body: &Body<'tcx>,
+ terminator: &Terminator<'tcx>,
+ ) -> bool {
+ let TerminatorKind::Call { func, args, .. } = &terminator.kind else {
+ return false;
+ };
+
// Resolving function type to a specific instance that is being called is expensive. To
// avoid the cost we check the number of arguments first, which is sufficient to reject
// most of calls as non-recursive.
@@ -70,30 +132,46 @@ impl<'mir, 'tcx> Search<'mir, 'tcx> {
let param_env = tcx.param_env(caller);
let func_ty = func.ty(body, tcx);
- if let ty::FnDef(callee, substs) = *func_ty.kind() {
- let normalized_substs = tcx.normalize_erasing_regions(param_env, substs);
- let (callee, call_substs) = if let Ok(Some(instance)) =
- Instance::resolve(tcx, param_env, callee, normalized_substs)
+ if let ty::FnDef(callee, args) = *func_ty.kind() {
+ let normalized_args = tcx.normalize_erasing_regions(param_env, args);
+ let (callee, call_args) = if let Ok(Some(instance)) =
+ Instance::resolve(tcx, param_env, callee, normalized_args)
{
- (instance.def_id(), instance.substs)
+ (instance.def_id(), instance.args)
} else {
- (callee, normalized_substs)
+ (callee, normalized_args)
};
// FIXME(#57965): Make this work across function boundaries
- // If this is a trait fn, the substs on the trait have to match, or we might be
+ // If this is a trait fn, the args on the trait have to match, or we might be
// calling into an entirely different method (for example, a call from the default
// method in the trait to `<A as Trait<B>>::method`, where `A` and/or `B` are
// specific types).
- return callee == caller && &call_substs[..trait_substs.len()] == trait_substs;
+ return callee == caller && &call_args[..self.trait_args.len()] == self.trait_args;
}
false
}
}
-impl<'mir, 'tcx> TriColorVisitor<BasicBlocks<'tcx>> for Search<'mir, 'tcx> {
+impl<'tcx> TerminatorClassifier<'tcx> for RecursiveDrop<'tcx> {
+ fn is_recursive_terminator(
+ &self,
+ tcx: TyCtxt<'tcx>,
+ body: &Body<'tcx>,
+ terminator: &Terminator<'tcx>,
+ ) -> bool {
+ let TerminatorKind::Drop { place, .. } = &terminator.kind else { return false };
+
+ let dropped_ty = place.ty(body, tcx).ty;
+ dropped_ty == self.drop_for
+ }
+}
+
+impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx>>
+ for Search<'mir, 'tcx, C>
+{
type BreakVal = NonRecursive;
fn node_examined(
@@ -138,10 +216,8 @@ impl<'mir, 'tcx> TriColorVisitor<BasicBlocks<'tcx>> for Search<'mir, 'tcx> {
fn node_settled(&mut self, bb: BasicBlock) -> ControlFlow<Self::BreakVal> {
// When we examine a node for the last time, remember it if it is a recursive call.
let terminator = self.body[bb].terminator();
- if let TerminatorKind::Call { func, args, .. } = &terminator.kind {
- if self.is_recursive_call(func, args) {
- self.reachable_recursive_calls.push(terminator.source_info.span);
- }
+ if self.classifier.is_recursive_terminator(self.tcx, self.body, terminator) {
+ self.reachable_recursive_calls.push(terminator.source_info.span);
}
ControlFlow::Continue(())
@@ -149,15 +225,14 @@ impl<'mir, 'tcx> TriColorVisitor<BasicBlocks<'tcx>> for Search<'mir, 'tcx> {
fn ignore_edge(&mut self, bb: BasicBlock, target: BasicBlock) -> bool {
let terminator = self.body[bb].terminator();
- if terminator.unwind() == Some(&mir::UnwindAction::Cleanup(target))
- && terminator.successors().count() > 1
+ let ignore_unwind = terminator.unwind() == Some(&mir::UnwindAction::Cleanup(target))
+ && terminator.successors().count() > 1;
+ if ignore_unwind || self.classifier.is_recursive_terminator(self.tcx, self.body, terminator)
{
return true;
}
- // Don't traverse successors of recursive calls or false CFG edges.
- match self.body[bb].terminator().kind {
- TerminatorKind::Call { ref func, ref args, .. } => self.is_recursive_call(func, args),
- TerminatorKind::FalseEdge { imaginary_target, .. } => imaginary_target == target,
+ match &terminator.kind {
+ TerminatorKind::FalseEdge { imaginary_target, .. } => imaginary_target == &target,
_ => false,
}
}
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 37537683f..6c1f7d7a6 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -15,9 +15,9 @@ use rustc_middle::thir::*;
use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCoercion,
};
-use rustc_middle::ty::subst::InternalSubsts;
+use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{
- self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType,
+ self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType,
};
use rustc_span::{sym, Span};
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
@@ -41,11 +41,6 @@ impl<'tcx> Cx<'tcx> {
let mut expr = self.make_mirror_unadjusted(hir_expr);
- let adjustment_span = match self.adjustment_span {
- Some((hir_id, span)) if hir_id == hir_expr.hir_id => Some(span),
- _ => None,
- };
-
trace!(?expr.ty);
// Now apply adjustments, if any.
@@ -53,12 +48,7 @@ impl<'tcx> Cx<'tcx> {
for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
trace!(?expr, ?adjustment);
let span = expr.span;
- expr = self.apply_adjustment(
- hir_expr,
- expr,
- adjustment,
- adjustment_span.unwrap_or(span),
- );
+ expr = self.apply_adjustment(hir_expr, expr, adjustment, span);
}
}
@@ -220,7 +210,7 @@ impl<'tcx> Cx<'tcx> {
let res = self.typeck_results().qpath_res(qpath, source.hir_id);
let ty = self.typeck_results().node_type(source.hir_id);
- let ty::Adt(adt_def, substs) = ty.kind() else {
+ let ty::Adt(adt_def, args) = ty.kind() else {
return ExprKind::Cast { source: self.mirror_expr(source) };
};
@@ -239,9 +229,7 @@ impl<'tcx> Cx<'tcx> {
let param_env_ty = self.param_env.and(discr_ty);
let size = tcx
.layout_of(param_env_ty)
- .unwrap_or_else(|e| {
- panic!("could not compute layout for {:?}: {:?}", param_env_ty, e)
- })
+ .unwrap_or_else(|e| panic!("could not compute layout for {param_env_ty:?}: {e:?}"))
.size;
let lit = ScalarInt::try_from_uint(discr_offset as u128, size).unwrap();
@@ -252,7 +240,7 @@ impl<'tcx> Cx<'tcx> {
// in case we are offsetting from a computed discriminant
// and not the beginning of discriminants (which is always `0`)
Some(did) => {
- let kind = ExprKind::NamedConst { def_id: did, substs, user_ty: None };
+ let kind = ExprKind::NamedConst { def_id: did, args, user_ty: None };
let lhs =
self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
@@ -274,7 +262,6 @@ impl<'tcx> Cx<'tcx> {
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
let tcx = self.tcx;
let expr_ty = self.typeck_results().expr_ty(expr);
- let expr_span = expr.span;
let temp_lifetime =
self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);
@@ -283,17 +270,11 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::MethodCall(segment, receiver, ref args, fn_span) => {
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
let expr = self.method_callee(expr, segment.ident.span, None);
- // When we apply adjustments to the receiver, use the span of
- // the overall method call for better diagnostics. args[0]
- // is guaranteed to exist, since a method call always has a receiver.
- let old_adjustment_span =
- self.adjustment_span.replace((receiver.hir_id, expr_span));
info!("Using method span: {:?}", expr.span);
let args = std::iter::once(receiver)
.chain(args.iter())
.map(|expr| self.mirror_expr(expr))
.collect();
- self.adjustment_span = old_adjustment_span;
ExprKind::Call {
ty: expr.ty,
fun: self.thir.exprs.push(expr),
@@ -389,7 +370,7 @@ impl<'tcx> Cx<'tcx> {
None
};
if let Some((adt_def, index)) = adt_data {
- let substs = self.typeck_results().node_substs(fun.hir_id);
+ let node_args = self.typeck_results().node_args(fun.hir_id);
let user_provided_types = self.typeck_results().user_provided_types();
let user_ty =
user_provided_types.get(fun.hir_id).copied().map(|mut u_ty| {
@@ -410,7 +391,7 @@ impl<'tcx> Cx<'tcx> {
.collect();
ExprKind::Adt(Box::new(AdtExpr {
adt_def,
- substs,
+ args: node_args,
variant_index: index,
fields: field_refs,
user_ty,
@@ -464,7 +445,6 @@ impl<'tcx> Cx<'tcx> {
let rhs = self.mirror_expr(rhs);
self.overloaded_operator(expr, Box::new([lhs, rhs]))
} else {
- // FIXME overflow
match op.node {
hir::BinOpKind::And => ExprKind::LogicalOp {
op: LogicalOp::And,
@@ -488,11 +468,17 @@ impl<'tcx> Cx<'tcx> {
}
}
- hir::ExprKind::Index(ref lhs, ref index) => {
+ hir::ExprKind::Index(ref lhs, ref index, brackets_span) => {
if self.typeck_results().is_method_call(expr) {
let lhs = self.mirror_expr(lhs);
let index = self.mirror_expr(index);
- self.overloaded_place(expr, expr_ty, None, Box::new([lhs, index]), expr.span)
+ self.overloaded_place(
+ expr,
+ expr_ty,
+ None,
+ Box::new([lhs, index]),
+ brackets_span,
+ )
} else {
ExprKind::Index { lhs: self.mirror_expr(lhs), index: self.mirror_expr(index) }
}
@@ -528,7 +514,7 @@ impl<'tcx> Cx<'tcx> {
}
hir::ExprKind::Struct(ref qpath, ref fields, ref base) => match expr_ty.kind() {
- ty::Adt(adt, substs) => match adt.adt_kind() {
+ ty::Adt(adt, args) => match adt.adt_kind() {
AdtKind::Struct | AdtKind::Union => {
let user_provided_types = self.typeck_results().user_provided_types();
let user_ty = user_provided_types.get(expr.hir_id).copied().map(Box::new);
@@ -536,7 +522,7 @@ impl<'tcx> Cx<'tcx> {
ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt,
variant_index: FIRST_VARIANT,
- substs,
+ args,
user_ty,
fields: self.field_refs(fields),
base: base.map(|base| FruInfo {
@@ -563,7 +549,7 @@ impl<'tcx> Cx<'tcx> {
ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt,
variant_index: index,
- substs,
+ args,
user_ty,
fields: self.field_refs(fields),
base: None,
@@ -582,10 +568,10 @@ impl<'tcx> Cx<'tcx> {
hir::ExprKind::Closure { .. } => {
let closure_ty = self.typeck_results().expr_ty(expr);
- let (def_id, substs, movability) = match *closure_ty.kind() {
- ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs), None),
- ty::Generator(def_id, substs, movability) => {
- (def_id, UpvarSubsts::Generator(substs), Some(movability))
+ let (def_id, args, movability) = match *closure_ty.kind() {
+ ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args), None),
+ ty::Generator(def_id, args, movability) => {
+ (def_id, UpvarArgs::Generator(args), Some(movability))
}
_ => {
span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
@@ -597,7 +583,7 @@ impl<'tcx> Cx<'tcx> {
.tcx
.closure_captures(def_id)
.iter()
- .zip(substs.upvar_tys())
+ .zip(args.upvar_tys())
.map(|(captured_place, ty)| {
let upvars = self.capture_upvar(expr, captured_place, ty);
self.thir.exprs.push(upvars)
@@ -618,7 +604,7 @@ impl<'tcx> Cx<'tcx> {
ExprKind::Closure(Box::new(ClosureExpr {
closure_id: def_id,
- substs,
+ args,
upvars,
movability,
fake_reads,
@@ -701,13 +687,11 @@ impl<'tcx> Cx<'tcx> {
let ty = self.typeck_results().node_type(anon_const.hir_id);
let did = anon_const.def_id.to_def_id();
let typeck_root_def_id = tcx.typeck_root_def_id(did);
- let parent_substs =
- tcx.erase_regions(InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
- let substs =
- InlineConstSubsts::new(tcx, InlineConstSubstsParts { parent_substs, ty })
- .substs;
+ let parent_args =
+ tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
+ let args = InlineConstArgs::new(tcx, InlineConstArgsParts { parent_args, ty }).args;
- ExprKind::ConstBlock { did, substs }
+ ExprKind::ConstBlock { did, args }
}
// Now comes the rote stuff:
hir::ExprKind::Repeat(ref v, _) => {
@@ -748,6 +732,7 @@ impl<'tcx> Cx<'tcx> {
},
hir::ExprKind::Match(ref discr, ref arms, _) => ExprKind::Match {
scrutinee: self.mirror_expr(discr),
+ scrutinee_hir_id: discr.hir_id,
arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
},
hir::ExprKind::Loop(ref body, ..) => {
@@ -826,12 +811,12 @@ impl<'tcx> Cx<'tcx> {
Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind }
}
- fn user_substs_applied_to_res(
+ fn user_args_applied_to_res(
&mut self,
hir_id: hir::HirId,
res: Res,
) -> Option<Box<ty::CanonicalUserType<'tcx>>> {
- debug!("user_substs_applied_to_res: res={:?}", res);
+ debug!("user_args_applied_to_res: res={:?}", res);
let user_provided_type = match res {
// A reference to something callable -- e.g., a fn, method, or
// a tuple-struct or tuple-variant. This has the type of a
@@ -849,15 +834,15 @@ impl<'tcx> Cx<'tcx> {
// this variant -- but with the substitutions given by the
// user.
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
- self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new)
+ self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)
}
// `Self` is used in expression as a tuple struct constructor or a unit struct constructor
- Res::SelfCtor(_) => self.user_substs_applied_to_ty_of_hir_id(hir_id).map(Box::new),
+ Res::SelfCtor(_) => self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new),
- _ => bug!("user_substs_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
+ _ => bug!("user_args_applied_to_res: unexpected res {:?} at {:?}", res, hir_id),
};
- debug!("user_substs_applied_to_res: user_provided_type={:?}", user_provided_type);
+ debug!("user_args_applied_to_res: user_provided_type={:?}", user_provided_type);
user_provided_type
}
@@ -876,13 +861,13 @@ impl<'tcx> Cx<'tcx> {
self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| {
span_bug!(expr.span, "no type-dependent def for method callee")
});
- let user_ty = self.user_substs_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
+ let user_ty = self.user_args_applied_to_res(expr.hir_id, Res::Def(kind, def_id));
debug!("method_callee: user_ty={:?}", user_ty);
(
Ty::new_fn_def(
self.tcx(),
def_id,
- self.typeck_results().node_substs(expr.hir_id),
+ self.typeck_results().node_args(expr.hir_id),
),
user_ty,
)
@@ -909,14 +894,14 @@ impl<'tcx> Cx<'tcx> {
}
fn convert_path_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, res: Res) -> ExprKind<'tcx> {
- let substs = self.typeck_results().node_substs(expr.hir_id);
+ let args = self.typeck_results().node_args(expr.hir_id);
match res {
// A regular function, constructor function or a constant.
Res::Def(DefKind::Fn, _)
| Res::Def(DefKind::AssocFn, _)
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
| Res::SelfCtor(_) => {
- let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
+ let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
ExprKind::ZstLiteral { user_ty }
}
@@ -931,8 +916,8 @@ impl<'tcx> Cx<'tcx> {
}
Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
- let user_ty = self.user_substs_applied_to_res(expr.hir_id, res);
- ExprKind::NamedConst { def_id, substs, user_ty }
+ let user_ty = self.user_args_applied_to_res(expr.hir_id, res);
+ ExprKind::NamedConst { def_id, args, user_ty }
}
Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
@@ -943,10 +928,10 @@ impl<'tcx> Cx<'tcx> {
match ty.kind() {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
- ty::Adt(adt_def, substs) => ExprKind::Adt(Box::new(AdtExpr {
+ ty::Adt(adt_def, args) => ExprKind::Adt(Box::new(AdtExpr {
adt_def: *adt_def,
variant_index: adt_def.variant_index_with_ctor_id(def_id),
- substs,
+ args,
user_ty,
fields: Box::new([]),
base: None,
@@ -1093,6 +1078,9 @@ impl<'tcx> Cx<'tcx> {
variant_index,
name: field,
},
+ HirProjectionKind::OpaqueCast => {
+ ExprKind::Use { source: self.thir.exprs.push(captured_place_expr) }
+ }
HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here
continue;
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index e6a98d1aa..d98cc76ad 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -16,7 +16,6 @@ use rustc_hir::Node;
use rustc_middle::middle::region;
use rustc_middle::thir::*;
use rustc_middle::ty::{self, RvalueScopes, Ty, TyCtxt};
-use rustc_span::Span;
pub(crate) fn thir_body(
tcx: TyCtxt<'_>,
@@ -62,14 +61,6 @@ struct Cx<'tcx> {
typeck_results: &'tcx ty::TypeckResults<'tcx>,
rvalue_scopes: &'tcx RvalueScopes,
- /// When applying adjustments to the expression
- /// with the given `HirId`, use the given `Span`,
- /// instead of the usual span. This is used to
- /// assign the span of an overall method call
- /// (e.g. `my_val.foo()`) to the adjustment expressions
- /// for the receiver.
- adjustment_span: Option<(HirId, Span)>,
-
/// False to indicate that adjustments should not be applied. Only used for `custom_mir`
apply_adjustments: bool,
@@ -110,7 +101,6 @@ impl<'tcx> Cx<'tcx> {
typeck_results,
rvalue_scopes: &typeck_results.rvalue_scopes,
body_owner: def.to_def_id(),
- adjustment_span: None,
apply_adjustments: hir
.attrs(hir_id)
.iter()
@@ -132,7 +122,7 @@ impl<'tcx> Cx<'tcx> {
DefKind::Closure => {
let closure_ty = self.typeck_results.node_type(owner_id);
- let ty::Closure(closure_def_id, closure_substs) = *closure_ty.kind() else {
+ let ty::Closure(closure_def_id, closure_args) = *closure_ty.kind() else {
bug!("closure expr does not have closure type: {:?}", closure_ty);
};
@@ -144,7 +134,7 @@ impl<'tcx> Cx<'tcx> {
};
let env_region = ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br);
let closure_env_ty =
- self.tcx.closure_env_ty(closure_def_id, closure_substs, env_region).unwrap();
+ self.tcx.closure_env_ty(closure_def_id, closure_args, env_region).unwrap();
let liberated_closure_env_ty = self.tcx.erase_late_bound_regions(
ty::Binder::bind_with_vars(closure_env_ty, bound_vars),
);
@@ -196,7 +186,7 @@ impl<'tcx> Cx<'tcx> {
self.tcx
.type_of(va_list_did)
- .subst(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
+ .instantiate(self.tcx, &[self.tcx.lifetimes.re_erased.into()])
} else {
fn_sig.inputs()[index]
};
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index ef60f08bf..383e80851 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -135,10 +135,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for MatchVisitor<'a, '_, 'tcx> {
});
return;
}
- ExprKind::Match { scrutinee, box ref arms } => {
+ ExprKind::Match { scrutinee, scrutinee_hir_id, box ref arms } => {
let source = match ex.span.desugaring_kind() {
Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
- Some(DesugaringKind::QuestionMark) => hir::MatchSource::TryDesugar,
+ Some(DesugaringKind::QuestionMark) => {
+ hir::MatchSource::TryDesugar(scrutinee_hir_id)
+ }
Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
_ => hir::MatchSource::Normal,
};
@@ -277,7 +279,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
| hir::MatchSource::FormatArgs => report_arm_reachability(&cx, &report),
// Unreachable patterns in try and await expressions occur when one of
// the arms are an uninhabited type. Which is OK.
- hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
+ hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar(_) => {}
}
// Check if the match is exhaustive.
@@ -501,12 +503,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
let witness_1_is_privately_uninhabited =
if cx.tcx.features().exhaustive_patterns
&& let Some(witness_1) = witnesses.get(0)
- && let ty::Adt(adt, substs) = witness_1.ty().kind()
+ && let ty::Adt(adt, args) = witness_1.ty().kind()
&& adt.is_enum()
&& let Constructor::Variant(variant_index) = witness_1.ctor()
{
let variant = adt.variant(*variant_index);
- let inhabited = variant.inhabited_predicate(cx.tcx, *adt).subst(cx.tcx, substs);
+ let inhabited = variant.inhabited_predicate(cx.tcx, *adt).instantiate(cx.tcx, args);
assert!(inhabited.apply(cx.tcx, cx.param_env, cx.module));
!inhabited.apply_ignore_module(cx.tcx, cx.param_env)
} else {
@@ -691,7 +693,7 @@ fn non_exhaustive_match<'p, 'tcx>(
err = create_e0004(
cx.tcx.sess,
sp,
- format!("non-exhaustive patterns: {} not covered", joined_patterns),
+ format!("non-exhaustive patterns: {joined_patterns} not covered"),
);
err.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
patterns_len = witnesses.len();
@@ -721,15 +723,13 @@ fn non_exhaustive_match<'p, 'tcx>(
&& matches!(witnesses[0].ctor(), Constructor::NonExhaustive)
{
err.note(format!(
- "`{}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \
+ "`{scrut_ty}` does not have a fixed maximum value, so a wildcard `_` is necessary to match \
exhaustively",
- scrut_ty,
));
if cx.tcx.sess.is_nightly_build() {
err.help(format!(
"add `#![feature(precise_pointer_size_matching)]` to the crate attributes to \
- enable precise `{}` matching",
- scrut_ty,
+ enable precise `{scrut_ty}` matching",
));
}
}
@@ -745,18 +745,13 @@ fn non_exhaustive_match<'p, 'tcx>(
[] if sp.eq_ctxt(expr_span) => {
// Get the span for the empty match body `{}`.
let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
- (format!("\n{}", snippet), " ")
+ (format!("\n{snippet}"), " ")
} else {
(" ".to_string(), "")
};
suggestion = Some((
sp.shrink_to_hi().with_hi(expr_span.hi()),
- format!(
- " {{{indentation}{more}{pattern} => todo!(),{indentation}}}",
- indentation = indentation,
- more = more,
- pattern = pattern,
- ),
+ format!(" {{{indentation}{more}{pattern} => todo!(),{indentation}}}",),
));
}
[only] => {
@@ -765,7 +760,7 @@ fn non_exhaustive_match<'p, 'tcx>(
&& let Ok(with_trailing) = sm.span_extend_while(only.span, |c| c.is_whitespace() || c == ',')
&& sm.is_multiline(with_trailing)
{
- (format!("\n{}", snippet), true)
+ (format!("\n{snippet}"), true)
} else {
(" ".to_string(), false)
};
@@ -780,7 +775,7 @@ fn non_exhaustive_match<'p, 'tcx>(
};
suggestion = Some((
only.span.shrink_to_hi(),
- format!("{}{}{} => todo!()", comma, pre_indentation, pattern),
+ format!("{comma}{pre_indentation}{pattern} => todo!()"),
));
}
[.., prev, last] => {
@@ -803,7 +798,7 @@ fn non_exhaustive_match<'p, 'tcx>(
if let Some(spacing) = spacing {
suggestion = Some((
last.span.shrink_to_hi(),
- format!("{}{}{} => todo!()", comma, spacing, pattern),
+ format!("{comma}{spacing}{pattern} => todo!()"),
));
}
}
@@ -900,7 +895,7 @@ fn adt_defined_here<'p, 'tcx>(
for pat in spans {
span.push_span_label(pat, "not covered");
}
- err.span_note(span, format!("`{}` defined here", ty));
+ err.span_note(span, format!("`{ty}` defined here"));
}
}
@@ -942,7 +937,9 @@ fn maybe_point_at_variant<'a, 'p: 'a, 'tcx: 'a>(
/// This analysis is *not* subsumed by NLL.
fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, '_, 'tcx>, pat: &Pat<'tcx>) {
// Extract `sub` in `binding @ sub`.
- let PatKind::Binding { name, mode, ty, subpattern: Some(box ref sub), .. } = pat.kind else { return };
+ let PatKind::Binding { name, mode, ty, subpattern: Some(box ref sub), .. } = pat.kind else {
+ return;
+ };
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 050b01294..1376344cf 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -325,6 +325,11 @@ impl<'tcx> ConstToPat<'tcx> {
// `PartialEq::eq` on it.
return Err(FallbackToConstRef);
}
+ ty::FnDef(..) => {
+ self.saw_const_match_error.set(true);
+ tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
+ PatKind::Wild
+ }
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
self.saw_const_match_error.set(true);
@@ -332,20 +337,20 @@ impl<'tcx> ConstToPat<'tcx> {
tcx.sess.emit_err(err);
PatKind::Wild
}
- ty::Adt(adt_def, substs) if adt_def.is_enum() => {
+ ty::Adt(adt_def, args) if adt_def.is_enum() => {
let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap();
let variant_index =
VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap());
PatKind::Variant {
adt_def: *adt_def,
- substs,
+ args,
variant_index,
subpatterns: self.field_pats(
fields.iter().copied().zip(
adt_def.variants()[variant_index]
.fields
.iter()
- .map(|field| field.ty(self.tcx(), substs)),
+ .map(|field| field.ty(self.tcx(), args)),
),
)?,
}
@@ -354,9 +359,9 @@ impl<'tcx> ConstToPat<'tcx> {
subpatterns: self
.field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?,
},
- ty::Adt(def, substs) => PatKind::Leaf {
+ ty::Adt(def, args) => PatKind::Leaf {
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
- def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), substs)),
+ def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), args)),
))?,
},
ty::Slice(elem_ty) => PatKind::Slice {
@@ -440,7 +445,7 @@ impl<'tcx> ConstToPat<'tcx> {
}
}
},
- ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => PatKind::Constant {
+ ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => PatKind::Constant {
value: mir::ConstantKind::Ty(ty::Const::new_value(tcx, cv, ty)),
},
ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(),
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index 9df6d2f43..bee1c4e46 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -306,9 +306,9 @@ impl fmt::Debug for IntRange {
let (lo, hi) = self.boundaries();
let bias = self.bias;
let (lo, hi) = (lo ^ bias, hi ^ bias);
- write!(f, "{}", lo)?;
+ write!(f, "{lo}")?;
write!(f, "{}", RangeEnd::Included)?;
- write!(f, "{}", hi)
+ write!(f, "{hi}")
}
}
@@ -922,7 +922,7 @@ impl<'tcx> SplitWildcard<'tcx> {
let kind = if cx.is_uninhabited(*sub_ty) { FixedLen(0) } else { VarLen(0, 0) };
smallvec![Slice(Slice::new(None, kind))]
}
- ty::Adt(def, substs) if def.is_enum() => {
+ ty::Adt(def, args) if def.is_enum() => {
// If the enum is declared as `#[non_exhaustive]`, we treat it as if it had an
// additional "unknown" constructor.
// There is no point in enumerating all possible variants, because the user can't
@@ -950,21 +950,19 @@ impl<'tcx> SplitWildcard<'tcx> {
let is_secretly_empty =
def.variants().is_empty() && !is_exhaustive_pat_feature && !pcx.is_top_level;
- let mut ctors: SmallVec<[_; 1]> = def
- .variants()
- .iter_enumerated()
- .filter(|(_, v)| {
- // If `exhaustive_patterns` is enabled, we exclude variants known to be
- // uninhabited.
- !is_exhaustive_pat_feature
- || v.inhabited_predicate(cx.tcx, *def).subst(cx.tcx, substs).apply(
- cx.tcx,
- cx.param_env,
- cx.module,
- )
- })
- .map(|(idx, _)| Variant(idx))
- .collect();
+ let mut ctors: SmallVec<[_; 1]> =
+ def.variants()
+ .iter_enumerated()
+ .filter(|(_, v)| {
+ // If `exhaustive_patterns` is enabled, we exclude variants known to be
+ // uninhabited.
+ !is_exhaustive_pat_feature
+ || v.inhabited_predicate(cx.tcx, *def)
+ .instantiate(cx.tcx, args)
+ .apply(cx.tcx, cx.param_env, cx.module)
+ })
+ .map(|(idx, _)| Variant(idx))
+ .collect();
if is_secretly_empty || is_declared_nonexhaustive {
ctors.push(NonExhaustive);
@@ -1156,12 +1154,12 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
ty: Ty<'tcx>,
variant: &'a VariantDef,
) -> impl Iterator<Item = (FieldIdx, Ty<'tcx>)> + Captures<'a> + Captures<'p> {
- let ty::Adt(adt, substs) = ty.kind() else { bug!() };
+ let ty::Adt(adt, args) = ty.kind() else { bug!() };
// Whether we must not match the fields of this variant exhaustively.
let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
- let ty = field.ty(cx.tcx, substs);
+ let ty = field.ty(cx.tcx, args);
// `field.ty()` doesn't normalize after substituting.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
@@ -1183,11 +1181,11 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
Single | Variant(_) => match pcx.ty.kind() {
ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter(), pcx.span),
ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty), pcx.span),
- ty::Adt(adt, substs) => {
+ ty::Adt(adt, args) => {
if adt.is_box() {
// The only legal patterns of type `Box` (outside `std`) are `_` and box
// patterns. If we're here we can assume this is a box pattern.
- Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)), pcx.span)
+ Fields::wildcards_from_tys(pcx.cx, once(args.type_at(0)), pcx.span)
} else {
let variant = &adt.variant(constructor.variant_index_for_adt(*adt));
let tys = Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant)
@@ -1294,7 +1292,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
fields = Fields::from_iter(cx, wilds);
}
- ty::Adt(adt, substs) if adt.is_box() => {
+ ty::Adt(adt, args) if adt.is_box() => {
// The only legal patterns of type `Box` (outside `std`) are `_` and box
// patterns. If we're here we can assume this is a box pattern.
// FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_,
@@ -1311,7 +1309,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
let pat = if let Some(pat) = pattern {
mkpat(&pat.pattern)
} else {
- DeconstructedPat::wildcard(substs.type_at(0), pat.span)
+ DeconstructedPat::wildcard(args.type_at(0), pat.span)
};
ctor = Single;
fields = Fields::singleton(cx, pat);
@@ -1437,7 +1435,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
// the pattern is a box pattern.
PatKind::Deref { subpattern: subpatterns.next().unwrap() }
}
- ty::Adt(adt_def, substs) => {
+ ty::Adt(adt_def, args) => {
let variant_index = self.ctor.variant_index_for_adt(*adt_def);
let variant = &adt_def.variant(variant_index);
let subpatterns = Fields::list_variant_nonhidden_fields(cx, self.ty, variant)
@@ -1446,7 +1444,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
.collect();
if adt_def.is_enum() {
- PatKind::Variant { adt_def: *adt_def, substs, variant_index, subpatterns }
+ PatKind::Variant { adt_def: *adt_def, args, variant_index, subpatterns }
} else {
PatKind::Leaf { subpatterns }
}
@@ -1621,7 +1619,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
// of `std`). So this branch is only reachable when the feature is enabled and
// the pattern is a box pattern.
let subpattern = self.iter_fields().next().unwrap();
- write!(f, "box {:?}", subpattern)
+ write!(f, "box {subpattern:?}")
}
ty::Adt(..) | ty::Tuple(..) => {
let variant = match self.ty.kind() {
@@ -1640,7 +1638,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
write!(f, "(")?;
for p in self.iter_fields() {
write!(f, "{}", start_or_comma())?;
- write!(f, "{:?}", p)?;
+ write!(f, "{p:?}")?;
}
write!(f, ")")
}
@@ -1676,11 +1674,11 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
write!(f, "]")
}
&FloatRange(lo, hi, end) => {
- write!(f, "{}", lo)?;
- write!(f, "{}", end)?;
- write!(f, "{}", hi)
+ write!(f, "{lo}")?;
+ write!(f, "{end}")?;
+ write!(f, "{hi}")
}
- IntRange(range) => write!(f, "{:?}", range), // Best-effort, will render e.g. `false` as `0..=0`
+ IntRange(range) => write!(f, "{range:?}"), // Best-effort, will render e.g. `false` as `0..=0`
Wildcard | Missing { .. } | NonExhaustive => write!(f, "_ : {:?}", self.ty),
Or => {
for pat in self.iter_fields() {
@@ -1688,7 +1686,7 @@ impl<'p, 'tcx> fmt::Debug for DeconstructedPat<'p, 'tcx> {
}
Ok(())
}
- Str(value) => write!(f, "{}", value),
+ Str(value) => write!(f, "{value}"),
Opaque => write!(f, "<constant pattern>"),
}
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 600995927..c08fe54c3 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -23,10 +23,10 @@ use rustc_middle::mir::interpret::{
use rustc_middle::mir::{self, ConstantKind, UserTypeProjection};
use rustc_middle::mir::{BorrowKind, Mutability};
use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange};
-use rustc_middle::ty::subst::{GenericArg, SubstsRef};
use rustc_middle::ty::CanonicalUserTypeAnnotation;
use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, AdtDef, Region, Ty, TyCtxt, UserType};
+use rustc_middle::ty::{GenericArg, GenericArgsRef};
use rustc_span::{Span, Symbol};
use rustc_target::abi::FieldIdx;
@@ -416,8 +416,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
let enum_id = self.tcx.parent(variant_id);
let adt_def = self.tcx.adt_def(enum_id);
if adt_def.is_enum() {
- let substs = match ty.kind() {
- ty::Adt(_, substs) | ty::FnDef(_, substs) => substs,
+ let args = match ty.kind() {
+ ty::Adt(_, args) | ty::FnDef(_, args) => args,
ty::Error(_) => {
// Avoid ICE (#50585)
return PatKind::Wild;
@@ -426,7 +426,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
};
PatKind::Variant {
adt_def,
- substs,
+ args,
variant_index: adt_def.variant_index_with_id(variant_id),
subpatterns,
}
@@ -439,7 +439,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
DefKind::Struct
| DefKind::Ctor(CtorOf::Struct, ..)
| DefKind::Union
- | DefKind::TyAlias
+ | DefKind::TyAlias { .. }
| DefKind::AssocTy,
_,
)
@@ -460,7 +460,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
}
};
- if let Some(user_ty) = self.user_substs_applied_to_ty_of_hir_id(hir_id) {
+ if let Some(user_ty) = self.user_args_applied_to_ty_of_hir_id(hir_id) {
debug!("lower_variant_or_leaf: kind={:?} user_ty={:?} span={:?}", kind, user_ty, span);
let annotation = CanonicalUserTypeAnnotation {
user_ty: Box::new(user_ty),
@@ -496,13 +496,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Use `Reveal::All` here because patterns are always monomorphic even if their function
// isn't.
let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx);
- // N.B. There is no guarantee that substs collected in typeck results are fully normalized,
+ // N.B. There is no guarantee that args collected in typeck results are fully normalized,
// so they need to be normalized in order to pass to `Instance::resolve`, which will ICE
// if given unnormalized types.
- let substs = self
+ let args = self
.tcx
- .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_substs(id));
- let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) {
+ .normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_args(id));
+ let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, args) {
Ok(Some(i)) => i,
Ok(None) => {
// It should be assoc consts if there's no error but we cannot resolve it.
@@ -617,16 +617,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
}
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
- let parent_substs =
- tcx.erase_regions(ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id));
- let substs =
- ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
- .substs;
+ let parent_args =
+ tcx.erase_regions(ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id));
+ let args = ty::InlineConstArgs::new(tcx, ty::InlineConstArgsParts { parent_args, ty }).args;
- let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None };
- debug_assert!(!substs.has_free_regions());
+ let uneval = mir::UnevaluatedConst { def: def_id.to_def_id(), args, promoted: None };
+ debug_assert!(!args.has_free_regions());
- let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), substs: substs };
+ let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args: args };
// First try using a valtree in order to destructure the constant into a pattern.
if let Ok(Some(valtree)) =
self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
@@ -754,7 +752,7 @@ macro_rules! ClonePatternFoldableImpls {
ClonePatternFoldableImpls! { <'tcx>
Span, FieldIdx, Mutability, Symbol, LocalVarId, usize,
Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>,
- SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
+ GenericArgsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>,
UserTypeProjection, CanonicalUserTypeAnnotation<'tcx>
}
@@ -804,10 +802,10 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
is_primary,
}
}
- PatKind::Variant { adt_def, substs, variant_index, ref subpatterns } => {
+ PatKind::Variant { adt_def, args, variant_index, ref subpatterns } => {
PatKind::Variant {
adt_def: adt_def.fold_with(folder),
- substs: substs.fold_with(folder),
+ args: args.fold_with(folder),
variant_index,
subpatterns: subpatterns.fold_with(folder),
}
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index e5b635069..08cfe98bb 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -459,7 +459,7 @@ impl<'p, 'tcx> fmt::Debug for PatStack<'p, 'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "+")?;
for pat in self.iter() {
- write!(f, " {:?} +", pat)?;
+ write!(f, " {pat:?} +")?;
}
Ok(())
}
@@ -530,7 +530,7 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
let Matrix { patterns: m, .. } = self;
let pretty_printed_matrix: Vec<Vec<String>> =
- m.iter().map(|row| row.iter().map(|pat| format!("{:?}", pat)).collect()).collect();
+ m.iter().map(|row| row.iter().map(|pat| format!("{pat:?}")).collect()).collect();
let column_count = m.iter().map(|row| row.len()).next().unwrap_or(0);
assert!(m.iter().all(|row| row.len() == column_count));
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 8d7c624a8..3b6276cfe 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -321,7 +321,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, format!("pat: {:?}", pat), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
- Match { scrutinee, arms } => {
+ Match { scrutinee, arms, .. } => {
print_indented!(self, "Match {", depth_lvl);
print_indented!(self, "scrutinee:", depth_lvl + 1);
self.print_expr(*scrutinee, depth_lvl + 2);
@@ -427,10 +427,10 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
self.print_expr(*value, depth_lvl + 2);
print_indented!(self, "}", depth_lvl);
}
- ConstBlock { did, substs } => {
+ ConstBlock { did, args } => {
print_indented!(self, "ConstBlock {", depth_lvl);
print_indented!(self, format!("did: {:?}", did), depth_lvl + 1);
- print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+ print_indented!(self, format!("args: {:?}", args), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
Repeat { value, count } => {
@@ -499,11 +499,11 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
ZstLiteral { user_ty } => {
print_indented!(self, format!("ZstLiteral(user_ty: {:?})", user_ty), depth_lvl);
}
- NamedConst { def_id, substs, user_ty } => {
+ NamedConst { def_id, args, user_ty } => {
print_indented!(self, "NamedConst {", depth_lvl);
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
print_indented!(self, format!("user_ty: {:?}", user_ty), depth_lvl + 1);
- print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+ print_indented!(self, format!("args: {:?}", args), depth_lvl + 1);
print_indented!(self, "}", depth_lvl);
}
ConstParam { param, def_id } => {
@@ -560,7 +560,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
format!("variant_index: {:?}", adt_expr.variant_index),
depth_lvl + 1
);
- print_indented!(self, format!("substs: {:?}", adt_expr.substs), depth_lvl + 1);
+ print_indented!(self, format!("args: {:?}", adt_expr.args), depth_lvl + 1);
print_indented!(self, format!("user_ty: {:?}", adt_expr.user_ty), depth_lvl + 1);
for (i, field_expr) in adt_expr.fields.iter().enumerate() {
@@ -662,11 +662,11 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
print_indented!(self, "}", depth_lvl + 1);
}
- PatKind::Variant { adt_def, substs, variant_index, subpatterns } => {
+ PatKind::Variant { adt_def, args, variant_index, subpatterns } => {
print_indented!(self, "Variant {", depth_lvl + 1);
print_indented!(self, "adt_def: ", depth_lvl + 2);
self.print_adt_def(*adt_def, depth_lvl + 3);
- print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 2);
+ print_indented!(self, format!("args: {:?}", args), depth_lvl + 2);
print_indented!(self, format!("variant_index: {:?}", variant_index), depth_lvl + 2);
if subpatterns.len() > 0 {
@@ -784,11 +784,11 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
}
fn print_closure_expr(&mut self, expr: &ClosureExpr<'tcx>, depth_lvl: usize) {
- let ClosureExpr { closure_id, substs, upvars, movability, fake_reads } = expr;
+ let ClosureExpr { closure_id, args, upvars, movability, fake_reads } = expr;
print_indented!(self, "ClosureExpr {", depth_lvl);
print_indented!(self, format!("closure_id: {:?}", closure_id), depth_lvl + 1);
- print_indented!(self, format!("substs: {:?}", substs), depth_lvl + 1);
+ print_indented!(self, format!("args: {:?}", args), depth_lvl + 1);
if upvars.len() > 0 {
print_indented!(self, "upvars: [", depth_lvl + 1);
diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs
index c58ed1ac0..9106b4d33 100644
--- a/compiler/rustc_mir_build/src/thir/util.rs
+++ b/compiler/rustc_mir_build/src/thir/util.rs
@@ -9,7 +9,7 @@ pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
/// Looks up the type associated with this hir-id and applies the
/// user-given substitutions; the hir-id must map to a suitable
/// type.
- fn user_substs_applied_to_ty_of_hir_id(
+ fn user_args_applied_to_ty_of_hir_id(
&self,
hir_id: hir::HirId,
) -> Option<CanonicalUserType<'tcx>> {