refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
parent
df5c2cf9bc
commit
e55583c4b8
466 changed files with 4574 additions and 4604 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
}));
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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(),
|
||||
}),
|
||||
));
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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),
|
||||
)
|
||||
})
|
||||
});
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
}))
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue