Upgrade ProjectionTy's Name to a DefId
Part of #42171, in preparation for downgrading the contained `TraitRef` to only its `substs`.
This commit is contained in:
parent
fd7b44b78e
commit
e5e664fb07
15 changed files with 91 additions and 59 deletions
|
|
@ -181,7 +181,7 @@ impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> for ty::Outlives
|
|||
}
|
||||
|
||||
impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
|
||||
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name });
|
||||
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_def_id });
|
||||
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
|
||||
|
|
|
|||
|
|
@ -1542,7 +1542,8 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
|
|||
pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
|
||||
match *self {
|
||||
GenericKind::Param(ref p) => p.to_ty(tcx),
|
||||
GenericKind::Projection(ref p) => tcx.mk_projection(p.trait_ref.clone(), p.item_name),
|
||||
GenericKind::Projection(ref p) => tcx.mk_projection(
|
||||
p.trait_ref.clone(), p.item_name(tcx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,7 +355,7 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
|
|||
|
||||
let tcx = selcx.infcx().tcx;
|
||||
let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i|
|
||||
i.name == projection_ty.item_name && i.kind == ty::AssociatedKind::Type
|
||||
i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type
|
||||
).map(|i| i.def_id).unwrap();
|
||||
let ty_var = selcx.infcx().next_ty_var(
|
||||
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
|
||||
|
|
@ -436,7 +436,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
|
|||
//
|
||||
// ```
|
||||
// let ty = selcx.tcx().mk_projection(projection_ty.trait_ref,
|
||||
// projection_ty.item_name);
|
||||
// projection_ty.item_name(tcx);
|
||||
// return Some(NormalizedTy { value: v, obligations: vec![] });
|
||||
// ```
|
||||
|
||||
|
|
@ -574,7 +574,7 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc
|
|||
predicate: trait_ref.to_predicate() };
|
||||
let tcx = selcx.infcx().tcx;
|
||||
let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i|
|
||||
i.name == projection_ty.item_name && i.kind == ty::AssociatedKind::Type
|
||||
i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type
|
||||
).map(|i| i.def_id).unwrap();
|
||||
let new_value = selcx.infcx().next_ty_var(
|
||||
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
|
||||
|
|
@ -729,7 +729,7 @@ fn project_type<'cx, 'gcx, 'tcx>(
|
|||
Ok(ProjectedTy::NoProgress(
|
||||
selcx.tcx().mk_projection(
|
||||
obligation.predicate.trait_ref.clone(),
|
||||
obligation.predicate.item_name)))
|
||||
obligation.predicate.item_name(selcx.tcx()))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -815,7 +815,8 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
|
|||
predicate);
|
||||
match predicate {
|
||||
ty::Predicate::Projection(ref data) => {
|
||||
let same_name = data.item_name() == obligation.predicate.item_name;
|
||||
let tcx = selcx.tcx();
|
||||
let same_name = data.item_name(tcx) == obligation.predicate.item_name(tcx);
|
||||
|
||||
let is_match = same_name && infcx.probe(|_| {
|
||||
let data_poly_trait_ref =
|
||||
|
|
@ -902,7 +903,7 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
|
|||
// type.
|
||||
let node_item = assoc_ty_def(selcx,
|
||||
impl_data.impl_def_id,
|
||||
obligation.predicate.item_name);
|
||||
obligation.predicate.item_name(selcx.tcx()));
|
||||
|
||||
let is_default = if node_item.node.is_from_trait() {
|
||||
// If true, the impl inherited a `type Foo = Bar`
|
||||
|
|
@ -1075,9 +1076,10 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
|
|||
|
||||
// select only those projections that are actually projecting an
|
||||
// item with the correct name
|
||||
let tcx = selcx.tcx();
|
||||
let env_predicates = env_predicates.filter_map(|p| match p {
|
||||
ty::Predicate::Projection(data) =>
|
||||
if data.item_name() == obligation.predicate.item_name {
|
||||
if data.item_name(tcx) == obligation.predicate.item_name(tcx) {
|
||||
Some(data)
|
||||
} else {
|
||||
None
|
||||
|
|
@ -1180,10 +1182,11 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
|
|||
flag);
|
||||
|
||||
let predicate = ty::Binder(ty::ProjectionPredicate { // (1) recreate binder here
|
||||
projection_ty: ty::ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_name: Symbol::intern(FN_OUTPUT_NAME),
|
||||
},
|
||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
trait_ref,
|
||||
Symbol::intern(FN_OUTPUT_NAME),
|
||||
),
|
||||
ty: ret_type
|
||||
});
|
||||
|
||||
|
|
@ -1228,7 +1231,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
|
|||
let VtableImplData { substs, nested, impl_def_id } = impl_vtable;
|
||||
|
||||
let tcx = selcx.tcx();
|
||||
let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name);
|
||||
let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name(tcx));
|
||||
|
||||
let ty = if !assoc_ty.item.defaultness.has_value() {
|
||||
// This means that the impl is missing a definition for the
|
||||
|
|
|
|||
|
|
@ -1321,7 +1321,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
item_name: Name)
|
||||
-> Ty<'tcx> {
|
||||
// take a copy of substs so that we own the vectors inside
|
||||
let inner = ProjectionTy { trait_ref: trait_ref, item_name: item_name };
|
||||
let inner = ProjectionTy::from_ref_and_name(self, trait_ref, item_name);
|
||||
self.mk_ty(TyProjection(inner))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1051,8 +1051,8 @@ pub struct ProjectionPredicate<'tcx> {
|
|||
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> PolyProjectionPredicate<'tcx> {
|
||||
pub fn item_name(&self) -> Name {
|
||||
self.0.projection_ty.item_name // safe to skip the binder to access a name
|
||||
pub fn item_name(&self, tcx: TyCtxt) -> Name {
|
||||
self.0.projection_ty.item_name(tcx) // safe to skip the binder to access a name
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -225,12 +225,13 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
|
|||
-> RelateResult<'tcx, ty::ProjectionTy<'tcx>>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
if a.item_name != b.item_name {
|
||||
let tcx = relation.tcx();
|
||||
if a.item_name(tcx) != b.item_name(tcx) {
|
||||
Err(TypeError::ProjectionNameMismatched(
|
||||
expected_found(relation, &a.item_name, &b.item_name)))
|
||||
expected_found(relation, &a.item_name(tcx), &b.item_name(tcx))))
|
||||
} else {
|
||||
let trait_ref = relation.relate(&a.trait_ref, &b.trait_ref)?;
|
||||
Ok(ty::ProjectionTy { trait_ref: trait_ref, item_name: a.item_name })
|
||||
Ok(ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, a.item_name(tcx)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +458,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
(&ty::TyProjection(ref a_data), &ty::TyProjection(ref b_data)) =>
|
||||
{
|
||||
let projection_ty = relation.relate(a_data, b_data)?;
|
||||
Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name))
|
||||
Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name(tcx)))
|
||||
}
|
||||
|
||||
(&ty::TyAnon(a_def_id, a_substs), &ty::TyAnon(b_def_id, b_substs))
|
||||
|
|
|
|||
|
|
@ -135,10 +135,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
|
|||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>)
|
||||
-> Option<ty::ProjectionTy<'tcx>> {
|
||||
tcx.lift(&self.trait_ref).map(|trait_ref| {
|
||||
ty::ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_name: self.item_name
|
||||
}
|
||||
ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, self.item_name(tcx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -771,7 +768,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
|
|||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ty::ProjectionTy {
|
||||
trait_ref: self.trait_ref.fold_with(folder),
|
||||
item_name: self.item_name,
|
||||
item_def_id: self.item_def_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -556,9 +556,34 @@ pub struct ProjectionTy<'tcx> {
|
|||
/// The trait reference `T as Trait<..>`.
|
||||
pub trait_ref: ty::TraitRef<'tcx>,
|
||||
|
||||
/// The name `N` of the associated type.
|
||||
pub item_name: Name,
|
||||
/// The DefId of the TraitItem for the associated type N.
|
||||
///
|
||||
/// Note that this is not the DefId of the TraitRef containing this
|
||||
/// associated type, which is in tcx.associated_item(item_def_id).container.
|
||||
pub item_def_id: DefId,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ProjectionTy<'tcx> {
|
||||
/// Construct a ProjectionTy by searching the trait from trait_ref for the
|
||||
/// associated item named item_name.
|
||||
pub fn from_ref_and_name(
|
||||
tcx: TyCtxt, trait_ref: ty::TraitRef<'tcx>, item_name: Name
|
||||
) -> ProjectionTy<'tcx> {
|
||||
let item_def_id = tcx.associated_items(trait_ref.def_id).find(
|
||||
|item| item.name == item_name).unwrap().def_id;
|
||||
|
||||
ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_def_id: item_def_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item_name(self, tcx: TyCtxt) -> Name {
|
||||
tcx.associated_item(self.item_def_id).name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Signature of a function type, which I have arbitrarily
|
||||
/// decided to use to refer to the input/output types.
|
||||
///
|
||||
|
|
@ -871,10 +896,10 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
|
|||
assert!(!self_ty.has_escaping_regions());
|
||||
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
trait_ref: self.trait_ref.with_self_ty(tcx, self_ty),
|
||||
item_name: self.item_name,
|
||||
},
|
||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
self.trait_ref.with_self_ty(tcx, self_ty),
|
||||
self.item_name),
|
||||
ty: self.ty,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -691,8 +691,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
|||
self.hash(p.name.as_str());
|
||||
}
|
||||
TyProjection(ref data) => {
|
||||
self.def_id(data.trait_ref.def_id);
|
||||
self.hash(data.item_name.as_str());
|
||||
self.def_id(data.item_def_id);
|
||||
}
|
||||
TyNever |
|
||||
TyBool |
|
||||
|
|
|
|||
|
|
@ -216,9 +216,11 @@ pub fn parameterized(f: &mut fmt::Formatter,
|
|||
|
||||
for projection in projections {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
write!(f, "{}={}",
|
||||
projection.projection_ty.item_name,
|
||||
projection.ty)?;
|
||||
ty::tls::with(|tcx|
|
||||
write!(f, "{}={}",
|
||||
projection.projection_ty.item_name(tcx),
|
||||
projection.ty)
|
||||
)?;
|
||||
}
|
||||
|
||||
start_or_continue(f, "", ">")?;
|
||||
|
|
@ -929,9 +931,10 @@ impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
|
|||
|
||||
impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let item_name = ty::tls::with(|tcx| self.item_name(tcx));
|
||||
write!(f, "{:?}::{}",
|
||||
self.trait_ref,
|
||||
self.item_name)
|
||||
item_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
if let ty::TyProjection(proj) = ty.sty {
|
||||
for item in self.tcx.associated_items(proj.trait_ref.def_id) {
|
||||
if item.kind == ty::AssociatedKind::Type {
|
||||
if item.name == proj.item_name {
|
||||
if item.name == proj.item_name(self.tcx) {
|
||||
return Def::AssociatedTy(item.def_id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -553,10 +553,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) {
|
||||
return Ok(trait_ref.map_bound(|trait_ref| {
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_name: binding.item_name,
|
||||
},
|
||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
trait_ref,
|
||||
binding.item_name,
|
||||
),
|
||||
ty: binding.ty,
|
||||
}
|
||||
}));
|
||||
|
|
@ -575,10 +576,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
|
||||
Ok(candidate.map_bound(|trait_ref| {
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_name: binding.item_name,
|
||||
},
|
||||
projection_ty: ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
trait_ref,
|
||||
binding.item_name,
|
||||
),
|
||||
ty: binding.ty,
|
||||
}
|
||||
}))
|
||||
|
|
@ -652,7 +654,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
let p = b.projection_ty;
|
||||
ty::ExistentialProjection {
|
||||
trait_ref: self.trait_ref_to_existential(p.trait_ref),
|
||||
item_name: p.item_name,
|
||||
item_name: p.item_name(tcx),
|
||||
ty: b.ty
|
||||
}
|
||||
})
|
||||
|
|
@ -679,7 +681,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
|
||||
for projection_bound in &projection_bounds {
|
||||
let pair = (projection_bound.0.projection_ty.trait_ref.def_id,
|
||||
projection_bound.0.projection_ty.item_name);
|
||||
projection_bound.0.projection_ty.item_name(tcx));
|
||||
associated_types.remove(&pair);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,10 +124,11 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
let normalized = traits::normalize_projection_type(&mut selcx,
|
||||
ty::ProjectionTy {
|
||||
trait_ref: trait_ref,
|
||||
item_name: Symbol::intern("Target"),
|
||||
},
|
||||
ty::ProjectionTy::from_ref_and_name(
|
||||
tcx,
|
||||
trait_ref,
|
||||
Symbol::intern("Target"),
|
||||
),
|
||||
cause,
|
||||
0);
|
||||
|
||||
|
|
|
|||
|
|
@ -1651,8 +1651,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
declared_bounds, projection_ty);
|
||||
|
||||
// see the extensive comment in projection_must_outlive
|
||||
|
||||
let ty = self.tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name);
|
||||
let item_name = projection_ty.item_name(self.tcx);
|
||||
let ty = self.tcx.mk_projection(projection_ty.trait_ref, item_name);
|
||||
let recursive_bound = self.recursive_type_bound(span, ty);
|
||||
|
||||
VerifyBound::AnyRegion(declared_bounds).or(recursive_bound)
|
||||
|
|
@ -1718,9 +1718,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
{
|
||||
debug!("projection_bounds(projection_ty={:?})",
|
||||
projection_ty);
|
||||
|
||||
let item_name = projection_ty.item_name(self.tcx);
|
||||
let ty = self.tcx.mk_projection(projection_ty.trait_ref.clone(),
|
||||
projection_ty.item_name);
|
||||
item_name);
|
||||
|
||||
// Say we have a projection `<T as SomeTrait<'a>>::SomeType`. We are interested
|
||||
// in looking for a trait definition like:
|
||||
|
|
@ -1758,7 +1758,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
let (outlives, _) =
|
||||
self.replace_late_bound_regions_with_fresh_var(
|
||||
span,
|
||||
infer::AssocTypeProjection(projection_ty.item_name),
|
||||
infer::AssocTypeProjection(projection_ty.item_name(self.tcx)),
|
||||
&outlives);
|
||||
|
||||
debug!("projection_bounds: outlives={:?} (3)",
|
||||
|
|
|
|||
|
|
@ -955,7 +955,7 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
|||
}
|
||||
};
|
||||
Type::QPath {
|
||||
name: self.item_name.clean(cx),
|
||||
name: self.item_name(cx.tcx).clean(cx),
|
||||
self_type: box self.trait_ref.self_ty().clean(cx),
|
||||
trait_: box trait_
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue