about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-08-27 21:46:52 -0400
committerNiko Matsakis <niko@alum.mit.edu>2014-08-27 21:46:52 -0400
commit1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f (patch)
tree552fabade603ab0d148a49ae3cf1abd3f399740a /src/libsyntax/ext
parent3ee047ae1ffab454270bc1859b3beef3556ef8f9 (diff)
downloadrust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.tar.gz
rust-1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f.zip
Implement generalized object and type parameter bounds (Fixes #16462)
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/asm.rs4
-rw-r--r--src/libsyntax/ext/base.rs70
-rw-r--r--src/libsyntax/ext/bytes.rs6
-rw-r--r--src/libsyntax/ext/cfg.rs6
-rw-r--r--src/libsyntax/ext/concat.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs4
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs6
-rw-r--r--src/libsyntax/ext/env.rs8
-rw-r--r--src/libsyntax/ext/expand.rs191
-rw-r--r--src/libsyntax/ext/fmt.rs2
-rw-r--r--src/libsyntax/ext/format.rs11
-rw-r--r--src/libsyntax/ext/log_syntax.rs8
-rw-r--r--src/libsyntax/ext/quote.rs39
-rw-r--r--src/libsyntax/ext/source_util.rs16
-rw-r--r--src/libsyntax/ext/trace_macros.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs39
16 files changed, 219 insertions, 195 deletions
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>
 }