Skip to content

Commit d80cd3d

Browse files
committed
auto merge of #17028 : pcwalton/rust/higher-rank-trait-lifetimes, r=pnkfelix
They will ICE during typechecking if used, because they depend on trait reform. This is part of unboxed closures. r? @nikomatsakis
2 parents 2f9669c + 5376b1c commit d80cd3d

File tree

10 files changed

+128
-10
lines changed

10 files changed

+128
-10
lines changed

src/librustc/middle/resolve_lifetime.rs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use driver::session::Session;
2121
use middle::subst;
2222
use syntax::ast;
2323
use syntax::codemap::Span;
24+
use syntax::owned_slice::OwnedSlice;
2425
use syntax::parse::token::special_idents;
2526
use syntax::parse::token;
2627
use syntax::print::pprust::{lifetime_to_string};
@@ -98,8 +99,22 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
9899
ast::ItemTy(_, ref generics) |
99100
ast::ItemEnum(_, ref generics) |
100101
ast::ItemStruct(_, ref generics) |
101-
ast::ItemImpl(ref generics, _, _, _) |
102-
ast::ItemTrait(ref generics, _, _, _) => &generics.lifetimes
102+
ast::ItemTrait(ref generics, _, _, _) => {
103+
self.with(|scope, f| {
104+
f(EarlyScope(subst::TypeSpace,
105+
&generics.lifetimes,
106+
scope))
107+
}, |v| v.check_lifetime_defs(&generics.lifetimes));
108+
&generics.lifetimes
109+
}
110+
ast::ItemImpl(ref generics, _, _, _) => {
111+
self.with(|scope, f| {
112+
f(EarlyScope(subst::TypeSpace,
113+
&generics.lifetimes,
114+
scope))
115+
}, |v| v.check_lifetime_defs(&generics.lifetimes));
116+
&generics.lifetimes
117+
}
103118
};
104119

105120
self.with(|_, f| f(EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE)), |v| {
@@ -155,6 +170,20 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
155170
}
156171
self.resolve_lifetime_ref(lifetime_ref);
157172
}
173+
174+
fn visit_generics(&mut self, generics: &ast::Generics) {
175+
for ty_param in generics.ty_params.iter() {
176+
self.visit_ty_param_bounds(&ty_param.bounds);
177+
match ty_param.default {
178+
Some(ref ty) => self.visit_ty(&**ty),
179+
None => {}
180+
}
181+
}
182+
for predicate in generics.where_clause.predicates.iter() {
183+
self.visit_ident(predicate.span, predicate.ident);
184+
self.visit_ty_param_bounds(&predicate.bounds);
185+
}
186+
}
158187
}
159188

160189
impl<'a> LifetimeContext<'a> {
@@ -167,6 +196,47 @@ impl<'a> LifetimeContext<'a> {
167196
}))
168197
}
169198

199+
fn visit_ty_param_bounds(&mut self,
200+
bounds: &OwnedSlice<ast::TyParamBound>) {
201+
for bound in bounds.iter() {
202+
match *bound {
203+
ast::TraitTyParamBound(ref trait_ref) => {
204+
self.visit_trait_ref(trait_ref);
205+
}
206+
ast::UnboxedFnTyParamBound(ref fn_decl) => {
207+
self.visit_unboxed_fn_ty_param_bound(&**fn_decl);
208+
}
209+
ast::RegionTyParamBound(ref lifetime) => {
210+
self.visit_lifetime_ref(lifetime);
211+
}
212+
}
213+
}
214+
}
215+
216+
fn visit_trait_ref(&mut self, trait_ref: &ast::TraitRef) {
217+
self.with(|scope, f| {
218+
f(LateScope(trait_ref.ref_id, &trait_ref.lifetimes, scope))
219+
}, |v| {
220+
v.check_lifetime_defs(&trait_ref.lifetimes);
221+
for lifetime in trait_ref.lifetimes.iter() {
222+
v.visit_lifetime_decl(lifetime);
223+
}
224+
v.visit_path(&trait_ref.path, trait_ref.ref_id);
225+
})
226+
}
227+
228+
fn visit_unboxed_fn_ty_param_bound(&mut self,
229+
bound: &ast::UnboxedFnBound) {
230+
self.with(|scope, f| {
231+
f(LateScope(bound.ref_id, &bound.lifetimes, scope))
232+
}, |v| {
233+
for argument in bound.decl.inputs.iter() {
234+
v.visit_ty(&*argument.ty);
235+
}
236+
v.visit_ty(&*bound.decl.output);
237+
})
238+
}
239+
170240
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
171241
fn visit_fn_decl(&mut self,
172242
n: ast::NodeId,

src/librustc/middle/typeck/infer/error_reporting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
11101110
ast::TraitTyParamBound(ast::TraitRef {
11111111
path: new_path,
11121112
ref_id: tr.ref_id,
1113+
lifetimes: tr.lifetimes.clone(),
11131114
})
11141115
}
11151116
}

