Skip to content

Commit ef11d4e

Browse files
committed
rustc: add TyAnon (impl Trait) to the typesystem.
1 parent f0baec6 commit ef11d4e

40 files changed

+250
-85
lines changed

src/librustc/hir/map/def_collector.rs

+6
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
268268
if let TyKind::FixedLengthVec(_, ref length) = ty.node {
269269
self.visit_ast_const_integer(length);
270270
}
271+
if let TyKind::ImplTrait(..) = ty.node {
272+
self.create_def(ty.id, DefPathData::ImplTrait);
273+
}
271274
visit::walk_ty(self, ty);
272275
}
273276

@@ -428,6 +431,9 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
428431
if let hir::TyFixedLengthVec(_, ref length) = ty.node {
429432
self.visit_hir_const_integer(length);
430433
}
434+
if let hir::TyImplTrait(..) = ty.node {
435+
self.create_def(ty.id, DefPathData::ImplTrait);
436+
}
431437
intravisit::walk_ty(self, ty);
432438
}
433439

src/librustc/hir/map/definitions.rs

+6
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ pub enum DefPathData {
215215
Initializer,
216216
/// Pattern binding
217217
Binding(InternedString),
218+
/// An `impl Trait` type node.
219+
ImplTrait
218220
}
219221

220222
impl Definitions {
@@ -369,6 +371,10 @@ impl DefPathData {
369371
Initializer => {
370372
InternedString::new("{{initializer}}")
371373
}
374+
375+
ImplTrait => {
376+
InternedString::new("{{impl-Trait}}")
377+
}
372378
}
373379
}
374380

src/librustc/infer/freshen.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
170170
ty::TyClosure(..) |
171171
ty::TyTuple(..) |
172172
ty::TyProjection(..) |
173-
ty::TyParam(..) => {
173+
ty::TyParam(..) |
174+
ty::TyAnon(..) => {
174175
t.super_fold_with(self)
175176
}
176177
}

src/librustc/traits/coherence.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)->
281281
true
282282
}
283283

284-
ty::TyClosure(..) => {
284+
ty::TyClosure(..) | ty::TyAnon(..) => {
285285
bug!("ty_is_local invoked on unexpected type: {:?}", ty)
286286
}
287287
}

src/librustc/traits/error_reporting.rs

+1
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
211211
ty::TyTuple(..) => Some(12),
212212
ty::TyProjection(..) => Some(13),
213213
ty::TyParam(..) => Some(14),
214+
ty::TyAnon(..) => Some(15),
214215
ty::TyInfer(..) | ty::TyError => None
215216
}
216217
}

src/librustc/traits/project.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,16 @@ pub enum Reveal {
9494
NotSpecializable,
9595

9696
/// At trans time, all monomorphic projections will succeed.
97+
/// Also, `impl Trait` is normalized to the concrete type,
98+
/// which has to be already collected by type-checking.
99+
///
100+
/// NOTE: As `impl Trait`'s concrete type should *never*
101+
/// be observable directly by the user, `Reveal::All`
102+
/// should not be used by checks which may expose
103+
/// type equality or type contents to the user.
104+
/// There are some exceptions, e.g. around OIBITS and
105+
/// transmute-checking, which expose some details, but
106+
/// not the whole concrete type of the `impl Trait`.
97107
All,
98108
}
99109

@@ -298,6 +308,17 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
298308

