Skip to content

Commit

Permalink
Rollup merge of rust-lang#42297 - tschottdorf:proj-ty, r=nikomatsakis
Browse files Browse the repository at this point in the history
Upgrade ProjectionTy's Name to a DefId

Part of rust-lang#42171, in preparation for downgrading the contained `TraitRef` to
only its `substs`.

Some inline questions in the diff. Look for `FIXME(tschottdorf)`. These comments
should be addressed before merging.
  • Loading branch information
frewsxcv authored Jun 1, 2017
2 parents 675454a + e5e664f commit b3947f8
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/infer/region_inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
}
}
}
Expand Down
27 changes: 15 additions & 12 deletions src/librustc/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down Expand Up @@ -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![] });
// ```

Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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()))))
}
}
}
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
});

Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,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))
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
}
}
}
Expand Down Expand Up @@ -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))
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
}
}
Expand Down Expand Up @@ -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,
}
}

Expand Down
37 changes: 31 additions & 6 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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,
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
11 changes: 7 additions & 4 deletions src/librustc/util/ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, "", ">")?;
Expand Down Expand Up @@ -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)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
22 changes: 12 additions & 10 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}));
Expand All @@ -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,
}
}))
Expand Down Expand Up @@ -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
}
})
Expand All @@ -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);
}

Expand Down
9 changes: 5 additions & 4 deletions src/librustc_typeck/check/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
10 changes: 5 additions & 5 deletions src/librustc_typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)",
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_
}
Expand Down

0 comments on commit b3947f8

Please sign in to comment.