Skip to content

Commit 37610c6

Browse files
committed
Downgrade ProjectionTy's TraitRef to its substs
WIP: please review the FIXME(tschottdorf) code comments, in particular the last remaining use of `deprecated_trait_ref`. ---- Addresses the second part of rust-lang#42171 by removing the `TraitRef` from `ProjectionTy`, and directly storing its `Substs`. Closes rust-lang#42171.
1 parent e72580c commit 37610c6

File tree

31 files changed

+295
-230
lines changed

31 files changed

+295
-230
lines changed

src/librustc/ich/impls_ty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ for ty::OutlivesPredicate<A, B>
187187
}
188188

189189
impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
190-
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_def_id });
190+
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
191191

192192

193193
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'tcx> {
@@ -599,8 +599,8 @@ impl_stable_hash_for!(struct ty::ExistentialTraitRef<'tcx> {
599599
});
600600

601601
impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> {
602-
trait_ref,
603-
item_name,
602+
item_def_id,
603+
substs,
604604
ty
605605
});
606606

src/librustc/infer/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1276,14 +1276,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12761276
match_b: ty::TraitRef<'tcx>)
12771277
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
12781278
{
1279+
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
12791280
let span = cause.span;
1280-
let match_trait_ref = match_a.skip_binder().projection_ty.trait_ref;
12811281
let trace = TypeTrace {
12821282
cause: cause,
1283-
values: TraitRefs(ExpectedFound::new(true, match_trait_ref, match_b))
1283+
values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
12841284
};
12851285

1286-
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
12871286
let mut combine = self.combine_fields(trace, param_env);
12881287
let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
12891288
Ok(InferOk { value: result, obligations: combine.obligations })

src/librustc/infer/region_inference/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1550,8 +1550,7 @@ impl<'a, 'gcx, 'tcx> GenericKind<'tcx> {
15501550
pub fn to_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Ty<'tcx> {
15511551
match *self {
15521552
GenericKind::Param(ref p) => p.to_ty(tcx),
1553-
GenericKind::Projection(ref p) => tcx.mk_projection(
1554-
p.trait_ref.clone(), p.item_name(tcx)),
1553+
GenericKind::Projection(ref p) => tcx.mk_projection(p.item_def_id, p.substs),
15551554
}
15561555
}
15571556
}

src/librustc/traits/object_safety.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
354354
// direct equality here because all of these types
355355
// are part of the formal parameter listing, and
356356
// hence there should be no inference variables.
357-
let projection_trait_ref = ty::Binder(data.trait_ref.clone());
357+
let projection_trait_ref = ty::Binder(data.trait_ref(self));
358358
let is_supertrait_of_current_trait =
359359
supertraits.as_ref().unwrap().contains(&projection_trait_ref);
360360

src/librustc/traits/project.rs

+18-23
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,7 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
365365
// information is available.
366366

367367
let tcx = selcx.infcx().tcx;
368-
let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i|
369-
i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type
370-
).map(|i| i.def_id).unwrap();
368+
let def_id = projection_ty.item_def_id;
371369
let ty_var = selcx.infcx().next_ty_var(
372370
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
373371
let projection = ty::Binder(ty::ProjectionPredicate {
@@ -447,8 +445,8 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
447445
// normalization. In that case, I think we will want this code:
448446
//
449447
// ```
450-
// let ty = selcx.tcx().mk_projection(projection_ty.trait_ref,
451-
// projection_ty.item_name(tcx);
448+
// let ty = selcx.tcx().mk_projection(projection_ty.item_def_id,
449+
// projection_ty.substs;
452450
// return Some(NormalizedTy { value: v, obligations: vec![] });
453451
// ```
454452

@@ -585,15 +583,13 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc
585583
depth: usize)
586584
-> NormalizedTy<'tcx>
587585
{
588-
let trait_ref = projection_ty.trait_ref.to_poly_trait_ref();
586+
let trait_ref = projection_ty.trait_ref(selcx.tcx()).to_poly_trait_ref();
589587
let trait_obligation = Obligation { cause: cause,
590588
recursion_depth: depth,
591589
param_env,
592590
predicate: trait_ref.to_predicate() };
593591
let tcx = selcx.infcx().tcx;
594-
let def_id = tcx.associated_items(projection_ty.trait_ref.def_id).find(|i|
595-
i.name == projection_ty.item_name(tcx) && i.kind == ty::AssociatedKind::Type
596-
).map(|i| i.def_id).unwrap();
592+
let def_id = projection_ty.item_def_id;
597593
let new_value = selcx.infcx().next_ty_var(
598594
TypeVariableOrigin::NormalizeProjectionType(tcx.def_span(def_id)));
599595
Normalized {
@@ -654,7 +650,7 @@ fn project_type<'cx, 'gcx, 'tcx>(
654650
selcx.infcx().report_overflow_error(&obligation, true);
655651
}
656652

657-
let obligation_trait_ref = &obligation.predicate.trait_ref;
653+
let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx());
658654

659655
debug!("project: obligation_trait_ref={:?}", obligation_trait_ref);
660656

@@ -743,12 +739,10 @@ fn project_type<'cx, 'gcx, 'tcx>(
743739
&obligation_trait_ref,
744740
candidate)))
745741
}
746-
None => {
747-
Ok(ProjectedTy::NoProgress(
748-
selcx.tcx().mk_projection(
749-
obligation.predicate.trait_ref.clone(),
750-
obligation.predicate.item_name(selcx.tcx()))))
751-
}
742+
None => Ok(ProjectedTy::NoProgress(
743+
selcx.tcx().mk_projection(
744+
obligation.predicate.item_def_id,
745+
obligation.predicate.substs)))
752746
}
753747
}
754748

