Skip to content

Commit ab7abfc

Browse files
committed
Auto merge of #46754 - cramertj:refactor-arg-impl, r=nikomatsakis
Refactor argument-position impl Trait Fixes #46685, #46470 r? @nikomatsakis cc @chrisvittal
2 parents 957dc8d + e502194 commit ab7abfc

File tree

10 files changed

+92
-185
lines changed

10 files changed

+92
-185
lines changed

src/librustc/hir/intravisit.rs

-3
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
602602
walk_list!(visitor, visit_ty_param_bound, bounds);
603603
walk_list!(visitor, visit_lifetime, lifetimes);
604604
}
605-
TyImplTraitUniversal(_, ref bounds) => {
606-
walk_list!(visitor, visit_ty_param_bound, bounds);
607-
}
608605
TyTypeof(expression) => {
609606
visitor.visit_nested_body(expression)
610607
}

src/librustc/hir/lowering.rs

+64-19
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ use syntax::attr;
6161
use syntax::ast::*;
6262
use syntax::errors;
6363
use syntax::ext::hygiene::{Mark, SyntaxContext};
64+
use syntax::print::pprust;
6465
use syntax::ptr::P;
6566
use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
6667
use syntax::std_inject;
@@ -106,6 +107,13 @@ pub struct LoweringContext<'a> {
106107
is_in_loop_condition: bool,
107108
is_in_trait_impl: bool,
108109

