summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/select/confirmation.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs110
1 files changed, 44 insertions, 66 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 82a59831b..21c158fd0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -8,12 +8,11 @@
//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
-use rustc_index::bit_set::GrowableBitSet;
use rustc_infer::infer::InferOk;
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
use rustc_middle::ty::{
- self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef,
- ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt,
+ self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
+ TraitRef, Ty, TyCtxt, TypeVisitableExt,
};
use rustc_session::config::TraitSolver;
use rustc_span::def_id::DefId;
@@ -152,7 +151,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
let placeholder_trait_predicate =
- self.infcx.replace_bound_vars_with_placeholders(trait_predicate).trait_ref;
+ 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() {
@@ -337,7 +336,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = obligation.derived_cause(BuiltinDerivedObligation);
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
- let trait_ref = self.infcx.replace_bound_vars_with_placeholders(poly_trait_ref);
+ let trait_ref = self.infcx.instantiate_binder_with_placeholders(poly_trait_ref);
let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations(
&cause,
obligation.recursion_depth + 1,
@@ -428,7 +427,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.tcx();
debug!(?obligation, ?index, "confirm_object_candidate");
- let trait_predicate = self.infcx.replace_bound_vars_with_placeholders(obligation.predicate);
+ let trait_predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
let ty::Dynamic(data, ..) = *self_ty.kind() else {
@@ -438,7 +437,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let object_trait_ref = data.principal().unwrap_or_else(|| {
span_bug!(obligation.cause.span, "object candidate with no principal")
});
- let object_trait_ref = self.infcx.replace_bound_vars_with_fresh_vars(
+ let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
object_trait_ref,
@@ -525,29 +524,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.kind
{
GenericParamDefKind::Type { .. } => {
- let kind = ty::BoundTyKind::Param(param.name);
+ let kind = ty::BoundTyKind::Param(param.def_id, param.name);
let bound_var = ty::BoundVariableKind::Ty(kind);
bound_vars.push(bound_var);
- tcx.mk_ty(ty::Bound(
+ tcx.mk_bound(
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);
- tcx.mk_region(ty::ReLateBound(
+ tcx.mk_re_late_bound(
ty::INNERMOST,
ty::BoundRegion {
var: ty::BoundVar::from_usize(bound_vars.len() - 1),
kind,
},
- ))
+ )
.into()
}
GenericParamDefKind::Const { .. } => {
@@ -558,15 +557,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::INNERMOST,
ty::BoundVar::from_usize(bound_vars.len() - 1),
),
- tcx.type_of(param.def_id),
+ 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.into_iter());
- let assoc_ty_substs = tcx.intern_substs(&substs);
-
- let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
+ 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);
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
@@ -630,7 +629,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
- let output_ty = self.infcx.replace_bound_vars_with_placeholders(sig.output());
+ let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
let output_ty = normalize_with_depth_to(
self,
obligation.param_env,
@@ -653,7 +652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?obligation, "confirm_trait_alias_candidate");
let alias_def_id = obligation.predicate.def_id();
- let predicate = self.infcx.replace_bound_vars_with_placeholders(obligation.predicate);
+ 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;
@@ -822,6 +821,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx
.at(&obligation.cause, obligation.param_env)
+ // needed for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
+ .define_opaque_types(true)
.sup(obligation_trait_ref, expected_trait_ref)
.map(|InferOk { mut obligations, .. }| {
obligations.extend(nested);
@@ -879,7 +880,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::ExistentialPredicate::AutoTrait)
.map(ty::Binder::dummy),
);
- let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+ let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a);
// Require that the traits involved in this upcast are **equal**;
@@ -978,7 +979,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::ExistentialPredicate::AutoTrait)
.map(ty::Binder::dummy),
);
- let existential_predicates = tcx.mk_poly_existential_predicates(iter);
+ let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a);
// Require that the traits involved in this upcast are **equal**;
@@ -1009,7 +1010,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// `T` -> `Trait`
(_, &ty::Dynamic(ref data, r, ty::Dyn)) => {
let mut object_dids = data.auto_traits().chain(data.principal_def_id());
- if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
+ if let Some(did) = object_dids.find(|did| !tcx.check_is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did));
}
@@ -1064,51 +1065,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// `Struct<T>` -> `Struct<U>`
(&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => {
- let maybe_unsizing_param_idx = |arg: GenericArg<'tcx>| match arg.unpack() {
- GenericArgKind::Type(ty) => match ty.kind() {
- ty::Param(p) => Some(p.index),
- _ => None,
- },
-
- // Lifetimes aren't allowed to change during unsizing.
- GenericArgKind::Lifetime(_) => None,
-
- GenericArgKind::Const(ct) => match ct.kind() {
- ty::ConstKind::Param(p) => Some(p.index),
- _ => None,
- },
- };
-
- // FIXME(eddyb) cache this (including computing `unsizing_params`)
- // by putting it in a query; it would only need the `DefId` as it
- // looks at declared field types, not anything substituted.
-
- // The last field of the structure has to exist and contain type/const parameters.
- let (tail_field, prefix_fields) =
- def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?;
- let tail_field_ty = tcx.bound_type_of(tail_field.did);
-
- let mut unsizing_params = GrowableBitSet::new_empty();
- for arg in tail_field_ty.0.walk() {
- if let Some(i) = maybe_unsizing_param_idx(arg) {
- unsizing_params.insert(i);
- }
- }
-
- // Ensure none of the other fields mention the parameters used
- // in unsizing.
- for field in prefix_fields {
- for arg in tcx.type_of(field.did).walk() {
- if let Some(i) = maybe_unsizing_param_idx(arg) {
- unsizing_params.remove(i);
- }
- }
- }
-
+ let unsizing_params = tcx.unsizing_params_for_adt(def.did());
if unsizing_params.is_empty() {
return Err(Unimplemented);
}
+ let tail_field = def
+ .non_enum_variant()
+ .fields
+ .last()
+ .expect("expected unsized ADT to have a tail field");
+ let tail_field_ty = tcx.type_of(tail_field.did);
+
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
// normalizing in the process, since `type_of` returns something directly from
// astconv (which means it's un-normalized).
@@ -1131,7 +1099,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Check that the source struct with the target's
// unsizing parameters is equal to the target.
- let substs = tcx.mk_substs(substs_a.iter().enumerate().map(|(i, k)| {
+ 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 = tcx.mk_adt(def, substs);
@@ -1163,7 +1131,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Check that the source tuple with the target's
// last element is equal to the target.
- let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last)));
+ let new_tuple =
+ tcx.mk_tup_from_iter(a_mid.iter().copied().chain(iter::once(b_last)));
let InferOk { obligations, .. } = self
.infcx
.at(&obligation.cause, obligation.param_env)
@@ -1223,7 +1192,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let cause = obligation.derived_cause(|derived| {
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
derived,
- impl_def_id,
+ impl_or_alias_def_id: impl_def_id,
+ impl_def_predicate_index: None,
span: obligation.cause.span,
}))
});
@@ -1285,6 +1255,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::GeneratorWitness(tys) => {
stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
}
+ ty::GeneratorWitnessMIR(def_id, substs) => {
+ let tcx = self.tcx();
+ stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
+ let ty = bty.subst(tcx, substs);
+ debug_assert!(!ty.has_late_bound_regions());
+ ty
+ }))
+ }
// If we have a projection type, make sure to normalize it so we replace it
// with a fresh infer variable