refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
@@ -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)?;
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user