@@ -788,10 +782,11 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
788782
{
789783
debug!("assemble_candidates_from_trait_def(..)");
790784

785+
let tcx = selcx.tcx();
791786
// Check whether the self-type is itself a projection.
792787
let (def_id, substs) = match obligation_trait_ref.self_ty().sty {
793788
ty::TyProjection(ref data) => {
794-
(data.trait_ref.def_id, data.trait_ref.substs)
789+
(data.trait_ref(tcx).def_id, data.substs)
795790
}
796791
ty::TyAnon(def_id, substs) => (def_id, substs),
797792
ty::TyInfer(ty::TyVar(_)) => {
@@ -804,9 +799,9 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
804799
};
805800

806801
// If so, extract what we know from the trait and try to come up with a good answer.
807-
let trait_predicates = selcx.tcx().predicates_of(def_id);
808-
let bounds = trait_predicates.instantiate(selcx.tcx(), substs);
809-
let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates);
802+
let trait_predicates = tcx.predicates_of(def_id);
803+
let bounds = trait_predicates.instantiate(tcx, substs);
804+
let bounds = elaborate_predicates(tcx, bounds.predicates);
810805
assemble_candidates_from_predicates(selcx,
811806
obligation,
812807
obligation_trait_ref,
@@ -1202,7 +1197,7 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
12021197
// Note: we unwrap the binder here but re-create it below (1)
12031198
let ty::Binder((trait_ref, ret_type)) =
12041199
tcx.closure_trait_ref_and_return_type(fn_once_def_id,
1205-
obligation.predicate.trait_ref.self_ty(),
1200+
obligation.predicate.self_ty(),
12061201
fn_sig,
12071202
flag);
12081203

@@ -1227,7 +1222,7 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
12271222
let infcx = selcx.infcx();
12281223
let cause = obligation.cause.clone();
12291224
let param_env = obligation.param_env;
1230-
let trait_ref = obligation.predicate.trait_ref;
1225+
let trait_ref = obligation.predicate.trait_ref(infcx.tcx);
12311226
match infcx.match_poly_projection_predicate(cause, param_env, poly_projection, trait_ref) {
12321227
Ok(InferOk { value: ty_match, obligations }) => {
12331228
Progress {
@@ -1267,7 +1262,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
12671262
// just return TyError.
12681263
debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
12691264
assoc_ty.item.name,
1270-
obligation.predicate.trait_ref);
1265+
obligation.predicate);
12711266
tcx.types.err
12721267
} else {
12731268
tcx.type_of(assoc_ty.item.def_id)

src/librustc/traits/select.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12121212
skol_map);
12131213

12141214
let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty {
1215-
ty::TyProjection(ref data) => (data.trait_ref.def_id, data.trait_ref.substs),
1215+
ty::TyProjection(ref data) =>
1216+
(data.trait_ref(self.tcx()).def_id, data.substs),
12161217
ty::TyAnon(def_id, substs) => (def_id, substs),
12171218
_ => {
12181219
span_bug!(

src/librustc/traits/trans/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,12 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
203203
let def_ids: Vec<DefId> =
204204
key.walk()
205205
.filter_map(|t| match t.sty {
206-
ty::TyAdt(adt_def, _) => Some(adt_def.did),
207-
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
208-
_ => None,
206+
ty::TyAdt(adt_def, _) => Some(adt_def.did),
207+
ty::TyProjection(ref proj) =>
208+
// FIXME(tschottdorf): prof.item_def_id might be good enough?
209+
// Either way, use of tls::with not appropriate here.
210+
Some(ty::tls::with(|tcx| proj.trait_ref(tcx).def_id)),
211+
_ => None,
209212
})
210213
.collect();
211214

src/librustc/ty/context.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use mir::transform::Passes;
2828
use ty::subst::{Kind, Substs};
2929
use ty::ReprOptions;
3030
use traits;
31-
use ty::{self, TraitRef, Ty, TypeAndMut};
31+
use ty::{self, Ty, TypeAndMut};
3232
use ty::{TyS, TypeVariants, Slice};
3333
use ty::{AdtKind, AdtDef, ClosureSubsts, Region};
3434
use hir::FreevarMap;
@@ -1395,12 +1395,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13951395
}
13961396

13971397
pub fn mk_projection(self,
1398-
trait_ref: TraitRef<'tcx>,
1399-
item_name: Name)
1398+
item_def_id: DefId,
1399+
substs: &'tcx Substs<'tcx>)
14001400
-> Ty<'tcx> {
1401-
// take a copy of substs so that we own the vectors inside
1402-
let inner = ProjectionTy::from_ref_and_name(self, trait_ref, item_name);
1403-
self.mk_ty(TyProjection(inner))
1401+
self.mk_ty(TyProjection(ProjectionTy {
1402+
item_def_id: item_def_id,
1403+
substs: substs,
1404+
}))
14041405
}
14051406

14061407
pub fn mk_closure(self,

src/librustc/ty/error.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ty::{self, BoundRegion, DefIdTree, Region, Ty, TyCtxt};
1414

1515
use std::fmt;
1616
use syntax::abi;
17-
use syntax::ast::{self, Name};
17+
use syntax::ast;
1818
use errors::DiagnosticBuilder;
1919
use syntax_pos::Span;
2020

@@ -47,7 +47,7 @@ pub enum TypeError<'tcx> {
4747
Traits(ExpectedFound<DefId>),
4848
VariadicMismatch(ExpectedFound<bool>),
4949
CyclicTy,
50-
ProjectionNameMismatched(ExpectedFound<Name>),
50+
ProjectionMismatched(ExpectedFound<DefId>),
5151
ProjectionBoundsLength(ExpectedFound<usize>),
5252
TyParamDefaultMismatch(ExpectedFound<type_variable::Default<'tcx>>),
5353
ExistentialMismatch(ExpectedFound<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>),
@@ -154,11 +154,11 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
154154
if values.expected { "variadic" } else { "non-variadic" },
155155
if values.found { "variadic" } else { "non-variadic" })
156156
}
157-
ProjectionNameMismatched(ref values) => {
157+
ProjectionMismatched(ref values) => ty::tls::with(|tcx| {
158158
write!(f, "expected {}, found {}",
159-
values.expected,
160-
values.found)
161-
}
159+
tcx.item_path_str(values.expected),
160+
tcx.item_path_str(values.found))
161+
}),
162162
ProjectionBoundsLength(ref values) => {
163163
write!(f, "expected {} associated type bindings, found {}",
164164
values.expected,

src/librustc/ty/flags.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,12 @@ impl FlagComputation {
193193
}
194194

195195
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection) {
196-
self.add_substs(projection.trait_ref.substs);
196+
self.add_substs(projection.substs);
197197
self.add_ty(projection.ty);
198198
}
199199

200200
fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy) {
201-
self.add_substs(projection_ty.trait_ref.substs);
201+
self.add_substs(projection_ty.substs);
202202
}
203203

204204
fn add_substs(&mut self, substs: &Substs) {

src/librustc/ty/fold.rs

-4
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,6 @@ pub trait TypeVisitor<'tcx> : Sized {
150150
t.super_visit_with(self)
151151
}
152152

153-
fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool {
154-
trait_ref.super_visit_with(self)
155-
}
156-
157153
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
158154
r.super_visit_with(self)
159155
}

