refactor(rustc_middle): Substs -> GenericArg

This commit is contained in:
Mahdi Dibaiee 2023-07-11 22:35:29 +01:00
parent df5c2cf9bc
commit e55583c4b8
466 changed files with 4574 additions and 4604 deletions

View file

@ -65,7 +65,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
direction,
Invert::Yes,
));
// Relate via substs
// Relate via args
let subst_relate_response = self
.assemble_subst_relate_candidate(param_env, alias_lhs, alias_rhs, direction);
candidates.extend(subst_relate_response);
@ -153,7 +153,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
alias_rhs: ty::AliasTy<'tcx>,
direction: ty::AliasRelationDirection,
) -> QueryResult<'tcx> {
self.probe_candidate("substs relate").enter(|ecx| {
self.probe_candidate("args relate").enter(|ecx| {
match direction {
ty::AliasRelationDirection::Equate => {
ecx.eq(param_env, alias_lhs, alias_rhs)?;

View file

@ -542,7 +542,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
};
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
for assumption in
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
{
match G::consider_alias_bound_candidate(self, goal, assumption) {
Ok(result) => {

View file

@ -51,36 +51,36 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
Ok(tys.iter().collect())
}
ty::Closure(_, ref substs) => Ok(vec![substs.as_closure().tupled_upvars_ty()]),
ty::Closure(_, ref args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
ty::Generator(_, ref substs, _) => {
let generator_substs = substs.as_generator();
Ok(vec![generator_substs.tupled_upvars_ty(), generator_substs.witness()])
ty::Generator(_, ref args, _) => {
let generator_args = args.as_generator();
Ok(vec![generator_args.tupled_upvars_ty(), generator_args.witness()])
}
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
.tcx()
.generator_hidden_types(def_id)
.map(|bty| {
ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
tcx,
bty.subst(tcx, substs),
bty.instantiate(tcx, args),
))
})
.collect()),
// For `PhantomData<T>`, we pass `T`.
ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![args.type_at(0)]),
ty::Adt(def, substs) => Ok(def.all_fields().map(|f| f.ty(tcx, substs)).collect()),
ty::Adt(def, args) => Ok(def.all_fields().map(|f| f.ty(tcx, args)).collect()),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
Ok(vec![tcx.type_of(def_id).subst(tcx, substs)])
Ok(vec![tcx.type_of(def_id).instantiate(tcx, args)])
}
}
}
@ -146,9 +146,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
ty::Tuple(tys) => Ok(tys.to_vec()),
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
let sized_crit = def.sized_constraint(ecx.tcx());
Ok(sized_crit.subst_iter_copied(ecx.tcx(), substs).collect())
Ok(sized_crit.arg_iter_copied(ecx.tcx(), args).collect())
}
}
}
@ -192,11 +192,11 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
ty::Tuple(tys) => Ok(tys.to_vec()),
ty::Closure(_, substs) => Ok(vec![substs.as_closure().tupled_upvars_ty()]),
ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
ty::Generator(_, substs, Movability::Movable) => {
ty::Generator(_, args, Movability::Movable) => {
if ecx.tcx().features().generator_clone {
let generator = substs.as_generator();
let generator = args.as_generator();
Ok(vec![generator.tupled_upvars_ty(), generator.witness()])
} else {
Err(NoSolution)
@ -205,13 +205,13 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
.tcx()
.generator_hidden_types(def_id)
.map(|bty| {
ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
ecx.tcx(),
bty.subst(ecx.tcx(), substs),
bty.instantiate(ecx.tcx(), args),
))
})
.collect()),
@ -226,13 +226,13 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
) -> Result<Option<ty::Binder<'tcx, (Ty<'tcx>, Ty<'tcx>)>>, NoSolution> {
match *self_ty.kind() {
// keep this in sync with assemble_fn_pointer_candidates until the old solver is removed.
ty::FnDef(def_id, substs) => {
ty::FnDef(def_id, args) => {
let sig = tcx.fn_sig(def_id);
if sig.skip_binder().is_fn_trait_compatible()
&& tcx.codegen_fn_attrs(def_id).target_features.is_empty()
{
Ok(Some(
sig.subst(tcx, substs)
sig.instantiate(tcx, args)
.map_bound(|sig| (Ty::new_tup(tcx, sig.inputs()), sig.output())),
))
} else {
@ -247,9 +247,9 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
Err(NoSolution)
}
}
ty::Closure(_, substs) => {
let closure_substs = substs.as_closure();
match closure_substs.kind_ty().to_opt_closure_kind() {
ty::Closure(_, args) => {
let closure_args = args.as_closure();
match closure_args.kind_ty().to_opt_closure_kind() {
// If the closure's kind doesn't extend the goal kind,
// then the closure doesn't implement the trait.
Some(closure_kind) => {
@ -265,7 +265,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
}
}
}
Ok(Some(closure_substs.sig().map_bound(|sig| (sig.inputs()[0], sig.output()))))
Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output()))))
}
ty::Bool
| ty::Char
@ -347,13 +347,13 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
let tcx = ecx.tcx();
let mut requirements = vec![];
requirements.extend(
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.substs).predicates,
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.args).predicates,
);
for item in tcx.associated_items(trait_ref.def_id).in_definition_order() {
// FIXME(associated_const_equality): Also add associated consts to
// the requirements here.
if item.kind == ty::AssocKind::Type {
requirements.extend(tcx.item_bounds(item.def_id).subst_iter(tcx, trait_ref.substs));
requirements.extend(tcx.item_bounds(item.def_id).arg_iter(tcx, trait_ref.args));
}
}

View file