src/libsyntax/ast.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ pub type TyParamBounds = OwnedSlice<TyParamBound>;
223223
pub struct UnboxedFnBound {
224224
pub path: Path,
225225
pub decl: P<FnDecl>,
226+
pub lifetimes: Vec<LifetimeDef>,
226227
pub ref_id: NodeId,
227228
}
228229

@@ -1219,6 +1220,7 @@ pub struct Attribute_ {
12191220
pub struct TraitRef {
12201221
pub path: Path,
12211222
pub ref_id: NodeId,
1223+
pub lifetimes: Vec<LifetimeDef>,
12221224
}
12231225

12241226
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]

src/libsyntax/ext/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
435435
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
436436
ast::TraitRef {
437437
path: path,
438-
ref_id: ast::DUMMY_NODE_ID
438+
ref_id: ast::DUMMY_NODE_ID,
439+
lifetimes: Vec::new(),
439440
}
440441
}
441442

src/libsyntax/fold.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -668,11 +668,13 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
668668
UnboxedFnBound {
669669
ref path,
670670
ref decl,
671+
ref lifetimes,
671672
ref_id
672673
} => {
673674
UnboxedFnTyParamBound(P(UnboxedFnBound {
674675
path: fld.fold_path(path.clone()),
675676
decl: fld.fold_fn_decl(decl.clone()),
677+
lifetimes: fld.fold_lifetime_defs(lifetimes.clone()),
676678
ref_id: fld.new_id(ref_id),
677679
}))
678680
}
@@ -808,10 +810,17 @@ pub fn noop_fold_struct_def<T: Folder>(struct_def: P<StructDef>, fld: &mut T) ->
808810
})
809811
}
810812

