diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-08-27 21:46:52 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-08-27 21:46:52 -0400 |
| commit | 1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f (patch) | |
| tree | 552fabade603ab0d148a49ae3cf1abd3f399740a /src/libsyntax | |
| parent | 3ee047ae1ffab454270bc1859b3beef3556ef8f9 (diff) | |
| download | rust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.tar.gz rust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.zip | |
Implement generalized object and type parameter bounds (Fixes #16462)
Diffstat (limited to 'src/libsyntax')
26 files changed, 426 insertions, 463 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7d5787092a5..d574a02fded 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -224,16 +224,17 @@ pub static DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - StaticRegionTyParamBound, UnboxedFnTyParamBound(UnboxedFnTy), - OtherRegionTyParamBound(Span) // FIXME -- just here until work for #5723 lands + RegionTyParamBound(Lifetime) } +pub type TyParamBounds = OwnedSlice<TyParamBound>; + #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TyParam { pub ident: Ident, pub id: NodeId, - pub bounds: OwnedSlice<TyParamBound>, + pub bounds: TyParamBounds, pub unbound: Option<TyParamBound>, pub default: Option<P<Ty>>, pub span: Span @@ -892,11 +893,7 @@ pub struct ClosureTy { pub fn_style: FnStyle, pub onceness: Onceness, pub decl: P<FnDecl>, - /// Optional optvec distinguishes between "fn()" and "fn:()" so we can - /// implement issue #7264. None means "fn()", which means infer a default - /// bound based on pointer sigil during typeck. Some(Empty) means "fn:()", - /// which means use no bounds (e.g., not even Owned on a ~fn()). - pub bounds: Option<OwnedSlice<TyParamBound>>, + pub bounds: TyParamBounds, } #[deriving(PartialEq, Eq, Encodable, Decodable, Hash, Show)] @@ -923,12 +920,12 @@ pub enum Ty_ { TyFixedLengthVec(P<Ty>, Gc<Expr>), TyPtr(MutTy), TyRptr(Option<Lifetime>, MutTy), - TyClosure(Gc<ClosureTy>, Option<Lifetime>), + TyClosure(Gc<ClosureTy>), TyProc(Gc<ClosureTy>), TyBareFn(Gc<BareFnTy>), TyUnboxedFn(Gc<UnboxedFnTy>), TyTup(Vec<P<Ty>> ), - TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above + TyPath(Path, Option<TyParamBounds>, NodeId), // for #7264; see above /// No-op; kept solely so that we can pretty-print faithfully TyParen(P<Ty>), TyTypeof(Gc<Expr>), @@ -1281,7 +1278,7 @@ pub enum Item_ { ItemTrait(Generics, Option<TyParamBound>, // (optional) default bound not required for Self. // Currently, only Sized makes sense here. - Vec<TraitRef> , + TyParamBounds, Vec<TraitItem>), ItemImpl(Generics, Option<TraitRef>, // (optional) trait this impl implements diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 5fccf6cc3f0..993c5ce676a 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -68,10 +68,15 @@ impl<'a> Iterator<PathElem> for LinkedPath<'a> { } } -// HACK(eddyb) move this into libstd (value wrapper for slice::Items). +#[cfg(stage0)] #[deriving(Clone)] pub struct Values<'a, T>(pub slice::Items<'a, T>); +// HACK(eddyb) move this into libstd (value wrapper for slice::Items). +#[cfg(not(stage0))] +#[deriving(Clone)] +pub struct Values<'a, T:'a>(pub slice::Items<'a, T>); + impl<'a, T: Copy> Iterator<T> for Values<'a, T> { fn next(&mut self) -> Option<T> { let &Values(ref mut items) = self; @@ -478,6 +483,7 @@ impl Map { } } +#[cfg(stage0)] pub struct NodesMatchingSuffix<'a, S> { map: &'a Map, item_name: &'a S, @@ -485,6 +491,14 @@ pub struct NodesMatchingSuffix<'a, S> { idx: NodeId, } +#[cfg(not(stage0))] +pub struct NodesMatchingSuffix<'a, S:'a> { + map: &'a Map, + item_name: &'a S, + in_which: &'a [S], + idx: NodeId, +} + impl<'a,S:Str> NodesMatchingSuffix<'a,S> { /// Returns true only if some suffix of the module path for parent /// matches `self.in_which`. @@ -676,11 +690,7 @@ impl<'a, F: FoldOps> Folder for Ctx<'a, F> { None => {} } } - ItemTrait(_, _, ref traits, ref methods) => { - for t in traits.iter() { - self.insert(t.ref_id, EntryItem(self.parent, i)); - } - + ItemTrait(_, _, _, ref methods) => { for tm in methods.iter() { match *tm { RequiredMethod(ref m) => { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 1a4b41404be..cc586a3affa 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -349,12 +349,20 @@ pub trait IdVisitingOperation { /// A visitor that applies its operation to all of the node IDs /// in a visitable thing. +#[cfg(stage0)] pub struct IdVisitor<'a, O> { pub operation: &'a O, pub pass_through_items: bool, pub visited_outermost: bool, } +#[cfg(not(stage0))] +pub struct IdVisitor<'a, O:'a> { + pub operation: &'a O, + pub pass_through_items: bool, + pub visited_outermost: bool, +} + impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { fn visit_generics_helper(&self, generics: &Generics) { for type_parameter in generics.ty_params.iter() { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 209296989fa..25a6a4c01bd 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -45,8 +45,10 @@ fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T { } } -pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span, - token_tree: &[TokenTree]) -> Box<MacResult> { +pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, + span: Span, + token_tree: &[TokenTree]) + -> Box<MacResult+'cx> { let code = match token_tree { [ast::TTTok(_, token::IDENT(code, _))] => code, _ => unreachable!() @@ -75,8 +77,10 @@ pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span, MacExpr::new(quote_expr!(ecx, ())) } -pub fn expand_register_diagnostic(ecx: &mut ExtCtxt, span: Span, - token_tree: &[TokenTree]) -> Box<MacResult> { +pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, + span: Span, + token_tree: &[TokenTree]) + -> Box<MacResult+'cx> { let (code, description) = match token_tree { [ast::TTTok(_, token::IDENT(ref code, _))] => { (code, None) @@ -101,8 +105,10 @@ pub fn expand_register_diagnostic(ecx: &mut ExtCtxt, span: Span, MacItem::new(quote_item!(ecx, mod $sym {}).unwrap()) } -pub fn expand_build_diagnostic_array(ecx: &mut ExtCtxt, span: Span, - token_tree: &[TokenTree]) -> Box<MacResult> { +pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, + span: Span, + token_tree: &[TokenTree]) + -> Box<MacResult+'cx> { let name = match token_tree { [ast::TTTok(_, token::IDENT(ref name, _))] => name, _ => unreachable!() diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 180f2409b8a..8028d51a7b5 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -45,8 +45,8 @@ impl State { static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"]; -pub fn expand_asm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let mut p = cx.new_parser_from_tts(tts); let mut asm = InternedString::new(""); let mut asm_str_style = None; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 01d3920a254..b3b66a6a604 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -52,23 +52,23 @@ pub struct BasicMacroExpander { /// Represents a thing that maps token trees to Macro Results pub trait TTMacroExpander { - fn expand(&self, - ecx: &mut ExtCtxt, - span: Span, - token_tree: &[ast::TokenTree]) - -> Box<MacResult>; + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt, + span: Span, + token_tree: &[ast::TokenTree]) + -> Box<MacResult+'cx>; } pub type MacroExpanderFn = - fn(ecx: &mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree]) - -> Box<MacResult>; + fn<'cx>(ecx: &'cx mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree]) + -> Box<MacResult+'cx>; impl TTMacroExpander for BasicMacroExpander { - fn expand(&self, - ecx: &mut ExtCtxt, - span: Span, - token_tree: &[ast::TokenTree]) - -> Box<MacResult> { + fn expand<'cx>(&self, + ecx: &'cx mut ExtCtxt, + span: Span, + token_tree: &[ast::TokenTree]) + -> Box<MacResult+'cx> { (self.expander)(ecx, span, token_tree) } } @@ -79,27 +79,27 @@ pub struct BasicIdentMacroExpander { } pub trait IdentMacroExpander { - fn expand(&self, - cx: &mut ExtCtxt, - sp: Span, - ident: ast::Ident, - token_tree: Vec<ast::TokenTree> ) - -> Box<MacResult>; + fn expand<'cx>(&self, + cx: &'cx mut ExtCtxt, + sp: Span, + ident: ast::Ident, + token_tree: Vec<ast::TokenTree> ) + -> Box<MacResult+'cx>; } impl IdentMacroExpander for BasicIdentMacroExpander { - fn expand(&self, - cx: &mut ExtCtxt, - sp: Span, - ident: ast::Ident, - token_tree: Vec<ast::TokenTree> ) - -> Box<MacResult> { + fn expand<'cx>(&self, + cx: &'cx mut ExtCtxt, + sp: Span, + ident: ast::Ident, + token_tree: Vec<ast::TokenTree> ) + -> Box<MacResult+'cx> { (self.expander)(cx, sp, ident, token_tree) } } pub type IdentMacroExpanderFn = - fn(&mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult>; + fn<'cx>(&'cx mut ExtCtxt, Span, ast::Ident, Vec<ast::TokenTree>) -> Box<MacResult+'cx>; /// The result of a macro expansion. The return values of the various /// methods are spliced into the AST at the callsite of the macro (or @@ -146,8 +146,8 @@ pub struct MacExpr { e: Gc<ast::Expr>, } impl MacExpr { - pub fn new(e: Gc<ast::Expr>) -> Box<MacResult> { - box MacExpr { e: e } as Box<MacResult> + pub fn new(e: Gc<ast::Expr>) -> Box<MacResult+'static> { + box MacExpr { e: e } as Box<MacResult+'static> } } impl MacResult for MacExpr { @@ -160,8 +160,8 @@ pub struct MacPat { p: Gc<ast::Pat>, } impl MacPat { - pub fn new(p: Gc<ast::Pat>) -> Box<MacResult> { - box MacPat { p: p } as Box<MacResult> + pub fn new(p: Gc<ast::Pat>) -> Box<MacResult+'static> { + box MacPat { p: p } as Box<MacResult+'static> } } impl MacResult for MacPat { @@ -174,8 +174,8 @@ pub struct MacItem { i: Gc<ast::Item> } impl MacItem { - pub fn new(i: Gc<ast::Item>) -> Box<MacResult> { - box MacItem { i: i } as Box<MacResult> + pub fn new(i: Gc<ast::Item>) -> Box<MacResult+'static> { + box MacItem { i: i } as Box<MacResult+'static> } } impl MacResult for MacItem { @@ -203,8 +203,8 @@ impl DummyResult { /// /// Use this as a return value after hitting any errors and /// calling `span_err`. - pub fn any(sp: Span) -> Box<MacResult> { - box DummyResult { expr_only: false, span: sp } as Box<MacResult> + pub fn any(sp: Span) -> Box<MacResult+'static> { + box DummyResult { expr_only: false, span: sp } as Box<MacResult+'static> } /// Create a default MacResult that can only be an expression. @@ -212,8 +212,8 @@ impl DummyResult { /// Use this for macros that must expand to an expression, so even /// if an error is encountered internally, the user will receive /// an error that they also used it in the wrong place. - pub fn expr(sp: Span) -> Box<MacResult> { - box DummyResult { expr_only: true, span: sp } as Box<MacResult> + pub fn expr(sp: Span) -> Box<MacResult+'static> { + box DummyResult { expr_only: true, span: sp } as Box<MacResult+'static> } /// A plain dummy expression. diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs index 6ea55096348..18367511495 100644 --- a/src/libsyntax/ext/bytes.rs +++ b/src/libsyntax/ext/bytes.rs @@ -17,8 +17,10 @@ use ext::base; use ext::build::AstBuilder; -pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { cx.span_warn(sp, "`bytes!` is deprecated, use `b\"foo\"` literals instead"); cx.parse_sess.span_diagnostic.span_note(sp, "see http://doc.rust-lang.org/rust.html#byte-and-byte-string-literals \ diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs index c2930662bc4..0c3a951c982 100644 --- a/src/libsyntax/ext/cfg.rs +++ b/src/libsyntax/ext/cfg.rs @@ -26,8 +26,10 @@ use parse::token::InternedString; use parse::token; -pub fn expand_cfg(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_cfg<'cx>(cx: &mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'static> { let mut p = cx.new_parser_from_tts(tts); let mut cfgs = Vec::new(); // parse `cfg!(meta_item, meta_item(x,y), meta_item="foo", ...)` diff --git a/src/libsyntax/ext/concat.rs b/src/libsyntax/ext/concat.rs index dd1153bf666..ea7a4d061c0 100644 --- a/src/libsyntax/ext/concat.rs +++ b/src/libsyntax/ext/concat.rs @@ -19,7 +19,7 @@ use std::string::String; pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, sp: codemap::Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let es = match base::get_exprs_from_tts(cx, sp, tts) { Some(e) => e, None => return base::DummyResult::expr(sp) diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 7cf901bbd5e..0ac26a3a904 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -18,8 +18,8 @@ use parse::token::{str_to_ident}; use std::gc::GC; -pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let mut res_str = String::new(); for (i, e) in tts.iter().enumerate() { if i & 1 == 1 { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 4b185419b40..50bdc296aad 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -407,9 +407,15 @@ impl<'a> TraitDef<'a> { cx.typarambound(p.to_path(cx, self.span, type_ident, generics)) }).collect(); + // require the current trait bounds.push(cx.typarambound(trait_path.clone())); + // also add in any bounds from the declaration + for declared_bound in ty_param.bounds.iter() { + bounds.push((*declared_bound).clone()); + } + cx.typaram(self.span, ty_param.ident, OwnedSlice::from_vec(bounds), diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index b24cfb85794..aae92ae85fc 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -23,8 +23,8 @@ use parse::token; use std::os; -pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") { None => return DummyResult::expr(sp), Some(v) => v @@ -59,8 +59,8 @@ pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) MacExpr::new(e) } -pub fn expand_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let exprs = match get_exprs_from_tts(cx, sp, tts) { Some(ref exprs) if exprs.len() == 0 => { cx.span_err(sp, "env! takes 1 or 2 arguments"); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d918b28d4dc..9dbea1c9ac2 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -31,6 +31,10 @@ use util::small_vector::SmallVector; use std::gc::{Gc, GC}; +enum Either<L,R> { + Left(L), + Right(R) +} fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> { match e.node { @@ -102,7 +106,8 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span, parse_thunk: |Box<MacResult>|->Option<T>, mark_thunk: |T,Mrk|->T, fld: &mut MacroExpander) - -> Option<T> { + -> Option<T> +{ match (*mac).node { // it would almost certainly be cleaner to pass the whole // macro invocation in, rather than pulling it apart and @@ -149,10 +154,13 @@ fn expand_mac_invoc<T>(mac: &ast::Mac, span: &codemap::Span, // the macro. let mac_span = original_span(fld.cx); - let expanded = expandfun.expand(fld.cx, - mac_span.call_site, - marked_before.as_slice()); - let parsed = match parse_thunk(expanded) { + let opt_parsed = { + let expanded = expandfun.expand(fld.cx, + mac_span.call_site, + marked_before.as_slice()); + parse_thunk(expanded) + }; + let parsed = match opt_parsed { Some(e) => e, None => { fld.cx.span_err( @@ -358,7 +366,8 @@ fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool { // Support for item-position macro invocations, exactly the same // logic as for expression-position macro invocations. fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander) - -> SmallVector<Gc<ast::Item>> { + -> SmallVector<Gc<ast::Item>> +{ let (pth, tts) = match it.node { ItemMac(codemap::Spanned { node: MacInvocTT(ref pth, ref tts, _), @@ -372,86 +381,93 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander) let extname = pth.segments.get(0).identifier; let extnamestr = token::get_ident(extname); let fm = fresh_mark(); - let expanded = match fld.cx.syntax_env.find(&extname.name) { - None => { - fld.cx.span_err(pth.span, - format!("macro undefined: '{}!'", - extnamestr).as_slice()); - // let compilation continue - return SmallVector::zero(); - } + let def_or_items = { + let expanded = match fld.cx.syntax_env.find(&extname.name) { + None => { + fld.cx.span_err(pth.span, + format!("macro undefined: '{}!'", + extnamestr).as_slice()); + // let compilation continue + return SmallVector::zero(); + } - Some(rc) => match *rc { - NormalTT(ref expander, span) => { - if it.ident.name != parse::token::special_idents::invalid.name { - fld.cx - .span_err(pth.span, - format!("macro {}! expects no ident argument, \ + Some(rc) => match *rc { + NormalTT(ref expander, span) => { + if it.ident.name != parse::token::special_idents::invalid.name { + fld.cx + .span_err(pth.span, + format!("macro {}! expects no ident argument, \ given '{}'", - extnamestr, - token::get_ident(it.ident)).as_slice()); - return SmallVector::zero(); + extnamestr, + token::get_ident(it.ident)).as_slice()); + return SmallVector::zero(); + } + fld.cx.bt_push(ExpnInfo { + call_site: it.span, + callee: NameAndSpan { + name: extnamestr.get().to_string(), + format: MacroBang, + span: span + } + }); + // mark before expansion: + let marked_before = mark_tts(tts.as_slice(), fm); + expander.expand(fld.cx, it.span, marked_before.as_slice()) } - fld.cx.bt_push(ExpnInfo { - call_site: it.span, - callee: NameAndSpan { - name: extnamestr.get().to_string(), - format: MacroBang, - span: span + IdentTT(ref expander, span) => { + if it.ident.name == parse::token::special_idents::invalid.name { + fld.cx.span_err(pth.span, + format!("macro {}! expects an ident argument", + extnamestr.get()).as_slice()); + return SmallVector::zero(); } - }); - // mark before expansion: - let marked_before = mark_tts(tts.as_slice(), fm); - expander.expand(fld.cx, it.span, marked_before.as_slice()) - } - IdentTT(ref expander, span) => { - if it.ident.name == parse::token::special_idents::invalid.name { - fld.cx.span_err(pth.span, - format!("macro {}! expects an ident argument", - extnamestr.get()).as_slice()); - return SmallVector::zero(); + fld.cx.bt_push(ExpnInfo { + call_site: it.span, + callee: NameAndSpan { + name: extnamestr.get().to_string(), + format: MacroBang, + span: span + } + }); + // mark before expansion: + let marked_tts = mark_tts(tts.as_slice(), fm); + expander.expand(fld.cx, it.span, it.ident, marked_tts) } - fld.cx.bt_push(ExpnInfo { - call_site: it.span, - callee: NameAndSpan { - name: extnamestr.get().to_string(), - format: MacroBang, - span: span + LetSyntaxTT(ref expander, span) => { + if it.ident.name == parse::token::special_idents::invalid.name { + fld.cx.span_err(pth.span, + format!("macro {}! expects an ident argument", + extnamestr.get()).as_slice()); + return SmallVector::zero(); } - }); - // mark before expansion: - let marked_tts = mark_tts(tts.as_slice(), fm); - expander.expand(fld.cx, it.span, it.ident, marked_tts) - } - LetSyntaxTT(ref expander, span) => { - if it.ident.name == parse::token::special_idents::invalid.name { - fld.cx.span_err(pth.span, - format!("macro {}! expects an ident argument", + fld.cx.bt_push(ExpnInfo { + call_site: it.span, + callee: NameAndSpan { + name: extnamestr.get().to_string(), + format: MacroBang, + span: span + } + }); + // DON'T mark before expansion: + expander.expand(fld.cx, it.span, it.ident, tts) + } + _ => { + fld.cx.span_err(it.span, + format!("{}! is not legal in item position", extnamestr.get()).as_slice()); return SmallVector::zero(); } - fld.cx.bt_push(ExpnInfo { - call_site: it.span, - callee: NameAndSpan { - name: extnamestr.get().to_string(), - format: MacroBang, - span: span - } - }); - // DON'T mark before expansion: - expander.expand(fld.cx, it.span, it.ident, tts) - } - _ => { - fld.cx.span_err(it.span, - format!("{}! is not legal in item position", - extnamestr.get()).as_slice()); - return SmallVector::zero(); } + }; + + match expanded.make_def() { + Some(def) => Left(def), + None => Right(expanded.make_items()) } }; - let items = match expanded.make_def() { - Some(MacroDef { name, ext }) => { + let items = match def_or_items { + Left(MacroDef { name, ext }) => { // hidden invariant: this should only be possible as the // result of expanding a LetSyntaxTT, and thus doesn't // need to be marked. Not that it could be marked anyway. @@ -462,23 +478,20 @@ fn expand_item_mac(it: Gc<ast::Item>, fld: &mut MacroExpander) } SmallVector::zero() } - None => { - match expanded.make_items() { - Some(items) => { - items.move_iter() - .map(|i| mark_item(i, fm)) - .flat_map(|i| fld.fold_item(i).move_iter()) - .collect() - } - None => { - fld.cx.span_err(pth.span, - format!("non-item macro in item position: {}", - extnamestr.get()).as_slice()); - return SmallVector::zero(); - } - } + Right(Some(items)) => { + items.move_iter() + .map(|i| mark_item(i, fm)) + .flat_map(|i| fld.fold_item(i).move_iter()) + .collect() + } + Right(None) => { + fld.cx.span_err(pth.span, + format!("non-item macro in item position: {}", + extnamestr.get()).as_slice()); + return SmallVector::zero(); } }; + fld.cx.bt_pop(); return items; } @@ -901,7 +914,7 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Blo } /// A tree-folder that performs macro expansion -pub struct MacroExpander<'a, 'b> { +pub struct MacroExpander<'a, 'b:'a> { pub cx: &'a mut ExtCtxt<'b>, } diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 4185458bfbe..5352cfaf749 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -19,7 +19,7 @@ use ext::build::AstBuilder; pub fn expand_syntax_ext(ecx: &mut base::ExtCtxt, sp: Span, _tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { ecx.span_err(sp, "`fmt!` is deprecated, use `format!` instead"); ecx.parse_sess.span_diagnostic.span_note(sp, "see http://doc.rust-lang.org/std/fmt/ \ diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 124e9e95942..0994abaadc7 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -33,7 +33,7 @@ enum Position { Named(String), } -struct Context<'a, 'b> { +struct Context<'a, 'b:'a> { ecx: &'a mut ExtCtxt<'b>, fmtsp: Span, @@ -668,8 +668,9 @@ impl<'a, 'b> Context<'a, 'b> { } } -pub fn expand_format_args(ecx: &mut ExtCtxt, sp: Span, - tts: &[ast::TokenTree]) -> Box<base::MacResult> { +pub fn expand_format_args<'cx>(ecx: &'cx mut ExtCtxt, sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { match parse_args(ecx, sp, false, tts) { (invocation, Some((efmt, args, order, names))) => { @@ -680,8 +681,8 @@ pub fn expand_format_args(ecx: &mut ExtCtxt, sp: Span, } } -pub fn expand_format_args_method(ecx: &mut ExtCtxt, sp: Span, - tts: &[ast::TokenTree]) -> Box<base::MacResult> { +pub fn expand_format_args_method<'cx>(ecx: &'cx mut ExtCtxt, sp: Span, + tts: &[ast::TokenTree]) -> Box<base::MacResult+'cx> { match parse_args(ecx, sp, true, tts) { (invocation, Some((efmt, args, order, names))) => { diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 1f4d087abd0..8df5746e412 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -15,10 +15,10 @@ use print; use std::rc::Rc; -pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, - sp: codemap::Span, - tt: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_syntax_ext<'cx>(cx: &'cx mut base::ExtCtxt, + sp: codemap::Span, + tt: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { cx.print_backtrace(); println!("{}", print::pprust::tt_to_string(&ast::TTDelim( diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index d7d6c20b475..0c41db7ecd6 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -410,35 +410,36 @@ pub mod rt { } -pub fn expand_quote_tokens(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_quote_tokens<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let (cx_expr, expr) = expand_tts(cx, sp, tts); let expanded = expand_wrapper(cx, sp, cx_expr, expr); base::MacExpr::new(expanded) } -pub fn expand_quote_expr(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) -> Box<base::MacResult> { +pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts); base::MacExpr::new(expanded) } -pub fn expand_quote_item(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes", vec!(), tts); base::MacExpr::new(expanded) } -pub fn expand_quote_pat(cx: &mut ExtCtxt, - sp: Span, - tts: &[ast::TokenTree]) - -> Box<base::MacResult> { +pub fn expand_quote_pat<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[ast::TokenTree]) + -> Box<base::MacResult+'cx> { let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts); base::MacExpr::new(expanded) } @@ -446,7 +447,7 @@ pub fn expand_quote_pat(cx: &mut ExtCtxt, pub fn expand_quote_arm(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts); base::MacExpr::new(expanded) } @@ -454,7 +455,7 @@ pub fn expand_quote_arm(cx: &mut ExtCtxt, pub fn expand_quote_ty(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let e_param_colons = cx.expr_lit(sp, ast::LitBool(false)); let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(e_param_colons), tts); @@ -464,7 +465,7 @@ pub fn expand_quote_ty(cx: &mut ExtCtxt, pub fn expand_quote_method(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let e_param_colons = cx.expr_none(sp); let expanded = expand_parse_call(cx, sp, "parse_method", vec!(e_param_colons), tts); @@ -474,7 +475,7 @@ pub fn expand_quote_method(cx: &mut ExtCtxt, pub fn expand_quote_stmt(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let e_attrs = cx.expr_vec_ng(sp); let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(e_attrs), tts); diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index 703adcbd335..5cc0ec4a122 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -29,7 +29,7 @@ use std::rc::Rc; /// line!(): expands to the current line number pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "line!"); let topmost = topmost_expn_info(cx.backtrace().unwrap()); @@ -40,7 +40,7 @@ pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) /* col!(): expands to the current column number */ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "col!"); let topmost = topmost_expn_info(cx.backtrace().unwrap()); @@ -52,7 +52,7 @@ pub fn expand_col(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) /// The filemap (`loc.file`) contains a bunch more information we could spit /// out if we wanted. pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "file!"); let topmost = topmost_expn_info(cx.backtrace().unwrap()); @@ -62,14 +62,14 @@ pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let s = pprust::tts_to_string(tts); base::MacExpr::new(cx.expr_str(sp, token::intern_and_get_ident(s.as_slice()))) } pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { base::check_zero_tts(cx, sp, tts, "module_path!"); let string = cx.mod_path() .iter() @@ -85,7 +85,7 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) /// This is generally a bad idea because it's going to behave /// unhygienically. pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let file = match get_single_str_from_tts(cx, sp, tts, "include!") { Some(f) => f, None => return DummyResult::expr(sp), @@ -105,7 +105,7 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) // include_str! : read the given file, insert it as a literal string expr pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") { Some(f) => f, None => return DummyResult::expr(sp) @@ -141,7 +141,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { let file = match get_single_str_from_tts(cx, sp, tts, "include_bin!") { Some(f) => f, None => return DummyResult::expr(sp) diff --git a/src/libsyntax/ext/trace_macros.rs b/src/libsyntax/ext/trace_macros.rs index 77324632664..1f50eb933bb 100644 --- a/src/libsyntax/ext/trace_macros.rs +++ b/src/libsyntax/ext/trace_macros.rs @@ -18,7 +18,7 @@ use parse::token::{keywords, is_keyword}; pub fn expand_trace_macros(cx: &mut ExtCtxt, sp: Span, tt: &[ast::TokenTree]) - -> Box<base::MacResult> { + -> Box<base::MacResult+'static> { match tt { [ast::TTTok(_, ref tok)] if is_keyword(keywords::True, tok) => { cx.set_trace_macros(true); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 1eb37abb781..d8f0eb32ad7 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -14,7 +14,6 @@ use ast; use codemap::{Span, Spanned, DUMMY_SP}; use ext::base::{ExtCtxt, MacResult, MacroDef}; use ext::base::{NormalTT, TTMacroExpander}; -use ext::base; use ext::tt::macro_parser::{Success, Error, Failure}; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; use ext::tt::macro_parser::{parse, parse_or_else}; @@ -113,11 +112,11 @@ struct MacroRulesMacroExpander { } impl TTMacroExpander for MacroRulesMacroExpander { - fn expand(&self, - cx: &mut ExtCtxt, - sp: Span, - arg: &[ast::TokenTree]) - -> Box<MacResult> { + fn expand<'cx>(&self, + cx: &'cx mut ExtCtxt, + sp: Span, + arg: &[ast::TokenTree]) + -> Box<MacResult+'cx> { generic_extension(cx, sp, self.name, @@ -137,13 +136,13 @@ impl MacResult for MacroRulesDefiner { } /// Given `lhses` and `rhses`, this is the new macro we create -fn generic_extension(cx: &ExtCtxt, - sp: Span, - name: Ident, - arg: &[ast::TokenTree], - lhses: &[Rc<NamedMatch>], - rhses: &[Rc<NamedMatch>]) - -> Box<MacResult> { +fn generic_extension<'cx>(cx: &'cx ExtCtxt, + sp: Span, + name: Ident, + arg: &[ast::TokenTree], + lhses: &[Rc<NamedMatch>], + rhses: &[Rc<NamedMatch>]) + -> Box<MacResult+'cx> { if cx.trace_macros() { println!("{}! {} {} {}", token::get_ident(name), @@ -195,7 +194,7 @@ fn generic_extension(cx: &ExtCtxt, // Weird, but useful for X-macros. return box ParserAnyMacro { parser: RefCell::new(p), - } as Box<MacResult> + } as Box<MacResult+'cx> } Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo { best_fail_spot = sp; @@ -213,11 +212,11 @@ fn generic_extension(cx: &ExtCtxt, /// This procedure performs the expansion of the /// macro_rules! macro. It parses the RHS and adds /// an extension to the current context. -pub fn add_new_extension(cx: &mut ExtCtxt, - sp: Span, - name: Ident, - arg: Vec<ast::TokenTree> ) - -> Box<base::MacResult> { +pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt, + sp: Span, + name: Ident, + arg: Vec<ast::TokenTree> ) + -> Box<MacResult+'cx> { // these spans won't matter, anyways fn ms(m: Matcher_) -> Matcher { Spanned { @@ -274,5 +273,5 @@ pub fn add_new_extension(cx: &mut ExtCtxt, name: token::get_ident(name).to_string(), ext: NormalTT(exp, Some(sp)) })) - } as Box<MacResult> + } as Box<MacResult+'cx> } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 4a0787aeb9e..be1c0d96711 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -227,15 +227,20 @@ pub trait Folder { noop_fold_variant_arg(va, self) } - fn fold_ty_param_bound(&mut self, tpb: &TyParamBound) -> TyParamBound { - noop_fold_ty_param_bound(tpb, self) - } - fn fold_opt_bounds(&mut self, b: &Option<OwnedSlice<TyParamBound>>) -> Option<OwnedSlice<TyParamBound>> { noop_fold_opt_bounds(b, self) } + fn fold_bounds(&mut self, b: &OwnedSlice<TyParamBound>) + -> OwnedSlice<TyParamBound> { + noop_fold_bounds(b, self) + } + + fn fold_ty_param_bound(&mut self, tpb: &TyParamBound) -> TyParamBound { + noop_fold_ty_param_bound(tpb, self) + } + fn fold_mt(&mut self, mt: &MutTy) -> MutTy { noop_fold_mt(mt, self) } @@ -349,20 +354,20 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { TyRptr(ref region, ref mt) => { TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) } - TyClosure(ref f, ref region) => { + TyClosure(ref f) => { TyClosure(box(GC) ClosureTy { fn_style: f.fn_style, onceness: f.onceness, - bounds: fld.fold_opt_bounds(&f.bounds), + bounds: fld.fold_bounds(&f.bounds), decl: fld.fold_fn_decl(&*f.decl), lifetimes: fld.fold_lifetime_defs(f.lifetimes.as_slice()), - }, fld.fold_opt_lifetime(region)) + }) } TyProc(ref f) => { TyProc(box(GC) ClosureTy { fn_style: f.fn_style, onceness: f.onceness, - bounds: fld.fold_opt_bounds(&f.bounds), + bounds: fld.fold_bounds(&f.bounds), decl: fld.fold_fn_decl(&*f.decl), lifetimes: fld.fold_lifetime_defs(f.lifetimes.as_slice()), }) @@ -648,14 +653,13 @@ pub fn noop_fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T) -> TyParamBound { match *tpb { TraitTyParamBound(ref ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), - StaticRegionTyParamBound => StaticRegionTyParamBound, + RegionTyParamBound(ref lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), UnboxedFnTyParamBound(ref unboxed_function_type) => { UnboxedFnTyParamBound(UnboxedFnTy { decl: fld.fold_fn_decl(&*unboxed_function_type.decl), kind: unboxed_function_type.kind, }) } - OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s) } } @@ -664,7 +668,7 @@ pub fn noop_fold_ty_param<T: Folder>(tp: &TyParam, fld: &mut T) -> TyParam { TyParam { ident: tp.ident, id: id, - bounds: tp.bounds.map(|x| fld.fold_ty_param_bound(x)), + bounds: fld.fold_bounds(&tp.bounds), unbound: tp.unbound.as_ref().map(|x| fld.fold_ty_param_bound(x)), default: tp.default.map(|x| fld.fold_ty(x)), span: tp.span @@ -792,11 +796,12 @@ pub fn noop_fold_mt<T: Folder>(mt: &MutTy, folder: &mut T) -> MutTy { pub fn noop_fold_opt_bounds<T: Folder>(b: &Option<OwnedSlice<TyParamBound>>, folder: &mut T) -> Option<OwnedSlice<TyParamBound>> { - b.as_ref().map(|bounds| { - bounds.map(|bound| { - folder.fold_ty_param_bound(bound) - }) - }) + b.as_ref().map(|bounds| folder.fold_bounds(bounds)) +} + +fn noop_fold_bounds<T: Folder>(bounds: &TyParamBounds, folder: &mut T) + -> TyParamBounds { + bounds.map(|bound| folder.fold_ty_param_bound(bound)) } pub fn noop_fold_variant_arg<T: Folder>(va: &VariantArg, folder: &mut T) -> VariantArg { @@ -889,7 +894,8 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ }).collect() ) } - ItemTrait(ref generics, ref unbound, ref traits, ref methods) => { + ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => { + let bounds = folder.fold_bounds(bounds); let methods = methods.iter().flat_map(|method| { let r = match *method { RequiredMethod(ref m) => { @@ -911,7 +917,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: &Item_, folder: &mut T) -> Item_ }).collect(); ItemTrait(folder.fold_generics(generics), unbound.clone(), - traits.iter().map(|p| folder.fold_trait_ref(p)).collect(), + bounds, methods) } ItemMac(ref m) => ItemMac(folder.fold_mac(m)), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 291c876082f..9bbd6b2a36e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -25,6 +25,7 @@ #![feature(macro_rules, globs, managed_boxes, default_type_params, phase)] #![feature(quote, struct_variant, unsafe_destructor, import_shadowing)] +#![feature(issue_5723_bootstrap)] #![allow(deprecated)] // NOTE(stage0, pcwalton): Remove after snapshot. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 816700681cf..37bda15ac2c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -12,7 +12,7 @@ use abi; use ast::{BareFnTy, ClosureTy}; -use ast::{StaticRegionTyParamBound, OtherRegionTyParamBound, TraitTyParamBound}; +use ast::{RegionTyParamBound, TraitTyParamBound}; use ast::{ProvidedMethod, Public, FnStyle}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, Block}; @@ -70,7 +70,7 @@ use parse; use parse::attr::ParserAttr; use parse::classify; use parse::common::{SeqSep, seq_sep_none}; -use parse::common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed}; +use parse::common::{seq_sep_trailing_allowed}; use parse::lexer::Reader; use parse::lexer::TokenAndSpan; use parse::obsolete::*; @@ -120,7 +120,7 @@ pub enum PathParsingMode { /// A path paired with optional type bounds. pub struct PathAndBounds { pub path: ast::Path, - pub bounds: Option<OwnedSlice<TyParamBound>>, + pub bounds: Option<ast::TyParamBounds>, } enum ItemOrViewItem { @@ -309,7 +309,7 @@ pub struct Parser<'a> { pub tokens_consumed: uint, pub restriction: restriction, pub quote_depth: uint, // not (yet) related to the quasiquoter - pub reader: Box<Reader>, + pub reader: Box<Reader+'a>, pub interner: Rc<token::IdentInterner>, /// The set of seen errors about obsolete syntax. Used to suppress /// extra detail when the same error is seen twice @@ -346,8 +346,11 @@ fn real_token(rdr: &mut Reader) -> TokenAndSpan { } impl<'a> Parser<'a> { - pub fn new(sess: &'a ParseSess, cfg: ast::CrateConfig, - mut rdr: Box<Reader>) -> Parser<'a> { + pub fn new(sess: &'a ParseSess, + cfg: ast::CrateConfig, + mut rdr: Box<Reader+'a>) + -> Parser<'a> + { let tok0 = real_token(rdr); let span = tok0.sp; let placeholder = TokenAndSpan { @@ -1073,14 +1076,7 @@ impl<'a> Parser<'a> { }; let (inputs, variadic) = self.parse_fn_args(false, false); - let bounds = { - if self.eat(&token::COLON) { - let (_, bounds) = self.parse_ty_param_bounds(false); - Some(bounds) - } else { - None - } - }; + let bounds = self.parse_colon_then_ty_param_bounds(); let (ret_style, ret_ty) = self.parse_ret_ty(); let decl = P(FnDecl { inputs: inputs, @@ -1168,14 +1164,7 @@ impl<'a> Parser<'a> { (optional_unboxed_closure_kind, inputs) }; - let (region, bounds) = { - if self.eat(&token::COLON) { - let (region, bounds) = self.parse_ty_param_bounds(true); - (region, Some(bounds)) - } else { - (None, None) - } - }; + let bounds = self.parse_colon_then_ty_param_bounds(); let (return_style, output) = self.parse_ret_ty(); let decl = P(FnDecl { @@ -1199,7 +1188,7 @@ impl<'a> Parser<'a> { bounds: bounds, decl: decl, lifetimes: lifetime_defs, - }, region) + }) } } } @@ -1687,7 +1676,7 @@ impl<'a> Parser<'a> { Some(INTERPOLATED(token::NtPath(box path))) => { return PathAndBounds { path: path, - bounds: None, + bounds: None } } _ => {} @@ -1744,25 +1733,31 @@ impl<'a> Parser<'a> { } } - // Next, parse a plus and bounded type parameters, if applicable. - let bounds = if mode == LifetimeAndTypesAndBounds { - let bounds = { - if self.eat(&token::BINOP(token::PLUS)) { - let (_, bounds) = self.parse_ty_param_bounds(false); - if bounds.len() == 0 { - let last_span = self.last_span; - self.span_err(last_span, - "at least one type parameter bound \ - must be specified after the `+`"); - } - Some(bounds) - } else { - None + // Next, parse a plus and bounded type parameters, if + // applicable. We need to remember whether the separate was + // present for later, because in some contexts it's a parse + // error. + let opt_bounds = { + if mode == LifetimeAndTypesAndBounds && + self.eat(&token::BINOP(token::PLUS)) + { + let bounds = self.parse_ty_param_bounds(); + + // For some reason that I do not fully understand, we + // do not permit an empty list in the case where it is + // introduced by a `+`, but we do for `:` and other + // separators. -nmatsakis + if bounds.len() == 0 { + let last_span = self.last_span; + self.span_err(last_span, + "at least one type parameter bound \ + must be specified"); } - }; - bounds - } else { - None + + Some(bounds) + } else { + None + } }; // Assemble the span. @@ -1775,7 +1770,7 @@ impl<'a> Parser<'a> { global: is_global, segments: segments, }, - bounds: bounds, + bounds: opt_bounds, } } @@ -3604,45 +3599,34 @@ impl<'a> Parser<'a> { } } - /// matches optbounds = ( ( : ( boundseq )? )? ) - /// where boundseq = ( bound + boundseq ) | bound - /// and bound = 'static | ty - /// Returns "None" if there's no colon (e.g. "T"); - /// Returns "Some(Empty)" if there's a colon but nothing after (e.g. "T:") - /// Returns "Some(stuff)" otherwise (e.g. "T:stuff"). - /// NB: The None/Some distinction is important for issue #7264. - /// - /// Note that the `allow_any_lifetime` argument is a hack for now while the - /// AST doesn't support arbitrary lifetimes in bounds on type parameters. In - /// the future, this flag should be removed, and the return value of this - /// function should be Option<~[TyParamBound]> - fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool) - -> (Option<ast::Lifetime>, - OwnedSlice<TyParamBound>) { - let mut ret_lifetime = None; + // Parses a sequence of bounds if a `:` is found, + // otherwise returns empty list. + fn parse_colon_then_ty_param_bounds(&mut self) + -> OwnedSlice<TyParamBound> + { + if !self.eat(&token::COLON) { + OwnedSlice::empty() + } else { + self.parse_ty_param_bounds() + } + } + + // matches bounds = ( boundseq )? + // where boundseq = ( bound + boundseq ) | bound + // and bound = 'region | ty + // NB: The None/Some distinction is important for issue #7264. + fn parse_ty_param_bounds(&mut self) + -> OwnedSlice<TyParamBound> + { let mut result = vec!(); loop { match self.token { token::LIFETIME(lifetime) => { - let lifetime_interned_string = token::get_ident(lifetime); - if lifetime_interned_string.equiv(&("'static")) { - result.push(StaticRegionTyParamBound); - if allow_any_lifetime && ret_lifetime.is_none() { - ret_lifetime = Some(ast::Lifetime { - id: ast::DUMMY_NODE_ID, - span: self.span, - name: lifetime.name - }); - } - } else if allow_any_lifetime && ret_lifetime.is_none() { - ret_lifetime = Some(ast::Lifetime { - id: ast::DUMMY_NODE_ID, - span: self.span, - name: lifetime.name - }); - } else { - result.push(OtherRegionTyParamBound(self.span)); - } + result.push(RegionTyParamBound(ast::Lifetime { + id: ast::DUMMY_NODE_ID, + span: self.span, + name: lifetime.name + })); self.bump(); } token::MOD_SEP | token::IDENT(..) => { @@ -3662,7 +3646,7 @@ impl<'a> Parser<'a> { } } - return (ret_lifetime, OwnedSlice::from_vec(result)); + return OwnedSlice::from_vec(result); } fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef { @@ -3699,16 +3683,7 @@ impl<'a> Parser<'a> { ident = self.parse_ident(); } - let opt_bounds = { - if self.eat(&token::COLON) { - let (_, bounds) = self.parse_ty_param_bounds(false); - Some(bounds) - } else { - None - } - }; - // For typarams we don't care about the difference b/w "<T>" and "<T:>". - let bounds = opt_bounds.unwrap_or_default(); + let bounds = self.parse_colon_then_ty_param_bounds(); let default = if self.token == token::EQ { self.bump(); @@ -3797,7 +3772,7 @@ impl<'a> Parser<'a> { }; self.expect(&token::COLON); - let (_, bounds) = self.parse_ty_param_bounds(false); + let bounds = self.parse_ty_param_bounds(); let hi = self.span.hi; let span = mk_sp(lo, hi); @@ -4273,19 +4248,13 @@ impl<'a> Parser<'a> { let mut tps = self.parse_generics(); let sized = self.parse_for_sized(); - // Parse traits, if necessary. - let traits; - if self.token == token::COLON { - self.bump(); - traits = self.parse_trait_ref_list(&token::LBRACE); - } else { - traits = Vec::new(); - } + // Parse supertrait bounds. + let bounds = self.parse_colon_then_ty_param_bounds(); self.parse_where_clause(&mut tps); let meths = self.parse_trait_methods(); - (ident, ItemTrait(tps, sized, traits, meths), None) + (ident, ItemTrait(tps, sized, bounds, meths), None) } fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) { @@ -4319,12 +4288,10 @@ impl<'a> Parser<'a> { // New-style trait. Reinterpret the type as a trait. let opt_trait_ref = match ty.node { TyPath(ref path, None, node_id) => { - Some(TraitRef { - path: /* bad */ (*path).clone(), - ref_id: node_id - }) + Some(TraitRef { path: (*path).clone(), + ref_id: node_id }) } - TyPath(..) => { + TyPath(_, Some(_), _) => { self.span_err(ty.span, "bounded traits are only valid in type position"); None @@ -4359,15 +4326,6 @@ impl<'a> Parser<'a> { } } - /// Parse B + C<String,int> + D - fn parse_trait_ref_list(&mut self, ket: &token::Token) -> Vec<TraitRef> { - self.parse_seq_to_before_end( - ket, - seq_sep_trailing_disallowed(token::BINOP(token::PLUS)), - |p| p.parse_trait_ref() - ) - } - /// Parse struct Foo { ... } fn parse_item_struct(&mut self, is_virtual: bool) -> ItemInfo { let class_name = self.parse_ident(); diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index f28e6829b00..70da4e11961 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -155,7 +155,7 @@ pub struct PrintStackElem { static SIZE_INFINITY: int = 0xffff; -pub fn mk_printer(out: Box<io::Writer>, linewidth: uint) -> Printer { +pub fn mk_printer(out: Box<io::Writer+'static>, linewidth: uint) -> Printer { // Yes 3, it makes the ring buffers big enough to never // fall behind. let n: uint = 3 * linewidth; @@ -260,7 +260,7 @@ pub fn mk_printer(out: Box<io::Writer>, linewidth: uint) -> Printer { /// the method called 'pretty_print', and the 'PRINT' process is the method /// called 'print'. pub struct Printer { - pub out: Box<io::Writer>, + pub out: Box<io::Writer+'static>, buf_len: uint, /// Width of lines we're constrained to margin: int, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 41f95fa75f5..da265d81250 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -10,8 +10,8 @@ use abi; use ast::{FnMutUnboxedClosureKind, FnOnceUnboxedClosureKind}; -use ast::{FnUnboxedClosureKind, MethodImplItem, P, OtherRegionTyParamBound}; -use ast::{StaticRegionTyParamBound, TraitTyParamBound, UnboxedClosureKind}; +use ast::{FnUnboxedClosureKind, MethodImplItem, P}; +use ast::{RegionTyParamBound, TraitTyParamBound, UnboxedClosureKind}; use ast::{UnboxedFnTyParamBound, RequiredMethod, ProvidedMethod}; use ast; use ast_util; @@ -60,16 +60,16 @@ pub struct State<'a> { literals: Option<Vec<comments::Literal> >, cur_cmnt_and_lit: CurrentCommentAndLiteral, boxes: Vec<pp::Breaks>, - ann: &'a PpAnn, + ann: &'a PpAnn+'a, encode_idents_with_hygiene: bool, } -pub fn rust_printer(writer: Box<io::Writer>) -> State<'static> { +pub fn rust_printer(writer: Box<io::Writer+'static>) -> State<'static> { static NO_ANN: NoAnn = NoAnn; rust_printer_annotated(writer, &NO_ANN) } -pub fn rust_printer_annotated<'a>(writer: Box<io::Writer>, +pub fn rust_printer_annotated<'a>(writer: Box<io::Writer+'static>, ann: &'a PpAnn) -> State<'a> { State { s: pp::mk_printer(writer, default_columns), @@ -98,7 +98,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap, krate: &ast::Crate, filename: String, input: &mut io::Reader, - out: Box<io::Writer>, + out: Box<io::Writer+'static>, ann: &'a PpAnn, is_expanded: bool) -> IoResult<()> { let mut s = State::new_from_input(cm, @@ -118,7 +118,7 @@ impl<'a> State<'a> { span_diagnostic: &diagnostic::SpanHandler, filename: String, input: &mut io::Reader, - out: Box<io::Writer>, + out: Box<io::Writer+'static>, ann: &'a PpAnn, is_expanded: bool) -> State<'a> { let (cmnts, lits) = comments::gather_comments_and_literals( @@ -138,7 +138,7 @@ impl<'a> State<'a> { } pub fn new(cm: &'a CodeMap, - out: Box<io::Writer>, + out: Box<io::Writer+'static>, ann: &'a PpAnn, comments: Option<Vec<comments::Comment>>, literals: Option<Vec<comments::Literal>>) -> State<'a> { @@ -594,17 +594,16 @@ impl<'a> State<'a> { }; try!(self.print_ty_fn(Some(f.abi), None, - &None, f.fn_style, ast::Many, &*f.decl, None, - &None, + &OwnedSlice::empty(), Some(&generics), None, None)); } - ast::TyClosure(f, ref region) => { + ast::TyClosure(f) => { let generics = ast::Generics { lifetimes: f.lifetimes.clone(), ty_params: OwnedSlice::empty(), @@ -615,7 +614,6 @@ impl<'a> State<'a> { }; try!(self.print_ty_fn(None, Some('&'), - region, f.fn_style, f.onceness, &*f.decl, @@ -636,7 +634,6 @@ impl<'a> State<'a> { }; try!(self.print_ty_fn(None, Some('~'), - &None, f.fn_style, f.onceness, &*f.decl, @@ -649,12 +646,11 @@ impl<'a> State<'a> { ast::TyUnboxedFn(f) => { try!(self.print_ty_fn(None, None, - &None, ast::NormalFn, ast::Many, &*f.decl, None, - &None, + &OwnedSlice::empty(), None, None, Some(f.kind))); @@ -837,7 +833,7 @@ impl<'a> State<'a> { } try!(self.bclose(item.span)); } - ast::ItemTrait(ref generics, ref unbound, ref traits, ref methods) => { + ast::ItemTrait(ref generics, ref unbound, ref bounds, ref methods) => { try!(self.head(visibility_qualified(item.vis, "trait").as_slice())); try!(self.print_ident(item.ident)); @@ -851,16 +847,7 @@ impl<'a> State<'a> { } _ => {} } - if traits.len() != 0u { - try!(word(&mut self.s, ":")); - for (i, trait_) in traits.iter().enumerate() { - try!(self.nbsp()); - if i != 0 { - try!(self.word_space("+")); - } - try!(self.print_path(&trait_.path, false)); - } - } + try!(self.print_bounds(":", bounds)); try!(self.print_where_clause(generics)); try!(word(&mut self.s, " ")); try!(self.bopen()); @@ -1073,12 +1060,11 @@ impl<'a> State<'a> { try!(self.print_outer_attributes(m.attrs.as_slice())); try!(self.print_ty_fn(None, None, - &None, m.fn_style, ast::Many, &*m.decl, Some(m.ident), - &None, + &OwnedSlice::empty(), Some(&m.generics), Some(m.explicit_self.node), None)); @@ -1808,7 +1794,7 @@ impl<'a> State<'a> { match *opt_bounds { None => Ok(()), - Some(ref bounds) => self.print_bounds(&None, bounds, true, true), + Some(ref bounds) => self.print_bounds("+", bounds) } } @@ -2132,30 +2118,12 @@ impl<'a> State<'a> { } pub fn print_bounds(&mut self, - region: &Option<ast::Lifetime>, - bounds: &OwnedSlice<ast::TyParamBound>, - print_colon_anyway: bool, - print_plus_before_bounds: bool) + prefix: &str, + bounds: &OwnedSlice<ast::TyParamBound>) -> IoResult<()> { - let separator = if print_plus_before_bounds { - "+" - } else { - ":" - }; - if !bounds.is_empty() || region.is_some() { - try!(word(&mut self.s, separator)); + if !bounds.is_empty() { + try!(word(&mut self.s, prefix)); let mut first = true; - match *region { - Some(ref lt) => { - let token = token::get_name(lt.name); - if token.get() != "'static" { - try!(self.nbsp()); - first = false; - try!(self.print_lifetime(lt)); - } - } - None => {} - } for bound in bounds.iter() { try!(self.nbsp()); if first { @@ -2165,27 +2133,27 @@ impl<'a> State<'a> { } try!(match *bound { - TraitTyParamBound(ref tref) => self.print_trait_ref(tref), - StaticRegionTyParamBound => word(&mut self.s, "'static"), + TraitTyParamBound(ref tref) => { + self.print_trait_ref(tref) + } + RegionTyParamBound(ref lt) => { + self.print_lifetime(lt) + } UnboxedFnTyParamBound(ref unboxed_function_type) => { self.print_ty_fn(None, None, - &None, ast::NormalFn, ast::Many, &*unboxed_function_type.decl, None, - &None, + &OwnedSlice::empty(), None, None, Some(unboxed_function_type.kind)) } - OtherRegionTyParamBound(_) => Ok(()) }) } Ok(()) - } else if print_colon_anyway { - word(&mut self.s, separator) } else { Ok(()) } @@ -2212,23 +2180,29 @@ impl<'a> State<'a> { Ok(()) } - fn print_type_parameters(&mut self, - lifetimes: &[ast::LifetimeDef], - ty_params: &[ast::TyParam]) - -> IoResult<()> { - let total = lifetimes.len() + ty_params.len(); + pub fn print_generics(&mut self, + generics: &ast::Generics) + -> IoResult<()> + { + let total = generics.lifetimes.len() + generics.ty_params.len(); + if total == 0 { + return Ok(()); + } + + try!(word(&mut self.s, "<")); + let mut ints = Vec::new(); for i in range(0u, total) { ints.push(i); } - self.commasep(Inconsistent, ints.as_slice(), |s, &idx| { - if idx < lifetimes.len() { - let lifetime = &lifetimes[idx]; + try!(self.commasep(Inconsistent, ints.as_slice(), |s, &idx| { + if idx < generics.lifetimes.len() { + let lifetime = generics.lifetimes.get(idx); s.print_lifetime_def(lifetime) } else { - let idx = idx - lifetimes.len(); - let param = &ty_params[idx]; + let idx = idx - generics.lifetimes.len(); + let param = generics.ty_params.get(idx); match param.unbound { Some(TraitTyParamBound(ref tref)) => { try!(s.print_trait_ref(tref)); @@ -2237,10 +2211,7 @@ impl<'a> State<'a> { _ => {} } try!(s.print_ident(param.ident)); - try!(s.print_bounds(&None, - ¶m.bounds, - false, - false)); + try!(s.print_bounds(":", ¶m.bounds)); match param.default { Some(ref default) => { try!(space(&mut s.s)); @@ -2250,19 +2221,10 @@ impl<'a> State<'a> { _ => Ok(()) } } - }) - } + })); - pub fn print_generics(&mut self, generics: &ast::Generics) - -> IoResult<()> { - if generics.lifetimes.len() + generics.ty_params.len() > 0 { - try!(word(&mut self.s, "<")); - try!(self.print_type_parameters(generics.lifetimes.as_slice(), - generics.ty_params.as_slice())); - word(&mut self.s, ">") - } else { - Ok(()) - } + try!(word(&mut self.s, ">")); + Ok(()) } pub fn print_where_clause(&mut self, generics: &ast::Generics) @@ -2283,7 +2245,7 @@ impl<'a> State<'a> { } try!(self.print_ident(predicate.ident)); - try!(self.print_bounds(&None, &predicate.bounds, false, false)); + try!(self.print_bounds(":", &predicate.bounds)); } Ok(()) @@ -2421,12 +2383,11 @@ impl<'a> State<'a> { pub fn print_ty_fn(&mut self, opt_abi: Option<abi::Abi>, opt_sigil: Option<char>, - opt_region: &Option<ast::Lifetime>, fn_style: ast::FnStyle, onceness: ast::Onceness, decl: &ast::FnDecl, id: Option<ast::Ident>, - opt_bounds: &Option<OwnedSlice<ast::TyParamBound>>, + bounds: &OwnedSlice<ast::TyParamBound>, generics: Option<&ast::Generics>, opt_explicit_self: Option<ast::ExplicitSelf_>, opt_unboxed_closure_kind: @@ -2495,9 +2456,7 @@ impl<'a> State<'a> { try!(self.pclose()); } - opt_bounds.as_ref().map(|bounds| { - self.print_bounds(opt_region, bounds, true, false) - }); + try!(self.print_bounds(":", bounds)); try!(self.maybe_print_comment(decl.output.span.lo)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6c6f59f0df6..7a35d82b0e4 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -298,13 +298,9 @@ pub fn walk_item<E: Clone, V: Visitor<E>>(visitor: &mut V, item: &Item, env: E) item.id, env.clone()) } - ItemTrait(ref generics, _, ref trait_paths, ref methods) => { + ItemTrait(ref generics, _, ref bounds, ref methods) => { visitor.visit_generics(generics, env.clone()); - for trait_path in trait_paths.iter() { - visitor.visit_path(&trait_path.path, - trait_path.ref_id, - env.clone()) - } + walk_ty_param_bounds(visitor, bounds, env.clone()); for method in methods.iter() { visitor.visit_trait_item(method, env.clone()) } @@ -375,18 +371,13 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) { visitor.visit_ty(&*tuple_element_type, env.clone()) } } - TyClosure(ref function_declaration, ref region) => { + TyClosure(ref function_declaration) => { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty, env.clone()) } visitor.visit_ty(&*function_declaration.decl.output, env.clone()); - for bounds in function_declaration.bounds.iter() { - walk_ty_param_bounds(visitor, bounds, env.clone()) - } - visitor.visit_opt_lifetime_ref( - typ.span, - region, - env.clone()); + walk_ty_param_bounds(visitor, &function_declaration.bounds, + env.clone()); walk_lifetime_decls(visitor, &function_declaration.lifetimes, env.clone()); } @@ -395,9 +386,8 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) { visitor.visit_ty(&*argument.ty, env.clone()) } visitor.visit_ty(&*function_declaration.decl.output, env.clone()); - for bounds in function_declaration.bounds.iter() { - walk_ty_param_bounds(visitor, bounds, env.clone()) - } + walk_ty_param_bounds(visitor, &function_declaration.bounds, + env.clone()); walk_lifetime_decls(visitor, &function_declaration.lifetimes, env.clone()); } @@ -415,10 +405,13 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) { } visitor.visit_ty(&*function_declaration.decl.output, env.clone()); } - TyPath(ref path, ref bounds, id) => { + TyPath(ref path, ref opt_bounds, id) => { visitor.visit_path(path, id, env.clone()); - for bounds in bounds.iter() { - walk_ty_param_bounds(visitor, bounds, env.clone()) + match *opt_bounds { + Some(ref bounds) => { + walk_ty_param_bounds(visitor, bounds, env.clone()); + } + None => { } } } TyFixedLengthVec(ref ty, ref expression) => { @@ -532,7 +525,6 @@ pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V, TraitTyParamBound(ref typ) => { walk_trait_ref_helper(visitor, typ, env.clone()) } - StaticRegionTyParamBound => {} UnboxedFnTyParamBound(ref function_declaration) => { for argument in function_declaration.decl.inputs.iter() { visitor.visit_ty(&*argument.ty, env.clone()) @@ -540,7 +532,9 @@ pub fn walk_ty_param_bounds<E: Clone, V: Visitor<E>>(visitor: &mut V, visitor.visit_ty(&*function_declaration.decl.output, env.clone()); } - OtherRegionTyParamBound(..) => {} + RegionTyParamBound(ref lifetime) => { + visitor.visit_lifetime_ref(lifetime, env.clone()); + } } } } |