@ -431,11 +431,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
ty::PredicateKind::Coerce(predicate) => {
self.compute_coerce_goal(Goal { param_env, predicate })
}
ty::PredicateKind::ClosureKind(def_id, substs, kind) => self
.compute_closure_kind_goal(Goal {
param_env,
predicate: (def_id, substs, kind),
}),
ty::PredicateKind::ClosureKind(def_id, args, kind) => self
.compute_closure_kind_goal(Goal { param_env, predicate: (def_id, args, kind) }),
ty::PredicateKind::ObjectSafe(trait_def_id) => {
self.compute_object_safe_goal(trait_def_id)
}
@ -775,24 +772,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.infcx.resolve_vars_if_possible(value)
}
pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> {
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
pub(super) fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
self.infcx.fresh_args_for_item(DUMMY_SP, def_id)
}
pub(super) fn translate_substs(
pub(super) fn translate_args(
&self,
param_env: ty::ParamEnv<'tcx>,
source_impl: DefId,
source_substs: ty::SubstsRef<'tcx>,
source_args: ty::GenericArgsRef<'tcx>,
target_node: specialization_graph::Node,
) -> ty::SubstsRef<'tcx> {
crate::traits::translate_substs(
self.infcx,
param_env,
source_impl,
source_substs,
target_node,
)
) -> ty::GenericArgsRef<'tcx> {
crate::traits::translate_args(self.infcx, param_env, source_impl, source_args, target_node)
}
pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) {
@ -864,14 +855,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn add_item_bounds_for_hidden_type(
&mut self,
opaque_def_id: DefId,
opaque_substs: ty::SubstsRef<'tcx>,
opaque_args: ty::GenericArgsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
hidden_ty: Ty<'tcx>,
) {
let mut obligations = Vec::new();
self.infcx.add_item_bounds_for_hidden_type(
opaque_def_id,
opaque_substs,
opaque_args,
ObligationCause::dummy(),
param_env,
hidden_ty,
@ -897,13 +888,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
continue;
}
values.extend(self.probe_candidate("opaque type storage").enter(|ecx| {
for (a, b) in std::iter::zip(candidate_key.substs, key.substs) {
for (a, b) in std::iter::zip(candidate_key.args, key.args) {
ecx.eq(param_env, a, b)?;
}
ecx.eq(param_env, candidate_ty, ty)?;
ecx.add_item_bounds_for_hidden_type(
candidate_key.def_id.to_def_id(),
candidate_key.substs,
candidate_key.args,
param_env,
candidate_ty,
);

View file

@ -111,7 +111,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> CanonicalResponse<'tcx> {
let unconstrained_response = Response {
var_values: CanonicalVarValues {
var_values: self.tcx().mk_substs_from_iter(self.var_values.var_values.iter().map(
var_values: self.tcx().mk_args_from_iter(self.var_values.var_values.iter().map(
|arg| -> ty::GenericArg<'tcx> {
match arg.unpack() {
GenericArgKind::Lifetime(_) => self.next_region_infer().into(),
@ -250,7 +250,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}
let var_values = self.tcx().mk_substs_from_iter(response.variables.iter().enumerate().map(
let var_values = self.tcx().mk_args_from_iter(response.variables.iter().enumerate().map(
|(index, info)| {
if info.universe() != ty::UniverseIndex::ROOT {
// A variable from inside a binder of the query. While ideally these shouldn't

View file

@ -202,8 +202,9 @@ fn rematch_impl<'tcx>(
impl_def_id: DefId,
mut nested: Vec<PredicateObligation<'tcx>>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
let substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap().subst(infcx.tcx, substs);
let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref =
infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args);
nested.extend(
infcx
@ -214,12 +215,12 @@ fn rematch_impl<'tcx>(
);
nested.extend(
infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, substs).into_iter().map(
infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map(
|(pred, _)| Obligation::new(infcx.tcx, ObligationCause::dummy(), goal.param_env, pred),
),
);
Ok(Some(ImplSource::UserDefined(ImplSourceUserDefinedData { impl_def_id, substs, nested })))
Ok(Some(ImplSource::UserDefined(ImplSourceUserDefinedData { impl_def_id, args, nested })))
}
fn rematch_object<'tcx>(
@ -231,21 +232,20 @@ fn rematch_object<'tcx>(
let ty::Dynamic(data, _, source_kind) = *self_ty.kind() else { bug!() };
let source_trait_ref = data.principal().unwrap().with_self_ty(infcx.tcx, self_ty);
let (is_upcasting, target_trait_ref_unnormalized) = if Some(goal.predicate.def_id())
== infcx.tcx.lang_items().unsize_trait()
{
assert_eq!(source_kind, ty::Dyn, "cannot upcast dyn*");
if let ty::Dynamic(data, _, ty::Dyn) = goal.predicate.trait_ref.substs.type_at(1).kind() {
// FIXME: We also need to ensure that the source lifetime outlives the
// target lifetime. This doesn't matter for codegen, though, and only
// *really* matters if the goal's certainty is ambiguous.
(true, data.principal().unwrap().with_self_ty(infcx.tcx, self_ty))
let (is_upcasting, target_trait_ref_unnormalized) =
if Some(goal.predicate.def_id()) == infcx.tcx.lang_items().unsize_trait() {
assert_eq!(source_kind, ty::Dyn, "cannot upcast dyn*");
if let ty::Dynamic(data, _, ty::Dyn) = goal.predicate.trait_ref.args.type_at(1).kind() {
// FIXME: We also need to ensure that the source lifetime outlives the
// target lifetime. This doesn't matter for codegen, though, and only
// *really* matters if the goal's certainty is ambiguous.
(true, data.principal().unwrap().with_self_ty(infcx.tcx, self_ty))
} else {
bug!()
}
} else {
bug!()
}
} else {
(false, ty::Binder::dummy(goal.predicate.trait_ref))
};
(false, ty::Binder::dummy(goal.predicate.trait_ref))
};
let mut target_trait_ref = None;
for candidate_trait_ref in supertraits(infcx.tcx, source_trait_ref) {
@ -323,7 +323,7 @@ fn rematch_unsize<'tcx>(
) -> SelectionResult<'tcx, Selection<'tcx>> {
let tcx = infcx.tcx;
let a_ty = goal.predicate.self_ty();
let b_ty = goal.predicate.trait_ref.substs.type_at(1);
let b_ty = goal.predicate.trait_ref.args.type_at(1);
match (a_ty.kind(), b_ty.kind()) {
(_, &ty::Dynamic(data, region, ty::Dyn)) => {
@ -364,7 +364,7 @@ fn rematch_unsize<'tcx>(
);
}
// Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
(&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
if a_def.is_struct() && a_def.did() == b_def.did() =>
{
let unsizing_params = tcx.unsizing_params_for_adt(a_def.did());
@ -382,17 +382,19 @@ fn rematch_unsize<'tcx>(
.expect("expected unsized ADT to have a tail field");
let tail_field_ty = tcx.type_of(tail_field.did);
let a_tail_ty = tail_field_ty.subst(tcx, a_substs);
let b_tail_ty = tail_field_ty.subst(tcx, b_substs);
let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
// Substitute just the unsizing params from B into A. The type after
// this substitution must be equal to B. This is so we don't unsize
// unrelated type parameters.
let new_a_substs =
tcx.mk_substs_from_iter(a_substs.iter().enumerate().map(|(i, a)| {
if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
}));
let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_substs);
let new_a_args = tcx.mk_args_from_iter(
a_args
.iter()
.enumerate()
.map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { a }),
);
let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_args);
nested.extend(
infcx

View file

@ -123,10 +123,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn compute_closure_kind_goal(
&mut self,
goal: Goal<'tcx, (DefId, ty::SubstsRef<'tcx>, ty::ClosureKind)>,
goal: Goal<'tcx, (DefId, ty::GenericArgsRef<'tcx>, ty::ClosureKind)>,
) -> QueryResult<'tcx> {
let (_, substs, expected_kind) = goal.predicate;
let found_kind = substs.as_closure().kind_ty().to_opt_closure_kind();
let (_, args, expected_kind) = goal.predicate;
let found_kind = args.as_closure().kind_ty().to_opt_closure_kind();
let Some(found_kind) = found_kind else {
return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);

View file

@ -117,7 +117,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
self.at.cause.clone(),
self.at.param_env,
ty::Binder::dummy(ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(uv.def, uv.substs),
projection_ty: tcx.mk_alias_ty(uv.def, uv.args),
term: new_infer_ct.into(),
}),
);

View file

@ -26,8 +26,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
if !self.can_define_opaque_ty(opaque_ty_def_id) {
return Err(NoSolution);
}
// FIXME: This may have issues when the substs contain aliases...
match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.substs) {
// FIXME: This may have issues when the args contain aliases...
match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.args) {
Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => {
return self.evaluate_added_goals_and_make_canonical_response(
Certainty::AMBIGUOUS,
@ -40,7 +40,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
// Prefer opaques registered already.
let opaque_type_key =
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, substs: opaque_ty.substs };
ty::OpaqueTypeKey { def_id: opaque_ty_def_id, args: opaque_ty.args };
let matches =
self.unify_existing_opaque_tys(goal.param_env, opaque_type_key, expected);
if !matches.is_empty() {
@ -54,7 +54,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
self.add_item_bounds_for_hidden_type(
opaque_ty.def_id,
opaque_ty.substs,
opaque_ty.args,
goal.param_env,
expected,
);
@ -65,7 +65,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
// e.g. assigning `impl Copy := NotCopy`
self.add_item_bounds_for_hidden_type(
opaque_ty.def_id,
opaque_ty.substs,
opaque_ty.args,
goal.param_env,
expected,
);
@ -73,7 +73,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
(Reveal::All, _) => {
// FIXME: Add an assertion that opaque type storage is empty.
let actual = tcx.type_of(opaque_ty.def_id).subst(tcx, opaque_ty.substs);
let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args);
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}

View file

@ -72,7 +72,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
goal.param_env,
ty::UnevaluatedConst::new(
goal.predicate.projection_ty.def_id,
goal.predicate.projection_ty.substs,
goal.predicate.projection_ty.args,
),
self.tcx()
.type_of(goal.predicate.projection_ty.def_id)
@ -142,19 +142,19 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
if !drcx.substs_refs_may_unify(goal_trait_ref.substs, impl_trait_ref.skip_binder().substs) {
if !drcx.args_refs_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args) {
return Err(NoSolution);
}
ecx.probe(|r| CandidateKind::Candidate { name: "impl".into(), result: *r }).enter(|ecx| {
let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
let impl_args = ecx.fresh_args_for_item(impl_def_id);
let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
let where_clause_bounds = tcx
.predicates_of(impl_def_id)
.instantiate(tcx, impl_substs)
.instantiate(tcx, impl_args)
.predicates
.into_iter()
.map(|pred| goal.with(tcx, pred));
@ -184,7 +184,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
tcx,
guar,
tcx.type_of(goal.predicate.def_id())
.subst(tcx, goal.predicate.projection_ty.substs),
.instantiate(tcx, goal.predicate.projection_ty.args),
)
.into(),
ty::AssocKind::Type => Ty::new_error(tcx, guar).into(),
@ -195,25 +195,25 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
}
// Getting the right substitutions here is complex, e.g. given:
// Getting the right args here is complex, e.g. given:
// - a goal `<Vec<u32> as Trait<i32>>::Assoc<u64>`
// - the applicable impl `impl<T> Trait<i32> for Vec<T>`
// - and the impl which defines `Assoc` being `impl<T, U> Trait<U> for Vec<T>`
//
// We first rebase the goal substs onto the impl, going from `[Vec<u32>, i32, u64]`
// We first rebase the goal args onto the impl, going from `[Vec<u32>, i32, u64]`
// to `[u32, u64]`.
//
// And then map these substs to the substs of the defining impl of `Assoc`, going
// And then map these args to the args of the defining impl of `Assoc`, going
// from `[u32, u64]` to `[u32, i32, u64]`.
let impl_substs_with_gat = goal.predicate.projection_ty.substs.rebase_onto(
let impl_args_with_gat = goal.predicate.projection_ty.args.rebase_onto(
tcx,
goal_trait_ref.def_id,
impl_substs,
impl_args,
);
let substs = ecx.translate_substs(
let args = ecx.translate_args(
goal.param_env,
impl_def_id,
impl_substs_with_gat,
impl_args_with_gat,
assoc_def.defining_node,
);
@ -224,7 +224,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
};
ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))
ecx.eq(goal.param_env, goal.predicate.term, term.instantiate(tcx, args))
.expect("expected goal term to be fully unconstrained");
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
@ -349,7 +349,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
ty::Dynamic(_, _, _) => {
let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
tcx.type_of(dyn_metadata)
.subst(tcx, &[ty::GenericArg::from(goal.predicate.self_ty())])
.instantiate(tcx, &[ty::GenericArg::from(goal.predicate.self_ty())])
}
ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
@ -364,20 +364,18 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
tcx.types.unit
}
ty::Adt(def, substs) if def.is_struct() => {
match def.non_enum_variant().tail_opt() {
None => tcx.types.unit,
Some(field_def) => {
let self_ty = field_def.ty(tcx, substs);
ecx.add_goal(goal.with(
tcx,
ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
));
return ecx
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
}
ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
None => tcx.types.unit,
Some(field_def) => {
let self_ty = field_def.ty(tcx, args);
ecx.add_goal(goal.with(
tcx,
ty::Binder::dummy(goal.predicate.with_self_ty(tcx, self_ty)),
));
return ecx
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
}
}
},
ty::Adt(_, _) => tcx.types.unit,
ty::Tuple(elements) => match elements.last() {
@ -412,7 +410,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
let self_ty = goal.predicate.self_ty();
let ty::Generator(def_id, substs, _) = *self_ty.kind() else {
let ty::Generator(def_id, args, _) = *self_ty.kind() else {
return Err(NoSolution);
};
@ -422,7 +420,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
return Err(NoSolution);
}
let term = substs.as_generator().return_ty().into();
let term = args.as_generator().return_ty().into();
Self::consider_implied_clause(
ecx,
@ -443,7 +441,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
let self_ty = goal.predicate.self_ty();
let ty::Generator(def_id, substs, _) = *self_ty.kind() else {
let ty::Generator(def_id, args, _) = *self_ty.kind() else {
return Err(NoSolution);
};
@ -453,7 +451,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
return Err(NoSolution);
}
let generator = substs.as_generator();
let generator = args.as_generator();
let name = tcx.associated_item(goal.predicate.def_id()).name;
let term = if name == sym::Return {

View file

@ -39,10 +39,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
if !drcx.substs_refs_may_unify(
goal.predicate.trait_ref.substs,
impl_trait_ref.skip_binder().substs,
) {
if !drcx
.args_refs_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
{
return Err(NoSolution);
}
@ -63,13 +62,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
};
ecx.probe_candidate("impl").enter(|ecx| {
let impl_substs = ecx.fresh_substs_for_item(impl_def_id);
let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
let impl_args = ecx.fresh_args_for_item(impl_def_id);
let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
let where_clause_bounds = tcx
.predicates_of(impl_def_id)
.instantiate(tcx, impl_substs)
.instantiate(tcx, impl_args)
.predicates
.into_iter()
.map(|pred| goal.with(tcx, pred));
@ -164,7 +163,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
ecx.probe_candidate("trait alias").enter(|ecx| {
let nested_obligations = tcx
.predicates_of(goal.predicate.def_id())
.instantiate(tcx, goal.predicate.trait_ref.substs);
.instantiate(tcx, goal.predicate.trait_ref.args);
ecx.add_goals(nested_obligations.predicates.into_iter().map(|p| goal.with(tcx, p)));
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
@ -337,7 +336,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}
let self_ty = goal.predicate.self_ty();
let ty::Generator(def_id, substs, _) = *self_ty.kind() else {
let ty::Generator(def_id, args, _) = *self_ty.kind() else {
return Err(NoSolution);
};
@ -347,7 +346,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution);
}
let generator = substs.as_generator();
let generator = args.as_generator();
Self::consider_implied_clause(
ecx,
goal,
@ -369,7 +368,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let tcx = ecx.tcx();
let a_ty = goal.predicate.self_ty();
let b_ty = goal.predicate.trait_ref.substs.type_at(1);
let b_ty = goal.predicate.trait_ref.args.type_at(1);
if b_ty.is_ty_var() {
return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
}
@ -378,7 +377,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
// Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`
(&ty::Dynamic(_, _, ty::Dyn), &ty::Dynamic(_, _, ty::Dyn)) => {
// Dyn upcasting is handled separately, since due to upcasting,
// when there are two supertraits that differ by substs, we
// when there are two supertraits that differ by args, we
// may return more than one query response.
Err(NoSolution)
}
@ -415,7 +414,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
// Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
(&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
if a_def.is_struct() && a_def.did() == b_def.did() =>
{
let unsizing_params = tcx.unsizing_params_for_adt(a_def.did());
@ -428,17 +427,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let tail_field = a_def.non_enum_variant().tail();
let tail_field_ty = tcx.type_of(tail_field.did);
let a_tail_ty = tail_field_ty.subst(tcx, a_substs);
let b_tail_ty = tail_field_ty.subst(tcx, b_substs);
let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
// Substitute just the unsizing params from B into A. The type after
// this substitution must be equal to B. This is so we don't unsize
// unrelated type parameters.
let new_a_substs =
tcx.mk_substs_from_iter(a_substs.iter().enumerate().map(|(i, a)| {
if unsizing_params.contains(i as u32) { b_substs[i] } else { a }
let new_a_args =
tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
if unsizing_params.contains(i as u32) { b_args[i] } else { a }
}));
let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_substs);
let unsized_a_ty = Ty::new_adt(tcx, a_def, new_a_args);
// Finally, we require that `TailA: Unsize<TailB>` for the tail field
// types.
@ -484,7 +483,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
let tcx = ecx.tcx();
let a_ty = goal.predicate.self_ty();
let b_ty = goal.predicate.trait_ref.substs.type_at(1);
let b_ty = goal.predicate.trait_ref.args.type_at(1);
let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
return vec![];
};
@ -598,17 +597,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
// Erase regions because we compute layouts in `rustc_transmute`,
// which will ICE for region vars.
let substs = ecx.tcx().erase_regions(goal.predicate.trait_ref.substs);
let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args);
let Some(assume) =
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, substs.const_at(3))
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(3))
else {
return Err(NoSolution);
};
let certainty = ecx.is_transmutable(
rustc_transmute::Types { dst: substs.type_at(0), src: substs.type_at(1) },
substs.type_at(2),
rustc_transmute::Types { dst: args.type_at(0), src: args.type_at(1) },
args.type_at(2),
assume,
)?;
ecx.evaluate_added_goals_and_make_canonical_response(certainty)

View file

@ -12,7 +12,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let weak_ty = goal.predicate.projection_ty;
let expected = goal.predicate.term.ty().expect("no such thing as a const alias");
let actual = tcx.type_of(weak_ty.def_id).subst(tcx, weak_ty.substs);
let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
self.eq(goal.param_env, expected, actual)?;
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}

View file

@ -324,7 +324,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
Ok(None) => {}
Err(SelectionError::Unimplemented) => {
if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) {
if self.is_param_no_infer(pred.skip_binder().trait_ref.args) {
already_visited.remove(&pred);
self.add_user_pred(&mut user_computed_preds, pred.to_predicate(self.tcx));
predicates.push_back(pred);
@ -334,7 +334,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
{:?} {:?} {:?}",
ty,
pred,
pred.skip_binder().trait_ref.substs
pred.skip_binder().trait_ref.args
);
return None;
}
@ -401,17 +401,17 @@ impl<'tcx> AutoTraitFinder<'tcx> {
) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
{
if new_trait.def_id() == old_trait.def_id() {
let new_substs = new_trait.trait_ref.substs;
let old_substs = old_trait.trait_ref.substs;
let new_args = new_trait.trait_ref.args;
let old_args = old_trait.trait_ref.args;
if !new_substs.types().eq(old_substs.types()) {
if !new_args.types().eq(old_args.types()) {
// We can't compare lifetimes if the types are different,
// so skip checking `old_pred`.
return true;
}
for (new_region, old_region) in
iter::zip(new_substs.regions(), old_substs.regions())
iter::zip(new_args.regions(), old_args.regions())
{
match (*new_region, *old_region) {
// If both predicates have an `ReLateBound` (a HRTB) in the
@ -564,8 +564,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
finished_map
}
fn is_param_no_infer(&self, substs: SubstsRef<'_>) -> bool {
self.is_of_param(substs.type_at(0)) && !substs.types().any(|t| t.has_infer_types())
fn is_param_no_infer(&self, args: GenericArgsRef<'_>) -> bool {
self.is_of_param(args.type_at(0)) && !args.types().any(|t| t.has_infer_types())
}
pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
@ -636,7 +636,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// an inference variable.
// Additionally, we check if we've seen this predicate before,
// to avoid rendering duplicate bounds to the user.
if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
if self.is_param_no_infer(p.skip_binder().projection_ty.args)
&& !p.term().skip_binder().has_infer_types()
&& is_new_pred
{

View file

@ -96,9 +96,7 @@ pub fn overlapping_impls(
let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
let may_overlap = match (impl1_ref, impl2_ref) {
(Some(a), Some(b)) => {
drcx.substs_refs_may_unify(a.skip_binder().substs, b.skip_binder().substs)
}
(Some(a), Some(b)) => drcx.args_refs_may_unify(a.skip_binder().args, b.skip_binder().args),
(None, None) => {
let self_ty1 = tcx.type_of(impl1_def_id).skip_binder();
let self_ty2 = tcx.type_of(impl2_def_id).skip_binder();
@ -143,15 +141,15 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
impl_def_id: DefId,
) -> ty::ImplHeader<'tcx> {
let tcx = selcx.tcx();
let impl_substs = selcx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
let impl_args = selcx.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let header = ty::ImplHeader {
impl_def_id,
self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs),
trait_ref: tcx.impl_trait_ref(impl_def_id).map(|i| i.subst(tcx, impl_substs)),
self_ty: tcx.type_of(impl_def_id).instantiate(tcx, impl_args),
trait_ref: tcx.impl_trait_ref(impl_def_id).map(|i| i.instantiate(tcx, impl_args)),
predicates: tcx
.predicates_of(impl_def_id)
.instantiate(tcx, impl_substs)
.instantiate(tcx, impl_args)
.iter()
.map(|(c, _)| c.as_predicate())
.collect(),
@ -353,7 +351,7 @@ fn impl_intersection_has_negative_obligation(
&infcx,
ObligationCause::dummy(),
impl_env,
tcx.impl_subject(impl1_def_id).subst_identity(),
tcx.impl_subject(impl1_def_id).instantiate_identity(),
) {
Ok(s) => s,
Err(err) => {
@ -367,9 +365,9 @@ fn impl_intersection_has_negative_obligation(
// Attempt to prove that impl2 applies, given all of the above.
let selcx = &mut SelectionContext::new(&infcx);
let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
let impl2_args = infcx.fresh_args_for_item(DUMMY_SP, impl2_def_id);
let (subject2, normalization_obligations) =
impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs, |_, _| {
impl_subject_and_oblig(selcx, impl_env, impl2_def_id, impl2_args, |_, _| {
ObligationCause::dummy()
});
@ -519,7 +517,7 @@ pub enum OrphanCheckErr<'tcx> {
pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanCheckErr<'_>> {
// We only except this routine to be invoked on implementations
// of a trait, not inherent implementations.
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity();
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
debug!(?trait_ref);
// If the *trait* is local to the crate, ok.
@ -728,11 +726,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OrphanChecker<'tcx> {
// For fundamental types, we just look inside of them.
ty::Ref(_, ty, _) => ty.visit_with(self),
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
if self.def_id_is_local(def.did()) {
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
} else if def.is_fundamental() {
substs.visit_with(self)
args.visit_with(self)
} else {
self.found_non_local_ty(ty)
}

View file

@ -191,7 +191,7 @@ fn satisfied_from_param_env<'tcx>(
if let ty::ConstKind::Expr(e) = c.kind() {
e.visit_with(self)
} else {
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s args.
// This is currently unobservable as `<T as Trait<{ U + 1 }>>::ASSOC` creates an anon const
// with its own `ConstEvaluatable` bound in the param env which we will visit separately.
//

View file

@ -26,8 +26,8 @@ pub fn recompute_applicable_impls<'tcx>(
let obligation_trait_ref =
ocx.normalize(&ObligationCause::dummy(), param_env, placeholder_obligation.trait_ref);
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().subst(tcx, impl_substs);
let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args);
let impl_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref);
if let Err(_) =
@ -36,7 +36,7 @@ pub fn recompute_applicable_impls<'tcx>(
return false;
}
let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs);
let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args);
ocx.register_obligations(impl_predicates.predicates.iter().map(|&predicate| {
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
}));

View file

@ -1050,8 +1050,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
report_object_safety_error(self.tcx, span, trait_def_id, violations)
}
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
let found_kind = self.closure_kind(closure_substs).unwrap();
ty::PredicateKind::ClosureKind(closure_def_id, closure_args, kind) => {
let found_kind = self.closure_kind(closure_args).unwrap();
self.report_closure_error(&obligation, closure_def_id, found_kind, kind)
}
@ -1627,14 +1627,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
ty::TermKind::Ty(_) => Ty::new_projection(
self.tcx,
data.projection_ty.def_id,
data.projection_ty.substs,
data.projection_ty.args,
)
.into(),
ty::TermKind::Const(ct) => ty::Const::new_unevaluated(
self.tcx,
ty::UnevaluatedConst {
def: data.projection_ty.def_id,
substs: data.projection_ty.substs,
args: data.projection_ty.args,
},
ct.ty(),
)
@ -1972,7 +1972,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
traits.sort();
traits.dedup();
// FIXME: this could use a better heuristic, like just checking
// that substs[1..] is the same.
// that args[1..] is the same.
let all_traits_equal = traits.len() == 1;
let candidates: Vec<String> = candidates
@ -2018,7 +2018,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|| self.tcx.is_automatically_derived(def_id)
})
.filter_map(|def_id| self.tcx.impl_trait_ref(def_id))
.map(ty::EarlyBinder::subst_identity)
.map(ty::EarlyBinder::instantiate_identity)
.filter(|trait_ref| {
let self_ty = trait_ref.self_ty();
// Avoid mentioning type parameters.
@ -2267,7 +2267,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Pick the first substitution that still contains inference variables as the one
// we're going to emit an error for. If there are none (see above), fall back to
// a more general error.
let subst = data.trait_ref.substs.iter().find(|s| s.has_non_region_infer());
let subst = data.trait_ref.args.iter().find(|s| s.has_non_region_infer());
let mut err = if let Some(subst) = subst {
self.emit_inference_failure_err(
@ -2292,7 +2292,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&obligation.with(self.tcx, trait_ref),
);
let has_non_region_infer =
trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
trait_ref.skip_binder().args.types().any(|t| !t.is_ty_or_numeric_infer());
// It doesn't make sense to talk about applicable impls if there are more
// than a handful of them.
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
@ -2330,7 +2330,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
}
if let Some(ty::subst::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack())
if let Some(ty::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack())
&& let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
{
let mut expr_finder = FindExprBySpan::new(span);
@ -2389,7 +2389,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Otherwise, use a placeholder comment for the implementation.
let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
"use the fully-qualified path to the only available implementation".to_string(),
format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
format!("<{} as ", self.tcx.type_of(impl_def_id).instantiate_identity())
)} else {(
format!(
"use a fully-qualified path to a specific available implementation ({} found)",
@ -2466,7 +2466,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
let subst = data
.projection_ty
.substs
.args
.iter()
.chain(Some(data.term.into_arg()))
.find(|g| g.has_non_region_infer());
@ -2829,9 +2829,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if obligated_types.iter().any(|ot| ot == &self_ty) {
return true;
}
if let ty::Adt(def, substs) = self_ty.kind()
&& let [arg] = &substs[..]
&& let ty::subst::GenericArgKind::Type(ty) = arg.unpack()
if let ty::Adt(def, args) = self_ty.kind()
&& let [arg] = &args[..]
&& let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Adt(inner_def, _) = ty.kind()
&& inner_def == def
{
@ -2883,14 +2883,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_ref = self.tcx.erase_regions(self.tcx.erase_late_bound_regions(trait_ref));
let src_and_dst = rustc_transmute::Types {
dst: trait_ref.substs.type_at(0),
src: trait_ref.substs.type_at(1),
dst: trait_ref.args.type_at(0),
src: trait_ref.args.type_at(1),
};
let scope = trait_ref.substs.type_at(2);
let scope = trait_ref.args.type_at(2);
let Some(assume) = rustc_transmute::Assume::from_const(
self.infcx.tcx,
obligation.param_env,
trait_ref.substs.const_at(3),
trait_ref.args.const_at(3),
) else {
span_bug!(
span,
@ -2905,8 +2905,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
assume,
) {
Answer::No(reason) => {
let dst = trait_ref.substs.type_at(0);
let src = trait_ref.substs.type_at(1);
let dst = trait_ref.args.type_at(0);
let src = trait_ref.args.type_at(1);
let err_msg = format!(
"`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`"
);
@ -3073,7 +3073,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Note any argument mismatches
let given_ty = params.skip_binder();
let expected_ty = trait_ref.skip_binder().substs.type_at(1);
let expected_ty = trait_ref.skip_binder().args.type_at(1);
if let ty::Tuple(given) = given_ty.kind()
&& let ty::Tuple(expected) = expected_ty.kind()
{
@ -3288,7 +3288,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut not_tupled = false;
let found = match found_trait_ref.skip_binder().substs.type_at(1).kind() {
let found = match found_trait_ref.skip_binder().args.type_at(1).kind() {
ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()],
_ => {
not_tupled = true;
@ -3296,7 +3296,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
};
let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1);
let expected_ty = expected_trait_ref.skip_binder().args.type_at(1);
let expected = match expected_ty.kind() {
ty::Tuple(ref tys) => {
tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect()

View file

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{struct_span_err, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt};
use rustc_parse_format::{ParseMode, Parser, Piece, Position};
use rustc_span::symbol::{kw, sym, Symbol};
@ -25,7 +25,7 @@ pub trait TypeErrCtxtExt<'tcx> {
&self,
trait_ref: ty::PolyTraitRef<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> Option<(DefId, SubstsRef<'tcx>)>;
) -> Option<(DefId, GenericArgsRef<'tcx>)>;
/*private*/
fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str>;
@ -56,7 +56,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
&self,
trait_ref: ty::PolyTraitRef<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> Option<(DefId, SubstsRef<'tcx>)> {
) -> Option<(DefId, GenericArgsRef<'tcx>)> {
let tcx = self.tcx;
let param_env = obligation.param_env;
let trait_ref = self.instantiate_binder_with_placeholders(trait_ref);
@ -66,26 +66,23 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut fuzzy_match_impls = vec![];
self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| {
let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id);
let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs);
let impl_args = self.fresh_args_for_item(obligation.cause.span, def_id);
let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate(tcx, impl_args);
let impl_self_ty = impl_trait_ref.self_ty();
if self.can_eq(param_env, trait_self_ty, impl_self_ty) {
self_match_impls.push((def_id, impl_substs));
self_match_impls.push((def_id, impl_args));
if iter::zip(
trait_ref.substs.types().skip(1),
impl_trait_ref.substs.types().skip(1),
)
.all(|(u, v)| self.fuzzy_match_tys(u, v, false).is_some())
if iter::zip(trait_ref.args.types().skip(1), impl_trait_ref.args.types().skip(1))
.all(|(u, v)| self.fuzzy_match_tys(u, v, false).is_some())
{
fuzzy_match_impls.push((def_id, impl_substs));
fuzzy_match_impls.push((def_id, impl_args));
}
}
});
let impl_def_id_and_substs = if self_match_impls.len() == 1 {
let impl_def_id_and_args = if self_match_impls.len() == 1 {
self_match_impls[0]
} else if fuzzy_match_impls.len() == 1 {
fuzzy_match_impls[0]
@ -93,8 +90,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
return None;
};
tcx.has_attr(impl_def_id_and_substs.0, sym::rustc_on_unimplemented)
.then_some(impl_def_id_and_substs)
tcx.has_attr(impl_def_id_and_args.0, sym::rustc_on_unimplemented)
.then_some(impl_def_id_and_args)
}
/// Used to set on_unimplemented's `ItemContext`
@ -143,9 +140,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
obligation: &PredicateObligation<'tcx>,
) -> OnUnimplementedNote {
let (def_id, substs) = self
let (def_id, args) = self
.impl_similar_to(trait_ref, obligation)
.unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs));
.unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().args));
let trait_ref = trait_ref.skip_binder();
let mut flags = vec![];
@ -192,14 +189,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// signature with no type arguments resolved
flags.push((
sym::_Self,
Some(self.tcx.type_of(def.did()).subst_identity().to_string()),
Some(self.tcx.type_of(def.did()).instantiate_identity().to_string()),
));
}
for param in generics.params.iter() {
let value = match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
substs[param.index as usize].to_string()
args[param.index as usize].to_string()
}
GenericParamDefKind::Lifetime => continue,
};
@ -207,13 +204,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
flags.push((name, Some(value)));
if let GenericParamDefKind::Type { .. } = param.kind {
let param_ty = substs[param.index as usize].expect_ty();
let param_ty = args[param.index as usize].expect_ty();
if let Some(def) = param_ty.ty_adt_def() {
// We also want to be able to select the parameter's
// original signature with no type arguments resolved
flags.push((
name,
Some(self.tcx.type_of(def.did()).subst_identity().to_string()),
Some(self.tcx.type_of(def.did()).instantiate_identity().to_string()),
));
}
}
@ -249,7 +246,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// signature with no type arguments resolved
flags.push((
sym::_Self,
Some(format!("[{}]", self.tcx.type_of(def.did()).subst_identity())),
Some(format!("[{}]", self.tcx.type_of(def.did()).instantiate_identity())),
));
}
if aty.is_integral() {
@ -268,7 +265,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let Some(def) = aty.ty_adt_def() {
// We also want to be able to select the array's type's original
// signature with no type arguments resolved
let def_ty = self.tcx.type_of(def.did()).subst_identity();
let def_ty = self.tcx.type_of(def.did()).instantiate_identity();
flags.push((sym::_Self, Some(format!("[{def_ty}; _]"))));
if let Some(n) = len {
flags.push((sym::_Self, Some(format!("[{def_ty}; {n}]"))));
@ -629,7 +626,7 @@ impl<'tcx> OnUnimplementedFormatString {
.filter_map(|param| {
let value = match param.kind {
GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => {
trait_ref.substs[param.index as usize].to_string()
trait_ref.args[param.index as usize].to_string()
}
GenericParamDefKind::Lifetime => return None,
};

View file

@ -30,7 +30,7 @@ use rustc_middle::hir::map;
use rustc_middle::ty::error::TypeError::{self, Sorts};
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, InferTy, InternalSubsts, IsSuggestable,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, GenericArgs, InferTy, IsSuggestable,
ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt, TypeckResults,
};
@ -670,7 +670,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// this that we do in `suggest_restriction` and pull the
// `impl Trait` into a new generic if it shows up somewhere
// else in the predicate.
if !trait_pred.skip_binder().trait_ref.substs[1..]
if !trait_pred.skip_binder().trait_ref.args[1..]
.iter()
.all(|g| g.is_suggestable(self.tcx, false))
{
@ -1183,21 +1183,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let fn_sig = found.fn_sig(self.tcx);
Some((DefIdOrName::DefId(def_id), fn_sig.output(), fn_sig.inputs()))
}
ty::Closure(def_id, substs) => {
let fn_sig = substs.as_closure().sig();
ty::Closure(def_id, args) => {
let fn_sig = args.as_closure().sig();
Some((
DefIdOrName::DefId(def_id),
fn_sig.output(),
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
))
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
self.tcx.item_bounds(def_id).subst(self.tcx, substs).iter().find_map(
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
self.tcx.item_bounds(def_id).instantiate(self.tcx, args).iter().find_map(
|pred| {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
// args tuple will always be args[1]
&& let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind()
{
Some((
DefIdOrName::DefId(def_id),
@ -1214,8 +1214,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
// for existential projection, substs are shifted over by 1
&& let ty::Tuple(args) = proj.substs.type_at(0).kind()
// for existential projection, args are shifted over by 1
&& let ty::Tuple(args) = proj.args.type_at(0).kind()
{
Some((
DefIdOrName::Name("trait object"),
@ -1242,8 +1242,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output()
&& proj.projection_ty.self_ty() == found
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
// args tuple will always be args[1]
&& let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind()
{
Some((
name,
@ -1699,7 +1699,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
if let Some(typeck_results) = &self.typeck_results
&& let ty = typeck_results.expr_ty_adjusted(base)
&& let ty::FnDef(def_id, _substs) = ty.kind()
&& let ty::FnDef(def_id, _args) = ty.kind()
&& let Some(hir::Node::Item(hir::Item { ident, span, vis_span, .. })) =
hir.get_if_local(*def_id)
{
@ -1980,7 +1980,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
infcx: &InferCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Ty<'tcx> {
let inputs = trait_ref.skip_binder().substs.type_at(1);
let inputs = trait_ref.skip_binder().args.type_at(1);
let sig = match inputs.kind() {
ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => {
infcx.tcx.mk_fn_sig(
@ -2061,12 +2061,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
let expected_self =
self.tcx.anonymize_bound_vars(pred.kind().rebind(trait_pred.self_ty()));
let expected_substs = self
let expected_args = self
.tcx
.anonymize_bound_vars(pred.kind().rebind(trait_pred.trait_ref.substs));
.anonymize_bound_vars(pred.kind().rebind(trait_pred.trait_ref.args));
// Find another predicate whose self-type is equal to the expected self type,
// but whose substs don't match.
// but whose args don't match.
let other_pred = predicates.into_iter()
.enumerate()
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
@ -2079,10 +2079,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
== self.tcx.anonymize_bound_vars(
pred.kind().rebind(trait_pred.self_ty()),
)
// But the substs don't match (i.e. incompatible args)
&& expected_substs
// But the args don't match (i.e. incompatible args)
&& expected_args
!= self.tcx.anonymize_bound_vars(
pred.kind().rebind(trait_pred.trait_ref.substs),
pred.kind().rebind(trait_pred.trait_ref.args),
) =>
{
true
@ -3070,7 +3070,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
err.note(msg.trim_end_matches(", ").to_string())
}
ty::GeneratorWitnessMIR(def_id, substs) => {
ty::GeneratorWitnessMIR(def_id, args) => {
use std::fmt::Write;
// FIXME: this is kind of an unusual format for rustc, can we make it more clear?
@ -3079,7 +3079,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut msg =
"required because it captures the following types: ".to_owned();
for bty in tcx.generator_hidden_types(*def_id) {
let ty = bty.subst(tcx, substs);
let ty = bty.instantiate(tcx, args);
write!(msg, "`{}`, ", ty).unwrap();
}
err.note(msg.trim_end_matches(", ").to_string())
@ -3407,7 +3407,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Ty::new_projection(
self.tcx,
item_def_id,
// Future::Output has no substs
// Future::Output has no args
[trait_pred.self_ty()],
)
});
@ -3448,7 +3448,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
_ => return,
};
if let ty::Float(_) = trait_ref.skip_binder().self_ty().kind()
&& let ty::Infer(InferTy::IntVar(_)) = trait_ref.skip_binder().substs.type_at(1).kind()
&& let ty::Infer(InferTy::IntVar(_)) = trait_ref.skip_binder().args.type_at(1).kind()
{
err.span_suggestion_verbose(
rhs_span.shrink_to_hi(),
@ -3468,15 +3468,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
return;
};
let (adt, substs) = match trait_pred.skip_binder().self_ty().kind() {
ty::Adt(adt, substs) if adt.did().is_local() => (adt, substs),
let (adt, args) = match trait_pred.skip_binder().self_ty().kind() {
ty::Adt(adt, args) if adt.did().is_local() => (adt, args),
_ => return,
};
let can_derive = {
let is_derivable_trait = match diagnostic_name {
sym::Default => !adt.is_enum(),
sym::PartialEq | sym::PartialOrd => {
let rhs_ty = trait_pred.skip_binder().trait_ref.substs.type_at(1);
let rhs_ty = trait_pred.skip_binder().trait_ref.args.type_at(1);
trait_pred.skip_binder().self_ty() == rhs_ty
}
sym::Eq | sym::Ord | sym::Clone | sym::Copy | sym::Hash | sym::Debug => true,
@ -3485,8 +3485,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
is_derivable_trait &&
// Ensure all fields impl the trait.
adt.all_fields().all(|field| {
let field_ty = field.ty(self.tcx, substs);
let trait_substs = match diagnostic_name {
let field_ty = field.ty(self.tcx, args);
let trait_args = match diagnostic_name {
sym::PartialEq | sym::PartialOrd => {
Some(field_ty)
}
@ -3495,7 +3495,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
trait_ref: ty::TraitRef::new(self.tcx,
trait_pred.def_id(),
[field_ty].into_iter().chain(trait_substs),
[field_ty].into_iter().chain(trait_args),
),
..*tr
});
@ -3530,7 +3530,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) {
if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code()
&& self.tcx.is_diagnostic_item(sym::SliceIndex, trait_pred.skip_binder().trait_ref.def_id)
&& let ty::Slice(_) = trait_pred.skip_binder().trait_ref.substs.type_at(1).kind()
&& let ty::Slice(_) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
&& let ty::Ref(_, inner_ty, _) = trait_pred.skip_binder().self_ty().kind()
&& let ty::Uint(ty::UintTy::Usize) = inner_ty.kind()
{
@ -3580,8 +3580,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
let mut type_diffs = vec![];
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
&& let Some(node_substs) = typeck_results.node_substs_opt(call_hir_id)
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs)
&& let Some(node_args) = typeck_results.node_args_opt(call_hir_id)
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args)
&& let Some(where_pred) = where_clauses.predicates.get(*idx)
{
if let Some(where_pred) = where_pred.as_trait_clause()
@ -3595,7 +3595,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
let zipped =
iter::zip(where_pred.trait_ref.substs, failed_pred.trait_ref.substs);
iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args);
for (expected, actual) in zipped {
self.probe(|_| {
match self
@ -3686,7 +3686,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, .. }))
= failed_pred.kind().skip_binder()
&& tcx.is_fn_trait(trait_ref.def_id)
&& let [self_ty, found_ty] = trait_ref.substs.as_slice()
&& let [self_ty, found_ty] = trait_ref.args.as_slice()
&& let Some(fn_ty) = self_ty.as_type().filter(|ty| ty.is_fn())
&& let fn_sig @ ty::FnSig {
abi: abi::Abi::Rust,
@ -3706,7 +3706,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Extract `<U as Deref>::Target` assoc type and check that it is `T`
&& let Some(deref_target_did) = tcx.lang_items().deref_target()
&& let projection = Ty::new_projection(tcx,deref_target_did, tcx.mk_substs(&[ty::GenericArg::from(found_ty)]))
&& let projection = Ty::new_projection(tcx,deref_target_did, tcx.mk_args(&[ty::GenericArg::from(found_ty)]))
&& let InferOk { value: deref_target, obligations } = infcx.at(&ObligationCause::dummy(), param_env).normalize(projection)
&& obligations.iter().all(|obligation| infcx.predicate_must_hold_modulo_regions(obligation))
&& infcx.can_eq(param_env, deref_target, target_ty)
@ -3908,7 +3908,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Make `Self` be equivalent to the type of the call chain
// expression we're looking at now, so that we can tell what
// for example `Iterator::Item` is at this point in the chain.
let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
let args = GenericArgs::for_item(self.tcx, trait_def_id, |param, _| {
match param.kind {
ty::GenericParamDefKind::Type { .. } => {
if param.index == 0 {
@ -3926,7 +3926,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// This corresponds to `<ExprTy as Iterator>::Item = _`.
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_ty: self.tcx.mk_alias_ty(proj.def_id, substs),
projection_ty: self.tcx.mk_alias_ty(proj.def_id, args),
term: ty_var.into(),
}),
));

View file

@ -8,7 +8,7 @@ use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, Binder, Const, TypeVisitableExt};
use std::marker::PhantomData;
@ -410,8 +410,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
}
}
ty::PredicateKind::ClosureKind(_, closure_substs, kind) => {
match self.selcx.infcx.closure_kind(closure_substs) {
ty::PredicateKind::ClosureKind(_, closure_args, kind) => {
match self.selcx.infcx.closure_kind(closure_args) {
Some(closure_kind) => {
if closure_kind.extends(kind) {
ProcessResult::Changed(vec![])
@ -536,7 +536,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
if let Ok(new_obligations) = infcx
.at(&obligation.cause, obligation.param_env)
.trace(c1, c2)
.eq(DefineOpaqueTypes::No, a.substs, b.substs)
.eq(DefineOpaqueTypes::No, a.args, b.args)
{
return ProcessResult::Changed(mk_pending(
new_obligations.into_obligations(),
@ -559,31 +559,30 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate = |c: Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
match self.selcx.infcx.try_const_eval_resolve(
obligation.param_env,
unevaluated,
c.ty(),
Some(obligation.cause.span),
) {
Ok(val) => Ok(val),
Err(e) => match e {
ErrorHandled::TooGeneric => {
stalled_on.extend(
unevaluated.substs.iter().filter_map(
let mut evaluate =
|c: Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
match self.selcx.infcx.try_const_eval_resolve(
obligation.param_env,
unevaluated,
c.ty(),
Some(obligation.cause.span),
) {
Ok(val) => Ok(val),
Err(e) => match e {
ErrorHandled::TooGeneric => {
stalled_on.extend(unevaluated.args.iter().filter_map(
TyOrConstInferVar::maybe_from_generic_arg,
),
);
Err(ErrorHandled::TooGeneric)
}
_ => Err(e),
},
));
Err(ErrorHandled::TooGeneric)
}
_ => Err(e),
},
}
} else {
Ok(c)
}
} else {
Ok(c)
}
};
};
match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => {
@ -696,9 +695,9 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
// trait selection is because we don't have enough
// information about the types in the trait.
stalled_on.clear();
stalled_on.extend(substs_infer_vars(
stalled_on.extend(args_infer_vars(
&self.selcx,
trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs),
trait_obligation.predicate.map_bound(|pred| pred.trait_ref.args),
));
debug!(
@ -753,9 +752,9 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
ProjectAndUnifyResult::FailedNormalization => {
stalled_on.clear();
stalled_on.extend(substs_infer_vars(
stalled_on.extend(args_infer_vars(
&self.selcx,
project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs),
project_obligation.predicate.map_bound(|pred| pred.projection_ty.args),
));
ProcessResult::Unchanged
}
@ -770,14 +769,14 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
}
}
/// Returns the set of inference variables contained in `substs`.
fn substs_infer_vars<'a, 'tcx>(
/// Returns the set of inference variables contained in `args`.
fn args_infer_vars<'a, 'tcx>(
selcx: &SelectionContext<'a, 'tcx>,
substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
selcx
.infcx
.resolve_vars_if_possible(substs)
.resolve_vars_if_possible(args)
.skip_binder() // ok because this check doesn't care about regions
.iter()
.filter(|arg| arg.has_non_region_infer())

View file

@ -43,7 +43,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
self_type: Ty<'tcx>,
parent_cause: ObligationCause<'tcx>,
) -> Result<(), CopyImplementationError<'tcx>> {
let (adt, substs) = match self_type.kind() {
let (adt, args) = match self_type.kind() {
// These types used to have a builtin impl.
// Now libcore provides that impl.
ty::Uint(_)
@ -56,7 +56,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
| ty::Ref(_, _, hir::Mutability::Not)
| ty::Array(..) => return Ok(()),
&ty::Adt(adt, substs) => (adt, substs),
&ty::Adt(adt, args) => (adt, args),
_ => return Err(CopyImplementationError::NotAnAdt),
};
@ -66,7 +66,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
param_env,
self_type,
adt,
substs,
args,
parent_cause,
hir::LangItem::Copy,
)
@ -91,7 +91,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
self_type: Ty<'tcx>,
parent_cause: ObligationCause<'tcx>,
) -> Result<(), ConstParamTyImplementationError<'tcx>> {
let (adt, substs) = match self_type.kind() {
let (adt, args) = match self_type.kind() {
// `core` provides these impls.
ty::Uint(_)
| ty::Int(_)
@ -103,7 +103,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
| ty::Ref(.., hir::Mutability::Not)
| ty::Tuple(_) => return Ok(()),
&ty::Adt(adt, substs) => (adt, substs),
&ty::Adt(adt, args) => (adt, args),
_ => return Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed),
};
@ -113,7 +113,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
param_env,
self_type,
adt,
substs,
args,
parent_cause,
hir::LangItem::ConstParamTy,
)
@ -128,7 +128,7 @@ pub fn all_fields_implement_trait<'tcx>(
param_env: ty::ParamEnv<'tcx>,
self_type: Ty<'tcx>,
adt: AdtDef<'tcx>,
substs: &'tcx List<GenericArg<'tcx>>,
args: &'tcx List<GenericArg<'tcx>>,
parent_cause: ObligationCause<'tcx>,
lang_item: LangItem,
) -> Result<(), Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>> {
@ -141,7 +141,7 @@ pub fn all_fields_implement_trait<'tcx>(
let infcx = tcx.infer_ctxt().build();
let ocx = traits::ObligationCtxt::new(&infcx);
let unnormalized_ty = field.ty(tcx, substs);
let unnormalized_ty = field.ty(tcx, args);
if unnormalized_ty.references_error() {
continue;
}
@ -154,11 +154,11 @@ pub fn all_fields_implement_trait<'tcx>(
// FIXME(compiler-errors): This gives us better spans for bad
// projection types like in issue-50480.
// If the ADT has substs, point to the cause we are given.
// If the ADT has args, point to the cause we are given.
// If it does not, then this field probably doesn't normalize
// to begin with, and point to the bad field's span instead.
let normalization_cause = if field
.ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did()))
.ty(tcx, traits::GenericArgs::identity_for_item(tcx, adt.did()))
.has_non_region_param()
{
parent_cause.clone()

View file

@ -32,7 +32,7 @@ use rustc_middle::query::Providers;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFolder, TypeSuperVisitable};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_span::def_id::DefId;
use rustc_span::Span;
@ -61,13 +61,13 @@ pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
pub use self::specialize::{
specialization_graph, translate_substs, translate_substs_with_cause, OverlapError,
specialization_graph, translate_args, translate_args_with_cause, OverlapError,
};
pub use self::structural_match::search_for_structural_match_violation;
pub use self::structural_normalize::StructurallyNormalizeExt;
pub use self::util::elaborate;
pub use self::util::{
check_substs_compatible, supertrait_def_ids, supertraits, transitive_bounds,
check_args_compatible, supertrait_def_ids, supertraits, transitive_bounds,
transitive_bounds_that_define_assoc_item, SupertraitDefIds,
};
pub use self::util::{expand_trait_aliases, TraitAliasExpander};
@ -454,7 +454,7 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
fn subst_and_check_impossible_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
key: (DefId, SubstsRef<'tcx>),
key: (DefId, GenericArgsRef<'tcx>),
) -> bool {
debug!("subst_and_check_impossible_predicates(key={:?})", key);
@ -521,7 +521,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
let impl_trait_ref = tcx
.impl_trait_ref(impl_def_id)
.expect("expected impl to correspond to trait")
.subst_identity();
.instantiate_identity();
let param_env = tcx.param_env(impl_def_id);
let mut visitor = ReferencesOnlyParentGenerics { tcx, generics, trait_item_def_id };
@ -531,7 +531,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI
tcx,
ObligationCause::dummy_with_span(*span),
param_env,
ty::EarlyBinder::bind(*pred).subst(tcx, impl_trait_ref.substs),
ty::EarlyBinder::bind(*pred).instantiate(tcx, impl_trait_ref.args),
)
})
});

View file

@ -17,10 +17,10 @@ use rustc_errors::{DelayDm, FatalError, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::query::Providers;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
use rustc_middle::ty::{
self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
};
use rustc_middle::ty::{GenericArg, GenericArgs};
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
use rustc_span::symbol::Symbol;
@ -270,7 +270,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span
tcx.associated_items(trait_def_id)
.in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type)
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied())
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).instantiate_identity_iter_copied())
.filter_map(|c| predicate_references_self(tcx, c))
.collect()
}
@ -284,7 +284,7 @@ fn predicate_references_self<'tcx>(
match predicate.kind().skip_binder() {
ty::ClauseKind::Trait(ref data) => {
// In the case of a trait predicate, we can skip the "self" type.
data.trait_ref.substs[1..].iter().any(has_self_ty).then_some(sp)
data.trait_ref.args[1..].iter().any(has_self_ty).then_some(sp)
}
ty::ClauseKind::Projection(ref data) => {
// And similarly for projections. This should be redundant with
@ -302,7 +302,7 @@ fn predicate_references_self<'tcx>(
//
// This is ALT2 in issue #56288, see that for discussion of the
// possible alternatives.
data.projection_ty.substs[1..].iter().any(has_self_ty).then_some(sp)
data.projection_ty.args[1..].iter().any(has_self_ty).then_some(sp)
}
ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp),
@ -414,7 +414,7 @@ fn virtual_call_violation_for_method<'tcx>(
trait_def_id: DefId,
method: ty::AssocItem,
) -> Option<MethodViolationCode> {
let sig = tcx.fn_sig(method.def_id).subst_identity();
let sig = tcx.fn_sig(method.def_id).instantiate_identity();
// The method's first parameter must be named `self`
if !method.fn_has_self_parameter {
@ -586,7 +586,7 @@ fn virtual_call_violation_for_method<'tcx>(
// allowed to have generic parameters so `auto trait Bound<T> {}`
// would already have reported an error at the definition of the
// auto trait.
if pred_trait_ref.substs.len() != 1 {
if pred_trait_ref.args.len() != 1 {
tcx.sess.diagnostic().delay_span_bug(
span,
"auto traits cannot have generic parameters",
@ -612,11 +612,11 @@ fn receiver_for_self_ty<'tcx>(
method_def_id: DefId,
) -> Ty<'tcx> {
debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id);
let substs = InternalSubsts::for_item(tcx, method_def_id, |param, _| {
let args = GenericArgs::for_item(tcx, method_def_id, |param, _| {
if param.index == 0 { self_ty.into() } else { tcx.mk_param_from_def(param) }
});
let result = EarlyBinder::bind(receiver_ty).subst(tcx, substs);
let result = EarlyBinder::bind(receiver_ty).instantiate(tcx, args);
debug!(
"receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}",
receiver_ty, self_ty, method_def_id, result
@ -751,11 +751,11 @@ fn receiver_is_dispatchable<'tcx>(
// U: Trait<Arg1, ..., ArgN>
let trait_predicate = {
let trait_def_id = method.trait_container(tcx).unwrap();
let substs = InternalSubsts::for_item(tcx, trait_def_id, |param, _| {
let args = GenericArgs::for_item(tcx, trait_def_id, |param, _| {
if param.index == 0 { unsized_self_ty.into() } else { tcx.mk_param_from_def(param) }
});
ty::TraitRef::new(tcx, trait_def_id, substs).to_predicate(tcx)
ty::TraitRef::new(tcx, trait_def_id, args).to_predicate(tcx)
};
let caller_bounds =

View file

@ -1,8 +1,8 @@
//! Code for projecting associated types out of trait references.
use super::check_substs_compatible;
use super::check_args_compatible;
use super::specialization_graph;
use super::translate_substs;
use super::translate_args;
use super::util;
use super::ImplSourceUserDefinedData;
use super::MismatchedProjectionTypes;
@ -524,7 +524,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
// ```
// for<'a> fn(<T as Foo>::One<'a, Box<dyn Bar<'a, Item=<T as Foo>::Two<'a>>>>)
// ```
// We normalize the substs on the projection before the projecting, but
// We normalize the args on the projection before the projecting, but
// if we're naive, we'll
// replace bound vars on inner, project inner, replace placeholders on inner,
// replace bound vars on outer, project outer, replace placeholders on outer
@ -539,7 +539,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
//
// On the other hand, this does add a bit of complexity, since we only
// replace bound vars if the current type is a `Projection` and we need
// to make sure we don't forget to fold the substs regardless.
// to make sure we don't forget to fold the args regardless.
match kind {
ty::Opaque => {
@ -558,9 +558,9 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
);
}
let substs = data.substs.fold_with(self);
let args = data.args.fold_with(self);
let generic_ty = self.interner().type_of(data.def_id);
let concrete_ty = generic_ty.subst(self.interner(), substs);
let concrete_ty = generic_ty.instantiate(self.interner(), args);
self.depth += 1;
let folded_ty = self.fold_ty(concrete_ty);
self.depth -= 1;
@ -660,11 +660,8 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
ty::Weak => {
let infcx = self.selcx.infcx;
self.obligations.extend(
infcx
.tcx
.predicates_of(data.def_id)
.instantiate_own(infcx.tcx, data.substs)
.map(|(mut predicate, span)| {
infcx.tcx.predicates_of(data.def_id).instantiate_own(infcx.tcx, data.args).map(
|(mut predicate, span)| {
if data.has_escaping_bound_vars() {
(predicate, ..) = BoundVarReplacer::replace_bound_vars(
infcx,
@ -677,9 +674,10 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
ObligationCauseCode::TypeAlias(code, span, data.def_id)
});
Obligation::new(infcx.tcx, cause, self.param_env, predicate)
}),
},
),
);
infcx.tcx.type_of(data.def_id).subst(infcx.tcx, data.substs).fold_with(self)
infcx.tcx.type_of(data.def_id).instantiate(infcx.tcx, data.args).fold_with(self)
}
ty::Inherent if !data.has_escaping_bound_vars() => {
@ -1337,7 +1335,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
});
}
let substs = compute_inherent_assoc_ty_substs(
let args = compute_inherent_assoc_ty_args(
selcx,
param_env,
alias_ty,
@ -1347,7 +1345,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
);
// Register the obligations arising from the impl and from the associated type itself.
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, substs);
let predicates = tcx.predicates_of(alias_ty.def_id).instantiate(tcx, args);
for (predicate, span) in predicates {
let predicate = normalize_with_depth_to(
selcx,
@ -1381,7 +1379,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
));
}
let ty = tcx.type_of(alias_ty.def_id).subst(tcx, substs);
let ty = tcx.type_of(alias_ty.def_id).instantiate(tcx, args);
let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
if ty.has_projections() {
@ -1391,20 +1389,20 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
ty
}
pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>(
pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
alias_ty: ty::AliasTy<'tcx>,
cause: ObligationCause<'tcx>,
depth: usize,
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> ty::SubstsRef<'tcx> {
) -> ty::GenericArgsRef<'tcx> {
let tcx = selcx.tcx();
let impl_def_id = tcx.parent(alias_ty.def_id);
let impl_substs = selcx.infcx.fresh_substs_for_item(cause.span, impl_def_id);
let impl_args = selcx.infcx.fresh_args_for_item(cause.span, impl_def_id);
let impl_ty = tcx.type_of(impl_def_id).subst(tcx, impl_substs);
let impl_ty = tcx.type_of(impl_def_id).instantiate(tcx, impl_args);
let impl_ty =
normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, impl_ty, obligations);
@ -1423,7 +1421,7 @@ pub fn compute_inherent_assoc_ty_substs<'a, 'b, 'tcx>(
}
}
alias_ty.rebase_substs_onto_impl(impl_substs, tcx)
alias_ty.rebase_args_onto_impl(impl_args, tcx)
}
enum Projected<'tcx> {
@ -1495,20 +1493,18 @@ fn project<'cx, 'tcx>(
ProjectionCandidateSet::None => {
let tcx = selcx.tcx();
let term = match tcx.def_kind(obligation.predicate.def_id) {
DefKind::AssocTy => Ty::new_projection(
tcx,
obligation.predicate.def_id,
obligation.predicate.substs,
)
.into(),
DefKind::AssocTy => {
Ty::new_projection(tcx, obligation.predicate.def_id, obligation.predicate.args)
.into()
}
DefKind::AssocConst => ty::Const::new_unevaluated(
tcx,
ty::UnevaluatedConst::new(
obligation.predicate.def_id,
obligation.predicate.substs,
obligation.predicate.args,
),
tcx.type_of(obligation.predicate.def_id)
.subst(tcx, obligation.predicate.substs),
.instantiate(tcx, obligation.predicate.args),
)
.into(),
kind => {
@ -1567,7 +1563,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
let bounds = match *obligation.predicate.self_ty().kind() {
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
ty::Alias(ty::Projection | ty::Opaque, ref data) => {
tcx.item_bounds(data.def_id).subst(tcx, data.substs)
tcx.item_bounds(data.def_id).instantiate(tcx, data.args)
}
ty::Infer(ty::TyVar(_)) => {
// If the self-type is an inference variable, then it MAY wind up
@ -2017,12 +2013,12 @@ fn confirm_generator_candidate<'cx, 'tcx>(
obligation: &ProjectionTyObligation<'tcx>,
nested: Vec<PredicateObligation<'tcx>>,
) -> Progress<'tcx> {
let ty::Generator(_, substs, _) =
let ty::Generator(_, args, _) =
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
else {
unreachable!()
};
let gen_sig = substs.as_generator().poly_sig();
let gen_sig = args.as_generator().poly_sig();
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
selcx,
obligation.param_env,
@ -2054,7 +2050,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
};
ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.substs),
projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.args),
term: ty.into(),
}
});
@ -2069,12 +2065,12 @@ fn confirm_future_candidate<'cx, 'tcx>(
obligation: &ProjectionTyObligation<'tcx>,
nested: Vec<PredicateObligation<'tcx>>,
) -> Progress<'tcx> {
let ty::Generator(_, substs, _) =
let ty::Generator(_, args, _) =
selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
else {
unreachable!()
};
let gen_sig = substs.as_generator().poly_sig();
let gen_sig = args.as_generator().poly_sig();
let Normalized { value: gen_sig, obligations } = normalize_with_depth(
selcx,
obligation.param_env,
@ -2098,7 +2094,7 @@ fn confirm_future_candidate<'cx, 'tcx>(
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.substs),
projection_ty: tcx.mk_alias_ty(obligation.predicate.def_id, trait_ref.args),
term: return_ty.into(),
}
});
@ -2115,7 +2111,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let self_ty = obligation.predicate.self_ty();
let substs = tcx.mk_substs(&[self_ty.into()]);
let args = tcx.mk_args(&[self_ty.into()]);
let lang_items = tcx.lang_items();
let item_def_id = obligation.predicate.def_id;
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
@ -2155,7 +2151,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
};
let predicate =
ty::ProjectionPredicate { projection_ty: tcx.mk_alias_ty(item_def_id, substs), term };
ty::ProjectionPredicate { projection_ty: tcx.mk_alias_ty(item_def_id, args), term };
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
.with_addl_obligations(obligations)
@ -2187,11 +2183,11 @@ fn confirm_closure_candidate<'cx, 'tcx>(
obligation: &ProjectionTyObligation<'tcx>,
nested: Vec<PredicateObligation<'tcx>>,
) -> Progress<'tcx> {
let ty::Closure(_, substs) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
let ty::Closure(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind()
else {
unreachable!()
};
let closure_sig = substs.as_closure().sig();
let closure_sig = args.as_closure().sig();
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
selcx,
obligation.param_env,
@ -2228,7 +2224,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
flag,
)
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
projection_ty: tcx.mk_alias_ty(fn_once_output_def_id, trait_ref.substs),
projection_ty: tcx.mk_alias_ty(fn_once_output_def_id, trait_ref.args),
term: ret_type.into(),
});
@ -2312,7 +2308,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
let ImplSourceUserDefinedData { impl_def_id, args, mut nested } = impl_impl_source;
let assoc_item_id = obligation.predicate.def_id;
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
@ -2336,23 +2332,22 @@ fn confirm_impl_candidate<'cx, 'tcx>(
// If we're trying to normalize `<Vec<u32> as X>::A<S>` using
//`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then:
//
// * `obligation.predicate.substs` is `[Vec<u32>, S]`
// * `substs` is `[u32]`
// * `substs` ends up as `[u32, S]`
let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs);
let substs =
translate_substs(selcx.infcx, param_env, impl_def_id, substs, assoc_ty.defining_node);
// * `obligation.predicate.args` is `[Vec<u32>, S]`
// * `args` is `[u32]`
// * `args` ends up as `[u32, S]`
let args = obligation.predicate.args.rebase_onto(tcx, trait_def_id, args);
let args = translate_args(selcx.infcx, param_env, impl_def_id, args, assoc_ty.defining_node);
let ty = tcx.type_of(assoc_ty.item.def_id);
let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst);
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
let did = assoc_ty.item.def_id;
let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did);
let uv = ty::UnevaluatedConst::new(did, identity_substs);
let identity_args = crate::traits::GenericArgs::identity_for_item(tcx, did);
let uv = ty::UnevaluatedConst::new(did, identity_args);
ty.map_bound(|ty| ty::Const::new_unevaluated(tcx, uv, ty).into())
} else {
ty.map_bound(|ty| ty.into())
};
if !check_substs_compatible(tcx, assoc_ty.item, substs) {
if !check_args_compatible(tcx, assoc_ty.item, args) {
let err = Ty::new_error_with_message(
tcx,
obligation.cause.span,
@ -2361,7 +2356,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
Progress { term: err.into(), obligations: nested }
} else {
assoc_ty_own_obligations(selcx, obligation, &mut nested);
Progress { term: term.subst(tcx, substs), obligations: nested }
Progress { term: term.instantiate(tcx, args), obligations: nested }
}
}
@ -2375,7 +2370,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
let tcx = selcx.tcx();
let predicates = tcx
.predicates_of(obligation.predicate.def_id)
.instantiate_own(tcx, obligation.predicate.substs);
.instantiate_own(tcx, obligation.predicate.args);
for (predicate, span) in predicates {
let normalized = normalize_with_depth_to(
selcx,

View file

@ -49,8 +49,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
// (T1..Tn) and closures have same properties as T1..Tn --
// check if *all* of them are trivial.
ty::Tuple(tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
ty::Closure(_, ref substs) => {
trivial_dropck_outlives(tcx, substs.as_closure().tupled_upvars_ty())
ty::Closure(_, ref args) => {
trivial_dropck_outlives(tcx, args.as_closure().tupled_upvars_ty())
}
ty::Adt(def, _) => {
@ -237,8 +237,8 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
Ok::<_, NoSolution>(())
})?,
ty::Closure(_, substs) => {
if !substs.as_closure().is_valid() {
ty::Closure(_, args) => {
if !args.as_closure().is_valid() {
// By the time this code runs, all type variables ought to
// be fully resolved.
@ -250,14 +250,14 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
}
rustc_data_structures::stack::ensure_sufficient_stack(|| {
for ty in substs.as_closure().upvar_tys() {
for ty in args.as_closure().upvar_tys() {
dtorck_constraint_for_ty_inner(tcx, span, for_ty, depth + 1, ty, constraints)?;
}
Ok::<_, NoSolution>(())
})?
}
ty::Generator(_, substs, _movability) => {
ty::Generator(_, args, _movability) => {
// rust-lang/rust#49918: types can be constructed, stored
// in the interior, and sit idle when generator yields
// (and is subsequently dropped).
@ -281,7 +281,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
// derived from lifetimes attached to the upvars and resume
// argument, and we *do* incorporate those here.
if !substs.as_generator().is_valid() {
if !args.as_generator().is_valid() {
// By the time this code runs, all type variables ought to
// be fully resolved.
tcx.sess.delay_span_bug(
@ -292,28 +292,25 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
}
constraints.outlives.extend(
substs
.as_generator()
.upvar_tys()
.map(|t| -> ty::subst::GenericArg<'tcx> { t.into() }),
args.as_generator().upvar_tys().map(|t| -> ty::GenericArg<'tcx> { t.into() }),
);
constraints.outlives.push(substs.as_generator().resume_ty().into());
constraints.outlives.push(args.as_generator().resume_ty().into());
}
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
let DropckConstraint { dtorck_types, outlives, overflows } =
tcx.at(span).adt_dtorck_constraint(def.did())?;
// FIXME: we can try to recursively `dtorck_constraint_on_ty`
// there, but that needs some way to handle cycles.
constraints
.dtorck_types
.extend(dtorck_types.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
.extend(dtorck_types.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args)));
constraints
.outlives
.extend(outlives.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
.extend(outlives.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args)));
constraints
.overflows
.extend(overflows.iter().map(|t| EarlyBinder::bind(*t).subst(tcx, substs)));
.extend(overflows.iter().map(|t| EarlyBinder::bind(*t).instantiate(tcx, args)));
}
// Objects must be alive in order for their destructor

View file

@ -217,7 +217,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
};
// See note in `rustc_trait_selection::traits::project` about why we
// wait to fold the substs.
// wait to fold the args.
// Wrap this in a closure so we don't accidentally return from the outer function
let res = match kind {
@ -227,7 +227,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
Reveal::UserFacing => ty.try_super_fold_with(self)?,
Reveal::All => {
let substs = data.substs.try_fold_with(self)?;
let args = data.args.try_fold_with(self)?;
let recursion_limit = self.interner().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {
// A closure or generator may have itself as in its upvars.
@ -243,14 +243,14 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
}
let generic_ty = self.interner().type_of(data.def_id);
let concrete_ty = generic_ty.subst(self.interner(), substs);
let concrete_ty = generic_ty.instantiate(self.interner(), args);
self.anon_depth += 1;
if concrete_ty == ty {
bug!(
"infinite recursion generic_ty: {:#?}, substs: {:#?}, \
"infinite recursion generic_ty: {:#?}, args: {:#?}, \
concrete_ty: {:#?}, ty: {:#?}",
generic_ty,
substs,
args,
concrete_ty,
ty
);

View file

@ -4,7 +4,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_infer::traits::Obligation;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserSelfTy, UserSubsts, UserType};
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserType};
pub use rustc_middle::traits::query::type_op::AscribeUserType;
use rustc_span::{Span, DUMMY_SP};
@ -47,8 +47,8 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
let span = span.unwrap_or(DUMMY_SP);
match user_ty {
UserType::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
UserType::TypeOf(def_id, user_substs) => {
relate_mir_and_user_substs(ocx, param_env, span, mir_ty, def_id, user_substs)?
UserType::TypeOf(def_id, user_args) => {
relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
}
};
Ok(())
@ -74,20 +74,20 @@ fn relate_mir_and_user_ty<'tcx>(
}
#[instrument(level = "debug", skip(ocx, param_env, span))]
fn relate_mir_and_user_substs<'tcx>(
fn relate_mir_and_user_args<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
span: Span,
mir_ty: Ty<'tcx>,
def_id: DefId,
user_substs: UserSubsts<'tcx>,
user_args: UserArgs<'tcx>,
) -> Result<(), NoSolution> {
let param_env = param_env.without_const();
let UserSubsts { user_self_ty, substs } = user_substs;
let UserArgs { user_self_ty, args } = user_args;
let tcx = ocx.infcx.tcx;
let cause = ObligationCause::dummy_with_span(span);
let ty = tcx.type_of(def_id).subst(tcx, substs);
let ty = tcx.type_of(def_id).instantiate(tcx, args);
let ty = ocx.normalize(&cause, param_env, ty);
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
@ -98,7 +98,7 @@ fn relate_mir_and_user_substs<'tcx>(
// Also, normalize the `instantiated_predicates`
// because otherwise we wind up with duplicate "type
// outlives" error messages.
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
debug!(?instantiated_predicates);
for (instantiated_predicate, predicate_span) in instantiated_predicates {
@ -116,7 +116,7 @@ fn relate_mir_and_user_substs<'tcx>(
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
let self_ty = ocx.normalize(&cause, param_env, self_ty);
let impl_self_ty = tcx.type_of(impl_def_id).subst(tcx, substs);
let impl_self_ty = tcx.type_of(impl_def_id).instantiate(tcx, args);
let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
@ -128,9 +128,9 @@ fn relate_mir_and_user_substs<'tcx>(
// In addition to proving the predicates, we have to
// prove that `ty` is well-formed -- this is because
// the WF of `ty` is predicated on the substs being
// the WF of `ty` is predicated on the args being
// well-formed, and we haven't proven *that*. We don't
// want to prove the WF of types from `substs` directly because they
// want to prove the WF of types from `args` directly because they
// haven't been normalized.
//
// FIXME(nmatsakis): Well, perhaps we should normalize

View file

@ -209,7 +209,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) {
// Okay to skip binder because the substs on generator types never
// Okay to skip binder because the args on generator types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
let self_ty = obligation.self_ty().skip_binder();
@ -261,14 +261,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return;
};
// Okay to skip binder because the substs on closure types never
// Okay to skip binder because the args on closure types never
// touch bound regions, they just capture the in-scope
// type/region parameters
match *obligation.self_ty().skip_binder().kind() {
ty::Closure(def_id, closure_substs) => {
ty::Closure(def_id, closure_args) => {
let is_const = self.tcx().is_const_fn_raw(def_id);
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
match self.infcx.closure_kind(closure_substs) {
match self.infcx.closure_kind(closure_args) {
Some(closure_kind) => {
debug!(?closure_kind, "assemble_unboxed_candidates");
if closure_kind.extends(kind) {
@ -351,7 +351,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
let obligation_substs = obligation.predicate.skip_binder().trait_ref.substs;
let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
self.tcx().for_each_relevant_impl(
obligation.predicate.def_id(),
obligation.predicate.skip_binder().trait_ref.self_ty(),
@ -360,9 +360,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// consider a "quick reject". This avoids creating more types
// and so forth that we need to.
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
if !drcx
.substs_refs_may_unify(obligation_substs, impl_trait_ref.skip_binder().substs)
{
if !drcx.args_refs_may_unify(obligation_args, impl_trait_ref.skip_binder().args) {
return;
}
if self.reject_fn_ptr_impls(
@ -374,7 +372,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
self.infcx.probe(|_| {
if let Ok(_substs) = self.match_impl(impl_def_id, impl_trait_ref, obligation) {
if let Ok(_args) = self.match_impl(impl_def_id, impl_trait_ref, obligation) {
candidates.vec.push(ImplCandidate(impl_def_id));
}
});
@ -650,7 +648,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let ty = traits::normalize_projection_type(
self,
param_env,
tcx.mk_alias_ty(tcx.lang_items().deref_target()?, trait_ref.substs),
tcx.mk_alias_ty(tcx.lang_items().deref_target()?, trait_ref.args),
cause.clone(),
0,
// We're *intentionally* throwing these away,
@ -688,7 +686,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Don't add any candidates if there are bound regions.
return;
};
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
debug!(?source, ?target, "assemble_candidates_for_unsizing");

View file

@ -13,7 +13,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
use rustc_middle::ty::{
self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
self, Binder, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt,
};
use rustc_span::def_id::DefId;
@ -158,15 +158,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref;
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() {
let (def_id, args) = match *placeholder_self_ty.kind() {
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
(def_id, substs)
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
(def_id, args)
}
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
};
let candidate_predicate = tcx.item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
let candidate_predicate =
tcx.item_bounds(def_id).map_bound(|i| i[idx]).instantiate(tcx, args);
let candidate = candidate_predicate
.as_trait_clause()
.expect("projection candidate is not a trait predicate")
@ -190,7 +191,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
})?);
if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
for (predicate, _) in predicates {
let normalized = normalize_with_depth_to(
self,
@ -298,8 +299,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.collect(),
Condition::IfTransmutable { src, dst } => {
let trait_def_id = obligation.predicate.def_id();
let scope = predicate.trait_ref.substs.type_at(2);
let assume_const = predicate.trait_ref.substs.const_at(3);
let scope = predicate.trait_ref.args.type_at(2);
let assume_const = predicate.trait_ref.args.const_at(3);
let make_obl = |from_ty, to_ty| {
let trait_ref1 = ty::TraitRef::new(
tcx,
@ -342,19 +343,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let Some(assume) = rustc_transmute::Assume::from_const(
self.infcx.tcx,
obligation.param_env,
predicate.trait_ref.substs.const_at(3),
predicate.trait_ref.args.const_at(3),
) else {
return Err(Unimplemented);
};
let dst = predicate.trait_ref.substs.type_at(0);
let src = predicate.trait_ref.substs.type_at(1);
let dst = predicate.trait_ref.args.type_at(0);
let src = predicate.trait_ref.args.type_at(1);
debug!(?src, ?dst);
let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx);
let maybe_transmutable = transmute_env.is_transmutable(
obligation.cause.clone(),
rustc_transmute::Types { dst, src },
predicate.trait_ref.substs.type_at(2),
predicate.trait_ref.args.type_at(2),
assume,
);
@ -402,7 +403,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.recursion_depth + 1,
obligation.param_env,
trait_def_id,
&trait_ref.substs,
&trait_ref.args,
obligation.predicate,
);
@ -433,12 +434,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// First, create the substitutions by matching the impl again,
// this time not in a probe.
let substs = self.rematch_impl(impl_def_id, obligation);
debug!(?substs, "impl substs");
let args = self.rematch_impl(impl_def_id, obligation);
debug!(?args, "impl args");
ensure_sufficient_stack(|| {
self.vtable_impl(
impl_def_id,
substs,
args,
&obligation.cause,
obligation.recursion_depth + 1,
obligation.param_env,
@ -450,33 +451,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn vtable_impl(
&mut self,
impl_def_id: DefId,
substs: Normalized<'tcx, SubstsRef<'tcx>>,
args: Normalized<'tcx, GenericArgsRef<'tcx>>,
cause: &ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
debug!(?impl_def_id, ?substs, ?recursion_depth, "vtable_impl");
debug!(?impl_def_id, ?args, ?recursion_depth, "vtable_impl");
let mut impl_obligations = self.impl_or_trait_obligations(
cause,
recursion_depth,
param_env,
impl_def_id,
&substs.value,
&args.value,
parent_trait_pred,
);
debug!(?impl_obligations, "vtable_impl");
// Because of RFC447, the impl-trait-ref and obligations
// are sufficient to determine the impl substs, without
// are sufficient to determine the impl args, without
// relying on projections in the impl-trait-ref.
//
// e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
impl_obligations.extend(substs.obligations);
impl_obligations.extend(args.obligations);
ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations }
ImplSourceUserDefinedData { impl_def_id, args: args.value, nested: impl_obligations }
}
fn confirm_object_candidate(
@ -531,7 +532,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// will be checked in the code below.
for super_trait in tcx
.super_predicates_of(trait_predicate.def_id())
.instantiate(tcx, trait_predicate.trait_ref.substs)
.instantiate(tcx, trait_predicate.trait_ref.args)
.predicates
.into_iter()
{
@ -569,68 +570,65 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// higher-ranked things.
// Prevent, e.g., `dyn Iterator<Item = str>`.
for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
let subst_bound =
if defs.count() == 0 {
bound.subst(tcx, trait_predicate.trait_ref.substs)
} else {
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
substs.extend(trait_predicate.trait_ref.substs.iter());
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(
bound.skip_binder().kind().bound_vars().len() + defs.count(),
);
bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter());
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
.kind
{
GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var);
Ty::new_bound(
tcx,
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
)
.into()
}
GenericParamDefKind::Lifetime => {
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
ty::Region::new_late_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
)
.into()
}
GenericParamDefKind::Const { .. } => {
let bound_var = ty::BoundVariableKind::Const;
bound_vars.push(bound_var);
ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(bound_vars.len() - 1),
tcx.type_of(param.def_id)
.no_bound_vars()
.expect("const parameter types cannot be generic"),
)
.into()
}
});
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
let assoc_ty_substs = tcx.mk_substs(&substs);
let bound =
bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
ty::Binder::bind_with_vars(bound, bound_vars).to_predicate(tcx)
};
let subst_bound = if defs.count() == 0 {
bound.instantiate(tcx, trait_predicate.trait_ref.args)
} else {
let mut args = smallvec::SmallVec::with_capacity(defs.count());
args.extend(trait_predicate.trait_ref.args.iter());
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
smallvec::SmallVec::with_capacity(
bound.skip_binder().kind().bound_vars().len() + defs.count(),
);
bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter());
GenericArgs::fill_single(&mut args, defs, &mut |param, _| match param.kind {
GenericParamDefKind::Type { .. } => {
let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var);
Ty::new_bound(
tcx,
ty::INNERMOST,
ty::BoundTy {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
)
.into()
}
GenericParamDefKind::Lifetime => {
let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Region(kind);
bound_vars.push(bound_var);
ty::Region::new_late_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
)
.into()
}
GenericParamDefKind::Const { .. } => {
let bound_var = ty::BoundVariableKind::Const;
bound_vars.push(bound_var);
ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(bound_vars.len() - 1),
tcx.type_of(param.def_id)
.no_bound_vars()
.expect("const parameter types cannot be generic"),
)
.into()
}
});
let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
let assoc_ty_args = tcx.mk_args(&args);
let bound =
bound.map_bound(|b| b.kind().skip_binder()).instantiate(tcx, assoc_ty_args);
ty::Binder::bind_with_vars(bound, bound_vars).to_predicate(tcx)
};
let normalized_bound = normalize_with_depth_to(
self,
obligation.param_env,
@ -685,8 +683,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if obligation.is_const() && !is_const {
// function is a trait method
if let ty::FnDef(def_id, substs) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
let trait_ref = TraitRef::from_method(tcx, trait_id, *substs);
if let ty::FnDef(def_id, args) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
let trait_ref = TraitRef::from_method(tcx, trait_id, *args);
let poly_trait_pred = Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred);
nested.push(obligation);
@ -718,14 +716,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
let trait_ref = predicate.trait_ref;
let trait_def_id = trait_ref.def_id;
let substs = trait_ref.substs;
let args = trait_ref.args;
let trait_obligations = self.impl_or_trait_obligations(
&obligation.cause,
obligation.recursion_depth,
obligation.param_env,
trait_def_id,
&substs,
&args,
obligation.predicate,
);
@ -738,17 +736,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// Okay to skip binder because the substs on generator types never
// Okay to skip binder because the args on generator types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
let ty::Generator(generator_def_id, args, _) = *self_ty.kind() else {
bug!("closure candidate for non-closure {:?}", obligation);
};
debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
debug!(?obligation, ?generator_def_id, ?args, "confirm_generator_candidate");
let gen_sig = substs.as_generator().poly_sig();
let gen_sig = args.as_generator().poly_sig();
// NOTE: The self-type is a generator type and hence is
// in fact unparameterized (or at least does not reference any
@ -777,17 +775,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &PolyTraitObligation<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
// Okay to skip binder because the substs on generator types never
// Okay to skip binder because the args on generator types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
let ty::Generator(generator_def_id, args, _) = *self_ty.kind() else {
bug!("closure candidate for non-closure {:?}", obligation);
};
debug!(?obligation, ?generator_def_id, ?substs, "confirm_future_candidate");
debug!(?obligation, ?generator_def_id, ?args, "confirm_future_candidate");
let gen_sig = substs.as_generator().poly_sig();
let gen_sig = args.as_generator().poly_sig();
let trait_ref = super::util::future_trait_ref_and_outputs(
self.tcx(),
@ -813,22 +811,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.fn_trait_kind_from_def_id(obligation.predicate.def_id())
.unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
// Okay to skip binder because the substs on closure types never
// Okay to skip binder because the args on closure types never
// touch bound regions, they just capture the in-scope
// type/region parameters.
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
let ty::Closure(closure_def_id, substs) = *self_ty.kind() else {
let ty::Closure(closure_def_id, args) = *self_ty.kind() else {
bug!("closure candidate for non-closure {:?}", obligation);
};
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
let trait_ref = self.closure_trait_ref_unnormalized(obligation, args);
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
nested.push(obligation.with(
self.tcx(),
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)),
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, args, kind)),
));
Ok(nested)
@ -905,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
debug!(?source, ?target, "confirm_trait_upcasting_unsize_candidate");
@ -1008,7 +1006,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// `assemble_candidates_for_unsizing` should ensure there are no late-bound
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
let target = self.infcx.shallow_resolve(target);
debug!(?source, ?target, "confirm_builtin_unsize_candidate");
@ -1116,7 +1114,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
// `Struct<T>` -> `Struct<U>`
(&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => {
(&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => {
let unsizing_params = tcx.unsizing_params_for_adt(def.did());
if unsizing_params.is_empty() {
return Err(Unimplemented);
@ -1133,7 +1131,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
tail_field_ty.subst(tcx, substs_a),
tail_field_ty.instantiate(tcx, args_a),
&mut nested,
);
let target_tail = normalize_with_depth_to(
@ -1141,16 +1139,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
tail_field_ty.subst(tcx, substs_b),
tail_field_ty.instantiate(tcx, args_b),
&mut nested,
);
// Check that the source struct with the target's
// unsizing parameters is equal to the target.
let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| {
if unsizing_params.contains(i as u32) { substs_b[i] } else { k }
}));
let new_struct = Ty::new_adt(tcx, def, substs);
let args =
tcx.mk_args_from_iter(args_a.iter().enumerate().map(|(i, k)| {
if unsizing_params.contains(i as u32) { args_b[i] } else { k }
}));
let new_struct = Ty::new_adt(tcx, def, args);
let InferOk { obligations, .. } = self
.infcx
.at(&obligation.cause, obligation.param_env)
@ -1230,8 +1229,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
trait_pred.trait_ref.def_id = drop_trait;
trait_pred
});
let substs = self.rematch_impl(impl_def_id, &new_obligation);
debug!(?substs, "impl substs");
let args = self.rematch_impl(impl_def_id, &new_obligation);
debug!(?args, "impl args");
let cause = obligation.derived_cause(|derived| {
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
@ -1244,7 +1243,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let obligations = ensure_sufficient_stack(|| {
self.vtable_impl(
impl_def_id,
substs,
args,
&cause,
new_obligation.recursion_depth + 1,
new_obligation.param_env,
@ -1256,7 +1255,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// We want to confirm the ADT's fields if we have an ADT
let mut stack = match *self_ty.skip_binder().kind() {
ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(tcx, substs)).collect(),
ty::Adt(def, args) => def.all_fields().map(|f| f.ty(tcx, args)).collect(),
_ => vec![self_ty.skip_binder()],
};
@ -1289,20 +1288,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Tuple(tys) => {
stack.extend(tys.iter());
}
ty::Closure(_, substs) => {
stack.push(substs.as_closure().tupled_upvars_ty());
ty::Closure(_, args) => {
stack.push(args.as_closure().tupled_upvars_ty());
}
ty::Generator(_, substs, _) => {
let generator = substs.as_generator();
ty::Generator(_, args, _) => {
let generator = args.as_generator();
stack.extend([generator.tupled_upvars_ty(), generator.witness()]);
}
ty::GeneratorWitness(tys) => {
stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
}
ty::GeneratorWitnessMIR(def_id, substs) => {
ty::GeneratorWitnessMIR(def_id, args) => {
let tcx = self.tcx();
stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
let ty = bty.subst(tcx, substs);
let ty = bty.instantiate(tcx, args);
debug_assert!(!ty.has_late_bound_regions());
ty
}))

View file

@ -40,7 +40,7 @@ use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_span::symbol::sym;
@ -843,8 +843,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::PredicateKind::ClosureKind(_, closure_substs, kind) => {
match self.infcx.closure_kind(closure_substs) {
ty::PredicateKind::ClosureKind(_, closure_args, kind) => {
match self.infcx.closure_kind(closure_args) {
Some(closure_kind) => {
if closure_kind.extends(kind) {
Ok(EvaluatedToOk)
@ -895,7 +895,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.infcx
.at(&obligation.cause, obligation.param_env)
.trace(c1, c2)
.eq(DefineOpaqueTypes::No, a.substs, b.substs)
.eq(DefineOpaqueTypes::No, a.args, b.args)
{
return self.evaluate_predicates_recursively(
previous_stack,
@ -1194,7 +1194,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// terms of `Fn` etc, but we could probably make this more
// precise still.
let unbound_input_types =
stack.fresh_trait_pred.skip_binder().trait_ref.substs.types().any(|ty| ty.is_fresh());
stack.fresh_trait_pred.skip_binder().trait_ref.args.types().any(|ty| ty.is_fresh());
if unbound_input_types
&& stack.iter().skip(1).any(|prev| {
@ -1635,9 +1635,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?placeholder_trait_predicate);
let tcx = self.infcx.tcx;
let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
(def_id, substs)
let (def_id, args) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
(def_id, args)
}
_ => {
span_bug!(
@ -1648,7 +1648,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
}
};
let bounds = tcx.item_bounds(def_id).subst(tcx, substs);
let bounds = tcx.item_bounds(def_id).instantiate(tcx, args);
// The bounds returned by `item_bounds` may contain duplicates after
// normalization, so try to deduplicate when possible to avoid
@ -1785,11 +1785,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if is_match {
let generics = self.tcx().generics_of(obligation.predicate.def_id);
// FIXME(generic-associated-types): Addresses aggressive inference in #92917.
// If this type is a GAT, and of the GAT substs resolve to something new,
// If this type is a GAT, and of the GAT args resolve to something new,
// that means that we must have newly inferred something about the GAT.
// We should give up in that case.
if !generics.params.is_empty()
&& obligation.predicate.substs[generics.parent_count..]
&& obligation.predicate.args[generics.parent_count..]
.iter()
.any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p)
{
@ -2127,13 +2127,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
),
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
let sized_crit = def.sized_constraint(self.tcx());
// (*) binder moved here
Where(
obligation
.predicate
.rebind(sized_crit.subst_iter_copied(self.tcx(), substs).collect()),
.rebind(sized_crit.arg_iter_copied(self.tcx(), args).collect()),
)
}
@ -2190,20 +2190,20 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
Where(obligation.predicate.rebind(tys.iter().collect()))
}
ty::Generator(_, substs, hir::Movability::Movable) => {
ty::Generator(_, args, hir::Movability::Movable) => {
if self.tcx().features().generator_clone {
let resolved_upvars =
self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
self.infcx.shallow_resolve(args.as_generator().tupled_upvars_ty());
let resolved_witness =
self.infcx.shallow_resolve(substs.as_generator().witness());
self.infcx.shallow_resolve(args.as_generator().witness());
if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
// Not yet resolved.
Ambiguous
} else {
let all = substs
let all = args
.as_generator()
.upvar_tys()
.chain(iter::once(substs.as_generator().witness()))
.chain(iter::once(args.as_generator().witness()))
.collect::<Vec<_>>();
Where(obligation.predicate.rebind(all))
}
@ -2227,24 +2227,24 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
}
ty::GeneratorWitnessMIR(def_id, ref substs) => {
ty::GeneratorWitnessMIR(def_id, ref args) => {
let hidden_types = bind_generator_hidden_types_above(
self.infcx,
def_id,
substs,
args,
obligation.predicate.bound_vars(),
);
Where(hidden_types)
}
ty::Closure(_, substs) => {
ty::Closure(_, args) => {
// (*) binder moved here
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
let ty = self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty());
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
// Not yet resolved.
Ambiguous
} else {
Where(obligation.predicate.rebind(substs.as_closure().upvar_tys().collect()))
Where(obligation.predicate.rebind(args.as_closure().upvar_tys().collect()))
}
}
@ -2321,14 +2321,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
t.rebind(tys.iter().collect())
}
ty::Closure(_, ref substs) => {
let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
ty::Closure(_, ref args) => {
let ty = self.infcx.shallow_resolve(args.as_closure().tupled_upvars_ty());
t.rebind(vec![ty])
}
ty::Generator(_, ref substs, _) => {
let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
let witness = substs.as_generator().witness();
ty::Generator(_, ref args, _) => {
let ty = self.infcx.shallow_resolve(args.as_generator().tupled_upvars_ty());
let witness = args.as_generator().witness();
t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
}
@ -2337,18 +2337,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
types.map_bound(|types| types.to_vec())
}
ty::GeneratorWitnessMIR(def_id, ref substs) => {
bind_generator_hidden_types_above(self.infcx, def_id, substs, t.bound_vars())
ty::GeneratorWitnessMIR(def_id, ref args) => {
bind_generator_hidden_types_above(self.infcx, def_id, args, t.bound_vars())
}
// For `PhantomData<T>`, we pass `T`.
ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),
ty::Adt(def, args) if def.is_phantom_data() => t.rebind(args.types().collect()),
ty::Adt(def, substs) => {
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
ty::Adt(def, args) => {
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), args)).collect())
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
let ty = self.tcx().type_of(def_id);
if ty.skip_binder().references_error() {
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
@ -2356,7 +2356,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// We can resolve the `impl Trait` to its concrete type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
t.rebind(vec![ty.subst(self.tcx(), substs)])
t.rebind(vec![ty.instantiate(self.tcx(), args)])
}
})
}
@ -2428,10 +2428,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
&mut self,
impl_def_id: DefId,
obligation: &PolyTraitObligation<'tcx>,
) -> Normalized<'tcx, SubstsRef<'tcx>> {
) -> Normalized<'tcx, GenericArgsRef<'tcx>> {
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
match self.match_impl(impl_def_id, impl_trait_ref, obligation) {
Ok(substs) => substs,
Ok(args) => args,
Err(()) => {
// FIXME: A rematch may fail when a candidate cache hit occurs
// on thefreshened form of the trait predicate, but the match
@ -2447,7 +2447,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
impl_def_id, obligation
),
);
let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
let value = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
let err = Ty::new_error(self.tcx(), guar);
let value = value.fold_with(&mut BottomUpFolder {
tcx: self.tcx(),
@ -2466,14 +2466,14 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
impl_def_id: DefId,
impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>,
obligation: &PolyTraitObligation<'tcx>,
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> {
let placeholder_obligation =
self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
let impl_trait_ref = impl_trait_ref.subst(self.tcx(), impl_substs);
let impl_trait_ref = impl_trait_ref.instantiate(self.tcx(), impl_args);
if impl_trait_ref.references_error() {
return Err(());
}
@ -2515,7 +2515,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
return Err(());
}
Ok(Normalized { value: impl_substs, obligations: nested_obligations })
Ok(Normalized { value: impl_args, obligations: nested_obligations })
}
/// Normalize `where_clause_trait_ref` and try to match it against
@ -2580,9 +2580,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
fn closure_trait_ref_unnormalized(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> ty::PolyTraitRef<'tcx> {
let closure_sig = substs.as_closure().sig();
let closure_sig = args.as_closure().sig();
debug!(?closure_sig);
@ -2615,8 +2615,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
cause: &ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
def_id: DefId, // of impl or trait
substs: SubstsRef<'tcx>, // for impl or trait
def_id: DefId, // of impl or trait
args: GenericArgsRef<'tcx>, // for impl or trait
parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
) -> Vec<PredicateObligation<'tcx>> {
let tcx = self.tcx();
@ -2637,7 +2637,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// that order.
let predicates = tcx.predicates_of(def_id);
assert_eq!(predicates.parent, None);
let predicates = predicates.instantiate_own(tcx, substs);
let predicates = predicates.instantiate_own(tcx, args);
let mut obligations = Vec::with_capacity(predicates.len());
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
let cause =
@ -2990,7 +2990,7 @@ pub enum ProjectionMatchesProjection {
fn bind_generator_hidden_types_above<'tcx>(
infcx: &InferCtxt<'tcx>,
def_id: DefId,
substs: ty::SubstsRef<'tcx>,
args: ty::GenericArgsRef<'tcx>,
bound_vars: &ty::List<ty::BoundVariableKind>,
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
let tcx = infcx.tcx;
@ -3006,7 +3006,7 @@ fn bind_generator_hidden_types_above<'tcx>(
// Deduplicate tys to avoid repeated work.
.filter(|bty| seen_tys.insert(*bty))
.map(|bty| {
let mut ty = bty.subst(tcx, substs);
let mut ty = bty.instantiate(tcx, args);
// Only remap erased regions if we use them.
if considering_regions {

View file

@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{error_code, DelayDm, Diagnostic};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
use rustc_span::{Span, DUMMY_SP};
@ -48,7 +48,7 @@ pub struct OverlapError<'tcx> {
/// When we have selected one impl, but are actually using item definitions from
/// a parent impl providing a default, we need a way to translate between the
/// type parameters of the two impls. Here the `source_impl` is the one we've
/// selected, and `source_substs` is a substitution of its generics.
/// selected, and `source_args` is a substitution of its generics.
/// And `target_node` is the impl/trait we're actually going to get the
/// definition from. The resulting substitution will map from `target_node`'s
/// generics to `source_impl`'s generics as instantiated by `source_subst`.
@ -76,51 +76,46 @@ pub struct OverlapError<'tcx> {
/// through associated type projection. We deal with such cases by using
/// *fulfillment* to relate the two impls, requiring that all projections are
/// resolved.
pub fn translate_substs<'tcx>(
pub fn translate_args<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
source_impl: DefId,
source_substs: SubstsRef<'tcx>,
source_args: GenericArgsRef<'tcx>,
target_node: specialization_graph::Node,
) -> SubstsRef<'tcx> {
translate_substs_with_cause(
infcx,
param_env,
source_impl,
source_substs,
target_node,
|_, _| ObligationCause::dummy(),
)
) -> GenericArgsRef<'tcx> {
translate_args_with_cause(infcx, param_env, source_impl, source_args, target_node, |_, _| {
ObligationCause::dummy()
})
}
/// Like [translate_substs], but obligations from the parent implementation
/// Like [translate_args], but obligations from the parent implementation
/// are registered with the provided `ObligationCause`.
///
/// This is for reporting *region* errors from those bounds. Type errors should
/// not happen because the specialization graph already checks for those, and
/// will result in an ICE.
pub fn translate_substs_with_cause<'tcx>(
pub fn translate_args_with_cause<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
source_impl: DefId,
source_substs: SubstsRef<'tcx>,
source_args: GenericArgsRef<'tcx>,
target_node: specialization_graph::Node,
cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
) -> SubstsRef<'tcx> {
) -> GenericArgsRef<'tcx> {
debug!(
"translate_substs({:?}, {:?}, {:?}, {:?})",
param_env, source_impl, source_substs, target_node
"translate_args({:?}, {:?}, {:?}, {:?})",
param_env, source_impl, source_args, target_node
);
let source_trait_ref =
infcx.tcx.impl_trait_ref(source_impl).unwrap().subst(infcx.tcx, &source_substs);
infcx.tcx.impl_trait_ref(source_impl).unwrap().instantiate(infcx.tcx, &source_args);
// translate the Self and Param parts of the substitution, since those
// vary across impls
let target_substs = match target_node {
let target_args = match target_node {
specialization_graph::Node::Impl(target_impl) => {
// no need to translate if we're targeting the impl we started with
if source_impl == target_impl {
return source_substs;
return source_args;
}
fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause)
@ -131,11 +126,11 @@ pub fn translate_substs_with_cause<'tcx>(
)
})
}
specialization_graph::Node::Trait(..) => source_trait_ref.substs,
specialization_graph::Node::Trait(..) => source_trait_ref.args,
};
// directly inherent the method generics, since those do not vary across impls
source_substs.rebase_onto(infcx.tcx, source_impl, target_substs)
source_args.rebase_onto(infcx.tcx, source_impl, target_args)
}
/// Is `impl1` a specialization of `impl2`?
@ -172,7 +167,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
let penv = tcx.param_env(impl1_def_id);
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity();
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap().instantiate_identity();
// Create an infcx, taking the predicates of impl1 as assumptions:
let infcx = tcx.infer_ctxt().build();
@ -196,7 +191,7 @@ fn fulfill_implication<'tcx>(
source_impl: DefId,
target_impl: DefId,
error_cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
) -> Result<SubstsRef<'tcx>, ()> {
) -> Result<GenericArgsRef<'tcx>, ()> {
debug!(
"fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)",
param_env, source_trait_ref, target_impl
@ -221,9 +216,9 @@ fn fulfill_implication<'tcx>(
let source_trait = ImplSubject::Trait(source_trait_ref);
let selcx = &mut SelectionContext::new(&infcx);
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
let target_args = infcx.fresh_args_for_item(DUMMY_SP, target_impl);
let (target_trait, obligations) =
util::impl_subject_and_oblig(selcx, param_env, target_impl, target_substs, error_cause);
util::impl_subject_and_oblig(selcx, param_env, target_impl, target_args, error_cause);
// do the impls unify? If not, no specialization.
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
@ -259,7 +254,7 @@ fn fulfill_implication<'tcx>(
// Now resolve the *substitution* we built for the target earlier, replacing
// the inference variables inside with whatever we got from fulfillment.
Ok(infcx.resolve_vars_if_possible(target_substs))
Ok(infcx.resolve_vars_if_possible(target_args))
}
/// Query provider for `specialization_graph_of`.
@ -467,21 +462,21 @@ fn report_conflicting_impls<'tcx>(
pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
use std::fmt::Write;
let trait_ref = tcx.impl_trait_ref(impl_def_id)?.subst_identity();
let trait_ref = tcx.impl_trait_ref(impl_def_id)?.instantiate_identity();
let mut w = "impl".to_owned();
let substs = InternalSubsts::identity_for_item(tcx, impl_def_id);
let args = GenericArgs::identity_for_item(tcx, impl_def_id);
// FIXME: Currently only handles ?Sized.
// Needs to support ?Move and ?DynSized when they are implemented.
let mut types_without_default_bounds = FxIndexSet::default();
let sized_trait = tcx.lang_items().sized_trait();
if !substs.is_empty() {
types_without_default_bounds.extend(substs.types());
if !args.is_empty() {
types_without_default_bounds.extend(args.types());
w.push('<');
w.push_str(
&substs
&args
.iter()
.map(|k| k.to_string())
.filter(|k| k != "'_")
@ -495,7 +490,7 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
w,
" {} for {}",
trait_ref.print_only_trait_path(),
tcx.type_of(impl_def_id).subst_identity()
tcx.type_of(impl_def_id).instantiate_identity()
)
.unwrap();

View file

@ -180,7 +180,7 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
if le && !ge {
debug!(
"descending as child of TraitRef {:?}",
tcx.impl_trait_ref(possible_sibling).unwrap().subst_identity()
tcx.impl_trait_ref(possible_sibling).unwrap().instantiate_identity()
);
// The impl specializes `possible_sibling`.
@ -188,7 +188,7 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
} else if ge && !le {
debug!(
"placing as parent of TraitRef {:?}",
tcx.impl_trait_ref(possible_sibling).unwrap().subst_identity()
tcx.impl_trait_ref(possible_sibling).unwrap().instantiate_identity()
);
replace_children.push(possible_sibling);

View file

@ -62,8 +62,8 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
debug!("Search visiting ty: {:?}", ty);
let (adt_def, substs) = match *ty.kind() {
ty::Adt(adt_def, substs) => (adt_def, substs),
let (adt_def, args) = match *ty.kind() {
ty::Adt(adt_def, args) => (adt_def, args),
ty::Param(_) => {
return ControlFlow::Break(ty);
}
@ -157,15 +157,15 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
// instead looks directly at its fields outside
// this match), so we skip super_visit_with.
//
// (Must not recur on substs for `PhantomData<T>` cf
// (Must not recur on args for `PhantomData<T>` cf
// rust-lang/rust#55028 and rust-lang/rust#55837; but also
// want to skip substs when only uses of generic are
// want to skip args when only uses of generic are
// behind unsafe pointers `*const T`/`*mut T`.)
// even though we skip super_visit_with, we must recur on
// fields of ADT.
let tcx = self.tcx;
adt_def.all_fields().map(|field| field.ty(tcx, substs)).try_for_each(|field_ty| {
adt_def.all_fields().map(|field| field.ty(tcx, args)).try_for_each(|field_ty| {
let ty = self.tcx.normalize_erasing_regions(ty::ParamEnv::empty(), field_ty);
debug!("structural-match ADT: field_ty={:?}, ty={:?}", field_ty, ty);
ty.visit_with(self)

View file

@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::InferOk;
use rustc_middle::ty::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
use smallvec::SmallVec;
@ -194,24 +194,24 @@ impl Iterator for SupertraitDefIds<'_> {
// Other
///////////////////////////////////////////////////////////////////////////
/// Instantiate all bound parameters of the impl subject with the given substs,
/// Instantiate all bound parameters of the impl subject with the given args,
/// returning the resulting subject and all obligations that arise.
/// The obligations are closed under normalization.
pub fn impl_subject_and_oblig<'a, 'tcx>(
selcx: &mut SelectionContext<'a, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
impl_def_id: DefId,
impl_substs: SubstsRef<'tcx>,
impl_args: GenericArgsRef<'tcx>,
cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);
let subject = subject.instantiate(selcx.tcx(), impl_args);
let InferOk { value: subject, obligations: normalization_obligations1 } =
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(subject);
let predicates = selcx.tcx().predicates_of(impl_def_id);
let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
let predicates = predicates.instantiate(selcx.tcx(), impl_args);
let InferOk { value: predicates, obligations: normalization_obligations2 } =
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
@ -303,13 +303,13 @@ pub enum TupleArgumentsFlag {
No,
}
// Verify that the trait item and its implementation have compatible substs lists
pub fn check_substs_compatible<'tcx>(
// Verify that the trait item and its implementation have compatible args lists
pub fn check_args_compatible<'tcx>(
tcx: TyCtxt<'tcx>,
assoc_item: ty::AssocItem,
substs: ty::SubstsRef<'tcx>,
args: ty::GenericArgsRef<'tcx>,
) -> bool {
fn check_substs_compatible_inner<'tcx>(
fn check_args_compatible_inner<'tcx>(
tcx: TyCtxt<'tcx>,
generics: &'tcx ty::Generics,
args: &'tcx [ty::GenericArg<'tcx>],
@ -322,7 +322,7 @@ pub fn check_substs_compatible<'tcx>(
if let Some(parent) = generics.parent
&& let parent_generics = tcx.generics_of(parent)
&& !check_substs_compatible_inner(tcx, parent_generics, parent_args) {
&& !check_args_compatible_inner(tcx, parent_generics, parent_args) {
return false;
}
@ -339,7 +339,7 @@ pub fn check_substs_compatible<'tcx>(
}
let generics = tcx.generics_of(assoc_item.def_id);
// Chop off any additional substs (RPITIT) substs
let substs = &substs[0..generics.count().min(substs.len())];
check_substs_compatible_inner(tcx, generics, substs)
// Chop off any additional args (RPITIT) args
let args = &args[0..generics.count().min(args.len())];
check_args_compatible_inner(tcx, generics, args)
}

View file

@ -6,7 +6,7 @@ use rustc_infer::traits::util::PredicateSet;
use rustc_infer::traits::ImplSource;
use rustc_middle::query::Providers;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::InternalSubsts;
use rustc_middle::ty::GenericArgs;
use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry};
use rustc_span::{sym, Span};
use smallvec::SmallVec;
@ -241,12 +241,12 @@ fn vtable_entries<'tcx>(
debug!("vtable_entries: trait_method={:?}", def_id);
// The method may have some early-bound lifetimes; add regions for those.
let substs = trait_ref.map_bound(|trait_ref| {
InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
let args = trait_ref.map_bound(|trait_ref| {
GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
GenericParamDefKind::Type { .. }
| GenericParamDefKind::Const { .. } => {
trait_ref.substs[param.index as usize]
trait_ref.args[param.index as usize]
}
})
});
@ -254,14 +254,14 @@ fn vtable_entries<'tcx>(
// The trait type may have higher-ranked lifetimes in it;
// erase them if they appear, so that we get the type
// at some particular call site.
let substs = tcx
.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), substs);
let args =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), args);
// It's possible that the method relies on where-clauses that
// do not hold for this particular set of type parameters.
// Note that this method could then never be called, so we
// do not want to try and codegen it, in that case (see #23435).
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
if impossible_predicates(
tcx,
predicates.map(|(predicate, _)| predicate).collect(),
@ -274,7 +274,7 @@ fn vtable_entries<'tcx>(
tcx,
ty::ParamEnv::reveal_all(),
def_id,
substs,
args,
)
.expect("resolution failed during building vtable representation");
VtblEntry::Method(instance)

View file

@ -2,8 +2,8 @@ use crate::infer::InferCtxt;
use crate::traits;
use rustc_hir as hir;
use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_span::{Span, DUMMY_SP};
@ -341,7 +341,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let trait_ref = &trait_pred.trait_ref;
// Negative trait predicates don't require supertraits to hold, just
// that their substs are WF.
// that their args are WF.
if trait_pred.polarity == ty::ImplPolarity::Negative {
self.compute_negative_trait_pred(trait_ref);
return;
@ -349,9 +349,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// if the trait predicate is not const, the wf obligations should not be const as well.
let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs)
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.args)
} else {
self.nominal_obligations(trait_ref.def_id, trait_ref.substs)
self.nominal_obligations(trait_ref.def_id, trait_ref.args)
};
debug!("compute_trait_pred obligations {:?}", obligations);
@ -383,7 +383,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
self.out.extend(
trait_ref
.substs
.args
.iter()
.enumerate()
.filter(|(_, arg)| {
@ -416,7 +416,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// Compute the obligations that are required for `trait_ref` to be WF,
// given that it is a *negative* trait predicate.
fn compute_negative_trait_pred(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
for arg in trait_ref.substs {
for arg in trait_ref.args {
self.compute(arg);
}
}
@ -427,7 +427,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// A projection is well-formed if
//
// (a) its predicates hold (*)
// (b) its substs are wf
// (b) its args are wf
//
// (*) The predicates of an associated type include the predicates of
// the trait that it's contained in. For example, given
@ -446,17 +446,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// `i32: Copy`
// ]
// Projection types do not require const predicates.
let obligations = self.nominal_obligations_without_const(data.def_id, data.substs);
let obligations = self.nominal_obligations_without_const(data.def_id, data.args);
self.out.extend(obligations);
self.compute_projection_substs(data.substs);
self.compute_projection_args(data.args);
}
fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) {
// An inherent projection is well-formed if
//
// (a) its predicates hold (*)
// (b) its substs are wf
// (b) its args are wf
//
// (*) The predicates of an inherent associated type include the
// predicates of the impl that it's contained in.
@ -464,7 +464,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
if !data.self_ty().has_escaping_bound_vars() {
// FIXME(inherent_associated_types): Should this happen inside of a snapshot?
// FIXME(inherent_associated_types): This is incompatible with the new solver and lazy norm!
let substs = traits::project::compute_inherent_assoc_ty_substs(
let args = traits::project::compute_inherent_assoc_ty_args(
&mut traits::SelectionContext::new(self.infcx),
self.param_env,
data,
@ -473,22 +473,21 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
&mut self.out,
);
// Inherent projection types do not require const predicates.
let obligations = self.nominal_obligations_without_const(data.def_id, substs);
let obligations = self.nominal_obligations_without_const(data.def_id, args);
self.out.extend(obligations);
}
self.compute_projection_substs(data.substs);
self.compute_projection_args(data.args);
}
fn compute_projection_substs(&mut self, substs: SubstsRef<'tcx>) {
fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) {
let tcx = self.tcx();
let cause = self.cause(traits::WellFormed(None));
let param_env = self.param_env;
let depth = self.recursion_depth;
self.out.extend(
substs
.iter()
args.iter()
.filter(|arg| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
})
@ -541,7 +540,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
match ct.kind() {
ty::ConstKind::Unevaluated(uv) => {
if !ct.has_escaping_bound_vars() {
let obligations = self.nominal_obligations(uv.def, uv.substs);
let obligations = self.nominal_obligations(uv.def, uv.args);
self.out.extend(obligations);
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
@ -661,14 +660,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
self.compute_inherent_projection(data);
}
ty::Adt(def, substs) => {
ty::Adt(def, args) => {
// WfNominalType
let obligations = self.nominal_obligations(def.did(), substs);
let obligations = self.nominal_obligations(def.did(), args);
self.out.extend(obligations);
}
ty::FnDef(did, substs) => {
let obligations = self.nominal_obligations_without_const(did, substs);
ty::FnDef(did, args) => {
let obligations = self.nominal_obligations_without_const(did, args);
self.out.extend(obligations);
}
@ -688,7 +687,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}
}
ty::Generator(did, substs, ..) => {
ty::Generator(did, args, ..) => {
// Walk ALL the types in the generator: this will
// include the upvar types as well as the yield
// type. Note that this is mildly distinct from
@ -696,11 +695,11 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// about the signature of the closure. We don't
// have the problem of implied bounds here since
// generators don't take arguments.
let obligations = self.nominal_obligations(did, substs);
let obligations = self.nominal_obligations(did, args);
self.out.extend(obligations);
}
ty::Closure(did, substs) => {
ty::Closure(did, args) => {
// Only check the upvar types for WF, not the rest
// of the types within. This is needed because we
// capture the signature and it may not be WF
@ -723,7 +722,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// fn(&'a T) }`, as discussed in #25860.
walker.skip_current_subtree(); // subtree handled below
// FIXME(eddyb) add the type to `walker` instead of recursing.
self.compute(substs.as_closure().tupled_upvars_ty().into());
self.compute(args.as_closure().tupled_upvars_ty().into());
// Note that we cannot skip the generic types
// types. Normally, within the fn
// body where they are created, the generics will
@ -739,7 +738,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// can cause compiler crashes when the user abuses unsafe
// code to procure such a closure.
// See tests/ui/type-alias-impl-trait/wf_check_closures.rs
let obligations = self.nominal_obligations(did, substs);
let obligations = self.nominal_obligations(did, args);
self.out.extend(obligations);
}
@ -748,18 +747,18 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
// types appearing in the fn signature
}
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
// All of the requirements on type parameters
// have already been checked for `impl Trait` in
// return position. We do need to check type-alias-impl-trait though.
if self.tcx().is_type_alias_impl_trait(def_id) {
let obligations = self.nominal_obligations(def_id, substs);
let obligations = self.nominal_obligations(def_id, args);
self.out.extend(obligations);
}
}
ty::Alias(ty::Weak, ty::AliasTy { def_id, substs, .. }) => {
let obligations = self.nominal_obligations(def_id, substs);
ty::Alias(ty::Weak, ty::AliasTy { def_id, args, .. }) => {
let obligations = self.nominal_obligations(def_id, args);
self.out.extend(obligations);
}
@ -826,7 +825,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
fn nominal_obligations_inner(
&mut self,
def_id: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
remap_constness: bool,
) -> Vec<traits::PredicateObligation<'tcx>> {
let predicates = self.tcx().predicates_of(def_id);
@ -837,7 +836,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
origins.extend(iter::repeat(parent).take(head.predicates.len()));
}
let predicates = predicates.instantiate(self.tcx(), substs);
let predicates = predicates.instantiate(self.tcx(), args);
trace!("{:#?}", predicates);
debug_assert_eq!(predicates.predicates.len(), origins.len());
@ -867,17 +866,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
fn nominal_obligations(
&mut self,
def_id: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
self.nominal_obligations_inner(def_id, substs, false)
self.nominal_obligations_inner(def_id, args, false)
}
fn nominal_obligations_without_const(
&mut self,
def_id: DefId,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
) -> Vec<traits::PredicateObligation<'tcx>> {
self.nominal_obligations_inner(def_id, substs, true)
self.nominal_obligations_inner(def_id, args, true)
}
fn from_object_ty(