Skip to content

Commit 1475e2c

Browse files
committed
Auto merge of #42388 - tschottdorf:projty-substs, r=nikomatsakis
Downgrade ProjectionTy's TraitRef to its substs Addresses the second part of #42171 by removing the `TraitRef` from `ProjectionTy`, and directly storing its `Substs`. Closes #42171.
2 parents dddf24d + 687ee7f commit 1475e2c

File tree

33 files changed

+341
-294
lines changed

33 files changed

+341
-294
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

+3-4
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ pub enum LateBoundRegionConversionTime {
274274
HigherRankedType,
275275

276276
/// when projecting an associated type
277-
AssocTypeProjection(ast::Name),
277+
AssocTypeProjection(ast::Name), // FIXME(tschottdorf): should contain DefId, not Name
278278
}
279279

280280
/// Reasons to create a region inference variable
@@ -1277,14 +1277,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12771277
match_b: ty::TraitRef<'tcx>)
12781278
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
12791279
{
1280+
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref(self.tcx), p.ty));
12801281
let span = cause.span;
1281-
let match_trait_ref = match_a.skip_binder().projection_ty.trait_ref;
12821282
let trace = TypeTrace {
12831283
cause,
1284-
values: TraitRefs(ExpectedFound::new(true, match_trait_ref, match_b))
1284+
values: TraitRefs(ExpectedFound::new(true, match_pair.skip_binder().0, match_b))
12851285
};
12861286

1287-
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
12881287
let mut combine = self.combine_fields(trace, param_env);
12891288
let result = combine.higher_ranked_match(span, &match_pair, &match_b, true)?;
12901289
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/fulfill.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,9 @@ fn process_predicate<'a, 'gcx, 'tcx>(
470470
let project_obligation = obligation.with(data.clone());
471471
match project::poly_project_and_unify_type(selcx, &project_obligation) {
472472
Ok(None) => {
473+
let tcx = selcx.tcx();
473474
pending_obligation.stalled_on =
474-
trait_ref_type_vars(selcx, data.to_poly_trait_ref());
475+
trait_ref_type_vars(selcx, data.to_poly_trait_ref(tcx));
475476
Ok(None)
476477
}
477478
Ok(v) => Ok(v),

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

+30-34
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,
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,
@@ -832,12 +827,12 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
832827
predicate);
833828
match predicate {
834829
ty::Predicate::Projection(ref data) => {
835-
let tcx = selcx.tcx();
836-
let same_name = data.item_name(tcx) == obligation.predicate.item_name(tcx);
830+
let same_def_id =
831+
data.0.projection_ty.item_def_id == obligation.predicate.item_def_id;
837832

838-
let is_match = same_name && infcx.probe(|_| {
833+
let is_match = same_def_id && infcx.probe(|_| {
839834
let data_poly_trait_ref =
840-
data.to_poly_trait_ref();
835+
data.to_poly_trait_ref(infcx.tcx);
841836
let obligation_poly_trait_ref =
842837
obligation_trait_ref.to_poly_trait_ref();
843838
infcx.at(&obligation.cause, obligation.param_env)
@@ -850,8 +845,8 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
850845
});
851846

852847
debug!("assemble_candidates_from_predicates: candidate={:?} \
853-
is_match={} same_name={}",
854-
data, is_match, same_name);
848+
is_match={} same_def_id={}",
849+
data, is_match, same_def_id);
855850

856851
if is_match {
857852
candidate_set.vec.push(ctor(data.clone()));
@@ -916,9 +911,10 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
916911
// In either case, we handle this by not adding a
917912
// candidate for an impl if it contains a `default`
918913
// type.
914+
let item_name = selcx.tcx().associated_item(obligation.predicate.item_def_id).name;
919915
let node_item = assoc_ty_def(selcx,
920916
impl_data.impl_def_id,
921-
obligation.predicate.item_name(selcx.tcx()));
917+
item_name);
922918

923919
let is_default = if node_item.node.is_from_trait() {
924920
// If true, the impl inherited a `type Foo = Bar`
@@ -1091,10 +1087,9 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
10911087

10921088
// select only those projections that are actually projecting an
10931089
// item with the correct name
1094-
let tcx = selcx.tcx();
10951090
let env_predicates = env_predicates.filter_map(|p| match p {
10961091
ty::Predicate::Projection(data) =>
1097-
if data.item_name(tcx) == obligation.predicate.item_name(tcx) {
1092+
if data.0.projection_ty.item_def_id == obligation.predicate.item_def_id {
10981093
Some(data)
10991094
} else {
11001095
None
@@ -1104,7 +1099,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
11041099

11051100
// select those with a relevant trait-ref
11061101
let mut env_predicates = env_predicates.filter(|data| {
1107-
let data_poly_trait_ref = data.to_poly_trait_ref();
1102+
let data_poly_trait_ref = data.to_poly_trait_ref(selcx.tcx());
11081103
let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
11091104
selcx.infcx().probe(|_| {
11101105
selcx.infcx().at(&obligation.cause, obligation.param_env)
@@ -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 {
@@ -1258,7 +1253,8 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
12581253

12591254
let tcx = selcx.tcx();
12601255
let param_env = obligation.param_env;
1261-
let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_name(tcx));
1256+
let assoc_ty = assoc_ty_def(selcx, impl_def_id,
1257+
tcx.associated_item(obligation.predicate.item_def_id).name);
12621258

12631259
let ty = if !assoc_ty.item.defaultness.has_value() {
12641260
// This means that the impl is missing a definition for the
@@ -1267,7 +1263,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
12671263
// just return TyError.
12681264
debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
12691265
assoc_ty.item.name,
1270-
obligation.predicate.trait_ref);
1266+
obligation.predicate);
12711267
tcx.types.err
12721268
} else {
12731269
tcx.type_of(assoc_ty.item.def_id)

src/librustc/traits/select.rs

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

13371337
let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty {
1338-
ty::TyProjection(ref data) => (data.trait_ref.def_id, data.trait_ref.substs),
1338+
ty::TyProjection(ref data) =>
1339+
(data.trait_ref(self.tcx()).def_id, data.substs),
13391340
ty::TyAnon(def_id, substs) => (def_id, substs),
13401341
_ => {
13411342
span_bug!(

src/librustc/traits/trans/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ 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) => Some(proj.item_def_id),
208+
_ => None,
209209
})
210210
.collect();
211211

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;
@@ -1387,12 +1387,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13871387
}
13881388

13891389
pub fn mk_projection(self,
1390-
trait_ref: TraitRef<'tcx>,
1391-
item_name: Name)
1390+
item_def_id: DefId,
1391+
substs: &'tcx Substs<'tcx>)
13921392
-> Ty<'tcx> {
1393-
// take a copy of substs so that we own the vectors inside
1394-
let inner = ProjectionTy::from_ref_and_name(self, trait_ref, item_name);
1395-
self.mk_ty(TyProjection(inner))
1393+
self.mk_ty(TyProjection(ProjectionTy {
1394+
item_def_id: item_def_id,
1395+
substs: substs,
1396+
}))
13961397
}
13971398

13981399
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
}

0 commit comments

Comments
 (0)