811-
pub fn noop_fold_trait_ref<T: Folder>(TraitRef {ref_id, path}: TraitRef, fld: &mut T) -> TraitRef {
812-
TraitRef {
813-
ref_id: fld.new_id(ref_id),
813+
pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef {
814+
let id = fld.new_id(p.ref_id);
815+
let TraitRef {
816+
path,
817+
lifetimes,
818+
..
819+
} = p;
820+
ast::TraitRef {
814821
path: fld.fold_path(path),
822+
ref_id: id,
823+
lifetimes: fld.fold_lifetime_defs(lifetimes),
815824
}
816825
}
817826

src/libsyntax/parse/parser.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ use ast::{FnOnceUnboxedClosureKind};
3434
use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod};
3535
use ast::{Ident, NormalFn, Inherited, ImplItem, Item, Item_, ItemStatic};
3636
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
37-
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
37+
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
38+
use ast::{LifetimeDef, Lit, Lit_};
3839
use ast::{LitBool, LitChar, LitByte, LitBinary};
3940
use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
4041
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
@@ -3791,8 +3792,21 @@ impl<'a> Parser<'a> {
37913792
{
37923793
let mut result = vec!();
37933794
loop {
3795+
let lifetime_defs = if self.eat(&token::LT) {
3796+
let lifetime_defs = self.parse_lifetime_defs();
3797+
self.expect_gt();
3798+
lifetime_defs
3799+
} else {
3800+
Vec::new()
3801+
};
37943802
match self.token {
37953803
token::LIFETIME(lifetime) => {
3804+
if lifetime_defs.len() > 0 {
3805+
let span = self.last_span;
3806+
self.span_err(span, "lifetime declarations are not \
3807+
allowed here")
3808+
}
3809+
37963810
result.push(RegionTyParamBound(ast::Lifetime {
37973811
id: ast::DUMMY_NODE_ID,
37983812
span: self.span,
@@ -3818,12 +3832,14 @@ impl<'a> Parser<'a> {
38183832
cf: return_style,
38193833
variadic: false,
38203834
}),
3835+
lifetimes: lifetime_defs,
38213836
ref_id: ast::DUMMY_NODE_ID,
38223837
})));
38233838
} else {
38243839
result.push(TraitTyParamBound(ast::TraitRef {
38253840
path: path,
38263841
ref_id: ast::DUMMY_NODE_ID,
3842+
lifetimes: lifetime_defs,
38273843
}))
38283844
}
38293845
}
@@ -3852,6 +3868,7 @@ impl<'a> Parser<'a> {
38523868
ast::TraitRef {
38533869
path: path,
38543870
ref_id: ast::DUMMY_NODE_ID,
3871+
lifetimes: Vec::new(),
38553872
}
38563873
}
38573874

@@ -4482,8 +4499,11 @@ impl<'a> Parser<'a> {
44824499
// New-style trait. Reinterpret the type as a trait.
44834500
let opt_trait_ref = match ty.node {
44844501
TyPath(ref path, None, node_id) => {
4485-
Some(TraitRef { path: (*path).clone(),
4486-
ref_id: node_id })
4502+
Some(TraitRef {
4503+
path: (*path).clone(),
4504+
ref_id: node_id,
4505+
lifetimes: Vec::new(),
4506+
})
44874507
}
44884508
TyPath(_, Some(_), _) => {
44894509
self.span_err(ty.span,

src/libsyntax/print/pprust.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,16 @@ impl<'a> State<'a> {
900900
}
901901

902902
fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> {
903+
if t.lifetimes.len() > 0 {
904+
try!(self.print_generics(&ast::Generics {
905+
lifetimes: t.lifetimes.clone(),
906+
ty_params: OwnedSlice::empty(),
907+
where_clause: ast::WhereClause {
908+
id: ast::DUMMY_NODE_ID,
909+
predicates: Vec::new(),
910+
},
911+
}));
912+
}
903913
self.print_path(&t.path, false)
904914
}
905915

src/libsyntax/visit.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V,
202202

203203
/// Like with walk_method_helper this doesn't correspond to a method
204204
/// in Visitor, and so it gets a _helper suffix.
205-
pub fn walk_trait_ref_helper<'v, V: Visitor<'v>>(visitor: &mut V, trait_ref: &'v TraitRef) {
205+
pub fn walk_trait_ref_helper<'v,V>(visitor: &mut V, trait_ref: &'v TraitRef)
206+
where V: Visitor<'v> {
207+
walk_lifetime_decls(visitor, &trait_ref.lifetimes);
206208
visitor.visit_path(&trait_ref.path, trait_ref.ref_id)
207209
}
208210

@@ -495,6 +497,7 @@ pub fn walk_ty_param_bounds<'v, V: Visitor<'v>>(visitor: &mut V,
495497
visitor.visit_ty(&*argument.ty)
496498
}
497499
visitor.visit_ty(&*function_declaration.decl.output);
500+
walk_lifetime_decls(visitor, &function_declaration.lifetimes);
498501
}
499502
RegionTyParamBound(ref lifetime) => {
500503
visitor.visit_lifetime_ref(lifetime);

src/test/compile-fail/regions-name-duplicated.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
struct Foo<'a, 'a> { //~ ERROR lifetime name `'a` declared twice
12+
//~^ ERROR lifetime name `'a` declared twice
1213
x: &'a int
1314
}
1415

src/test/compile-fail/regions-name-static.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
struct Foo<'static> { //~ ERROR illegal lifetime parameter name: `'static`
12+
//~^ ERROR illegal lifetime parameter name: `'static`
1213
x: &'static int
1314
}
1415

0 commit comments

Comments
 (0)