src/librustc/ty/instance.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,12 @@ impl<'tcx> InstanceDef<'tcx> {
7373
DepConstructor::MirShim(
7474
Some(self.def_id()).into_iter().chain(
7575
ty.flat_map(|t| t.walk()).flat_map(|t| match t.sty {
76-
ty::TyAdt(adt_def, _) => Some(adt_def.did),
77-
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
78-
_ => None,
76+
ty::TyAdt(adt_def, _) => Some(adt_def.did),
77+
ty::TyProjection(ref proj) =>
78+
// FIXME(tschottdorf): prof.item_def_id might be good enough?
79+
// Either way, use of tls::with not appropriate here.
80+
Some(ty::tls::with(|tcx| proj.trait_ref(tcx).def_id)),
81+
_ => None,
7982
})
8083
).collect()
8184
)

src/librustc/ty/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyProjectionPredicate<'tcx> {
10591059
// This is because here `self` has a `Binder` and so does our
10601060
// return value, so we are preserving the number of binding
10611061
// levels.
1062-
ty::Binder(self.0.projection_ty.trait_ref)
1062+
ty::Binder(ty::tls::with(|tcx| self.0.projection_ty.trait_ref(tcx)))
10631063
}
10641064
}
10651065

@@ -1132,8 +1132,7 @@ impl<'tcx> Predicate<'tcx> {
11321132
vec![]
11331133
}
11341134
ty::Predicate::Projection(ref data) => {
1135-
let trait_inputs = data.0.projection_ty.trait_ref.input_types();
1136-
trait_inputs.chain(Some(data.0.ty)).collect()
1135+
data.0.projection_ty.substs.types().chain(Some(data.0.ty)).collect()
11371136
}
11381137
ty::Predicate::WellFormed(data) => {
11391138
vec![data]

src/librustc/ty/relate.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,15 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
225225
-> RelateResult<'tcx, ty::ProjectionTy<'tcx>>
226226
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
227227
{
228-
let tcx = relation.tcx();
229-
if a.item_name(tcx) != b.item_name(tcx) {
230-
Err(TypeError::ProjectionNameMismatched(
231-
expected_found(relation, &a.item_name(tcx), &b.item_name(tcx))))
228+
if a.item_def_id != b.item_def_id {
229+
Err(TypeError::ProjectionMismatched(
230+
expected_found(relation, &a.item_def_id, &b.item_def_id)))
232231
} else {
233-
let trait_ref = relation.relate(&a.trait_ref, &b.trait_ref)?;
234-
Ok(ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, a.item_name(tcx)))
232+
let substs = relation.relate(&a.substs, &b.substs)?;
233+
Ok(ty::ProjectionTy {
234+
item_def_id: a.item_def_id,
235+
substs: &substs,
236+
})
235237
}
236238
}
237239
}
@@ -243,16 +245,16 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
243245
-> RelateResult<'tcx, ty::ExistentialProjection<'tcx>>
244246
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
245247
{
246-
if a.item_name != b.item_name {
247-
Err(TypeError::ProjectionNameMismatched(
248-
expected_found(relation, &a.item_name, &b.item_name)))
248+
if a.item_def_id != b.item_def_id {
249+
Err(TypeError::ProjectionMismatched(
250+
expected_found(relation, &a.item_def_id, &b.item_def_id)))
249251
} else {
250-
let trait_ref = relation.relate(&a.trait_ref, &b.trait_ref)?;
251252
let ty = relation.relate(&a.ty, &b.ty)?;
253+
let substs = relation.relate(&a.substs, &b.substs)?;
252254
Ok(ty::ExistentialProjection {
253-
trait_ref: trait_ref,
254-
item_name: a.item_name,
255-
ty: ty
255+
item_def_id: a.item_def_id,
256+
substs: substs,
257+
ty: ty,
256258
})
257259
}
258260
}
@@ -456,7 +458,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
456458
(&ty::TyProjection(ref a_data), &ty::TyProjection(ref b_data)) =>
457459
{
458460
let projection_ty = relation.relate(a_data, b_data)?;
459-
Ok(tcx.mk_projection(projection_ty.trait_ref, projection_ty.item_name(tcx)))
461+
Ok(tcx.mk_projection(projection_ty.item_def_id, projection_ty.substs))
460462
}
461463

462464
(&ty::TyAnon(a_def_id, a_substs), &ty::TyAnon(b_def_id, b_substs))

0 commit comments

Comments
 (0)