Auto merge of #104986 - compiler-errors:opaques, r=oli-obk
Combine `ty::Projection` and `ty::Opaque` into `ty::Alias` Implements https://github.com/rust-lang/types-team/issues/79. This PR consolidates `ty::Projection` and `ty::Opaque` into a single `ty::Alias`, with an `AliasKind` and `AliasTy` type (renamed from `ty::ProjectionTy`, which is the inner data of `ty::Projection`) defined as so: ``` enum AliasKind { Projection, Opaque, } struct AliasTy<'tcx> { def_id: DefId, substs: SubstsRef<'tcx>, } ``` Since we don't have access to `TyCtxt` in type flags computation, and because repeatedly calling `DefKind` on the def-id is expensive, these two types are distinguished with `ty::AliasKind`, conveniently glob-imported into `ty::{Projection, Opaque}`. For example: ```diff match ty.kind() { - ty::Opaque(..) => + ty::Alias(ty::Opaque, ..) => {} _ => {} } ``` This PR also consolidates match arms that treated `ty::Opaque` and `ty::Projection` identically. r? `@ghost`
This commit is contained in:
commit
918d0ac38e
115 changed files with 632 additions and 674 deletions
|
@ -579,14 +579,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
pub fn is_of_param(&self, ty: Ty<'_>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::Param(_) => true,
|
||||
ty::Projection(p) => self.is_of_param(p.self_ty()),
|
||||
ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
|
||||
if let Some(ty) = p.term().skip_binder().ty() {
|
||||
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
|
||||
matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -659,7 +659,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
|
|||
| ty::RawPtr(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(..)
|
||||
| ty::Projection(..) => self.found_non_local_ty(ty),
|
||||
| ty::Alias(ty::Projection, ..) => self.found_non_local_ty(ty),
|
||||
|
||||
ty::Param(..) => self.found_param_ty(ty),
|
||||
|
||||
|
@ -704,7 +704,7 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> {
|
|||
);
|
||||
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
|
||||
}
|
||||
ty::Opaque(..) => {
|
||||
ty::Alias(ty::Opaque, ..) => {
|
||||
// This merits some explanation.
|
||||
// Normally, opaque types are not involved when performing
|
||||
// coherence checking, since it is illegal to directly
|
||||
|
|
|
@ -1636,8 +1636,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let normalized_ty = ocx.normalize(
|
||||
&obligation.cause,
|
||||
obligation.param_env,
|
||||
self.tcx
|
||||
.mk_projection(data.projection_ty.item_def_id, data.projection_ty.substs),
|
||||
self.tcx.mk_projection(data.projection_ty.def_id, data.projection_ty.substs),
|
||||
);
|
||||
|
||||
debug!(?obligation.cause, ?obligation.param_env);
|
||||
|
@ -1688,10 +1687,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let secondary_span = match predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
|
||||
.tcx
|
||||
.opt_associated_item(proj.projection_ty.item_def_id)
|
||||
.opt_associated_item(proj.projection_ty.def_id)
|
||||
.and_then(|trait_assoc_item| {
|
||||
self.tcx
|
||||
.trait_of_item(proj.projection_ty.item_def_id)
|
||||
.trait_of_item(proj.projection_ty.def_id)
|
||||
.map(|id| (trait_assoc_item, id))
|
||||
})
|
||||
.and_then(|(trait_assoc_item, id)| {
|
||||
|
@ -1747,7 +1746,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let trait_def_id = pred.projection_ty.trait_def_id(self.tcx);
|
||||
let self_ty = pred.projection_ty.self_ty();
|
||||
|
||||
if Some(pred.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output() {
|
||||
if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() {
|
||||
Some(format!(
|
||||
"expected `{self_ty}` to be a {fn_kind} that returns `{expected_ty}`, but it returns `{normalized_ty}`",
|
||||
fn_kind = self_ty.prefix_string(self.tcx)
|
||||
|
@ -1790,8 +1789,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ty::Closure(..) => Some(9),
|
||||
ty::Tuple(..) => Some(10),
|
||||
ty::Param(..) => Some(11),
|
||||
ty::Projection(..) => Some(12),
|
||||
ty::Opaque(..) => Some(13),
|
||||
ty::Alias(ty::Projection, ..) => Some(12),
|
||||
ty::Alias(ty::Opaque, ..) => Some(13),
|
||||
ty::Never => Some(14),
|
||||
ty::Adt(..) => Some(15),
|
||||
ty::Generator(..) => Some(16),
|
||||
|
|
|
@ -371,7 +371,7 @@ fn suggest_restriction<'tcx>(
|
|||
msg: &str,
|
||||
err: &mut Diagnostic,
|
||||
fn_sig: Option<&hir::FnSig<'_>>,
|
||||
projection: Option<&ty::ProjectionTy<'_>>,
|
||||
projection: Option<&ty::AliasTy<'_>>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
// When we are dealing with a trait, `super_traits` will be `Some`:
|
||||
// Given `trait T: A + B + C {}`
|
||||
|
@ -497,7 +497,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let self_ty = trait_pred.skip_binder().self_ty();
|
||||
let (param_ty, projection) = match self_ty.kind() {
|
||||
ty::Param(_) => (true, None),
|
||||
ty::Projection(projection) => (false, Some(projection)),
|
||||
ty::Alias(ty::Projection, projection) => (false, Some(projection)),
|
||||
_ => (false, None),
|
||||
};
|
||||
|
||||
|
@ -857,10 +857,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
fn_sig.inputs().map_bound(|inputs| &inputs[1..]),
|
||||
))
|
||||
}
|
||||
ty::Opaque(def_id, substs) => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
|
||||
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
|
||||
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
&& 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()
|
||||
{
|
||||
|
@ -877,7 +877,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ty::Dynamic(data, _, ty::Dyn) => {
|
||||
data.iter().find_map(|pred| {
|
||||
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
|
||||
&& Some(proj.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
&& 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()
|
||||
{
|
||||
|
@ -894,7 +894,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ty::Param(_) => {
|
||||
obligation.param_env.caller_bounds().iter().find_map(|pred| {
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
|
||||
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
|
||||
&& 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()
|
||||
|
@ -2641,7 +2641,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
Some(ident) => err.span_note(ident.span, &msg),
|
||||
None => err.note(&msg),
|
||||
},
|
||||
ty::Opaque(def_id, _) => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs: _ }) => {
|
||||
// Avoid printing the future from `core::future::identity_future`, it's not helpful
|
||||
if tcx.parent(*def_id) == identity_future {
|
||||
break 'print;
|
||||
|
@ -3218,7 +3218,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
|
||||
for diff in &type_diffs {
|
||||
let Sorts(expected_found) = diff else { continue; };
|
||||
let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
|
||||
let ty::Alias(ty::Projection, proj) = expected_found.expected.kind() else { continue; };
|
||||
|
||||
let origin =
|
||||
TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
|
||||
|
@ -3245,7 +3245,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
// This corresponds to `<ExprTy as Iterator>::Item = _`.
|
||||
let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||
ty::Clause::Projection(ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: proj.item_def_id },
|
||||
projection_ty: ty::AliasTy { substs, def_id: proj.def_id },
|
||||
term: ty_var.into(),
|
||||
}),
|
||||
));
|
||||
|
@ -3260,7 +3260,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
if ocx.select_where_possible().is_empty() {
|
||||
// `ty_var` now holds the type that `Item` is for `ExprTy`.
|
||||
let ty_var = self.resolve_vars_if_possible(ty_var);
|
||||
assocs_in_this_method.push(Some((span, (proj.item_def_id, ty_var))));
|
||||
assocs_in_this_method.push(Some((span, (proj.def_id, ty_var))));
|
||||
} else {
|
||||
// `<ExprTy as Iterator>` didn't select, so likely we've
|
||||
// reached the end of the iterator chain, like the originating
|
||||
|
|
|
@ -589,7 +589,7 @@ fn object_ty_for_trait<'tcx>(
|
|||
let pred = obligation.predicate.to_opt_poly_projection_pred()?;
|
||||
Some(pred.map_bound(|p| {
|
||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
||||
item_def_id: p.projection_ty.item_def_id,
|
||||
def_id: p.projection_ty.def_id,
|
||||
substs: p.projection_ty.substs,
|
||||
term: p.term,
|
||||
})
|
||||
|
@ -794,13 +794,13 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
|
|||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
ty::Projection(ref data)
|
||||
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
ty::Alias(ty::Projection, ref data)
|
||||
if self.tcx.def_kind(data.def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
{
|
||||
// We'll deny these later in their own pass
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
ty::Projection(ref data) => {
|
||||
ty::Alias(ty::Projection, ref data) => {
|
||||
// This is a projected type `<Foo as SomeTrait>::X`.
|
||||
|
||||
// Compute supertraits of current trait lazily.
|
||||
|
@ -861,10 +861,10 @@ pub fn contains_illegal_impl_trait_in_trait<'tcx>(
|
|||
// FIXME(RPITIT): Perhaps we should use a visitor here?
|
||||
ty.skip_binder().walk().find_map(|arg| {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Projection(proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||
&& let ty::Alias(ty::Projection, proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
|
||||
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.def_id)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPre
|
|||
|
||||
pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>;
|
||||
|
||||
pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>;
|
||||
pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>;
|
||||
|
||||
pub(super) struct InProgress;
|
||||
|
||||
|
@ -496,7 +496,9 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
// This is really important. While we *can* handle this, this has
|
||||
// severe performance implications for large opaque types with
|
||||
// late-bound regions. See `issue-88862` benchmark.
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs })
|
||||
if !substs.has_escaping_bound_vars() =>
|
||||
{
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
|
@ -523,7 +525,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Projection(data) if !data.has_escaping_bound_vars() => {
|
||||
ty::Alias(ty::Projection, data) if !data.has_escaping_bound_vars() => {
|
||||
// This branch is *mostly* just an optimization: when we don't
|
||||
// have escaping bound vars, we don't need to replace them with
|
||||
// placeholders (see branch below). *Also*, we know that we can
|
||||
|
@ -562,7 +564,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
normalized_ty.ty().unwrap()
|
||||
}
|
||||
|
||||
ty::Projection(data) => {
|
||||
ty::Alias(ty::Projection, data) => {
|
||||
// If there are escaping bound vars, we temporarily replace the
|
||||
// bound vars with placeholders. Note though, that in the case
|
||||
// that we still can't project for whatever reason (e.g. self
|
||||
|
@ -957,7 +959,7 @@ impl<'tcx> TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
|||
pub fn normalize_projection_type<'a, 'b, 'tcx>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
projection_ty: ty::ProjectionTy<'tcx>,
|
||||
projection_ty: ty::AliasTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
||||
|
@ -995,7 +997,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
|
|||
fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
projection_ty: ty::ProjectionTy<'tcx>,
|
||||
projection_ty: ty::AliasTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
||||
|
@ -1177,7 +1179,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
|||
fn normalize_to_error<'a, 'tcx>(
|
||||
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
projection_ty: ty::ProjectionTy<'tcx>,
|
||||
projection_ty: ty::AliasTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
) -> NormalizedTy<'tcx> {
|
||||
|
@ -1189,10 +1191,9 @@ fn normalize_to_error<'a, 'tcx>(
|
|||
predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
|
||||
};
|
||||
let tcx = selcx.infcx.tcx;
|
||||
let def_id = projection_ty.item_def_id;
|
||||
let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::NormalizeProjectionType,
|
||||
span: tcx.def_span(def_id),
|
||||
span: tcx.def_span(projection_ty.def_id),
|
||||
});
|
||||
Normalized { value: new_value, obligations: vec![trait_obligation] }
|
||||
}
|
||||
|
@ -1270,7 +1271,7 @@ fn project<'cx, 'tcx>(
|
|||
// need to investigate whether or not this is fine.
|
||||
selcx
|
||||
.tcx()
|
||||
.mk_projection(obligation.predicate.item_def_id, obligation.predicate.substs)
|
||||
.mk_projection(obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
)),
|
||||
// Error occurred while trying to processing impls.
|
||||
|
@ -1290,13 +1291,12 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
|||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
let tcx = selcx.tcx();
|
||||
if tcx.def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
|
||||
if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
|
||||
// If we are trying to project an RPITIT with trait's default `Self` parameter,
|
||||
// then we must be within a default trait body.
|
||||
if obligation.predicate.self_ty()
|
||||
== ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.item_def_id)
|
||||
.type_at(0)
|
||||
== ty::InternalSubsts::identity_for_item(tcx, obligation.predicate.def_id).type_at(0)
|
||||
&& tcx.associated_item(trait_fn_def_id).defaultness(tcx).has_value()
|
||||
{
|
||||
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(
|
||||
|
@ -1377,8 +1377,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
|
|||
// Check whether the self-type is itself a projection.
|
||||
// If so, extract what we know from the trait and try to come up with a good answer.
|
||||
let bounds = match *obligation.predicate.self_ty().kind() {
|
||||
ty::Projection(ref data) => tcx.bound_item_bounds(data.item_def_id).subst(tcx, data.substs),
|
||||
ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
|
||||
ty::Alias(_, ref data) => tcx.bound_item_bounds(data.def_id).subst(tcx, data.substs),
|
||||
ty::Infer(ty::TyVar(_)) => {
|
||||
// If the self-type is an inference variable, then it MAY wind up
|
||||
// being a projected type, so induce an ambiguity.
|
||||
|
@ -1430,7 +1429,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
|
|||
};
|
||||
let env_predicates = data
|
||||
.projection_bounds()
|
||||
.filter(|bound| bound.item_def_id() == obligation.predicate.item_def_id)
|
||||
.filter(|bound| bound.item_def_id() == obligation.predicate.def_id)
|
||||
.map(|p| p.with_self_ty(tcx, object_ty).to_predicate(tcx));
|
||||
|
||||
assemble_candidates_from_predicates(
|
||||
|
@ -1462,7 +1461,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
|
|||
predicate.kind().skip_binder()
|
||||
{
|
||||
let data = bound_predicate.rebind(data);
|
||||
if data.projection_def_id() != obligation.predicate.item_def_id {
|
||||
if data.projection_def_id() != obligation.predicate.def_id {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1502,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
candidate_set: &mut ProjectionCandidateSet<'tcx>,
|
||||
) {
|
||||
// Can't assemble candidate from impl for RPITIT
|
||||
if selcx.tcx().def_kind(obligation.predicate.item_def_id) == DefKind::ImplTraitPlaceholder {
|
||||
if selcx.tcx().def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1555,7 +1554,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// NOTE: This should be kept in sync with the similar code in
|
||||
// `rustc_ty_utils::instance::resolve_associated_item()`.
|
||||
let node_item =
|
||||
assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id)
|
||||
assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.def_id)
|
||||
.map_err(|ErrorGuaranteed { .. }| ())?;
|
||||
|
||||
if node_item.is_final() {
|
||||
|
@ -1616,8 +1615,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
|
@ -1671,7 +1669,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
|
||||
ty::Param(_) | ty::Alias(..)
|
||||
if selcx.infcx.predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
|
@ -1687,8 +1685,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
|
||||
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
|
@ -1788,7 +1785,7 @@ fn confirm_candidate<'cx, 'tcx>(
|
|||
ProjectionCandidate::ImplTraitInTrait(ImplTraitInTraitCandidate::Trait) => Progress {
|
||||
term: selcx
|
||||
.tcx()
|
||||
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
|
||||
.mk_opaque(obligation.predicate.def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
obligations: vec![],
|
||||
},
|
||||
|
@ -1860,7 +1857,7 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
|||
gen_sig,
|
||||
)
|
||||
.map_bound(|(trait_ref, yield_ty, return_ty)| {
|
||||
let name = tcx.associated_item(obligation.predicate.item_def_id).name;
|
||||
let name = tcx.associated_item(obligation.predicate.def_id).name;
|
||||
let ty = if name == sym::Return {
|
||||
return_ty
|
||||
} else if name == sym::Yield {
|
||||
|
@ -1870,9 +1867,9 @@ fn confirm_generator_candidate<'cx, 'tcx>(
|
|||
};
|
||||
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
projection_ty: ty::AliasTy {
|
||||
substs: trait_ref.substs,
|
||||
item_def_id: obligation.predicate.item_def_id,
|
||||
def_id: obligation.predicate.def_id,
|
||||
},
|
||||
term: ty.into(),
|
||||
}
|
||||
|
@ -1909,12 +1906,12 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
|||
gen_sig,
|
||||
)
|
||||
.map_bound(|(trait_ref, return_ty)| {
|
||||
debug_assert_eq!(tcx.associated_item(obligation.predicate.item_def_id).name, sym::Output);
|
||||
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
|
||||
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
projection_ty: ty::AliasTy {
|
||||
substs: trait_ref.substs,
|
||||
item_def_id: obligation.predicate.item_def_id,
|
||||
def_id: obligation.predicate.def_id,
|
||||
},
|
||||
term: return_ty.into(),
|
||||
}
|
||||
|
@ -1934,7 +1931,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
|
|||
let self_ty = obligation.predicate.self_ty();
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let lang_items = tcx.lang_items();
|
||||
let item_def_id = obligation.predicate.item_def_id;
|
||||
let item_def_id = obligation.predicate.def_id;
|
||||
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
|
||||
let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
||||
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
||||
|
@ -1968,8 +1965,10 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
|
|||
bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
|
||||
};
|
||||
|
||||
let predicate =
|
||||
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::AliasTy { substs, def_id: item_def_id },
|
||||
term,
|
||||
};
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
.with_addl_obligations(obligations)
|
||||
|
@ -2038,10 +2037,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
|
|||
flag,
|
||||
)
|
||||
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
substs: trait_ref.substs,
|
||||
item_def_id: fn_once_output_def_id,
|
||||
},
|
||||
projection_ty: ty::AliasTy { substs: trait_ref.substs, def_id: fn_once_output_def_id },
|
||||
term: ret_type.into(),
|
||||
});
|
||||
|
||||
|
@ -2122,7 +2118,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
|||
let tcx = selcx.tcx();
|
||||
|
||||
let ImplSourceUserDefinedData { impl_def_id, substs, mut nested } = impl_impl_source;
|
||||
let assoc_item_id = obligation.predicate.item_def_id;
|
||||
let assoc_item_id = obligation.predicate.def_id;
|
||||
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
|
||||
|
||||
let param_env = obligation.param_env;
|
||||
|
@ -2222,7 +2218,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
|||
let tcx = selcx.tcx();
|
||||
let mut obligations = data.nested;
|
||||
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
|
||||
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
|
||||
let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
|
||||
return Progress { term: tcx.ty_error().into(), obligations };
|
||||
};
|
||||
|
@ -2233,9 +2229,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
|||
// Use the default `impl Trait` for the trait, e.g., for a default trait body
|
||||
if leaf_def.item.container == ty::AssocItemContainer::TraitContainer {
|
||||
return Progress {
|
||||
term: tcx
|
||||
.mk_opaque(obligation.predicate.item_def_id, obligation.predicate.substs)
|
||||
.into(),
|
||||
term: tcx.mk_opaque(obligation.predicate.def_id, obligation.predicate.substs).into(),
|
||||
obligations,
|
||||
};
|
||||
}
|
||||
|
@ -2302,7 +2296,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
|||
obligation.recursion_depth + 1,
|
||||
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
|
||||
.map_bound(|tys| {
|
||||
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
|
||||
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id])
|
||||
})
|
||||
.subst(tcx, impl_fn_substs),
|
||||
&mut obligations,
|
||||
|
@ -2320,7 +2314,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
|
|||
) {
|
||||
let tcx = selcx.tcx();
|
||||
let own = tcx
|
||||
.predicates_of(obligation.predicate.item_def_id)
|
||||
.predicates_of(obligation.predicate.def_id)
|
||||
.instantiate_own(tcx, obligation.predicate.substs);
|
||||
for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
|
||||
let normalized = normalize_with_depth_to(
|
||||
|
@ -2343,13 +2337,13 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
|
|||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
super::ItemObligation(obligation.predicate.item_def_id),
|
||||
super::ItemObligation(obligation.predicate.def_id),
|
||||
)
|
||||
} else {
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
super::BindingObligation(obligation.predicate.item_def_id, span),
|
||||
super::BindingObligation(obligation.predicate.def_id, span),
|
||||
)
|
||||
};
|
||||
nested.push(Obligation::with_depth(
|
||||
|
|
|
@ -62,9 +62,8 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
|
||||
// The following *might* require a destructor: needs deeper inspection.
|
||||
ty::Dynamic(..)
|
||||
| ty::Projection(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Param(_)
|
||||
| ty::Opaque(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(_)
|
||||
| ty::Bound(..)
|
||||
|
|
|
@ -205,7 +205,9 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
// This is really important. While we *can* handle this, this has
|
||||
// severe performance implications for large opaque types with
|
||||
// late-bound regions. See `issue-88862` benchmark.
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs })
|
||||
if !substs.has_escaping_bound_vars() =>
|
||||
{
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.try_super_fold_with(self),
|
||||
|
@ -242,7 +244,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Projection(data) if !data.has_escaping_bound_vars() => {
|
||||
ty::Alias(ty::Projection, data) if !data.has_escaping_bound_vars() => {
|
||||
// This branch is just an optimization: when we don't have escaping bound vars,
|
||||
// we don't need to replace them with placeholders (see branch below).
|
||||
|
||||
|
@ -291,7 +293,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Projection(data) => {
|
||||
ty::Alias(ty::Projection, data) => {
|
||||
// See note in `rustc_trait_selection::traits::project`
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
|
|
|
@ -138,7 +138,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Before we go into the whole placeholder thing, just
|
||||
// quickly check if the self-type is a projection at all.
|
||||
match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
|
||||
ty::Projection(_) | ty::Opaque(..) => {}
|
||||
ty::Alias(..) => {}
|
||||
ty::Infer(ty::TyVar(_)) => {
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
|
@ -394,7 +394,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// still be provided by a manual implementation for
|
||||
// this trait and type.
|
||||
}
|
||||
ty::Param(..) | ty::Projection(..) => {
|
||||
ty::Param(..) | ty::Alias(ty::Projection, ..) => {
|
||||
// In these cases, we don't know what the actual
|
||||
// type is. Therefore, we cannot break it down
|
||||
// into its constituent types. So we don't
|
||||
|
@ -536,10 +536,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let ty = traits::normalize_projection_type(
|
||||
self,
|
||||
param_env,
|
||||
ty::ProjectionTy {
|
||||
item_def_id: tcx.lang_items().deref_target()?,
|
||||
substs: trait_ref.substs,
|
||||
},
|
||||
ty::AliasTy { def_id: tcx.lang_items().deref_target()?, substs: trait_ref.substs },
|
||||
cause.clone(),
|
||||
0,
|
||||
// We're *intentionally* throwing these away,
|
||||
|
@ -737,13 +734,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
|
||||
match self_ty.skip_binder().kind() {
|
||||
ty::Opaque(..)
|
||||
ty::Alias(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Error(_)
|
||||
| ty::Bound(..)
|
||||
| ty::Param(_)
|
||||
| ty::Placeholder(_)
|
||||
| ty::Projection(_) => {
|
||||
| ty::Placeholder(_) => {
|
||||
// We don't know if these are `~const Destruct`, at least
|
||||
// not structurally... so don't push a candidate.
|
||||
}
|
||||
|
@ -829,8 +825,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Generator(_, _, _)
|
||||
| ty::GeneratorWitness(_)
|
||||
| ty::Never
|
||||
| ty::Projection(_)
|
||||
| ty::Opaque(_, _)
|
||||
| ty::Alias(..)
|
||||
| ty::Param(_)
|
||||
| ty::Bound(_, _)
|
||||
| ty::Error(_)
|
||||
|
|
|
@ -155,8 +155,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
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() {
|
||||
ty::Projection(proj) => (proj.item_def_id, proj.substs),
|
||||
ty::Opaque(def_id, substs) => (def_id, substs),
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
|
||||
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
|
||||
};
|
||||
|
||||
|
@ -184,7 +183,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
.map_err(|_| Unimplemented)
|
||||
})?);
|
||||
|
||||
if let ty::Projection(..) = placeholder_self_ty.kind() {
|
||||
if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
|
||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
|
||||
debug!(?predicates, "projection predicates");
|
||||
for predicate in predicates {
|
||||
|
@ -1279,7 +1278,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
// If we have a projection type, make sure to normalize it so we replace it
|
||||
// with a fresh infer variable
|
||||
ty::Projection(..) => {
|
||||
ty::Alias(ty::Projection, ..) => {
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
obligation.param_env,
|
||||
|
|
|
@ -1595,8 +1595,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
let tcx = self.infcx.tcx;
|
||||
let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
|
||||
ty::Projection(ref data) => (data.item_def_id, data.substs),
|
||||
ty::Opaque(def_id, substs) => (def_id, substs),
|
||||
ty::Alias(_, ty::AliasTy { def_id, substs }) => (def_id, substs),
|
||||
_ => {
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
|
@ -1745,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
});
|
||||
|
||||
if is_match {
|
||||
let generics = self.tcx().generics_of(obligation.predicate.item_def_id);
|
||||
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,
|
||||
// that means that we must have newly inferred something about the GAT.
|
||||
|
@ -2067,7 +2066,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}))
|
||||
}
|
||||
|
||||
ty::Projection(_) | ty::Param(_) | ty::Opaque(..) => None,
|
||||
ty::Alias(..) | ty::Param(_) => None,
|
||||
ty::Infer(ty::TyVar(_)) => Ambiguous,
|
||||
|
||||
ty::Placeholder(..)
|
||||
|
@ -2167,7 +2166,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ty::Adt(..) | ty::Projection(..) | ty::Param(..) | ty::Opaque(..) => {
|
||||
ty::Adt(..) | ty::Alias(..) | ty::Param(..) => {
|
||||
// Fallback to whatever user-defined impls exist in this case.
|
||||
None
|
||||
}
|
||||
|
@ -2220,7 +2219,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Dynamic(..)
|
||||
| ty::Param(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Projection(..)
|
||||
| ty::Alias(ty::Projection, ..)
|
||||
| ty::Bound(..)
|
||||
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("asked to assemble constituent types of unexpected type: {:?}", t);
|
||||
|
@ -2260,7 +2259,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
|
||||
}
|
||||
|
||||
ty::Opaque(def_id, substs) => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
|
||||
// We can resolve the `impl Trait` to its concrete type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
|
|
|
@ -95,10 +95,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
|
|||
ty::Foreign(_) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::Opaque(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::Projection(..) => {
|
||||
ty::Alias(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::Closure(..) => {
|
||||
|
|
|
@ -234,9 +234,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
|||
// projection coming from another associated type. See
|
||||
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
||||
// `traits-assoc-type-in-supertrait-bad.rs`.
|
||||
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind())
|
||||
if let Some(ty::Alias(ty::Projection, projection_ty)) = proj.term.ty().map(|ty| ty.kind())
|
||||
&& let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
|
||||
&& let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.owner_id.to_def_id() == impl_item_id)
|
||||
|
@ -249,9 +249,9 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
|||
// An associated item obligation born out of the `trait` failed to be met. An example
|
||||
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
|
||||
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
|
||||
if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = *pred.self_ty().kind()
|
||||
if let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = *pred.self_ty().kind()
|
||||
&& let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&item_def_id)
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&def_id)
|
||||
&& let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.owner_id.to_def_id() == impl_item_id)
|
||||
|
@ -369,7 +369,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
|
||||
/// Pushes the obligations required for `trait_ref::Item` to be WF
|
||||
/// into `self.out`.
|
||||
fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) {
|
||||
fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) {
|
||||
// A projection is well-formed if
|
||||
//
|
||||
// (a) its predicates hold (*)
|
||||
|
@ -392,7 +392,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
// `i32: Copy`
|
||||
// ]
|
||||
// Projection types do not require const predicates.
|
||||
let obligations = self.nominal_obligations_without_const(data.item_def_id, data.substs);
|
||||
let obligations = self.nominal_obligations_without_const(data.def_id, data.substs);
|
||||
self.out.extend(obligations);
|
||||
|
||||
let tcx = self.tcx();
|
||||
|
@ -556,7 +556,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
// Simple cases that are WF if their type args are WF.
|
||||
}
|
||||
|
||||
ty::Projection(data) => {
|
||||
ty::Alias(ty::Projection, data) => {
|
||||
walker.skip_current_subtree(); // Subtree handled by compute_projection.
|
||||
self.compute_projection(data);
|
||||
}
|
||||
|
@ -648,12 +648,12 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||
// types appearing in the fn signature
|
||||
}
|
||||
|
||||
ty::Opaque(did, substs) => {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs }) => {
|
||||
// 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 ty::is_impl_trait_defn(self.tcx, did).is_none() {
|
||||
let obligations = self.nominal_obligations(did, substs);
|
||||
if ty::is_impl_trait_defn(self.tcx, def_id).is_none() {
|
||||
let obligations = self.nominal_obligations(def_id, substs);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue