Add term to ExistentialProjection
Also prevent ICE when adding a const in associated const equality.
This commit is contained in:
parent
f396888c4d
commit
1c1ce2fbda
35 changed files with 213 additions and 71 deletions
|
@ -4,7 +4,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind};
|
|||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{
|
||||
ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy,
|
||||
ProjectionTy, TyCtxt, TyS, TypeAndMut,
|
||||
ProjectionTy, Term, TyCtxt, TyS, TypeAndMut,
|
||||
};
|
||||
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
|
@ -105,8 +105,14 @@ impl<'tcx> TyS<'tcx> {
|
|||
ExistentialPredicate::Trait(ExistentialTraitRef { substs, .. }) => {
|
||||
substs.iter().all(generic_arg_is_suggestible)
|
||||
}
|
||||
ExistentialPredicate::Projection(ExistentialProjection { substs, ty, .. }) => {
|
||||
ty.is_suggestable() && substs.iter().all(generic_arg_is_suggestible)
|
||||
ExistentialPredicate::Projection(ExistentialProjection {
|
||||
substs, term, ..
|
||||
}) => {
|
||||
let term_is_suggestable = match term {
|
||||
Term::Ty(ty) => ty.is_suggestable(),
|
||||
Term::Const(c) => const_is_suggestable(c.val),
|
||||
};
|
||||
term_is_suggestable && substs.iter().all(generic_arg_is_suggestible)
|
||||
}
|
||||
_ => true,
|
||||
}),
|
||||
|
|
|
@ -320,7 +320,10 @@ impl FlagComputation {
|
|||
|
||||
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
|
||||
self.add_substs(projection.substs);
|
||||
self.add_ty(projection.ty);
|
||||
match projection.term {
|
||||
ty::Term::Ty(ty) => self.add_ty(ty),
|
||||
ty::Term::Const(ct) => self.add_const(ct),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_projection_ty(&mut self, projection_ty: ty::ProjectionTy<'_>) {
|
||||
|
|
|
@ -795,7 +795,7 @@ pub struct CoercePredicate<'tcx> {
|
|||
}
|
||||
pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable)]
|
||||
pub enum Term<'tcx> {
|
||||
Ty(Ty<'tcx>),
|
||||
|
|
|
@ -905,29 +905,27 @@ pub trait PrettyPrinter<'tcx>:
|
|||
}
|
||||
|
||||
for (assoc_item_def_id, term) in assoc_items {
|
||||
let ty = match term.skip_binder() {
|
||||
Term::Ty(ty) => ty,
|
||||
Term::Const(c) => {
|
||||
p!(print(c));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if !first {
|
||||
p!(", ");
|
||||
}
|
||||
p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident));
|
||||
|
||||
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
|
||||
match ty.kind() {
|
||||
ty::Projection(ty::ProjectionTy { item_def_id, .. })
|
||||
if Some(*item_def_id) == self.tcx().lang_items().generator_return() =>
|
||||
{
|
||||
p!("[async output]")
|
||||
match term.skip_binder() {
|
||||
Term::Ty(ty) => {
|
||||
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
|
||||
if matches!(
|
||||
ty.kind(), ty::Projection(ty::ProjectionTy { item_def_id, .. })
|
||||
if Some(*item_def_id) == self.tcx().lang_items().generator_return()
|
||||
) {
|
||||
p!("[async output]")
|
||||
} else {
|
||||
p!(print(ty))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
p!(print(ty))
|
||||
Term::Const(c) => {
|
||||
p!(print(c));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
@ -1031,7 +1029,11 @@ pub trait PrettyPrinter<'tcx>:
|
|||
let mut projections = predicates.projection_bounds();
|
||||
if let (Some(proj), None) = (projections.next(), projections.next()) {
|
||||
let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
|
||||
p!(pretty_fn_sig(&tys, false, proj.skip_binder().ty));
|
||||
p!(pretty_fn_sig(
|
||||
&tys,
|
||||
false,
|
||||
proj.skip_binder().term.ty().expect("Return type was a const")
|
||||
));
|
||||
resugared = true;
|
||||
}
|
||||
}
|
||||
|
@ -2454,7 +2456,7 @@ define_print_and_forward_display! {
|
|||
|
||||
ty::ExistentialProjection<'tcx> {
|
||||
let name = cx.tcx().associated_item(self.item_def_id).ident;
|
||||
p!(write("{} = ", name), print(self.ty))
|
||||
p!(write("{} = ", name), print(self.term))
|
||||
}
|
||||
|
||||
ty::ExistentialPredicate<'tcx> {
|
||||
|
|
|
@ -291,11 +291,11 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
|
|||
b.item_def_id,
|
||||
)))
|
||||
} else {
|
||||
let ty = relation.relate_with_variance(
|
||||
let term = relation.relate_with_variance(
|
||||
ty::Invariant,
|
||||
ty::VarianceDiagInfo::default(),
|
||||
a.ty,
|
||||
b.ty,
|
||||
a.term,
|
||||
b.term,
|
||||
)?;
|
||||
let substs = relation.relate_with_variance(
|
||||
ty::Invariant,
|
||||
|
@ -303,7 +303,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
|
|||
a.substs,
|
||||
b.substs,
|
||||
)?;
|
||||
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, ty })
|
||||
Ok(ty::ExistentialProjection { item_def_id: a.item_def_id, substs, term })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
|
|||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(self.substs).map(|substs| ty::ExistentialProjection {
|
||||
substs,
|
||||
ty: tcx.lift(self.ty).expect("type must lift when substs do"),
|
||||
term: tcx.lift(self.term).expect("type must lift when substs do"),
|
||||
item_def_id: self.item_def_id,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1540,7 +1540,7 @@ impl From<BoundVar> for BoundTy {
|
|||
pub struct ExistentialProjection<'tcx> {
|
||||
pub item_def_id: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub term: Term<'tcx>,
|
||||
}
|
||||
|
||||
pub type PolyExistentialProjection<'tcx> = Binder<'tcx, ExistentialProjection<'tcx>>;
|
||||
|
@ -1570,7 +1570,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
|||
item_def_id: self.item_def_id,
|
||||
substs: tcx.mk_substs_trait(self_ty, self.substs),
|
||||
},
|
||||
term: self.ty.into(),
|
||||
term: self.term,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1580,15 +1580,11 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
|||
) -> Self {
|
||||
// Assert there is a Self.
|
||||
projection_predicate.projection_ty.substs.type_at(0);
|
||||
let ty = match projection_predicate.term {
|
||||
Term::Ty(ty) => ty,
|
||||
Term::Const(_c) => unimplemented!(),
|
||||
};
|
||||
|
||||
Self {
|
||||
item_def_id: projection_predicate.projection_ty.item_def_id,
|
||||
substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]),
|
||||
ty,
|
||||
term: projection_predicate.term,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -157,7 +157,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
|||
stack.extend(obj.iter().rev().flat_map(|predicate| {
|
||||
let (substs, opt_ty) = match predicate.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(tr) => (tr.substs, None),
|
||||
ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.ty)),
|
||||
ty::ExistentialPredicate::Projection(p) => (p.substs, Some(p.term)),
|
||||
ty::ExistentialPredicate::AutoTrait(_) =>
|
||||
// Empty iterator
|
||||
{
|
||||
|
@ -165,7 +165,10 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
|||
}
|
||||
};
|
||||
|
||||
substs.iter().rev().chain(opt_ty.map(|ty| ty.into()))
|
||||
substs.iter().rev().chain(opt_ty.map(|term| match term {
|
||||
ty::Term::Ty(ty) => ty.into(),
|
||||
ty::Term::Const(ct) => ct.into(),
|
||||
}))
|
||||
}));
|
||||
}
|
||||
ty::Adt(_, substs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue