Skip to content

Commit aaa53ec

Browse files
author
Alexander Regueiro
committed
Implemented for traits (associated type definitions).
1 parent 3816958 commit aaa53ec

File tree

12 files changed

+313
-250
lines changed

12 files changed

+313
-250
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
626626
TyKind::CVarArgs(ref lt) => {
627627
visitor.visit_lifetime(lt)
628628
}
629+
TyKind::AssocTyExistential(ref bounds) => {
630+
walk_list!(visitor, visit_param_bound, bounds);
631+
}
629632
TyKind::Infer | TyKind::Err => {}
630633
}
631634
}

src/librustc/hir/lowering.rs

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ enum ImplTraitContext<'a> {
195195
/// (e.g., for consts and statics).
196196
Existential(Option<DefId> /* fn def-ID */),
197197

198+
/// Treat `impl Trait` as a bound on the associated type applied to the trait.
199+
/// Example: `trait Foo { type Bar: Iterator<Item = impl Debug>; }` is conceptually
200+
/// equivalent to `trait Foo where <Self::Bar as Iterator>::Item: Debug
201+
/// { type Bar: Iterator; }`.
202+
AssociatedTy,
203+
198204
/// `impl Trait` is not accepted in this position.
199205
Disallowed(ImplTraitPosition),
200206
}
@@ -217,6 +223,7 @@ impl<'a> ImplTraitContext<'a> {
217223
match self {
218224
Universal(params) => Universal(params),
219225
Existential(fn_def_id) => Existential(*fn_def_id),
226+
AssociatedTy => AssociatedTy,
220227
Disallowed(pos) => Disallowed(*pos),
221228
}
222229
}
@@ -1537,6 +1544,16 @@ impl<'a> LoweringContext<'a> {
15371544
}),
15381545
))
15391546
}
1547+
ImplTraitContext::AssociatedTy => {
1548+
let hir_bounds = self.lower_param_bounds(
1549+
bounds,
1550+
ImplTraitContext::AssociatedTy,
1551+
);
1552+
1553+
hir::TyKind::AssocTyExistential(
1554+
hir_bounds,
1555+
)
1556+
}
15401557
ImplTraitContext::Disallowed(pos) => {
15411558
let allowed_in = if self.sess.features_untracked()
15421559
.impl_trait_in_bindings {
@@ -1640,8 +1657,8 @@ impl<'a> LoweringContext<'a> {
16401657
})
16411658
}
16421659

1643-
/// Registers a new existential type with the proper `NodeId`ss and
1644-
/// returns the lowered node ID for the existential type.
1660+
/// Registers a new existential type with the proper `NodeId`s and
1661+
/// returns the lowered node-ID for the existential type.
16451662
fn generate_existential_type(
16461663
&mut self,
16471664
exist_ty_node_id: NodeId,
@@ -2226,8 +2243,9 @@ impl<'a> LoweringContext<'a> {
22262243
(
22272244
hir::GenericArgs {
22282245
args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(),
2229-
bindings: constraints.iter().map(
2230-
|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())).collect(),
2246+
bindings: constraints.iter()
2247+
.map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow()))
2248+
.collect(),
22312249
parenthesized: false,
22322250
},
22332251
!has_types && param_mode == ParamMode::Optional
@@ -3257,13 +3275,13 @@ impl<'a> LoweringContext<'a> {
32573275
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
32583276
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
32593277
ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty(
3260-
self.lower_ty(t, ImplTraitContext::disallowed()),
3261-
self.lower_generics(generics, ImplTraitContext::disallowed()),
3278+
self.lower_ty(t, ImplTraitContext::AssociatedTy),
3279+
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
32623280
),
32633281
ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(
32643282
hir::ExistTy {
3265-
generics: self.lower_generics(generics, ImplTraitContext::disallowed()),
3266-
bounds: self.lower_param_bounds(b, ImplTraitContext::Existential(None)),
3283+
generics: self.lower_generics(generics, ImplTraitContext::AssociatedTy),
3284+
bounds: self.lower_param_bounds(b, ImplTraitContext::AssociatedTy),
32673285
impl_trait_fn: None,
32683286
origin: hir::ExistTyOrigin::ExistentialType,
32693287
},
@@ -3276,20 +3294,20 @@ impl<'a> LoweringContext<'a> {
32763294
.map(|x| self.lower_variant(x))
32773295
.collect(),
32783296
},
3279-
self.lower_generics(generics, ImplTraitContext::disallowed()),
3297+
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
32803298
),
32813299
ItemKind::Struct(ref struct_def, ref generics) => {
32823300
let struct_def = self.lower_variant_data(struct_def);
32833301
hir::ItemKind::Struct(
32843302
struct_def,
3285-
self.lower_generics(generics, ImplTraitContext::disallowed()),
3303+
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
32863304
)
32873305
}
32883306
ItemKind::Union(ref vdata, ref generics) => {
32893307
let vdata = self.lower_variant_data(vdata);
32903308
hir::ItemKind::Union(
32913309
vdata,
3292-
self.lower_generics(generics, ImplTraitContext::disallowed()),
3310+
self.lower_generics(generics, ImplTraitContext::AssociatedTy),
32933311
)
32943312
}
32953313
ItemKind::Impl(
@@ -3656,15 +3674,17 @@ impl<'a> LoweringContext<'a> {
36563674
);
36573675
(generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
36583676
}
3659-
TraitItemKind::Type(ref bounds, ref default) => (
3660-
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
3661-
hir::TraitItemKind::Type(
3662-
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
3677+
TraitItemKind::Type(ref bounds, ref default) => {
3678+
let generics = self.lower_generics(&i.generics, ImplTraitContext::AssociatedTy);
3679+
let node = hir::TraitItemKind::Type(
3680+
self.lower_param_bounds(bounds, ImplTraitContext::AssociatedTy),
36633681
default
36643682
.as_ref()
36653683
.map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
3666-
),
3667-
),
3684+
);
3685+
3686+
(generics, node)
3687+
},
36683688
TraitItemKind::Macro(..) => bug!("macro item shouldn't exist at this point"),
36693689
};
36703690

src/librustc/hir/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,8 @@ pub enum TyKind {
18981898
/// Placeholder for C-variadic arguments. We "spoof" the `VaList` created
18991899
/// from the variadic arguments. This type is only valid up to typeck.
19001900
CVarArgs(Lifetime),
1901+
/// The existential type (i.e., `impl Trait`) that constrains an associated type.
1902+
AssocTyExistential(HirVec<GenericBound>),
19011903
}
19021904

19031905
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]

