about summary refs log tree commit diff
path: root/src/libsyntax/diagnostics/plugin.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-28 15:01:39 +0000
committerbors <bors@rust-lang.org>2014-08-28 15:01:39 +0000
commitb5165321e48c1fd8422803fb40693afab7939c8c (patch)
treea3206dbc34acc88311a3ec676155240681784906 /src/libsyntax/diagnostics/plugin.rs
parent0d3bd7720c50e3ada4bac77331d43926493be4fe (diff)
parent1b487a890695e7d6dfbfe5dcd7d4fa0e8ca8003f (diff)
downloadrust-b5165321e48c1fd8422803fb40693afab7939c8c.tar.gz
rust-b5165321e48c1fd8422803fb40693afab7939c8c.zip
auto merge of #16453 : nikomatsakis/rust/type-bounds-3, r=pcwalton
Implements https://github.com/rust-lang/rfcs/pull/192.

In particular:

1. type parameters can have lifetime bounds and objects can close over borrowed values, presuming that they have suitable bounds.
2. objects must have a bound, though it may be derived from the trait itself or from a `Send` bound.
3. all types must be well-formed.
4. type parameters and lifetime parameters may themselves have lifetimes as bounds. Something like `T:'a` means "the type T outlives 'a`" and something like `'a:'b`" means "'a outlives 'b". Outlives here means "all borrowed data has a lifetime at least as long".

This is a [breaking-change]. The most common things you have to fix after this change are:

1. Introduce lifetime bounds onto type parameters if your type (directly or indirectly) contains a reference. Thus a struct like `struct Ref<'a, T> { x: &'a T }` would be changed to `struct Ref<'a, T:'a> { x: &'a T }`.
2. Introduce lifetime bounds onto lifetime parameters if your type contains a double reference. Thus a type like `struct RefWrapper<'a, 'b> { r: &'a Ref<'b, int> }` (where `Ref` is defined as before) would need to be changed to `struct RefWrapper<'a, 'b:'a> { ... }`.
2. Explicitly give object lifetimes in structure definitions. Most commonly, this means changing something like `Box<Reader>` to `Box<Reader+'static>`, so as to indicate that this is a reader without any borrowed data. (Note: you may wish to just change to `Box<Reader+Send>` while you're at it; it's a more restrictive type, technically, but means you can send the reader between threads.)

The intuition for points 1 and 2 is that a reference must never outlive its referent (the thing it points at). Therefore, if you have a type `&'a T`, we must know that `T` (whatever it is) outlives `'a`. And so on.

Closes #5723.
Diffstat (limited to 'src/libsyntax/diagnostics/plugin.rs')
-rw-r--r--src/libsyntax/diagnostics/plugin.rs18
1 files changed, 12 insertions, 6 deletions
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!()