299309
let ty = ty.super_fold_with(self);
300310
match ty.sty {
311+
ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => { // (*)
312+
// Only normalize `impl Trait` after type-checking, usually in trans.
313+
if self.selcx.projection_mode() == Reveal::All {
314+
let generic_ty = self.tcx().lookup_item_type(def_id).ty;
315+
let concrete_ty = generic_ty.subst(self.tcx(), substs);
316+
self.fold_ty(concrete_ty)
317+
} else {
318+
ty
319+
}
320+
}
321+
301322
ty::TyProjection(ref data) if !data.has_escaping_regions() => { // (*)
302323

303324
// (*) This is kind of hacky -- we need to be able to
@@ -773,8 +794,11 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
773794
debug!("assemble_candidates_from_trait_def(..)");
774795

775796
// Check whether the self-type is itself a projection.
776-
let trait_ref = match obligation_trait_ref.self_ty().sty {
777-
ty::TyProjection(ref data) => data.trait_ref.clone(),
797+
let (def_id, substs) = match obligation_trait_ref.self_ty().sty {
798+
ty::TyProjection(ref data) => {
799+
(data.trait_ref.def_id, data.trait_ref.substs)
800+
}
801+
ty::TyAnon(def_id, substs) => (def_id, substs),
778802
ty::TyInfer(ty::TyVar(_)) => {
779803
// If the self-type is an inference variable, then it MAY wind up
780804
// being a projected type, so induce an ambiguity.
@@ -785,8 +809,8 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
785809
};
786810

787811
// If so, extract what we know from the trait and try to come up with a good answer.
788-
let trait_predicates = selcx.tcx().lookup_predicates(trait_ref.def_id);
789-
let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs);
812+
let trait_predicates = selcx.tcx().lookup_predicates(def_id);
813+
let bounds = trait_predicates.instantiate(selcx.tcx(), substs);
790814
let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates.into_vec());
791815
assemble_candidates_from_predicates(selcx,
792816
obligation,

src/librustc/traits/select.rs

+25-24
Original file line numberDiff line numberDiff line change
@@ -1158,20 +1158,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11581158

11591159
// before we go into the whole skolemization thing, just
11601160
// quickly check if the self-type is a projection at all.
1161-
let trait_def_id = match obligation.predicate.0.trait_ref.self_ty().sty {
1162-
ty::TyProjection(ref data) => data.trait_ref.def_id,
1161+
match obligation.predicate.0.trait_ref.self_ty().sty {
1162+
ty::TyProjection(_) | ty::TyAnon(..) => {}
11631163
ty::TyInfer(ty::TyVar(_)) => {
11641164
span_bug!(obligation.cause.span,
11651165
"Self=_ should have been handled by assemble_candidates");
11661166
}
1167-
_ => { return; }
1168-
};
1169-
1170-
debug!("assemble_candidates_for_projected_tys: trait_def_id={:?}",
1171-
trait_def_id);
1167+
_ => return
1168+
}
11721169

11731170
let result = self.probe(|this, snapshot| {
1174-
this.match_projection_obligation_against_bounds_from_trait(obligation,
1171+
this.match_projection_obligation_against_definition_bounds(obligation,
11751172
snapshot)
11761173
});
11771174

@@ -1180,7 +1177,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11801177
}
11811178
}
11821179

1183-
fn match_projection_obligation_against_bounds_from_trait(
1180+
fn match_projection_obligation_against_definition_bounds(
11841181
&mut self,
11851182
obligation: &TraitObligation<'tcx>,
11861183
snapshot: &infer::CombinedSnapshot)
@@ -1190,28 +1187,29 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11901187
self.infcx().resolve_type_vars_if_possible(&obligation.predicate);
11911188
let (skol_trait_predicate, skol_map) =
11921189
self.infcx().skolemize_late_bound_regions(&poly_trait_predicate, snapshot);
1193-
debug!("match_projection_obligation_against_bounds_from_trait: \
1190+
debug!("match_projection_obligation_against_definition_bounds: \
11941191
skol_trait_predicate={:?} skol_map={:?}",
11951192
skol_trait_predicate,
11961193
skol_map);
11971194

1198-
let projection_trait_ref = match skol_trait_predicate.trait_ref.self_ty().sty {
1199-
ty::TyProjection(ref data) => &data.trait_ref,
1195+
let (def_id, substs) = match skol_trait_predicate.trait_ref.self_ty().sty {
1196+
ty::TyProjection(ref data) => (data.trait_ref.def_id, data.trait_ref.substs),
1197+
ty::TyAnon(def_id, substs) => (def_id, substs),
12001198
_ => {
12011199
span_bug!(
12021200
obligation.cause.span,
1203-
"match_projection_obligation_against_bounds_from_trait() called \
1201+
"match_projection_obligation_against_definition_bounds() called \
12041202
but self-ty not a projection: {:?}",
12051203
skol_trait_predicate.trait_ref.self_ty());
12061204
}
12071205
};
1208-
debug!("match_projection_obligation_against_bounds_from_trait: \
1209-
projection_trait_ref={:?}",
1210-
projection_trait_ref);
1206+
debug!("match_projection_obligation_against_definition_bounds: \
1207+
def_id={:?}, substs={:?}",
1208+
def_id, substs);
12111209

1212-
let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id);
1213-
let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
1214-
debug!("match_projection_obligation_against_bounds_from_trait: \
1210+
let item_predicates = self.tcx().lookup_predicates(def_id);
1211+
let bounds = item_predicates.instantiate(self.tcx(), substs);
1212+
debug!("match_projection_obligation_against_definition_bounds: \
12151213
bounds={:?}",
12161214
bounds);
12171215

@@ -1226,7 +1224,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12261224
&skol_map,
12271225
snapshot)));
12281226

1229-
debug!("match_projection_obligation_against_bounds_from_trait: \
1227+
debug!("match_projection_obligation_against_definition_bounds: \
12301228
matching_bound={:?}",
12311229
matching_bound);
12321230
match matching_bound {
@@ -1472,7 +1470,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
14721470
}
14731471
}
14741472
ty::TyParam(..) |
1475-
ty::TyProjection(..) => {
1473+
ty::TyProjection(..) |
1474+
ty::TyAnon(..) => {
14761475
// In these cases, we don't know what the actual
14771476
// type is. Therefore, we cannot break it down
14781477
// into its constituent types. So we don't
@@ -1796,7 +1795,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17961795
}))
17971796
}
17981797

