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

@@ -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
}))