src/librustc/hir/print.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ impl<'a> State<'a> {
409409
hir::TyKind::CVarArgs(_) => {
410410
self.s.word("...")?;
411411
}
412+
hir::TyKind::AssocTyExistential(ref bounds) => {
413+
self.print_bounds(":", bounds)?;
414+
}
412415
}
413416
self.end()
414417
}

src/librustc/infer/opaque_types/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -948,15 +948,17 @@ pub fn may_define_existential_type(
948948
let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
949949
trace!(
950950
"may_define_existential_type(def={:?}, opaque_node={:?})",
951-
tcx.hir().get(hir_id),
952-
tcx.hir().get(opaque_hir_id)
951+
tcx.hir().get_by_hir_id(hir_id),
952+
tcx.hir().get_by_hir_id(opaque_hir_id)
953953
);
954954

955955
// Named existential types can be defined by any siblings or children of siblings.
956-
let scope_id = tcx.hir().get_defining_scope(opaque_hir_id)
957-
.expect("could not get defining scope");
956+
let scope_node_id = tcx.hir()
957+
.get_defining_scope(tcx.hir().hir_to_node_id(opaque_hir_id))
958+
.expect("could not get defining scope");
959+
let scope_id = tcx.hir().node_to_hir_id(scope_node_id);
958960
// We walk up the node tree until we hit the root or the scope of the opaque type.
959-
while hir_id != scope_id && hir_id != ast::CRATE_hir_ID {
961+
while hir_id != scope_id && hir_id != hir::CRATE_HIR_ID {
960962
hir_id = tcx.hir().get_parent_item(hir_id);
961963
}
962964
// Syntactically, we are allowed to define the concrete type if:

src/librustc_interface/util.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,8 @@ impl<'a> ReplaceBodyWithLoop<'a> {
726726
any_assoc_ty_bounds ||
727727
any_involves_impl_trait(types.into_iter()) ||
728728
any_involves_impl_trait(data.constraints.iter().filter_map(|c| {
729-
if let ast::AssocTyConstraintKind::Equality { ref ty } = c.kind {
729+
if let ast::AssocTyConstraintKind::Equality { ref ty }
730+
= c.kind {
730731
Some(ty)
731732
} else {
732733
None

src/librustc_privacy/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,12 +1040,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
10401040
if !self.in_body {
10411041
// Avoid calling `hir_trait_to_predicates` in bodies, it will ICE.
10421042
// The traits' privacy in bodies is already checked as a part of trait object types.
1043-
let (principal, projections) =
1044-
rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref);
1043+
let (principal, bounds) = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref);
10451044
if self.visit_trait(*principal.skip_binder()) {
10461045
return;
10471046
}
1048-
for (poly_predicate, _) in projections {
1047+
for (poly_predicate, _) in bounds.projection_bounds {
10491048
let tcx = self.tcx;
10501049
if self.visit(poly_predicate.skip_binder().ty) ||
10511050
self.visit_trait(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) {

0 commit comments

Comments
 (0)