110+
// This is a list of in-band type definitions being generated by
111+
// Argument-position `impl Trait`.
112+
// When traversing a signature such as `fn foo(x: impl Trait)`,
113+
// we record `impl Trait` as a new type parameter, then later
114+
// add it on to `foo`s generics.
115+
in_band_ty_params: Vec<hir::TyParam>,
116+
109117
// Used to create lifetime definitions from in-band lifetime usages.
110118
// e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
111119
// When a named lifetime is encountered in a function or impl header and
@@ -197,6 +205,7 @@ pub fn lower_crate(sess: &Session,
197205
node_id_to_hir_id: IndexVec::new(),
198206
is_generator: false,
199207
is_in_trait_impl: false,
208+
in_band_ty_params: Vec::new(),
200209
lifetimes_to_define: Vec::new(),
201210
is_collecting_in_band_lifetimes: false,
202211
in_scope_lifetimes: Vec::new(),
@@ -526,20 +535,23 @@ impl<'a> LoweringContext<'a> {
526535
// Creates a new hir::LifetimeDef for every new lifetime encountered
527536
// while evaluating `f`. Definitions are created with the parent provided.
528537
// If no `parent_id` is provided, no definitions will be returned.
529-
fn collect_in_band_lifetime_defs<T, F>(
538+
fn collect_in_band_defs<T, F>(
530539
&mut self,
531540
parent_id: Option<DefId>,
532541
f: F
533-
) -> (Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T
542+
) -> (Vec<hir::TyParam>, Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T
534543
{
535544
assert!(!self.is_collecting_in_band_lifetimes);
536545
assert!(self.lifetimes_to_define.is_empty());
537546
self.is_collecting_in_band_lifetimes = self.sess.features.borrow().in_band_lifetimes;
538547

548+
assert!(self.in_band_ty_params.is_empty());
549+
539550
let res = f(self);
540551

541552
self.is_collecting_in_band_lifetimes = false;
542553

554+
let in_band_ty_params = self.in_band_ty_params.split_off(0);
543555
let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
544556

545557
let lifetime_defs = match parent_id {
@@ -569,7 +581,7 @@ impl<'a> LoweringContext<'a> {
569581
None => Vec::new(),
570582
};
571583

572-
(lifetime_defs, res)
584+
(in_band_ty_params, lifetime_defs, res)
573585
}
574586

575587
// Evaluates `f` with the lifetimes in `lt_defs` in-scope.
@@ -613,29 +625,33 @@ impl<'a> LoweringContext<'a> {
613625
res
614626
}
615627

616-
// Appends in-band lifetime defs to the existing set of out-of-band lifetime defs.
617-
// Evaluates all within the context of the out-of-band defs.
618-
// If provided, `impl_item_id` is used to find the parent impls of impl items so
619-
// that their generics are not duplicated.
620-
fn add_in_band_lifetime_defs<F, T>(
628+
// Appends in-band lifetime defs and argument-position `impl Trait` defs
629+
// to the existing set of generics.
630+
fn add_in_band_defs<F, T>(
621631
&mut self,
622632
generics: &Generics,
623633
parent_id: Option<DefId>,
624634
f: F
625635
) -> (hir::Generics, T)
626636
where F: FnOnce(&mut LoweringContext) -> T
627637
{
628-
let (in_band_defs, (mut lowered_generics, res)) =
638+
let (in_band_ty_defs, in_band_lifetime_defs, (mut lowered_generics, res)) =
629639
self.with_in_scope_lifetime_defs(&generics.lifetimes, |this| {
630-
this.collect_in_band_lifetime_defs(parent_id, |this| {
640+
this.collect_in_band_defs(parent_id, |this| {
631641
(this.lower_generics(generics), f(this))
632642
})
633643
});
634644

645+
lowered_generics.ty_params =
646+
lowered_generics.ty_params
647+
.iter().cloned()
648+
.chain(in_band_ty_defs.into_iter())
649+
.collect();
650+
635651
lowered_generics.lifetimes =
636652
lowered_generics.lifetimes
637653
.iter().cloned()
638-
.chain(in_band_defs.into_iter())
654+
.chain(in_band_lifetime_defs.into_iter())
639655
.collect();
640656

641657
(lowered_generics, res)
@@ -922,6 +938,7 @@ impl<'a> LoweringContext<'a> {
922938
}
923939
TyKind::ImplTrait(ref bounds) => {
924940
use syntax::feature_gate::{emit_feature_err, GateIssue};
941+
let span = t.span;
925942
match itctx {
926943
ImplTraitContext::Existential => {
927944
let has_feature = self.sess.features.borrow().conservative_impl_trait;
@@ -944,7 +961,7 @@ impl<'a> LoweringContext<'a> {
944961
id: self.next_id().node_id,
945962
predicates: Vec::new().into(),
946963
},
947-
span: t.span,
964+
span,
948965
},
949966
bounds: hir_bounds,
950967
}, lifetimes)
@@ -956,7 +973,35 @@ impl<'a> LoweringContext<'a> {
956973
t.span, GateIssue::Language,
957974
"`impl Trait` in argument position is experimental");
958975
}
959-
hir::TyImplTraitUniversal(def_id, self.lower_bounds(bounds, itctx))
976+
977+
let def_node_id = self.next_id().node_id;
978+
979+
// Add a definition for the in-band TyParam
980+
let def_index = self.resolver.definitions().create_def_with_parent(
981+
def_id.index,
982+
def_node_id,
983+
DefPathData::ImplTrait,
984+
DefIndexAddressSpace::High,
985+
Mark::root()
986+
);
987+
988+
let hir_bounds = self.lower_bounds(bounds, itctx);
989+
self.in_band_ty_params.push(hir::TyParam {
990+
// Set the name to `impl Bound1 + Bound2`
991+
name: Symbol::intern(&pprust::ty_to_string(t)),
992+
id: def_node_id,
993+
bounds: hir_bounds,
994+
default: None,
995+
span,
996+
pure_wrt_drop: false,
997+
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
998+
});
999+
1000+
hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
1001+
span,
1002+
def: Def::TyParam(DefId::local(def_index)),
1003+
segments: vec![].into(),
1004+
})))
9601005
},
9611006
ImplTraitContext::Disallowed => {
9621007
span_err!(self.sess, t.span, E0562,
@@ -1829,7 +1874,7 @@ impl<'a> LoweringContext<'a> {
18291874
this.expr_block(body, ThinVec::new())
18301875
});
18311876
let (generics, fn_decl) =
1832-
this.add_in_band_lifetime_defs(generics, fn_def_id, |this|
1877+
this.add_in_band_defs(generics, fn_def_id, |this|
18331878
this.lower_fn_decl(decl, fn_def_id, true));
18341879

18351880
hir::ItemFn(fn_decl,
@@ -1883,7 +1928,7 @@ impl<'a> LoweringContext<'a> {
18831928
ref impl_items) => {
18841929
let def_id = self.resolver.definitions().opt_local_def_id(id);
18851930
let (generics, (ifce, lowered_ty)) =
1886-
self.add_in_band_lifetime_defs(ast_generics, def_id, |this| {
1931+
self.add_in_band_defs(ast_generics, def_id, |this| {
18871932
let ifce = ifce.as_ref().map(|trait_ref| {
18881933
this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
18891934
});
@@ -2059,7 +2104,7 @@ impl<'a> LoweringContext<'a> {
20592104
}
20602105
TraitItemKind::Method(ref sig, None) => {
20612106
let names = this.lower_fn_args_to_names(&sig.decl);
2062-
this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
2107+
this.add_in_band_defs(&i.generics, fn_def_id, |this|
20632108
hir::TraitItemKind::Method(
20642109
this.lower_method_sig(sig, fn_def_id, false),
20652110
hir::TraitMethod::Required(names)))
@@ -2070,7 +2115,7 @@ impl<'a> LoweringContext<'a> {
20702115
this.expr_block(body, ThinVec::new())
20712116
});
20722117

2073-
this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
2118+
this.add_in_band_defs(&i.generics, fn_def_id, |this|
20742119
hir::TraitItemKind::Method(
20752120
this.lower_method_sig(sig, fn_def_id, false),
20762121
hir::TraitMethod::Provided(body_id)))
@@ -2147,7 +2192,7 @@ impl<'a> LoweringContext<'a> {
21472192
});
21482193
let impl_trait_return_allow = !this.is_in_trait_impl;
21492194

2150-
this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
2195+
this.add_in_band_defs(&i.generics, fn_def_id, |this|
21512196
hir::ImplItemKind::Method(
21522197
this.lower_method_sig(sig, fn_def_id, impl_trait_return_allow),
21532198
body_id))
@@ -2280,7 +2325,7 @@ impl<'a> LoweringContext<'a> {
22802325
ForeignItemKind::Fn(ref fdec, ref generics) => {
22812326
// Disallow impl Trait in foreign items
22822327
let (generics, (fn_dec, fn_args)) =
2283-
this.add_in_band_lifetime_defs(
2328+
this.add_in_band_defs(
22842329
generics,
22852330
Some(def_id),
22862331
|this| (

src/librustc/hir/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1511,7 +1511,7 @@ pub enum Ty_ {
15111511
/// A trait object type `Bound1 + Bound2 + Bound3`
15121512
/// where `Bound` is a trait or a lifetime.
15131513
TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
1514-
/// An exsitentially quantified (there exists a type satisfying) `impl
1514+
/// An existentially quantified (there exists a type satisfying) `impl
15151515
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
15161516
///
15171517
/// The `ExistTy` structure emulates an
@@ -1523,9 +1523,6 @@ pub enum Ty_ {
15231523
/// because all in-scope type parameters are captured by `impl Trait`,
15241524
/// so they are resolved directly through the parent `Generics`.
15251525
TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
1526-
/// An universally quantified (for all types satisfying) `impl
1527-
/// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
1528-
TyImplTraitUniversal(DefId, TyParamBounds),
15291526
/// Unused for now
15301527
TyTypeof(BodyId),
15311528
/// TyInfer means the type should be inferred instead of it having been

src/librustc/hir/print.rs

-3
Original file line numberDiff line numberDiff line change
@@ -425,9 +425,6 @@ impl<'a> State<'a> {
425425
hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
426426
self.print_bounds("impl", &existty.bounds[..])?;
427427
}
428-
hir::TyImplTraitUniversal(_, ref bounds) => {
429-
self.print_bounds("impl", &bounds[..])?;
430-
}
431428
hir::TyArray(ref ty, v) => {
432429
self.s.word("[")?;
433430
self.print_type(&ty)?;

src/librustc/ich/impls_hir.rs

-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ impl_stable_hash_for!(enum hir::Ty_ {
312312
TyPath(qpath),
313313
TyTraitObject(trait_refs, lifetime),
314314
TyImplTraitExistential(existty, lifetimes),
315-
TyImplTraitUniversal(def_id, bounds),
316315
TyTypeof(body_id),
317316
TyErr,
318317
TyInfer

src/librustc/middle/resolve_lifetime.rs

-13
Original file line numberDiff line numberDiff line change
@@ -2212,19 +2212,6 @@ fn insert_late_bound_lifetimes(
22122212
visit_where_predicate,
22132213
&generics.where_clause.predicates
22142214
);
2215-
// We need to collect argument impl Trait lifetimes as well,
2216-
// we do so here.
2217-
walk_list!(
2218-
&mut appears_in_where_clause,
2219-
visit_ty,
2220-
decl.inputs
2221-
.iter()
2222-
.filter(|ty| if let hir::TyImplTraitUniversal(..) = ty.node {
2223-
true
2224-
} else {
2225-
false
2226-
})
2227-
);
22282215
for lifetime_def in &generics.lifetimes {
22292216
if !lifetime_def.bounds.is_empty() {
22302217
// `'a: 'b` means both `'a` and `'b` are referenced

src/librustc_typeck/astconv.rs

-8
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use util::nodemap::FxHashSet;
3030

3131
use std::iter;
3232
use syntax::{abi, ast};
33-
use syntax::symbol::Symbol;
3433
use syntax::feature_gate::{GateIssue, emit_feature_err};
3534
use syntax_pos::Span;
3635

@@ -1066,13 +1065,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10661065
let def_id = tcx.hir.local_def_id(ast_ty.id);
10671066
self.impl_trait_ty_to_ty(def_id, lifetimes)
10681067
}
1069-
hir::TyImplTraitUniversal(fn_def_id, _) => {
1070-
let impl_trait_def_id = tcx.hir.local_def_id(ast_ty.id);
1071-
let generics = tcx.generics_of(fn_def_id);
1072-
let index = generics.type_param_to_index[&impl_trait_def_id.index];
1073-
tcx.mk_param(index,
1074-
Symbol::intern(&tcx.hir.node_to_pretty_string(ast_ty.id)))
1075-
}
10761068
hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
10771069
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
10781070
let opt_self_ty = maybe_qself.as_ref().map(|qself| {

0 commit comments

Comments
 (0)