Skip to content

Commit 8fd48e7

Browse files
committed
Split hir::TyImplTrait, move checks to HIR lowering
Replace hir::TyImplTrait with TyImplTraitUniversal and TyImplTraitExistential. Add an ImplTraitContext enum to rustc::hir::lowering to track the kind and allowedness of an impl Trait. Significantly alter lowering to thread ImplTraitContext and one other boolean parameter described below throughought much of lowering. The other parameter is for tracking if lowering a function is in a trait impl, as there is not enough information to otherwise know this information during lowering otherwise. This change also removes the checks from ast_ty_to_ty for impl trait allowedness as they are now all taking place in HIR lowering.
1 parent 779fc37 commit 8fd48e7

File tree

11 files changed

+211
-148
lines changed

11 files changed

+211
-148
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
591591
}
592592
visitor.visit_lifetime(lifetime);
593593
}
594-
TyImplTrait(ref bounds) => {
594+
TyImplTraitExistential(ref bounds) => {
595+
walk_list!(visitor, visit_ty_param_bound, bounds);
596+
}
597+
TyImplTraitUniversal(_, ref bounds) => {
595598
walk_list!(visitor, visit_ty_param_bound, bounds);
596599
}
597600
TyTypeof(expression) => {

src/librustc/hir/lowering.rs

Lines changed: 176 additions & 86 deletions
Large diffs are not rendered by default.

src/librustc/hir/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,9 +1461,12 @@ pub enum Ty_ {
14611461
/// A trait object type `Bound1 + Bound2 + Bound3`
14621462
/// where `Bound` is a trait or a lifetime.
14631463
TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
1464-
/// An `impl Bound1 + Bound2 + Bound3` type
1465-
/// where `Bound` is a trait or a lifetime.
1466-
TyImplTrait(TyParamBounds),
1464+
/// An exsitentially quantified (there exists a type satisfying) `impl
1465+
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
1466+
TyImplTraitExistential(TyParamBounds),
1467+
/// An universally quantified (for all types satisfying) `impl
1468+
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
1469+
TyImplTraitUniversal(DefId, TyParamBounds),
14671470
/// Unused for now
14681471
TyTypeof(BodyId),
14691472
/// TyInfer means the type should be inferred instead of it having been

src/librustc/hir/print.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,8 @@ impl<'a> State<'a> {
421421
self.print_lifetime(lifetime)?;
422422
}
423423
}
424-
hir::TyImplTrait(ref bounds) => {
424+
hir::TyImplTraitExistential(ref bounds) |
425+
hir::TyImplTraitUniversal(_, ref bounds) => {
425426
self.print_bounds("impl ", &bounds[..])?;
426427
}
427428
hir::TyArray(ref ty, v) => {

src/librustc/ich/impls_hir.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ impl_stable_hash_for!(enum hir::Ty_ {
287287
TyTup(ts),
288288
TyPath(qpath),
289289
TyTraitObject(trait_refs, lifetime),
290-
TyImplTrait(bounds),
290+
TyImplTraitExistential(bounds),
291+
TyImplTraitUniversal(def_id, bounds),
291292
TyTypeof(body_id),
292293
TyErr,
293294
TyInfer

src/librustc/middle/resolve_lifetime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,7 @@ fn insert_late_bound_lifetimes(map: &mut NamedRegionMap,
16981698
}
16991699

17001700
fn visit_ty(&mut self, ty: &hir::Ty) {
1701-
if let hir::TyImplTrait(_) = ty.node {
1701+
if let hir::TyImplTraitExistential(_) = ty.node {
17021702
self.impl_trait = true;
17031703
}
17041704
intravisit::walk_ty(self, ty);

src/librustc_metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
14871487

14881488
fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
14891489
match ty.node {
1490-
hir::TyImplTrait(_) => {
1490+
hir::TyImplTraitExistential(_) => {
14911491
let def_id = self.tcx.hir.local_def_id(ty.id);
14921492
self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
14931493
}

src/librustc_privacy/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
373373
}
374374

375375
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
376-
if let hir::TyImplTrait(..) = ty.node {
376+
if let hir::TyImplTraitExistential(..) = ty.node {
377377
if self.get(ty.id).is_some() {
378378
// Reach the (potentially private) type and the API being exposed.
379379
self.reach(ty.id).ty().predicates();
@@ -1557,7 +1557,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
15571557
}
15581558

15591559
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
1560-
if let hir::TyImplTrait(..) = ty.node {
1560+
if let hir::TyImplTraitExistential(..) = ty.node {
15611561
// Check the traits being exposed, as they're separate,
15621562
// e.g. `impl Iterator<Item=T>` has two predicates,
15631563
// `X: Iterator` and `<X as Iterator>::Item == T`,

src/librustc_typeck/astconv.rs

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use util::nodemap::FxHashSet;
3030

3131
use std::iter;
3232
use syntax::{abi, ast};
33+
use syntax::symbol::keywords;
3334
use syntax::feature_gate::{GateIssue, emit_feature_err};
3435
use syntax_pos::Span;
3536

@@ -1033,53 +1034,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10331034
hir::TyTraitObject(ref bounds, ref lifetime) => {
10341035
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
10351036
}
1036-
hir::TyImplTrait(_) => {
1037-
// Figure out if we can allow an `impl Trait` here, by walking up
1038-
// to a `fn` or inherent `impl` method, going only through `Ty`
1039-
// or `TraitRef` nodes (as nothing else should be in types) and
1040-
// ensuring that we reach the `fn`/method signature's return type.
1041-
let mut node_id = ast_ty.id;
1042-
let fn_decl = loop {
1043-
let parent = tcx.hir.get_parent_node(node_id);
1044-
match tcx.hir.get(parent) {
1045-
hir::map::NodeItem(&hir::Item {
1046-
node: hir::ItemFn(ref fn_decl, ..), ..
1047-
}) => break Some(fn_decl),
1048-
1049-
hir::map::NodeImplItem(&hir::ImplItem {
1050-
node: hir::ImplItemKind::Method(ref sig, _), ..
1051-
}) => {
1052-
match tcx.hir.expect_item(tcx.hir.get_parent(parent)).node {
1053-
hir::ItemImpl(.., None, _, _) => {
1054-
break Some(&sig.decl)
1055-
}
1056-
_ => break None
1057-
}
1058-
}
1059-
1060-
hir::map::NodeTy(_) | hir::map::NodeTraitRef(_) => {}
1061-
1062-
_ => break None
1063-
}
1064-
node_id = parent;
1065-
};
1066-
let allow = fn_decl.map_or(false, |fd| {
1067-
match fd.output {
1068-
hir::DefaultReturn(_) => false,
1069-
hir::Return(ref ty) => ty.id == node_id
1070-
}
1071-
});
1072-
1073-
// Create the anonymized type.
1074-
if allow {
1075-
let def_id = tcx.hir.local_def_id(ast_ty.id);
1076-
tcx.mk_anon(def_id, Substs::identity_for_item(tcx, def_id))
1077-
} else {
1078-
span_err!(tcx.sess, ast_ty.span, E0562,
1079-
"`impl Trait` not allowed outside of function \
1080-
and inherent method return types");
1081-
tcx.types.err
1082-
}
1037+
hir::TyImplTraitExistential(_) => {
1038+
let def_id = tcx.hir.local_def_id(ast_ty.id);
1039+
tcx.mk_anon(def_id, Substs::identity_for_item(tcx, def_id))
1040+
}
1041+
hir::TyImplTraitUniversal(fn_def_id, _) => {
1042+
let impl_trait_def_id = tcx.hir.local_def_id(ast_ty.id);
1043+
let generics = tcx.generics_of(fn_def_id);
1044+
let index = generics.type_param_to_index[&impl_trait_def_id.index];
1045+
tcx.mk_param(index, keywords::Invalid.name() /* FIXME(chrisvittal) invalid? */)
10831046
}
10841047
hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
10851048
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);

src/librustc_typeck/collect.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
130130
}
131131

132132
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
133-
if let hir::TyImplTrait(..) = ty.node {
133+
if let hir::TyImplTraitExistential(..) = ty.node {
134134
let def_id = self.tcx.hir.local_def_id(ty.id);
135135
self.tcx.generics_of(def_id);
136136
self.tcx.predicates_of(def_id);
@@ -854,7 +854,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
854854
NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
855855
Some(tcx.closure_base_def_id(def_id))
856856
}
857-
NodeTy(&hir::Ty { node: hir::TyImplTrait(..), .. }) => {
857+
NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(..), .. }) => {
858858
let mut parent_id = node_id;
859859
loop {
860860
match tcx.hir.get(parent_id) {
@@ -1155,7 +1155,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11551155
icx.to_ty(ty)
11561156
}
11571157

1158-
NodeTy(&hir::Ty { node: TyImplTrait(..), .. }) => {
1158+
NodeTy(&hir::Ty { node: TyImplTraitExistential(..), .. }) => {
11591159
let owner = tcx.hir.get_parent_did(node_id);
11601160
let hir_id = tcx.hir.node_to_hir_id(node_id);
11611161
tcx.typeck_tables_of(owner).node_id_to_type(hir_id)
@@ -1373,7 +1373,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
13731373
}
13741374
}
13751375

1376-
NodeTy(&Ty { node: TyImplTrait(ref bounds), span, .. }) => {
1376+
NodeTy(&Ty { node: TyImplTraitExistential(ref bounds), span, .. }) => {
13771377
let substs = Substs::identity_for_item(tcx, def_id);
13781378
let anon_ty = tcx.mk_anon(def_id, substs);
13791379

0 commit comments

Comments
 (0)