1799-
ty::TyProjection(_) | ty::TyParam(_) => None,
1798+
ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None,
18001799
ty::TyInfer(ty::TyVar(_)) => Ambiguous,
18011800

18021801
ty::TyInfer(ty::FreshTy(_))
@@ -1842,7 +1841,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
18421841
Where(ty::Binder(tys.to_vec()))
18431842
}
18441843

1845-
ty::TyStruct(..) | ty::TyEnum(..) | ty::TyProjection(..) | ty::TyParam(..) => {
1844+
ty::TyStruct(..) | ty::TyEnum(..) |
1845+
ty::TyProjection(..) | ty::TyParam(..) | ty::TyAnon(..) => {
18461846
// Fallback to whatever user-defined impls exist in this case.
18471847
None
18481848
}
@@ -1893,6 +1893,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
18931893
ty::TyTrait(..) |
18941894
ty::TyParam(..) |
18951895
ty::TyProjection(..) |
1896+
ty::TyAnon(..) |
18961897
ty::TyInfer(ty::TyVar(_)) |
18971898
ty::TyInfer(ty::FreshTy(_)) |
18981899
ty::TyInfer(ty::FreshIntTy(_)) |
@@ -2073,7 +2074,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
20732074
{
20742075
self.in_snapshot(|this, snapshot| {
20752076
let result =
2076-
this.match_projection_obligation_against_bounds_from_trait(obligation,
2077+
this.match_projection_obligation_against_definition_bounds(obligation,
20772078
snapshot);
20782079
assert!(result);
20792080
})

src/librustc/ty/contents.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
240240
}
241241

242242
ty::TyProjection(..) |
243-
ty::TyParam(_) => {
243+
ty::TyParam(_) |
244+
ty::TyAnon(..) => {
244245
TC::All
245246
}
246247

src/librustc/ty/context.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
10161016
sty_debug_print!(
10171017
self,
10181018
TyEnum, TyBox, TyArray, TySlice, TyRawPtr, TyRef, TyFnDef, TyFnPtr,
1019-
TyTrait, TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection);
1019+
TyTrait, TyStruct, TyClosure, TyTuple, TyParam, TyInfer, TyProjection, TyAnon);
10201020

10211021
println!("Substs interner: #{}", self.interners.substs.borrow().len());
10221022
println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len());
@@ -1355,6 +1355,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13551355
self.mk_param(def.space, def.index, def.name)
13561356
}
13571357

1358+
pub fn mk_anon(self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
1359+
self.mk_ty(TyAnon(def_id, substs))
1360+
}
1361+
13581362
pub fn trait_items(self, trait_did: DefId) -> Rc<Vec<ty::ImplOrTraitItem<'gcx>>> {
13591363
self.trait_items_cache.memoize(trait_did, || {
13601364
let def_ids = self.trait_item_def_ids(trait_did);

src/librustc/ty/error.rs

+1
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
247247
"type parameter".to_string()
248248
}
249249
}
250+
ty::TyAnon(..) => "anonymized type".to_string(),
250251
ty::TyError => "type error".to_string(),
251252
}
252253
}

src/librustc/ty/fast_reject.rs

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub enum SimplifiedType {
3030
TraitSimplifiedType(DefId),
3131
StructSimplifiedType(DefId),
3232
ClosureSimplifiedType(DefId),
33+
AnonSimplifiedType(DefId),
3334
FunctionSimplifiedType(usize),
3435
ParameterSimplifiedType,
3536
}
@@ -98,6 +99,9 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
9899
None
99100
}
100101
}
102+
ty::TyAnon(def_id, _) => {
103+
Some(AnonSimplifiedType(def_id))
104+
}
101105
ty::TyInfer(_) | ty::TyError => None,
102106
}
103107
}

src/librustc/ty/flags.rs

+5
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ impl FlagComputation {
110110
self.add_projection_ty(data);
111111
}
112112

113+
&ty::TyAnon(_, substs) => {
114+
self.add_flags(TypeFlags::HAS_PROJECTION);
115+
self.add_substs(substs);
116+
}
117+
113118
&ty::TyTrait(box ty::TraitTy { ref principal, ref bounds }) => {
114119
let mut computation = FlagComputation::new();
115120
computation.add_substs(principal.0.substs);

src/librustc/ty/fold.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
695695
// in the normalized form
696696
if self.just_constrained {
697697
match t.sty {
698-
ty::TyProjection(..) => { return false; }
698+
ty::TyProjection(..) | ty::TyAnon(..) => { return false; }
699699
_ => { }
700700
}
701701
}

src/librustc/ty/item_path.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
188188
data @ DefPathData::Initializer |
189189
data @ DefPathData::MacroDef(..) |
190190
data @ DefPathData::ClosureExpr |
191-
data @ DefPathData::Binding(..) => {
191+
data @ DefPathData::Binding(..) |
192+
data @ DefPathData::ImplTrait => {
192193
let parent_def_id = self.parent_def_id(def_id).unwrap();
193194
self.push_item_path(buffer, parent_def_id);
194195
buffer.push(&data.as_interned_str());
@@ -345,6 +346,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
345346
ty::TyFnPtr(_) |
346347
ty::TyProjection(_) |
347348
ty::TyParam(_) |
349+
ty::TyAnon(..) |
348350
ty::TyInfer(_) |
349351
ty::TyError |
350352
ty::TyFloat(_) => None,

src/librustc/ty/layout.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl<'a, 'gcx, 'tcx> Struct {
594594
Struct::non_zero_field_path(infcx, Some(ety).into_iter())
595595
}
596596

597-
(_, &ty::TyProjection(_)) => {
597+
(_, &ty::TyProjection(_)) | (_, &ty::TyAnon(..)) => {
598598
let normalized = normalize_associated_type(infcx, ty);
599599
if ty == normalized {
600600
return Ok(None);
@@ -1108,7 +1108,7 @@ impl<'a, 'gcx, 'tcx> Layout {
11081108
}
11091109

11101110
// Types with no meaningful known layout.
1111-
ty::TyProjection(_) => {
1111+
ty::TyProjection(_) | ty::TyAnon(..) => {
11121112
let normalized = normalize_associated_type(infcx, ty);
11131113
if ty == normalized {
11141114
return Err(LayoutError::Unknown(ty));
@@ -1332,7 +1332,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
13321332
}
13331333
}
13341334

1335-
ty::TyProjection(_) => {
1335+
ty::TyProjection(_) | ty::TyAnon(..) => {
13361336
let normalized = normalize_associated_type(infcx, ty);
13371337
if ty == normalized {
13381338
Err(err)

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1885,7 +1885,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
18851885
}
18861886
}
18871887

1888-
TyProjection(..) => {
1888+
TyProjection(..) | TyAnon(..) => {
18891889
// must calculate explicitly.
18901890
// FIXME: consider special-casing always-Sized projections
18911891
vec![ty]

src/librustc/ty/outlives.rs

+1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
174174
ty::TyEnum(..) | // OutlivesNominalType
175175
ty::TyStruct(..) | // OutlivesNominalType
176176
ty::TyBox(..) | // OutlivesNominalType (ish)
177+
ty::TyAnon(..) | // OutlivesNominalType (ish)
177178
ty::TyStr | // OutlivesScalar (ish)
178179
ty::TyArray(..) | // ...
179180
ty::TySlice(..) | // ...

0 commit comments

Comments
 (0)