]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #30641 - tsion:match-range, r=eddyb
authorbors <bors@rust-lang.org>
Thu, 31 Dec 2015 09:40:02 +0000 (09:40 +0000)
committerbors <bors@rust-lang.org>
Thu, 31 Dec 2015 09:40:02 +0000 (09:40 +0000)
The previous version using `PartialOrd::le` was broken since it passed `T` arguments where `&T` was expected.

It makes sense to use primitive comparisons since range patterns can only be used with chars and numeric types.

r? @eddyb

136 files changed:
.gitmodules
src/doc/book/choosing-your-guarantees.md
src/doc/book/documentation.md
src/doc/book/lifetimes.md
src/doc/book/match.md
src/doc/book/references-and-borrowing.md
src/liballoc/arc.rs
src/liballoc/rc.rs
src/libcore/iter.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/dependency_format.rs
src/librustc/middle/entry.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/liveness.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/error_reporting.rs
src/librustc/middle/traits/object_safety.rs
src/librustc/middle/ty/error.rs
src/librustc/middle/ty/mod.rs
src/librustc/session/mod.rs
src/librustc/util/ppaux.rs
src/librustc_borrowck/borrowck/check_loans.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_driver/driver.rs
src/librustc_driver/test.rs
src/librustc_front/lowering.rs
src/librustc_lint/builtin.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/loader.rs
src/librustc_plugin/build.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_trans/back/archive.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/write.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/mir/rvalue.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/fs.rs
src/libstd/io/buffered.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/io/util.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/net/tcp.rs
src/libstd/net/udp.rs
src/libstd/num/f32.rs
src/libstd/num/f64.rs
src/libstd/num/mod.rs
src/libstd/os/raw.rs
src/libstd/rand/os.rs
src/libstd/rand/reader.rs
src/libstd/rt.rs
src/libstd/sync/condvar.rs
src/libstd/sys/common/io.rs
src/libstd/sys/common/remutex.rs
src/libstd/sys/common/wtf8.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/stack_overflow.rs
src/libstd/thread/mod.rs
src/libstd/time/duration.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/attr.rs
src/libsyntax/diagnostics/macros.rs
src/libsyntax/diagnostics/plugin.rs
src/libsyntax/errors/emitter.rs
src/libsyntax/errors/mod.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/quote.rs
src/libsyntax/ext/source_util.rs
src/libsyntax/ext/tt/macro_parser.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/attr.rs
src/libsyntax/parse/lexer/mod.rs
src/libsyntax/parse/lexer/unicode_chars.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/show_span.rs
src/libsyntax/util/parser_testing.rs
src/libsyntax/visit.rs
src/libsyntax_ext/format.rs
src/libsyntax_ext/lib.rs
src/snapshots.txt
src/test/compile-fail/pub-item-macro.rs [deleted file]
src/test/compile-fail/pub-method-macro.rs [deleted file]
src/test/parse-fail/assoc-oddities-3.rs [deleted file]
src/test/parse-fail/pub-item-macro.rs [new file with mode: 0644]
src/test/parse-fail/pub-macro-rules.rs [new file with mode: 0644]
src/test/parse-fail/pub-method-macro.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
src/test/run-pass/assoc-oddities-3.rs [new file with mode: 0644]
src/test/run-pass/issue-28777.rs [new file with mode: 0644]
src/test/run-pass/mir_misc_casts.rs [new file with mode: 0644]

index 83be070b3854a99eeb6848008ef8a3555b3bb908..eb033f5401d3c8a54f41b94e9e46723d44044612 100644 (file)
@@ -13,7 +13,7 @@
        url = https://github.com/rust-lang/jemalloc.git
 [submodule "src/rust-installer"]
        path = src/rust-installer
-       url = https://github.com/rust-lang/rust-installer
+       url = https://github.com/rust-lang/rust-installer.git
 [submodule "src/liblibc"]
        path = src/liblibc
-       url = https://github.com/rust-lang/libc
+       url = https://github.com/rust-lang-nursery/libc.git
index d9e92de8d9abcbf5b21f16166b28e5b49e562a6f..edf5e2ff738187aaeb9302e024b76d95c9b907c1 100644 (file)
@@ -340,11 +340,11 @@ With the former, the `RefCell<T>` is wrapping the `Vec<T>`, so the `Vec<T>` in i
 mutable. At the same time, there can only be one mutable borrow of the whole `Vec` at a given time.
 This means that your code cannot simultaneously work on different elements of the vector from
 different `Rc` handles. However, we are able to push and pop from the `Vec<T>` at will. This is
-similar to an `&mut Vec<T>` with the borrow checking done at runtime.
+similar to a `&mut Vec<T>` with the borrow checking done at runtime.
 
 With the latter, the borrowing is of individual elements, but the overall vector is immutable. Thus,
 we can independently borrow separate elements, but we cannot push or pop from the vector. This is
-similar to an `&mut [T]`[^3], but, again, the borrow checking is at runtime.
+similar to a `&mut [T]`[^3], but, again, the borrow checking is at runtime.
 
 In concurrent programs, we have a similar situation with `Arc<Mutex<T>>`, which provides shared
 mutability and ownership.
index 0d0fd8cf1d0a641e1c4f526be1f79181532e3f58..86c07f9cf6c18673d70361c9a3b067e19b8bcf77 100644 (file)
@@ -73,7 +73,7 @@ hello.rs:4 }
 ```
 
 This [unfortunate error](https://github.com/rust-lang/rust/issues/22547) is
-correct: documentation comments apply to the thing after them, and there's
+correct; documentation comments apply to the thing after them, and there's
 nothing after that last comment.
 
 [rc-new]: https://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new
@@ -385,7 +385,7 @@ error handling. Lets say you want the following,
 
 ```rust,ignore
 /// use std::io;
-/// let mut input = String::new(); 
+/// let mut input = String::new();
 /// try!(io::stdin().read_line(&mut input));
 ```
 
@@ -398,7 +398,7 @@ don't return anything so this will give a mismatched types error.
 /// ```
 /// use std::io;
 /// # fn foo() -> io::Result<()> {
-/// let mut input = String::new(); 
+/// let mut input = String::new();
 /// try!(io::stdin().read_line(&mut input));
 /// # Ok(())
 /// # }
index 68bbd0c98993dad5e3ac960a73cdfb936efb8bfc..2d418786e9a1ecbdced56712107249c77c91a714 100644 (file)
@@ -103,7 +103,7 @@ Then in our parameter list, we use the lifetimes we’ve named:
 ...(x: &'a i32)
 ```
 
-If we wanted an `&mut` reference, we’d do this:
+If we wanted a `&mut` reference, we’d do this:
 
 ```rust,ignore
 ...(x: &'a mut i32)
index 113e218883b34c4b089d02eaf82fd7863f4e1848..acffaf4544b10182466cc619365a42d62015969e 100644 (file)
@@ -23,26 +23,24 @@ match x {
 `match` takes an expression and then branches based on its value. Each â€˜arm’ of
 the branch is of the form `val => expression`. When the value matches, that arm’s
 expression will be evaluated. It’s called `match` because of the term â€˜pattern
-matching’, which `match` is an implementation of. There’s an [entire section on
+matching’, which `match` is an implementation of. There’s a [separate section on
 patterns][patterns] that covers all the patterns that are possible here.
 
 [patterns]: patterns.html
 
-So what’s the big advantage? Well, there are a few. First of all, `match`
-enforces â€˜exhaustiveness checking’. Do you see that last arm, the one with the
-underscore (`_`)? If we remove that arm, Rust will give us an error:
+One of the many advantages of `match` is it enforces â€˜exhaustiveness checking’. 
+For example if we remove the last arm with the underscore `_`, the compiler will 
+give us an error:
 
 ```text
 error: non-exhaustive patterns: `_` not covered
 ```
 
-In other words, Rust is trying to tell us we forgot a value. Because `x` is an
-integer, Rust knows that it can have a number of different values â€“ for
-example, `6`. Without the `_`, however, there is no arm that could match, and
-so Rust refuses to compile the code. `_` acts like a â€˜catch-all arm’. If none
-of the other arms match, the arm with `_` will, and since we have this
-catch-all arm, we now have an arm for every possible value of `x`, and so our
-program will compile successfully.
+Rust is telling us that we forgot a value. The compiler infers from `x` that it
+can have any positive 32bit value; for example 1 to 2,147,483,647. The `_` acts 
+as a 'catch-all', and will catch all possible values that *aren't* specified in 
+an arm of `match`. As you can see with the previous example, we provide `match` 
+arms for integers 1-5, if `x` is 6 or any other value, then it is caught by `_`.
 
 `match` is also an expression, which means we can use it on the right-hand
 side of a `let` binding or directly where an expression is used:
@@ -60,7 +58,8 @@ let number = match x {
 };
 ```
 
-Sometimes it’s a nice way of converting something from one type to another.
+Sometimes it’s a nice way of converting something from one type to another; in 
+this example the integers are converted to `String`.
 
 # Matching on enums
 
@@ -91,7 +90,8 @@ fn process_message(msg: Message) {
 
 Again, the Rust compiler checks exhaustiveness, so it demands that you
 have a match arm for every variant of the enum. If you leave one off, it
-will give you a compile-time error unless you use `_`.
+will give you a compile-time error unless you use `_` or provide all possible 
+arms.
 
 Unlike the previous uses of `match`, you can’t use the normal `if`
 statement to do this. You can use the [`if let`][if-let] statement,
index 546636720ca212d295cb665639a0f68ba6cafd2a..a172390a02126a6a4ffde7c15b72594b0fdc57fd 100644 (file)
@@ -126,7 +126,7 @@ the thing `y` points at. You’ll notice that `x` had to be marked `mut` as well
 If it wasn’t, we couldn’t take a mutable borrow to an immutable value.
 
 You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
-this is because `y` is an `&mut` reference. You'll also need to use them for
+this is because `y` is a `&mut` reference. You'll also need to use them for
 accessing the contents of a reference as well.
 
 Otherwise, `&mut` references are just like references. There _is_ a large
index 755e44899fc86f6e4e204abf72c42535b70bb2b3..1feac7fdf7e07014b9dd390148be5c1d79aa0e79 100644 (file)
@@ -79,6 +79,7 @@
 use core::mem::{align_of_val, size_of_val};
 use core::intrinsics::abort;
 use core::mem;
+use core::mem::uninitialized;
 use core::ops::Deref;
 use core::ops::CoerceUnsized;
 use core::ptr::{self, Shared};
@@ -904,6 +905,35 @@ fn from(t: T) -> Self {
     }
 }
 
+impl<T> Weak<T> {
+    /// Constructs a new `Weak<T>` without an accompanying instance of T.
+    ///
+    /// This allocates memory for T, but does not initialize it. Calling
+    /// Weak<T>::upgrade() on the return value always gives None.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(downgraded_weak)]
+    ///
+    /// use std::sync::Weak;
+    ///
+    /// let empty: Weak<i64> = Weak::new();
+    /// ```
+    #[unstable(feature = "downgraded_weak",
+               reason = "recently added",
+               issue = "30425")]
+    pub fn new() -> Weak<T> {
+        unsafe {
+            Weak { _ptr: Shared::new(Box::into_raw(box ArcInner {
+                strong: atomic::AtomicUsize::new(0),
+                weak: atomic::AtomicUsize::new(1),
+                data: uninitialized(),
+            }))}
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use std::clone::Clone;
@@ -1154,6 +1184,12 @@ fn test_from_owned() {
         let foo_arc = Arc::from(foo);
         assert!(123 == *foo_arc);
     }
+
+    #[test]
+    fn test_new_weak() {
+        let foo: Weak<usize> = Weak::new();
+        assert!(foo.upgrade().is_none());
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 52f035b67bdc98d20752139004aae3b5f4c4b117..ba61a37456ae858bed26f8db466f902de6f55ace 100644 (file)
 use core::intrinsics::{assume, abort};
 use core::marker;
 use core::marker::Unsize;
-use core::mem::{self, align_of_val, size_of_val, forget};
+use core::mem::{self, align_of_val, size_of_val, forget, uninitialized};
 use core::ops::Deref;
 use core::ops::CoerceUnsized;
 use core::ptr::{self, Shared};
@@ -824,6 +824,37 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl<T> Weak<T> {
+    /// Constructs a new `Weak<T>` without an accompanying instance of T.
+    ///
+    /// This allocates memory for T, but does not initialize it. Calling
+    /// Weak<T>::upgrade() on the return value always gives None.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(downgraded_weak)]
+    ///
+    /// use std::rc::Weak;
+    ///
+    /// let empty: Weak<i64> = Weak::new();
+    /// ```
+    #[unstable(feature = "downgraded_weak",
+               reason = "recently added",
+               issue="30425")]
+    pub fn new() -> Weak<T> {
+        unsafe {
+            Weak {
+                _ptr: Shared::new(Box::into_raw(box RcBox {
+                    strong: Cell::new(0),
+                    weak: Cell::new(1),
+                    value: uninitialized(),
+                })),
+            }
+        }
+    }
+}
+
 // NOTE: We checked_add here to deal with mem::forget safety. In particular
 // if you mem::forget Rcs (or Weaks), the ref-count can overflow, and then
 // you can free the allocation while outstanding Rcs (or Weaks) exist.
@@ -1116,6 +1147,12 @@ fn test_from_owned() {
         let foo_rc = Rc::from(foo);
         assert!(123 == *foo_rc);
     }
+
+    #[test]
+    fn test_new_weak() {
+        let foo: Weak<usize> = Weak::new();
+        assert!(foo.upgrade().is_none());
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 526c2e1c6b523c4cb5acdcdf4fb1564fa65ca758..6f052f964c675a67f1995a0a1543fdfbf01b868d 100644 (file)
@@ -1113,16 +1113,22 @@ fn take(self, n: usize) -> Take<Self> where Self: Sized, {
         Take{iter: self, n: n}
     }
 
-    /// An iterator similar to `fold()`, with internal state.
-    ///
-    /// `scan()` accumulates a final value, similar to [`fold()`], but instead
-    /// of passing along an accumulator, it maintains the accumulator internally.
+    /// An iterator adaptor similar to [`fold()`] that holds internal state and
+    /// produces a new iterator.
     ///
     /// [`fold()`]: #method.fold
     ///
-    /// On each iteraton of `scan()`, you can assign to the internal state, and
-    /// a mutable reference to the state is passed as the first argument to the
-    /// closure, allowing you to modify it on each iteration.
+    /// `scan()` takes two arguments: an initial value which seeds the internal
+    /// state, and a closure with two arguments, the first being a mutable
+    /// reference to the internal state and the second an iterator element.
+    /// The closure can assign to the internal state to share state between
+    /// iterations.
+    ///
+    /// On iteration, the closure will be applied to each element of the
+    /// iterator and the return value from the closure, an [`Option`], is
+    /// yielded by the iterator.
+    ///
+    /// [`Option`]: ../option/enum.Option.html
     ///
     /// # Examples
     ///
index db22000fd9f5d1b5080315b0324aa61c2ab04579..464f29a33937f053c0ba9ae191b5b7ddd5667219 100644 (file)
@@ -40,6 +40,7 @@
 use syntax::ast_util::{self, IdVisitingOperation};
 use syntax::attr::{self, AttrMetaMethods};
 use syntax::codemap::Span;
+use syntax::errors::{self, DiagnosticBuilder};
 use syntax::parse::token::InternedString;
 use syntax::ast;
 use syntax::attr::ThinAttributesExt;
@@ -47,7 +48,6 @@
 use rustc_front::util;
 use rustc_front::intravisit as hir_visit;
 use syntax::visit as ast_visit;
-use syntax::errors;
 
 /// Information about the registered lints.
 ///
@@ -363,10 +363,24 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
 /// in trans that run after the main lint pass is finished. Most
 /// lints elsewhere in the compiler should call
 /// `Session::add_lint()` instead.
-pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
-                     lvlsrc: LevelSource, span: Option<Span>, msg: &str) {
+pub fn raw_emit_lint(sess: &Session,
+                     lint: &'static Lint,
+                     lvlsrc: LevelSource,
+                     span: Option<Span>,
+                     msg: &str) {
+    raw_struct_lint(sess, lint, lvlsrc, span, msg).emit();
+}
+
+pub fn raw_struct_lint<'a>(sess: &'a Session,
+                           lint: &'static Lint,
+                           lvlsrc: LevelSource,
+                           span: Option<Span>,
+                           msg: &str)
+                           -> DiagnosticBuilder<'a> {
     let (mut level, source) = lvlsrc;
-    if level == Allow { return }
+    if level == Allow {
+        return sess.diagnostic().struct_dummy();
+    }
 
     let name = lint.name_lower();
     let mut def = None;
@@ -391,17 +405,19 @@ pub fn raw_emit_lint(sess: &Session, lint: &'static Lint,
     // For purposes of printing, we can treat forbid as deny.
     if level == Forbid { level = Deny; }
 
-    match (level, span) {
-        (Warn, Some(sp)) => sess.span_warn(sp, &msg[..]),
-        (Warn, None)     => sess.warn(&msg[..]),
-        (Deny, Some(sp)) => sess.span_err(sp, &msg[..]),
-        (Deny, None)     => sess.err(&msg[..]),
+    let mut err = match (level, span) {
+        (Warn, Some(sp)) => sess.struct_span_warn(sp, &msg[..]),
+        (Warn, None)     => sess.struct_warn(&msg[..]),
+        (Deny, Some(sp)) => sess.struct_span_err(sp, &msg[..]),
+        (Deny, None)     => sess.struct_err(&msg[..]),
         _ => sess.bug("impossible level in raw_emit_lint"),
-    }
+    };
 
     if let Some(span) = def {
-        sess.span_note(span, "lint level defined here");
+        err.span_note(span, "lint level defined here");
     }
+
+    err
 }
 
 pub trait LintContext: Sized {
@@ -418,44 +434,74 @@ fn current_level(&self, lint: &'static Lint) -> Level {
         self.lints().levels.get(&LintId::of(lint)).map_or(Allow, |&(lvl, _)| lvl)
     }
 
-    fn lookup_and_emit(&self, lint: &'static Lint, span: Option<Span>, msg: &str) {
-        let (level, src) = match self.lints().levels.get(&LintId::of(lint)) {
-            None => return,
-            Some(&(Warn, src)) => {
+    fn level_src(&self, lint: &'static Lint) -> Option<LevelSource> {
+        self.lints().levels.get(&LintId::of(lint)).map(|ls| match ls {
+            &(Warn, src) => {
                 let lint_id = LintId::of(builtin::WARNINGS);
                 (self.lints().get_level_source(lint_id).0, src)
             }
-            Some(&pair) => pair,
+            _ => *ls
+        })
+    }
+
+    fn lookup_and_emit(&self, lint: &'static Lint, span: Option<Span>, msg: &str) {
+        let (level, src) = match self.level_src(lint) {
+            None => return,
+            Some(pair) => pair,
         };
 
         raw_emit_lint(&self.sess(), lint, (level, src), span, msg);
     }
 
+    fn lookup(&self,
+              lint: &'static Lint,
+              span: Option<Span>,
+              msg: &str)
+              -> DiagnosticBuilder {
+        let (level, src) = match self.level_src(lint) {
+            None => return self.sess().diagnostic().struct_dummy(),
+            Some(pair) => pair,
+        };
+
+        raw_struct_lint(&self.sess(), lint, (level, src), span, msg)
+    }
+
     /// Emit a lint at the appropriate level, for a particular span.
     fn span_lint(&self, lint: &'static Lint, span: Span, msg: &str) {
         self.lookup_and_emit(lint, Some(span), msg);
     }
 
+    fn struct_span_lint(&self,
+                        lint: &'static Lint,
+                        span: Span,
+                        msg: &str)
+                        -> DiagnosticBuilder {
+        self.lookup(lint, Some(span), msg)
+    }
+
     /// Emit a lint and note at the appropriate level, for a particular span.
     fn span_lint_note(&self, lint: &'static Lint, span: Span, msg: &str,
                       note_span: Span, note: &str) {
-        self.span_lint(lint, span, msg);
+        let mut err = self.lookup(lint, Some(span), msg);
         if self.current_level(lint) != Level::Allow {
             if note_span == span {
-                self.sess().fileline_note(note_span, note)
+                err.fileline_note(note_span, note);
             } else {
-                self.sess().span_note(note_span, note)
+                err.span_note(note_span, note);
             }
         }
+        err.emit();
     }
 
     /// Emit a lint and help at the appropriate level, for a particular span.
     fn span_lint_help(&self, lint: &'static Lint, span: Span,
                       msg: &str, help: &str) {
+        let mut err = self.lookup(lint, Some(span), msg);
         self.span_lint(lint, span, msg);
         if self.current_level(lint) != Level::Allow {
-            self.sess().span_help(span, help)
+            err.span_help(span, help);
         }
+        err.emit();
     }
 
     /// Emit a lint at the appropriate level, with no associated span.
index 23be6117f190f51376c31aee808d994756fd9c93..9c689daab86a797173f102cb47fe8f6ee3e8cebf 100644 (file)
@@ -41,7 +41,7 @@
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                         raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
-                        GatherNodeLevels};
+                        raw_struct_lint, GatherNodeLevels};
 
 /// Specification of a single lint.
 #[derive(Copy, Clone, Debug)]
index d6f05ffd8a513013a6e36ebeb886fcb97492154f..c2acd0e4795c9ae0f51cf34c281a318b34153804 100644 (file)
@@ -224,14 +224,15 @@ fn handle_const_fn_call(&mut self,
                 // this doesn't come from a macro that has #[allow_internal_unstable]
                 !self.tcx.sess.codemap().span_allows_unstable(expr.span)
             {
-                self.tcx.sess.span_err(
+                let mut err = self.tcx.sess.struct_span_err(
                     expr.span,
                     "const fns are an unstable feature");
                 fileline_help!(
-                    self.tcx.sess,
+                    &mut err,
                     expr.span,
                     "in Nightly builds, add `#![feature(const_fn)]` to the crate \
                      attributes to enable");
+                err.emit();
             }
 
             let qualif = self.fn_like(fn_like.kind(),
@@ -714,27 +715,27 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             if !is_const {
                 v.add_qualif(ConstQualif::NOT_CONST);
                 if v.mode != Mode::Var {
-                    fn span_limited_call_error(tcx: &ty::ctxt, span: Span, s: &str) {
-                        span_err!(tcx.sess, span, E0015, "{}", s);
-                    }
-
                     // FIXME(#24111) Remove this check when const fn stabilizes
-                    if let UnstableFeatures::Disallow = v.tcx.sess.opts.unstable_features {
-                        span_limited_call_error(&v.tcx, e.span,
-                                                &format!("function calls in {}s are limited to \
-                                                          struct and enum constructors",
-                                                         v.msg()));
-                        v.tcx.sess.span_note(e.span,
-                                             "a limited form of compile-time function \
-                                              evaluation is available on a nightly \
-                                              compiler via `const fn`");
+                    let (msg, note) =
+                        if let UnstableFeatures::Disallow = v.tcx.sess.opts.unstable_features {
+                        (format!("function calls in {}s are limited to \
+                                  struct and enum constructors",
+                                 v.msg()),
+                         Some("a limited form of compile-time function \
+                               evaluation is available on a nightly \
+                               compiler via `const fn`"))
                     } else {
-                        span_limited_call_error(&v.tcx, e.span,
-                                                &format!("function calls in {}s are limited \
-                                                          to constant functions, \
-                                                          struct and enum constructors",
-                                                         v.msg()));
+                        (format!("function calls in {}s are limited \
+                                  to constant functions, \
+                                  struct and enum constructors",
+                                 v.msg()),
+                         None)
+                    };
+                    let mut err = struct_span_err!(v.tcx.sess, e.span, E0015, "{}", msg);
+                    if let Some(note) = note {
+                        err.span_note(e.span, note);
                     }
+                    err.emit();
                 }
             }
         }
index cab7e45ee62832522f99b664a1d4b3f269967ff7..8439b439d76498c65a2f0f62d6e5ad5d36fabca4 100644 (file)
@@ -215,12 +215,13 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
             if inlined_arms.is_empty() {
                 if !pat_ty.is_empty(cx.tcx) {
                     // We know the type is inhabited, so this must be wrong
-                    span_err!(cx.tcx.sess, ex.span, E0002,
-                              "non-exhaustive patterns: type {} is non-empty",
-                              pat_ty);
-                    span_help!(cx.tcx.sess, ex.span,
+                    let mut err = struct_span_err!(cx.tcx.sess, ex.span, E0002,
+                                                   "non-exhaustive patterns: type {} is non-empty",
+                                                   pat_ty);
+                    span_help!(&mut err, ex.span,
                         "Please ensure that all possible cases are being handled; \
                          possibly adding wildcards or more match arms.");
+                    err.emit();
                 }
                 // If the type *is* empty, it's vacuously exhaustive
                 return;
@@ -251,14 +252,15 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
                                 && variant.kind() == VariantKind::Unit
                         ) {
                             let ty_path = cx.tcx.item_path_str(edef.did);
-                            span_warn!(cx.tcx.sess, p.span, E0170,
+                            let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
                                 "pattern binding `{}` is named the same as one \
                                  of the variants of the type `{}`",
                                 ident.node, ty_path);
-                            fileline_help!(cx.tcx.sess, p.span,
+                            fileline_help!(err, p.span,
                                 "if you meant to match on a variant, \
                                  consider making the path in the pattern qualified: `{}::{}`",
                                 ty_path, ident.node);
+                            err.emit();
                         }
                     }
                 }
@@ -282,13 +284,13 @@ fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
                 Ok(_) => {}
 
                 Err(err) => {
-                    span_err!(cx.tcx.sess, err.span, E0471,
-                              "constant evaluation error: {}",
-                              err.description());
+                    let mut diag = struct_span_err!(cx.tcx.sess, err.span, E0471,
+                                                    "constant evaluation error: {}",
+                                                    err.description());
                     if !p.span.contains(err.span) {
-                        cx.tcx.sess.span_note(p.span,
-                                              "in pattern here")
+                        diag.span_note(p.span, "in pattern here");
                     }
+                    diag.emit();
                 }
             }
         }
@@ -1076,9 +1078,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
         } else if has_guard {
             span_err!(cx.tcx.sess, p.span, E0008, "cannot bind by-move into a pattern guard");
         } else if by_ref_span.is_some() {
-            span_err!(cx.tcx.sess, p.span, E0009,
-                "cannot bind by-move and by-ref in the same pattern");
-            span_note!(cx.tcx.sess, by_ref_span.unwrap(), "by-ref binding occurs here");
+            let mut err = struct_span_err!(cx.tcx.sess, p.span, E0009,
+                                           "cannot bind by-move and by-ref in the same pattern");
+            span_note!(&mut err, by_ref_span.unwrap(), "by-ref binding occurs here");
+            err.emit();
         }
     };
 
index ab5153e1a61d4b86025656e4fb4a856034cd61af..aac6f1edc051da6fe085ebf06848cc85fd2581c0 100644 (file)
@@ -243,10 +243,11 @@ fn add_library(sess: &session::Session,
             // This error is probably a little obscure, but I imagine that it
             // can be refined over time.
             if link2 != link || link == RequireStatic {
-                sess.err(&format!("cannot satisfy dependencies so `{}` only \
-                                   shows up once", sess.cstore.crate_name(cnum)));
-                sess.help("having upstream crates all available in one format \
-                           will likely make this go away");
+                sess.struct_err(&format!("cannot satisfy dependencies so `{}` only \
+                                          shows up once", sess.cstore.crate_name(cnum)))
+                    .help("having upstream crates all available in one format \
+                           will likely make this go away")
+                    .emit();
             }
         }
         None => { m.insert(cnum, link); }
index ecf16aaed836a699c72457bb2781a120fce1e7d1..2d096f66e09f6798e5e9358410bc36322c4fbdbc 100644 (file)
@@ -146,17 +146,20 @@ fn configure_main(this: &mut EntryContext) {
         this.session.entry_type.set(Some(config::EntryMain));
     } else {
         // No main function
-        this.session.err("main function not found");
+        let mut err = this.session.struct_err("main function not found");
         if !this.non_main_fns.is_empty() {
             // There were some functions named 'main' though. Try to give the user a hint.
-            this.session.note("the main function must be defined at the crate level \
-                               but you have one or more functions named 'main' that are not \
-                               defined at the crate level. Either move the definition or \
-                               attach the `#[main]` attribute to override this behavior.");
+            err.note("the main function must be defined at the crate level \
+                      but you have one or more functions named 'main' that are not \
+                      defined at the crate level. Either move the definition or \
+                      attach the `#[main]` attribute to override this behavior.");
             for &(_, span) in &this.non_main_fns {
-                this.session.span_note(span, "here is a function named 'main'");
+                err.span_note(span, "here is a function named 'main'");
             }
+            err.emit();
             this.session.abort_if_errors();
+        } else {
+            err.emit();
         }
     }
 }
index 181e0c0fbc86b895e521de0b8d3633d2d41993c8..d628227d5e63cacad504cbc7c232eb909502c4cb 100644 (file)
 use std::char::from_u32;
 use std::fmt;
 use syntax::ast;
+use syntax::errors::DiagnosticBuilder;
 use syntax::codemap::{self, Pos, Span};
 use syntax::parse::token;
 use syntax::ptr::P;
 
 impl<'tcx> ty::ctxt<'tcx> {
     pub fn note_and_explain_region(&self,
+                                   err: &mut DiagnosticBuilder,
                                    prefix: &str,
                                    region: ty::Region,
                                    suffix: &str) {
@@ -126,7 +128,10 @@ fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
                 };
                 let span = match scope.span(&self.region_maps, &self.map) {
                     Some(s) => s,
-                    None => return self.sess.note(&unknown_scope())
+                    None => {
+                        err.note(&unknown_scope());
+                        return;
+                    }
                 };
                 let tag = match self.map.find(scope.node_id(&self.region_maps)) {
                     Some(ast_map::NodeBlock(_)) => "block",
@@ -142,7 +147,8 @@ fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
                     Some(ast_map::NodeStmt(_)) => "statement",
                     Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
                     Some(_) | None => {
-                        return self.sess.span_note(span, &unknown_scope());
+                        err.span_note(span, &unknown_scope());
+                        return;
                     }
                 };
                 let scope_decorated_tag = match self.region_maps.code_extent_data(scope) {
@@ -214,9 +220,9 @@ fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
         };
         let message = format!("{}{}{}", prefix, description, suffix);
         if let Some(span) = span {
-            self.sess.span_note(span, &message);
+            err.span_note(span, &message);
         } else {
-            self.sess.note(&message);
+            err.note(&message);
         }
     }
 }
@@ -228,9 +234,15 @@ fn report_region_errors(&self,
     fn process_errors(&self, errors: &Vec<RegionResolutionError<'tcx>>)
                       -> Vec<RegionResolutionError<'tcx>>;
 
-    fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &TypeError<'tcx>);
+    fn report_type_error(&self,
+                         trace: TypeTrace<'tcx>,
+                         terr: &TypeError<'tcx>)
+                         -> DiagnosticBuilder<'tcx>;
 
-    fn check_and_note_conflicting_crates(&self, terr: &TypeError<'tcx>, sp: Span);
+    fn check_and_note_conflicting_crates(&self,
+                                         err: &mut DiagnosticBuilder,
+                                         terr: &TypeError<'tcx>,
+                                         sp: Span);
 
     fn report_and_explain_type_error(&self,
                                      trace: TypeTrace<'tcx>,
@@ -265,17 +277,20 @@ fn report_processed_errors(&self,
                                trace_origin: &[(TypeTrace<'tcx>, TypeError<'tcx>)],
                                same_regions: &[SameRegions]);
 
-    fn give_suggestion(&self, same_regions: &[SameRegions]);
+    fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegions]);
 }
 
 trait ErrorReportingHelpers<'tcx> {
     fn report_inference_failure(&self,
-                                var_origin: RegionVariableOrigin);
+                                var_origin: RegionVariableOrigin)
+                                -> DiagnosticBuilder<'tcx>;
 
     fn note_region_origin(&self,
+                          err: &mut DiagnosticBuilder,
                           origin: &SubregionOrigin<'tcx>);
 
     fn give_expl_lifetime_param(&self,
+                                err: &mut DiagnosticBuilder,
                                 decl: &hir::FnDecl,
                                 unsafety: hir::Unsafety,
                                 constness: hir::Constness,
@@ -460,35 +475,47 @@ fn append_to_same_regions(same_regions: &mut Vec<SameRegions>,
         }
     }
 
-    fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &TypeError<'tcx>) {
+    fn report_type_error(&self,
+                         trace: TypeTrace<'tcx>,
+                         terr: &TypeError<'tcx>)
+                         -> DiagnosticBuilder<'tcx> {
         let expected_found_str = match self.values_str(&trace.values) {
             Some(v) => v,
             None => {
-                return; /* derived error */
+                return self.tcx.sess.diagnostic().struct_dummy(); /* derived error */
             }
         };
 
-        span_err!(self.tcx.sess, trace.origin.span(), E0308,
-            "{}: {} ({})",
-                 trace.origin,
-                 expected_found_str,
-                 terr);
+        let mut err = struct_span_err!(self.tcx.sess,
+                                       trace.origin.span(),
+                                       E0308,
+                                       "{}: {} ({})",
+                                       trace.origin,
+                                       expected_found_str,
+                                       terr);
 
-        self.check_and_note_conflicting_crates(terr, trace.origin.span());
+        self.check_and_note_conflicting_crates(&mut err, terr, trace.origin.span());
 
         match trace.origin {
             TypeOrigin::MatchExpressionArm(_, arm_span, source) => match source {
-                hir::MatchSource::IfLetDesugar{..} =>
-                    self.tcx.sess.span_note(arm_span, "`if let` arm with an incompatible type"),
-                _ => self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"),
+                hir::MatchSource::IfLetDesugar{..} => {
+                    err.span_note(arm_span, "`if let` arm with an incompatible type");
+                }
+                _ => {
+                    err.span_note(arm_span, "match arm with an incompatible type");
+                }
             },
             _ => ()
         }
+        err
     }
 
     /// Adds a note if the types come from similarly named crates
-    fn check_and_note_conflicting_crates(&self, terr: &TypeError<'tcx>, sp: Span) {
-        let report_path_match = |did1: DefId, did2: DefId| {
+    fn check_and_note_conflicting_crates(&self,
+                                         err: &mut DiagnosticBuilder,
+                                         terr: &TypeError<'tcx>,
+                                         sp: Span) {
+        let report_path_match = |err: &mut DiagnosticBuilder, did1: DefId, did2: DefId| {
             // Only external crates, if either is from a local
             // module we could have false positives
             if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
@@ -502,9 +529,9 @@ fn check_and_note_conflicting_crates(&self, terr: &TypeError<'tcx>, sp: Span) {
                 // for imported and non-imported crates
                 if exp_path == found_path {
                     let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
-                    self.tcx.sess.span_note(sp, &format!("Perhaps two different versions \
-                                                          of crate `{}` are being used?",
-                                                          crate_name));
+                    err.span_note(sp, &format!("Perhaps two different versions \
+                                                of crate `{}` are being used?",
+                                               crate_name));
                 }
             }
         };
@@ -517,13 +544,13 @@ fn check_and_note_conflicting_crates(&self, terr: &TypeError<'tcx>, sp: Span) {
                     (&ty::TyStruct(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
                     (&ty::TyEnum(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
                     (&ty::TyStruct(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) => {
-                        report_path_match(exp_adt.did, found_adt.did);
+                        report_path_match(err, exp_adt.did, found_adt.did);
                     },
                     _ => ()
                 }
             },
             TypeError::Traits(ref exp_found) => {
-                report_path_match(exp_found.expected, exp_found.found);
+                report_path_match(err, exp_found.expected, exp_found.found);
             },
             _ => () // FIXME(#22750) handle traits and stuff
         }
@@ -533,8 +560,9 @@ fn report_and_explain_type_error(&self,
                                      trace: TypeTrace<'tcx>,
                                      terr: &TypeError<'tcx>) {
         let span = trace.origin.span();
-        self.report_type_error(trace, terr);
-        self.tcx.note_and_explain_type_err(terr, span);
+        let mut err = self.report_type_error(trace, terr);
+        self.tcx.note_and_explain_type_err(&mut err, terr, span);
+        err.emit();
     }
 
     /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
@@ -584,51 +612,56 @@ fn report_generic_bound_failure(&self,
                 format!("the associated type `{}`", p),
         };
 
-        match sub {
+        let mut err = match sub {
             ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
                 // Does the required lifetime have a nice name we can print?
-                span_err!(
-                    self.tcx.sess, origin.span(), E0309,
-                    "{} may not live long enough", labeled_user_string);
-                self.tcx.sess.fileline_help(
-                    origin.span(),
-                    &format!(
-                        "consider adding an explicit lifetime bound `{}: {}`...",
-                        bound_kind,
-                        sub));
+                let mut err = struct_span_err!(self.tcx.sess,
+                                               origin.span(),
+                                               E0309,
+                                               "{} may not live long enough",
+                                               labeled_user_string);
+                err.fileline_help(origin.span(),
+                                  &format!("consider adding an explicit lifetime bound `{}: {}`...",
+                                           bound_kind,
+                                           sub));
+                err
             }
 
             ty::ReStatic => {
                 // Does the required lifetime have a nice name we can print?
-                span_err!(
-                    self.tcx.sess, origin.span(), E0310,
-                    "{} may not live long enough", labeled_user_string);
-                self.tcx.sess.fileline_help(
-                    origin.span(),
-                    &format!(
-                        "consider adding an explicit lifetime bound `{}: 'static`...",
-                        bound_kind));
+                let mut err = struct_span_err!(self.tcx.sess,
+                                               origin.span(),
+                                               E0310,
+                                               "{} may not live long enough",
+                                               labeled_user_string);
+                err.fileline_help(origin.span(),
+                                  &format!("consider adding an explicit lifetime \
+                                            bound `{}: 'static`...",
+                                           bound_kind));
+                err
             }
 
             _ => {
                 // If not, be less specific.
-                span_err!(
-                    self.tcx.sess, origin.span(), E0311,
-                    "{} may not live long enough",
-                    labeled_user_string);
-                self.tcx.sess.fileline_help(
-                    origin.span(),
-                    &format!(
-                        "consider adding an explicit lifetime bound for `{}`",
-                        bound_kind));
+                let mut err = struct_span_err!(self.tcx.sess,
+                                               origin.span(),
+                                               E0311,
+                                               "{} may not live long enough",
+                                               labeled_user_string);
+                err.fileline_help(origin.span(),
+                                  &format!("consider adding an explicit lifetime bound for `{}`",
+                                           bound_kind));
                 self.tcx.note_and_explain_region(
+                    &mut err,
                     &format!("{} must be valid for ", labeled_user_string),
                     sub,
                     "...");
+                err
             }
-        }
+        };
 
-        self.note_region_origin(&origin);
+        self.note_region_origin(&mut err, &origin);
+        err.emit();
     }
 
     fn report_concrete_failure(&self,
@@ -641,239 +674,262 @@ fn report_concrete_failure(&self,
                 self.report_and_explain_type_error(trace, &terr);
             }
             infer::Reborrow(span) => {
-                span_err!(self.tcx.sess, span, E0312,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0312,
                     "lifetime of reference outlines \
                      lifetime of borrowed content...");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "...the reference is valid for ",
                     sub,
                     "...");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "...but the borrowed content is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::ReborrowUpvar(span, ref upvar_id) => {
-                span_err!(self.tcx.sess, span, E0313,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0313,
                     "lifetime of borrowed pointer outlives \
                             lifetime of captured variable `{}`...",
                             self.tcx.local_var_name_str(upvar_id.var_id));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "...the borrowed pointer is valid for ",
                     sub,
                     "...");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     &format!("...but `{}` is only valid for ",
                              self.tcx.local_var_name_str(upvar_id.var_id)),
                     sup,
                     "");
+                err.emit();
             }
             infer::InfStackClosure(span) => {
-                span_err!(self.tcx.sess, span, E0314,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0314,
                     "closure outlives stack frame");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "...the closure must be valid for ",
                     sub,
                     "...");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "...but the closure's stack frame is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::InvokeClosure(span) => {
-                span_err!(self.tcx.sess, span, E0315,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0315,
                     "cannot invoke closure outside of its lifetime");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the closure is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::DerefPointer(span) => {
-                span_err!(self.tcx.sess, span, E0473,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0473,
                           "dereference of reference outside its lifetime");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the reference is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::FreeVariable(span, id) => {
-                span_err!(self.tcx.sess, span, E0474,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0474,
                           "captured variable `{}` does not outlive the enclosing closure",
                           self.tcx.local_var_name_str(id));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "captured variable is valid for ",
                     sup,
                     "");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "closure is valid for ",
                     sub,
                     "");
+                err.emit();
             }
             infer::IndexSlice(span) => {
-                span_err!(self.tcx.sess, span, E0475,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0475,
                           "index of slice outside its lifetime");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the slice is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::RelateObjectBound(span) => {
-                span_err!(self.tcx.sess, span, E0476,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0476,
                           "lifetime of the source pointer does not outlive \
                            lifetime bound of the object type");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "object type is valid for ",
                     sub,
                     "");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "source pointer is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::RelateParamBound(span, ty) => {
-                span_err!(self.tcx.sess, span, E0477,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0477,
                           "the type `{}` does not fulfill the required lifetime",
                           self.ty_to_string(ty));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                                         "type must outlive ",
                                         sub,
                                         "");
+                err.emit();
             }
             infer::RelateRegionParamBound(span) => {
-                span_err!(self.tcx.sess, span, E0478,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0478,
                           "lifetime bound not satisfied");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "lifetime parameter instantiated with ",
                     sup,
                     "");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "but lifetime parameter must outlive ",
                     sub,
                     "");
+                err.emit();
             }
             infer::RelateDefaultParamBound(span, ty) => {
-                span_err!(self.tcx.sess, span, E0479,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0479,
                           "the type `{}` (provided as the value of \
                            a type parameter) is not valid at this point",
                           self.ty_to_string(ty));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                                         "type must outlive ",
                                         sub,
                                         "");
+                err.emit();
             }
             infer::CallRcvr(span) => {
-                span_err!(self.tcx.sess, span, E0480,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0480,
                           "lifetime of method receiver does not outlive \
                            the method call");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the receiver is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::CallArg(span) => {
-                span_err!(self.tcx.sess, span, E0481,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0481,
                           "lifetime of function argument does not outlive \
                            the function call");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the function argument is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::CallReturn(span) => {
-                span_err!(self.tcx.sess, span, E0482,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0482,
                           "lifetime of return value does not outlive \
                            the function call");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the return value is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::Operand(span) => {
-                span_err!(self.tcx.sess, span, E0483,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0483,
                           "lifetime of operand does not outlive \
                            the operation");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the operand is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::AddrOf(span) => {
-                span_err!(self.tcx.sess, span, E0484,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0484,
                           "reference is not valid at the time of borrow");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the borrow is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::AutoBorrow(span) => {
-                span_err!(self.tcx.sess, span, E0485,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0485,
                           "automatically reference is not valid \
                            at the time of borrow");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the automatic borrow is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::ExprTypeIsNotInScope(t, span) => {
-                span_err!(self.tcx.sess, span, E0486,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0486,
                           "type of expression contains references \
                            that are not valid during the expression: `{}`",
                           self.ty_to_string(t));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "type is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::SafeDestructor(span) => {
-                span_err!(self.tcx.sess, span, E0487,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0487,
                           "unsafe use of destructor: destructor might be called \
                            while references are dead");
                 // FIXME (22171): terms "super/subregion" are suboptimal
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "superregion: ",
                     sup,
                     "");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "subregion: ",
                     sub,
                     "");
+                err.emit();
             }
             infer::BindingTypeIsNotValidAtDecl(span) => {
-                span_err!(self.tcx.sess, span, E0488,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0488,
                           "lifetime of variable does not enclose its declaration");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the variable is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
             infer::ParameterInScope(_, span) => {
-                span_err!(self.tcx.sess, span, E0489,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0489,
                           "type/lifetime parameter not in scope here");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the parameter is only valid for ",
                     sub,
                     "");
+                err.emit();
             }
             infer::DataBorrowed(ty, span) => {
-                span_err!(self.tcx.sess, span, E0490,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0490,
                           "a value of type `{}` is borrowed for too long",
                           self.ty_to_string(ty));
-                self.tcx.note_and_explain_region("the type is valid for ", sub, "");
-                self.tcx.note_and_explain_region("but the borrow lasts for ", sup, "");
+                self.tcx.note_and_explain_region(&mut err, "the type is valid for ", sub, "");
+                self.tcx.note_and_explain_region(&mut err, "but the borrow lasts for ", sup, "");
+                err.emit();
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
-                span_err!(self.tcx.sess, span, E0491,
+                let mut err = struct_span_err!(self.tcx.sess, span, E0491,
                           "in type `{}`, reference has a longer lifetime \
                            than the data it references",
                           self.ty_to_string(ty));
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "the pointer is valid for ",
                     sub,
                     "");
-                self.tcx.note_and_explain_region(
+                self.tcx.note_and_explain_region(&mut err,
                     "but the referenced data is only valid for ",
                     sup,
                     "");
+                err.emit();
             }
         }
     }
@@ -884,37 +940,42 @@ fn report_sub_sup_conflict(&self,
                                sub_region: Region,
                                sup_origin: SubregionOrigin<'tcx>,
                                sup_region: Region) {
-        self.report_inference_failure(var_origin);
+        let mut err = self.report_inference_failure(var_origin);
 
-        self.tcx.note_and_explain_region(
+        self.tcx.note_and_explain_region(&mut err,
             "first, the lifetime cannot outlive ",
             sup_region,
             "...");
 
-        self.note_region_origin(&sup_origin);
+        self.note_region_origin(&mut err, &sup_origin);
 
-        self.tcx.note_and_explain_region(
+        self.tcx.note_and_explain_region(&mut err,
             "but, the lifetime must be valid for ",
             sub_region,
             "...");
 
-        self.note_region_origin(&sub_origin);
+        self.note_region_origin(&mut err, &sub_origin);
+        err.emit();
     }
 
     fn report_processed_errors(&self,
                                var_origins: &[RegionVariableOrigin],
                                trace_origins: &[(TypeTrace<'tcx>, TypeError<'tcx>)],
                                same_regions: &[SameRegions]) {
-        for vo in var_origins {
-            self.report_inference_failure(vo.clone());
+        for (i, vo) in var_origins.iter().enumerate() {
+            let mut err = self.report_inference_failure(vo.clone());
+            if i == var_origins.len() - 1 {
+                self.give_suggestion(&mut err, same_regions);
+            }
+            err.emit();
         }
-        self.give_suggestion(same_regions);
+
         for &(ref trace, ref terr) in trace_origins {
             self.report_and_explain_type_error(trace.clone(), terr);
         }
     }
 
-    fn give_suggestion(&self, same_regions: &[SameRegions]) {
+    fn give_suggestion(&self, err: &mut DiagnosticBuilder, same_regions: &[SameRegions]) {
         let scope_id = same_regions[0].scope_id;
         let parent = self.tcx.map.get_parent(scope_id);
         let parent_node = self.tcx.map.find(parent);
@@ -968,7 +1029,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
         let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
                                        generics, same_regions, &life_giver);
         let (fn_decl, expl_self, generics) = rebuilder.rebuild();
-        self.give_expl_lifetime_param(&fn_decl, unsafety, constness, name,
+        self.give_expl_lifetime_param(err, &fn_decl, unsafety, constness, name,
                                       expl_self.as_ref(), &generics, span);
     }
 }
@@ -1520,6 +1581,7 @@ fn rebuild_path(&self,
 
 impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
     fn give_expl_lifetime_param(&self,
+                                err: &mut DiagnosticBuilder,
                                 decl: &hir::FnDecl,
                                 unsafety: hir::Unsafety,
                                 constness: hir::Constness,
@@ -1531,11 +1593,12 @@ fn give_expl_lifetime_param(&self,
                                                  opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
-        self.tcx.sess.span_help(span, &msg[..]);
+        err.span_help(span, &msg[..]);
     }
 
     fn report_inference_failure(&self,
-                                var_origin: RegionVariableOrigin) {
+                                var_origin: RegionVariableOrigin)
+                                -> DiagnosticBuilder<'tcx> {
         let br_string = |br: ty::BoundRegion| {
             let mut s = br.to_string();
             if !s.is_empty() {
@@ -1574,13 +1637,13 @@ fn report_inference_failure(&self,
             }
         };
 
-        span_err!(self.tcx.sess, var_origin.span(), E0495,
+        struct_span_err!(self.tcx.sess, var_origin.span(), E0495,
                   "cannot infer an appropriate lifetime{} \
                    due to conflicting requirements",
-                  var_description);
+                  var_description)
     }
 
-    fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
+    fn note_region_origin(&self, err: &mut DiagnosticBuilder, origin: &SubregionOrigin<'tcx>) {
         match *origin {
             infer::Subtype(ref trace) => {
                 let desc = match trace.origin {
@@ -1622,7 +1685,7 @@ fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
 
                 match self.values_str(&trace.values) {
                     Some(values_str) => {
-                        self.tcx.sess.span_note(
+                        err.span_note(
                             trace.origin.span(),
                             &format!("...so that {} ({})",
                                     desc, values_str));
@@ -1632,130 +1695,130 @@ fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
                         // all, since it is derived, but that would
                         // require more refactoring than I feel like
                         // doing right now. - nmatsakis
-                        self.tcx.sess.span_note(
+                        err.span_note(
                             trace.origin.span(),
                             &format!("...so that {}", desc));
                     }
                 }
             }
             infer::Reborrow(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that reference does not outlive \
                     borrowed content");
             }
             infer::ReborrowUpvar(span, ref upvar_id) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!(
                         "...so that closure can access `{}`",
                         self.tcx.local_var_name_str(upvar_id.var_id)
-                            .to_string()))
+                            .to_string()));
             }
             infer::InfStackClosure(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that closure does not outlive its stack frame");
             }
             infer::InvokeClosure(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that closure is not invoked outside its lifetime");
             }
             infer::DerefPointer(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that pointer is not dereferenced \
                     outside its lifetime");
             }
             infer::FreeVariable(span, id) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so that captured variable `{}` \
                             does not outlive the enclosing closure",
                             self.tcx.local_var_name_str(id)));
             }
             infer::IndexSlice(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that slice is not indexed outside the lifetime");
             }
             infer::RelateObjectBound(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that it can be closed over into an object");
             }
             infer::CallRcvr(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that method receiver is valid for the method call");
             }
             infer::CallArg(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that argument is valid for the call");
             }
             infer::CallReturn(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that return value is valid for the call");
             }
             infer::Operand(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that operand is valid for operation");
             }
             infer::AddrOf(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that reference is valid \
                      at the time of borrow");
             }
             infer::AutoBorrow(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that auto-reference is valid \
                      at the time of borrow");
             }
             infer::ExprTypeIsNotInScope(t, span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so type `{}` of expression is valid during the \
                              expression",
                             self.ty_to_string(t)));
             }
             infer::BindingTypeIsNotValidAtDecl(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that variable is valid at time of its declaration");
             }
             infer::ParameterInScope(_, span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that a type/lifetime parameter is in scope here");
             }
             infer::DataBorrowed(ty, span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so that the type `{}` is not borrowed for too long",
                              self.ty_to_string(ty)));
             }
             infer::ReferenceOutlivesReferent(ty, span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so that the reference type `{}` \
                              does not outlive the data it points at",
                             self.ty_to_string(ty)));
             }
             infer::RelateParamBound(span, t) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so that the type `{}` \
                              will meet its required lifetime bounds",
                             self.ty_to_string(t)));
             }
             infer::RelateDefaultParamBound(span, t) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     &format!("...so that type parameter \
                              instantiated with `{}`, \
@@ -1763,16 +1826,16 @@ fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) {
                             self.ty_to_string(t)));
             }
             infer::RelateRegionParamBound(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that the declared lifetime parameter bounds \
                                 are satisfied");
             }
             infer::SafeDestructor(span) => {
-                self.tcx.sess.span_note(
+                err.span_note(
                     span,
                     "...so that references are valid when the destructor \
-                     runs")
+                     runs");
             }
         }
     }
index d0ffed56635f7e3e183bd4de6a6359dc6bef0ca4..21a1ee37b7f436c1e8fb772e9ad2511263193a76 100644 (file)
@@ -40,6 +40,7 @@
 use syntax::ast;
 use syntax::codemap;
 use syntax::codemap::{Span, DUMMY_SP};
+use syntax::errors::DiagnosticBuilder;
 use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
 
 use self::combine::CombineFields;
@@ -1269,19 +1270,43 @@ pub fn type_error_message_str<M>(&self,
                                      sp: Span,
                                      mk_msg: M,
                                      actual_ty: String,
-                                     err: Option<&TypeError<'tcx>>) where
-        M: FnOnce(Option<String>, String) -> String,
+                                     err: Option<&TypeError<'tcx>>)
+        where M: FnOnce(Option<String>, String) -> String,
     {
         self.type_error_message_str_with_expected(sp, mk_msg, None, actual_ty, err)
     }
 
+    pub fn type_error_struct_str<M>(&self,
+                                    sp: Span,
+                                    mk_msg: M,
+                                    actual_ty: String,
+                                    err: Option<&TypeError<'tcx>>)
+                                    -> DiagnosticBuilder<'tcx>
+        where M: FnOnce(Option<String>, String) -> String,
+    {
+        self.type_error_struct_str_with_expected(sp, mk_msg, None, actual_ty, err)
+    }
+
     pub fn type_error_message_str_with_expected<M>(&self,
                                                    sp: Span,
                                                    mk_msg: M,
                                                    expected_ty: Option<Ty<'tcx>>,
                                                    actual_ty: String,
-                                                   err: Option<&TypeError<'tcx>>) where
-        M: FnOnce(Option<String>, String) -> String,
+                                                   err: Option<&TypeError<'tcx>>)
+        where M: FnOnce(Option<String>, String) -> String,
+    {
+        self.type_error_struct_str_with_expected(sp, mk_msg, expected_ty, actual_ty, err)
+            .emit();
+    }
+
+    pub fn type_error_struct_str_with_expected<M>(&self,
+                                                  sp: Span,
+                                                  mk_msg: M,
+                                                  expected_ty: Option<Ty<'tcx>>,
+                                                  actual_ty: String,
+                                                  err: Option<&TypeError<'tcx>>)
+                                                  -> DiagnosticBuilder<'tcx>
+        where M: FnOnce(Option<String>, String) -> String,
     {
         debug!("hi! expected_ty = {:?}, actual_ty = {}", expected_ty, actual_ty);
 
@@ -1292,13 +1317,16 @@ pub fn type_error_message_str_with_expected<M>(&self,
                 format!(" ({})", t_err)
             });
 
-            self.tcx.sess.span_err(sp, &format!("{}{}",
+            let mut db = self.tcx.sess.struct_span_err(sp, &format!("{}{}",
                 mk_msg(resolved_expected.map(|t| self.ty_to_string(t)), actual_ty),
                 error_str));
 
             if let Some(err) = err {
-                self.tcx.note_and_explain_type_err(err, sp)
+                self.tcx.note_and_explain_type_err(&mut db, err, sp);
             }
+            db
+        } else {
+            self.tcx.sess.diagnostic().struct_dummy()
         }
     }
 
@@ -1306,19 +1334,30 @@ pub fn type_error_message<M>(&self,
                                  sp: Span,
                                  mk_msg: M,
                                  actual_ty: Ty<'tcx>,
-                                 err: Option<&TypeError<'tcx>>) where
-        M: FnOnce(String) -> String,
+                                 err: Option<&TypeError<'tcx>>)
+        where M: FnOnce(String) -> String,
+    {
+        self.type_error_struct(sp, mk_msg, actual_ty, err).emit();
+    }
+
+    pub fn type_error_struct<M>(&self,
+                                sp: Span,
+                                mk_msg: M,
+                                actual_ty: Ty<'tcx>,
+                                err: Option<&TypeError<'tcx>>)
+                                -> DiagnosticBuilder<'tcx>
+        where M: FnOnce(String) -> String,
     {
         let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
 
         // Don't report an error if actual type is TyError.
         if actual_ty.references_error() {
-            return;
+            return self.tcx.sess.diagnostic().struct_dummy();
         }
 
-        self.type_error_message_str(sp,
+        self.type_error_struct_str(sp,
             move |_e, a| { mk_msg(a) },
-            self.ty_to_string(actual_ty), err);
+            self.ty_to_string(actual_ty), err)
     }
 
     pub fn report_mismatched_types(&self,
index 540af4ae001656a807208f63d90a5ac54a0c5657..29299f01ed36fcc2f4a4829a1906e8ef9549c321 100644 (file)
@@ -1500,7 +1500,10 @@ fn check_ret(&self,
                             },
                         _ => false
                     };
-                    span_err!(self.ir.tcx.sess, sp, E0269, "not all control paths return a value");
+                    let mut err = struct_span_err!(self.ir.tcx.sess,
+                                                   sp,
+                                                   E0269,
+                                                   "not all control paths return a value");
                     if ends_with_stmt {
                         let last_stmt = body.stmts.first().unwrap();
                         let original_span = original_sp(self.ir.tcx.sess.codemap(),
@@ -1510,9 +1513,9 @@ fn check_ret(&self,
                             hi: original_span.hi,
                             expn_id: original_span.expn_id
                         };
-                        self.ir.tcx.sess.span_help(
-                            span_semicolon, "consider removing this semicolon:");
+                        err.span_help(span_semicolon, "consider removing this semicolon:");
                     }
+                    err.emit();
                 }
             }
             ty::FnDiverging
index 9b133c5401519f595ff08dbe9a6f86bc99e89ecd..2c74f3a82e41441e39cc501e9436691c96b5a669 100644 (file)
@@ -345,25 +345,25 @@ fn desc(&self) -> &'static str {
     }
 }
 
-fn signal_shadowing_problem(
-    sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) {
-    if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
+fn signal_shadowing_problem(sess: &Session, name: ast::Name, orig: Original, shadower: Shadower) {
+    let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
         // lifetime/lifetime shadowing is an error
-        span_err!(sess, shadower.span, E0496,
-                  "{} name `{}` shadows a \
-                   {} name that is already in scope",
-                  shadower.kind.desc(), name, orig.kind.desc());
+        struct_span_err!(sess, shadower.span, E0496,
+                         "{} name `{}` shadows a \
+                          {} name that is already in scope",
+                         shadower.kind.desc(), name, orig.kind.desc())
     } else {
         // shadowing involving a label is only a warning, due to issues with
         // labels and lifetimes not being macro-hygienic.
-        sess.span_warn(shadower.span,
-                      &format!("{} name `{}` shadows a \
-                                {} name that is already in scope",
-                               shadower.kind.desc(), name, orig.kind.desc()));
-    }
-    sess.span_note(orig.span,
-                   &format!("shadowed {} `{}` declared here",
-                            orig.kind.desc(), name));
+        sess.struct_span_warn(shadower.span,
+                              &format!("{} name `{}` shadows a \
+                                        {} name that is already in scope",
+                                       shadower.kind.desc(), name, orig.kind.desc()))
+    };
+    err.span_note(orig.span,
+                  &format!("shadowed {} `{}` declared here",
+                           orig.kind.desc(), name));
+    err.emit();
 }
 
 // Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
index a41ee51fb5546023991fd29f56b2f53a0b190806..f6af680d441ebc72bffe19053bb28b32685a904f 100644 (file)
@@ -394,17 +394,19 @@ fn check(&mut self, id: DefId, span: Span,
                 // This is an 'unmarked' API, which should not exist
                 // in the standard library.
                 if self.tcx.sess.features.borrow().unmarked_api {
-                    self.tcx.sess.span_warn(span, "use of unmarked library feature");
-                    self.tcx.sess.span_note(span, "this is either a bug in the library you are \
+                    self.tcx.sess.struct_span_warn(span, "use of unmarked library feature")
+                                 .span_note(span, "this is either a bug in the library you are \
                                                    using or a bug in the compiler - please \
-                                                   report it in both places");
+                                                   report it in both places")
+                                 .emit()
                 } else {
-                    self.tcx.sess.span_err(span, "use of unmarked library feature");
-                    self.tcx.sess.span_note(span, "this is either a bug in the library you are \
+                    self.tcx.sess.struct_span_err(span, "use of unmarked library feature")
+                                 .span_note(span, "this is either a bug in the library you are \
                                                    using or a bug in the compiler - please \
-                                                   report it in both places");
-                    self.tcx.sess.span_note(span, "use #![feature(unmarked_api)] in the \
-                                                   crate attributes to override this");
+                                                   report it in both places")
+                                 .span_note(span, "use #![feature(unmarked_api)] in the \
+                                                   crate attributes to override this")
+                                 .emit()
                 }
             }
         }
index 9cf8043be3ba1bf6c34bd7bf6dc89e7658bad50b..9193b1a09f9faa7fa7f081995329be4f00bb4f7d 100644 (file)
@@ -31,8 +31,9 @@
 use util::nodemap::{FnvHashMap, FnvHashSet};
 
 use std::fmt;
-use syntax::codemap::Span;
 use syntax::attr::{AttributeMethods, AttrMetaMethods};
+use syntax::codemap::Span;
+use syntax::errors::DiagnosticBuilder;
 
 #[derive(Debug, PartialEq, Eq, Hash)]
 pub struct TraitErrorKey<'tcx> {
@@ -94,12 +95,12 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
     // then $X will be unified with TyError, but the error still needs to be
     // reported.
     if !infcx.tcx.sess.has_errors() || !predicate.references_error() {
-        span_err!(
-            infcx.tcx.sess, obligation.cause.span, E0271,
+        let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0271,
             "type mismatch resolving `{}`: {}",
             predicate,
             error.err);
-        note_obligation_cause(infcx, obligation);
+        note_obligation_cause(infcx, &mut err, obligation);
+        err.emit();
     }
 }
 
@@ -186,14 +187,15 @@ pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
 {
     let predicate =
         infcx.resolve_type_vars_if_possible(&obligation.predicate);
-    span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
-              "overflow evaluating the requirement `{}`",
-              predicate);
+    let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0275,
+                                   "overflow evaluating the requirement `{}`",
+                                   predicate);
 
-    suggest_new_overflow_limit(infcx.tcx, obligation.cause.span);
+    suggest_new_overflow_limit(infcx.tcx, &mut err, obligation.cause.span);
 
-    note_obligation_cause(infcx, obligation);
+    note_obligation_cause(infcx, &mut err, obligation);
 
+    err.emit();
     infcx.tcx.sess.abort_if_errors();
     unreachable!();
 }
@@ -218,7 +220,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 
                         if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() {
                             let trait_ref = trait_predicate.to_poly_trait_ref();
-                            span_err!(
+                            let mut err = struct_span_err!(
                                 infcx.tcx.sess, obligation.cause.span, E0277,
                                 "the trait `{}` is not implemented for the type `{}`",
                                 trait_ref, trait_ref.self_ty());
@@ -228,9 +230,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                             let custom_note = report_on_unimplemented(infcx, &trait_ref.0,
                                                                       obligation.cause.span);
                             if let Some(s) = custom_note {
-                                infcx.tcx.sess.fileline_note(obligation.cause.span, &s);
+                                err.fileline_note(obligation.cause.span, &s);
                             }
-                            note_obligation_cause(infcx, obligation);
+                            note_obligation_cause(infcx, &mut err, obligation);
+                            err.emit();
                         }
                     }
 
@@ -238,44 +241,48 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                         let predicate = infcx.resolve_type_vars_if_possible(predicate);
                         let err = infcx.equality_predicate(obligation.cause.span,
                                                            &predicate).err().unwrap();
-                        span_err!(
+                        let mut err = struct_span_err!(
                             infcx.tcx.sess, obligation.cause.span, E0278,
                             "the requirement `{}` is not satisfied (`{}`)",
                             predicate,
                             err);
-                        note_obligation_cause(infcx, obligation);
+                        note_obligation_cause(infcx, &mut err, obligation);
+                        err.emit();
                     }
 
                     ty::Predicate::RegionOutlives(ref predicate) => {
                         let predicate = infcx.resolve_type_vars_if_possible(predicate);
                         let err = infcx.region_outlives_predicate(obligation.cause.span,
                                                                   &predicate).err().unwrap();
-                        span_err!(
+                        let mut err = struct_span_err!(
                             infcx.tcx.sess, obligation.cause.span, E0279,
                             "the requirement `{}` is not satisfied (`{}`)",
                             predicate,
                             err);
-                        note_obligation_cause(infcx, obligation);
+                        note_obligation_cause(infcx, &mut err, obligation);
+                        err.emit();
                     }
 
                     ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
                         let predicate =
                             infcx.resolve_type_vars_if_possible(&obligation.predicate);
-                        span_err!(
+                        let mut err = struct_span_err!(
                             infcx.tcx.sess, obligation.cause.span, E0280,
                             "the requirement `{}` is not satisfied",
                             predicate);
-                        note_obligation_cause(infcx, obligation);
+                        note_obligation_cause(infcx, &mut err, obligation);
+                        err.emit();
                     }
 
                     ty::Predicate::ObjectSafe(trait_def_id) => {
                         let violations = object_safety_violations(
                             infcx.tcx, trait_def_id);
-                        report_object_safety_error(infcx.tcx,
-                                                   obligation.cause.span,
-                                                   trait_def_id,
-                                                   violations);
-                        note_obligation_cause(infcx, obligation);
+                        let mut err = report_object_safety_error(infcx.tcx,
+                                                                 obligation.cause.span,
+                                                                 trait_def_id,
+                                                                 violations);
+                        note_obligation_cause(infcx, &mut err, obligation);
+                        err.emit();
                     }
 
                     ty::Predicate::WellFormed(ty) => {
@@ -296,7 +303,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
             let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref);
             let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref);
             if !actual_trait_ref.self_ty().references_error() {
-                span_err!(
+                let mut err = struct_span_err!(
                     infcx.tcx.sess, obligation.cause.span, E0281,
                     "type mismatch: the type `{}` implements the trait `{}`, \
                      but the trait `{}` is required ({})",
@@ -304,14 +311,17 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                     expected_trait_ref,
                     actual_trait_ref,
                     e);
-                note_obligation_cause(infcx, obligation);
+                note_obligation_cause(infcx, &mut err, obligation);
+                err.emit();
             }
         }
 
         TraitNotObjectSafe(did) => {
             let violations = object_safety_violations(infcx.tcx, did);
-            report_object_safety_error(infcx.tcx, obligation.cause.span, did, violations);
-            note_obligation_cause(infcx, obligation);
+            let mut err = report_object_safety_error(infcx.tcx, obligation.cause.span, did,
+                                                     violations);
+            note_obligation_cause(infcx, &mut err, obligation);
+            err.emit();
         }
     }
 }
@@ -320,8 +330,9 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         span: Span,
                                         trait_def_id: DefId,
                                         violations: Vec<ObjectSafetyViolation>)
+                                        -> DiagnosticBuilder<'tcx>
 {
-    span_err!(
+    let mut err = struct_span_err!(
         tcx.sess, span, E0038,
         "the trait `{}` cannot be made into an object",
         tcx.item_path_str(trait_def_id));
@@ -333,13 +344,13 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
         }
         match violation {
             ObjectSafetyViolation::SizedSelf => {
-                tcx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     "the trait cannot require that `Self : Sized`");
             }
 
             ObjectSafetyViolation::SupertraitSelf => {
-                tcx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     "the trait cannot use `Self` as a type parameter \
                      in the supertrait listing");
@@ -347,7 +358,7 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
 
             ObjectSafetyViolation::Method(method,
                                           MethodViolationCode::StaticMethod) => {
-                tcx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     &format!("method `{}` has no receiver",
                              method.name));
@@ -355,7 +366,7 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
 
             ObjectSafetyViolation::Method(method,
                                           MethodViolationCode::ReferencesSelf) => {
-                tcx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     &format!("method `{}` references the `Self` type \
                               in its arguments or return type",
@@ -364,13 +375,14 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
 
             ObjectSafetyViolation::Method(method,
                                           MethodViolationCode::Generic) => {
-                tcx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     &format!("method `{}` has generic type parameters",
                              method.name));
             }
         }
     }
+    err
 }
 
 pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
@@ -424,10 +436,12 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                     {
                         need_type_info(infcx, obligation.cause.span, self_ty);
                     } else {
-                        span_err!(infcx.tcx.sess, obligation.cause.span, E0283,
-                                "type annotations required: cannot resolve `{}`",
-                                predicate);
-                        note_obligation_cause(infcx, obligation);
+                        let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0283,
+                                                       "type annotations required: \
+                                                        cannot resolve `{}`",
+                                                       predicate);
+                        note_obligation_cause(infcx, &mut err, obligation);
+                        err.emit();
                     }
                 }
             }
@@ -443,10 +457,11 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 
         _ => {
             if !infcx.tcx.sess.has_errors() {
-                span_err!(infcx.tcx.sess, obligation.cause.span, E0284,
-                        "type annotations required: cannot resolve `{}`",
-                        predicate);
-                note_obligation_cause(infcx, obligation);
+                let mut err = struct_span_err!(infcx.tcx.sess, obligation.cause.span, E0284,
+                                               "type annotations required: cannot resolve `{}`",
+                                               predicate);
+                note_obligation_cause(infcx, &mut err, obligation);
+                err.emit();
             }
         }
     }
@@ -463,16 +478,19 @@ fn need_type_info<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
 }
 
 fn note_obligation_cause<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
+                                      err: &mut DiagnosticBuilder,
                                       obligation: &Obligation<'tcx, T>)
     where T: fmt::Display
 {
     note_obligation_cause_code(infcx,
+                               err,
                                &obligation.predicate,
                                obligation.cause.span,
                                &obligation.cause.code);
 }
 
 fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
+                                           err: &mut DiagnosticBuilder,
                                            predicate: &T,
                                            cause_span: Span,
                                            cause_code: &ObligationCauseCode<'tcx>)
@@ -482,59 +500,59 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
     match *cause_code {
         ObligationCauseCode::MiscObligation => { }
         ObligationCauseCode::SliceOrArrayElem => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "slice and array elements must have `Sized` type");
         }
         ObligationCauseCode::ProjectionWf(data) => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("required so that the projection `{}` is well-formed",
                          data));
         }
         ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("required so that reference `{}` does not outlive its referent",
                          ref_ty));
         }
         ObligationCauseCode::ItemObligation(item_def_id) => {
             let item_name = tcx.item_path_str(item_def_id);
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("required by `{}`", item_name));
         }
         ObligationCauseCode::ObjectCastObligation(object_ty) => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!(
                     "required for the cast to the object type `{}`",
                     infcx.ty_to_string(object_ty)));
         }
         ObligationCauseCode::RepeatVec => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "the `Copy` trait is required because the \
                  repeated element will be copied");
         }
         ObligationCauseCode::VariableType(_) => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "all local variables must have a statically known size");
         }
         ObligationCauseCode::ReturnType => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "the return type of a function must have a \
                  statically known size");
         }
         ObligationCauseCode::AssignmentLhsSized => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "the left-hand-side of an assignment must have a statically known size");
         }
         ObligationCauseCode::StructInitializerSized => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "structs must have a statically known size to be initialized");
         }
@@ -542,7 +560,7 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
             let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
             let trait_name = tcx.item_path_str(def_id);
             let name = tcx.local_var_name_str(var_id);
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("the closure that captures `{}` requires that all captured variables \
                           implement the trait `{}`",
@@ -550,37 +568,45 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
                          trait_name));
         }
         ObligationCauseCode::FieldSized => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "only the last field of a struct or enum variant \
                  may have a dynamically sized type");
         }
         ObligationCauseCode::SharedStatic => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 "shared static variables must have a type that implements `Sync`");
         }
         ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
             let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("required because it appears within the type `{}`",
                          parent_trait_ref.0.self_ty()));
             let parent_predicate = parent_trait_ref.to_predicate();
-            note_obligation_cause_code(infcx, &parent_predicate, cause_span, &*data.parent_code);
+            note_obligation_cause_code(infcx,
+                                       err,
+                                       &parent_predicate,
+                                       cause_span,
+                                       &*data.parent_code);
         }
         ObligationCauseCode::ImplDerivedObligation(ref data) => {
             let parent_trait_ref = infcx.resolve_type_vars_if_possible(&data.parent_trait_ref);
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("required because of the requirements on the impl of `{}` for `{}`",
                          parent_trait_ref,
                          parent_trait_ref.0.self_ty()));
             let parent_predicate = parent_trait_ref.to_predicate();
-            note_obligation_cause_code(infcx, &parent_predicate, cause_span, &*data.parent_code);
+            note_obligation_cause_code(infcx,
+                                       err,
+                                       &parent_predicate,
+                                       cause_span,
+                                       &*data.parent_code);
         }
         ObligationCauseCode::CompareImplMethodObligation => {
-            tcx.sess.fileline_note(
+            err.fileline_note(
                 cause_span,
                 &format!("the requirement `{}` appears on the impl method \
                           but not on the corresponding trait method",
@@ -589,10 +615,10 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
     }
 }
 
-fn suggest_new_overflow_limit(tcx: &ty::ctxt, span: Span) {
+fn suggest_new_overflow_limit(tcx: &ty::ctxt, err:&mut DiagnosticBuilder, span: Span) {
     let current_limit = tcx.sess.recursion_limit.get();
     let suggested_limit = current_limit * 2;
-    tcx.sess.fileline_note(
+    err.fileline_note(
         span,
         &format!(
             "consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
index bd60d0a212252f549ba9c54d5437bf1a74a30ee3..c8e34165b90212e9e924a8a38e5b423f809f5d52 100644 (file)
@@ -254,13 +254,13 @@ fn virtual_call_violation_for_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     // autorefs) to `&self`. For now, we only accept `self`, `&self`
     // and `Box<Self>`.
     match method.explicit_self {
-        ty::StaticExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::Static => {
             return Some(MethodViolationCode::StaticMethod);
         }
 
-        ty::ByValueExplicitSelfCategory |
-        ty::ByReferenceExplicitSelfCategory(..) |
-        ty::ByBoxExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::ByValue |
+        ty::ExplicitSelfCategory::ByReference(..) |
+        ty::ExplicitSelfCategory::ByBox => {
         }
     }
 
index d9033eaa29f6b8ab3d132f3f79e894e15c28bd7c..ab48fd7fb8665f2727903f471f5e872ff5b6f5a8 100644 (file)
@@ -17,6 +17,7 @@
 use syntax::abi;
 use syntax::ast::{self, Name};
 use syntax::codemap::Span;
+use syntax::errors::DiagnosticBuilder;
 
 use rustc_front::hir;
 
@@ -252,27 +253,30 @@ fn sort_string(&self, cx: &ty::ctxt) -> String {
 }
 
 impl<'tcx> ty::ctxt<'tcx> {
-    pub fn note_and_explain_type_err(&self, err: &TypeError<'tcx>, sp: Span) {
+    pub fn note_and_explain_type_err(&self,
+                                     db: &mut DiagnosticBuilder,
+                                     err: &TypeError<'tcx>,
+                                     sp: Span) {
         use self::TypeError::*;
 
         match err.clone() {
             RegionsDoesNotOutlive(subregion, superregion) => {
-                self.note_and_explain_region("", subregion, "...");
-                self.note_and_explain_region("...does not necessarily outlive ",
+                self.note_and_explain_region(db, "", subregion, "...");
+                self.note_and_explain_region(db, "...does not necessarily outlive ",
                                            superregion, "");
             }
             RegionsNotSame(region1, region2) => {
-                self.note_and_explain_region("", region1, "...");
-                self.note_and_explain_region("...is not the same lifetime as ",
+                self.note_and_explain_region(db, "", region1, "...");
+                self.note_and_explain_region(db, "...is not the same lifetime as ",
                                            region2, "");
             }
             RegionsNoOverlap(region1, region2) => {
-                self.note_and_explain_region("", region1, "...");
-                self.note_and_explain_region("...does not overlap ",
+                self.note_and_explain_region(db, "", region1, "...");
+                self.note_and_explain_region(db, "...does not overlap ",
                                            region2, "");
             }
             RegionsInsufficientlyPolymorphic(_, conc_region) => {
-                self.note_and_explain_region("concrete lifetime that was found is ",
+                self.note_and_explain_region(db, "concrete lifetime that was found is ",
                                            conc_region, "");
             }
             RegionsOverlyPolymorphic(_, ty::ReVar(_)) => {
@@ -280,42 +284,40 @@ pub fn note_and_explain_type_err(&self, err: &TypeError<'tcx>, sp: Span) {
                 // inference variables, it's not very illuminating.
             }
             RegionsOverlyPolymorphic(_, conc_region) => {
-                self.note_and_explain_region("expected concrete lifetime is ",
+                self.note_and_explain_region(db, "expected concrete lifetime is ",
                                            conc_region, "");
             }
             Sorts(values) => {
                 let expected_str = values.expected.sort_string(self);
                 let found_str = values.found.sort_string(self);
                 if expected_str == found_str && expected_str == "closure" {
-                    self.sess.span_note(sp,
+                    db.span_note(sp,
                         "no two closures, even if identical, have the same type");
-                    self.sess.span_help(sp,
+                    db.span_help(sp,
                         "consider boxing your closure and/or using it as a trait object");
                 }
             },
             TyParamDefaultMismatch(values) => {
                 let expected = values.expected;
                 let found = values.found;
-                self.sess.span_note(sp,
-                                    &format!("conflicting type parameter defaults `{}` and `{}`",
-                                             expected.ty,
-                                             found.ty));
+                db.span_note(sp, &format!("conflicting type parameter defaults `{}` and `{}`",
+                                          expected.ty,
+                                          found.ty));
 
                 match
                     self.map.as_local_node_id(expected.def_id)
                             .and_then(|node_id| self.map.opt_span(node_id))
                 {
                     Some(span) => {
-                        self.sess.span_note(span, "a default was defined here...");
+                        db.span_note(span, "a default was defined here...");
                     }
                     None => {
-                        self.sess.note(
-                            &format!("a default is defined on `{}`",
-                                     self.item_path_str(expected.def_id)));
+                        db.note(&format!("a default is defined on `{}`",
+                                         self.item_path_str(expected.def_id)));
                     }
                 }
 
-                self.sess.span_note(
+                db.span_note(
                     expected.origin_span,
                     "...that was applied to an unconstrained type variable here");
 
@@ -324,18 +326,16 @@ pub fn note_and_explain_type_err(&self, err: &TypeError<'tcx>, sp: Span) {
                             .and_then(|node_id| self.map.opt_span(node_id))
                 {
                     Some(span) => {
-                        self.sess.span_note(span, "a second default was defined here...");
+                        db.span_note(span, "a second default was defined here...");
                     }
                     None => {
-                        self.sess.note(
-                            &format!("a second default is defined on `{}`",
-                                     self.item_path_str(found.def_id)));
+                        db.note(&format!("a second default is defined on `{}`",
+                                         self.item_path_str(found.def_id)));
                     }
                 }
 
-                self.sess.span_note(
-                    found.origin_span,
-                    "...that also applies to the same type variable here");
+                db.span_note(found.origin_span,
+                             "...that also applies to the same type variable here");
             }
             _ => {}
         }
index 50c9a1a31f2208b047638d239f2fe4f6a586d646..5daa9bcd0d1ae0a89d49961d4f8fea668f9c4d67 100644 (file)
@@ -12,7 +12,6 @@
 pub use self::ClosureKind::*;
 pub use self::Variance::*;
 pub use self::DtorKind::*;
-pub use self::ExplicitSelfCategory::*;
 pub use self::ImplOrTraitItemContainer::*;
 pub use self::BorrowKind::*;
 pub use self::ImplOrTraitItem::*;
@@ -2733,10 +2732,10 @@ pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
 /// The category of explicit self.
 #[derive(Clone, Copy, Eq, PartialEq, Debug)]
 pub enum ExplicitSelfCategory {
-    StaticExplicitSelfCategory,
-    ByValueExplicitSelfCategory,
-    ByReferenceExplicitSelfCategory(Region, hir::Mutability),
-    ByBoxExplicitSelfCategory,
+    Static,
+    ByValue,
+    ByReference(Region, hir::Mutability),
+    ByBox,
 }
 
 /// A free variable referred to in a function.
index a8587e83736812314e8d66673e78cf38130da892..80b4c1916a81626d9c28cc3b8b5271f29acf5328 100644 (file)
@@ -16,7 +16,7 @@
 
 use syntax::ast::{NodeId, NodeIdAssigner, Name};
 use syntax::codemap::Span;
-use syntax::errors;
+use syntax::errors::{self, DiagnosticBuilder};
 use syntax::errors::emitter::{Emitter, BasicEmitter};
 use syntax::diagnostics;
 use syntax::feature_gate;
@@ -80,6 +80,61 @@ pub struct Session {
 }
 
 impl Session {
+    pub fn struct_span_warn<'a>(&'a self,
+                                sp: Span,
+                                msg: &str)
+                                -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_span_warn(sp, msg)
+    }
+    pub fn struct_span_warn_with_code<'a>(&'a self,
+                                          sp: Span,
+                                          msg: &str,
+                                          code: &str)
+                                          -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_span_warn_with_code(sp, msg, code)
+    }
+    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_warn(msg)
+    }
+    pub fn struct_span_err<'a>(&'a self,
+                               sp: Span,
+                               msg: &str)
+                               -> DiagnosticBuilder<'a>  {
+        match split_msg_into_multilines(msg) {
+            Some(ref msg) => self.diagnostic().struct_span_err(sp, msg),
+            None => self.diagnostic().struct_span_err(sp, msg),
+        }
+    }
+    pub fn struct_span_err_with_code<'a>(&'a self,
+                                         sp: Span,
+                                         msg: &str,
+                                         code: &str)
+                                         -> DiagnosticBuilder<'a>  {
+        match split_msg_into_multilines(msg) {
+            Some(ref msg) => self.diagnostic().struct_span_err_with_code(sp, msg, code),
+            None => self.diagnostic().struct_span_err_with_code(sp, msg, code),
+        }
+    }
+    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_err(msg)
+    }
+    pub fn struct_span_fatal<'a>(&'a self,
+                                 sp: Span,
+                                 msg: &str)
+                                 -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_span_fatal(sp, msg)
+    }
+    pub fn struct_span_fatal_with_code<'a>(&'a self,
+                                           sp: Span,
+                                           msg: &str,
+                                           code: &str)
+                                           -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_span_fatal_with_code(sp, msg, code)
+    }
+    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a>  {
+        self.diagnostic().struct_fatal(msg)
+    }
+
     pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
         panic!(self.diagnostic().span_fatal(sp, msg))
     }
@@ -98,13 +153,13 @@ pub fn span_err_or_warn(&self, is_warning: bool, sp: Span, msg: &str) {
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err(sp, &msg[..]),
+            Some(msg) => self.diagnostic().span_err(sp, &msg),
             None => self.diagnostic().span_err(sp, msg)
         }
     }
     pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
         match split_msg_into_multilines(msg) {
-            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg[..], code),
+            Some(msg) => self.diagnostic().span_err_with_code(sp, &msg, code),
             None => self.diagnostic().span_err_with_code(sp, msg, code)
         }
     }
@@ -144,34 +199,6 @@ pub fn opt_span_warn(&self, opt_sp: Option<Span>, msg: &str) {
             None => self.warn(msg),
         }
     }
-    pub fn span_note(&self, sp: Span, msg: &str) {
-        self.diagnostic().span_note(sp, msg)
-    }
-    pub fn span_end_note(&self, sp: Span, msg: &str) {
-        self.diagnostic().span_end_note(sp, msg)
-    }
-
-    /// Prints out a message with a suggested edit of the code.
-    ///
-    /// See `errors::RenderSpan::Suggestion` for more information.
-    pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
-        self.diagnostic().span_suggestion(sp, msg, suggestion)
-    }
-    pub fn span_help(&self, sp: Span, msg: &str) {
-        self.diagnostic().span_help(sp, msg)
-    }
-    pub fn fileline_note(&self, sp: Span, msg: &str) {
-        self.diagnostic().fileline_note(sp, msg)
-    }
-    pub fn fileline_help(&self, sp: Span, msg: &str) {
-        self.diagnostic().fileline_help(sp, msg)
-    }
-    pub fn note(&self, msg: &str) {
-        self.diagnostic().note(msg)
-    }
-    pub fn help(&self, msg: &str) {
-        self.diagnostic().help(msg)
-    }
     pub fn opt_span_bug(&self, opt_sp: Option<Span>, msg: &str) -> ! {
         match opt_sp {
             Some(sp) => self.span_bug(sp, msg),
@@ -188,6 +215,12 @@ pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
     pub fn bug(&self, msg: &str) -> ! {
         self.diagnostic().bug(msg)
     }
+    pub fn note_without_error(&self, msg: &str) {
+        self.diagnostic().note_without_error(msg)
+    }
+    pub fn span_note_without_error(&self, sp: Span, msg: &str) {
+        self.diagnostic().span_note_without_error(sp, msg)
+    }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
         self.diagnostic().span_unimpl(sp, msg)
     }
index 0b362be215dfef40e6b9bc83158bb7430523436a..11d3068f065b7fb2578f35e38440116f6765decf 100644 (file)
@@ -919,13 +919,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 impl fmt::Display for ty::ExplicitSelfCategory {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(match *self {
-            ty::StaticExplicitSelfCategory => "static",
-            ty::ByValueExplicitSelfCategory => "self",
-            ty::ByReferenceExplicitSelfCategory(_, hir::MutMutable) => {
+            ty::ExplicitSelfCategory::Static => "static",
+            ty::ExplicitSelfCategory::ByValue => "self",
+            ty::ExplicitSelfCategory::ByReference(_, hir::MutMutable) => {
                 "&mut self"
             }
-            ty::ByReferenceExplicitSelfCategory(_, hir::MutImmutable) => "&self",
-            ty::ByBoxExplicitSelfCategory => "Box<self>",
+            ty::ExplicitSelfCategory::ByReference(_, hir::MutImmutable) => "&self",
+            ty::ExplicitSelfCategory::ByBox => "Box<self>",
         })
     }
 }
index 3f48051029d9dfe49a71d9f3fe0ce100f392b78f..df181aec4ea4c536b13aba9959f6c17f1257d73e 100644 (file)
@@ -465,44 +465,44 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 format!("`{}`", ol)
             };
 
-            match (new_loan.kind, old_loan.kind) {
+            let mut err = match (new_loan.kind, old_loan.kind) {
                 (ty::MutBorrow, ty::MutBorrow) => {
-                    span_err!(self.bccx, new_loan.span, E0499,
-                              "cannot borrow `{}`{} as mutable \
-                               more than once at a time",
-                              nl, new_loan_msg);
+                    struct_span_err!(self.bccx, new_loan.span, E0499,
+                                     "cannot borrow `{}`{} as mutable \
+                                      more than once at a time",
+                                     nl, new_loan_msg)
                 }
 
                 (ty::UniqueImmBorrow, _) => {
-                    span_err!(self.bccx, new_loan.span, E0500,
-                              "closure requires unique access to `{}` \
-                               but {} is already borrowed{}",
-                              nl, ol_pronoun, old_loan_msg);
+                    struct_span_err!(self.bccx, new_loan.span, E0500,
+                                     "closure requires unique access to `{}` \
+                                      but {} is already borrowed{}",
+                                     nl, ol_pronoun, old_loan_msg)
                 }
 
                 (_, ty::UniqueImmBorrow) => {
-                    span_err!(self.bccx, new_loan.span, E0501,
-                              "cannot borrow `{}`{} as {} because \
-                               previous closure requires unique access",
-                              nl, new_loan_msg, new_loan.kind.to_user_str());
+                    struct_span_err!(self.bccx, new_loan.span, E0501,
+                                     "cannot borrow `{}`{} as {} because \
+                                      previous closure requires unique access",
+                                     nl, new_loan_msg, new_loan.kind.to_user_str())
                 }
 
                 (_, _) => {
-                    span_err!(self.bccx, new_loan.span, E0502,
-                              "cannot borrow `{}`{} as {} because \
-                               {} is also borrowed as {}{}",
-                              nl,
-                              new_loan_msg,
-                              new_loan.kind.to_user_str(),
-                              ol_pronoun,
-                              old_loan.kind.to_user_str(),
-                              old_loan_msg);
+                    struct_span_err!(self.bccx, new_loan.span, E0502,
+                                     "cannot borrow `{}`{} as {} because \
+                                      {} is also borrowed as {}{}",
+                                     nl,
+                                     new_loan_msg,
+                                     new_loan.kind.to_user_str(),
+                                     ol_pronoun,
+                                     old_loan.kind.to_user_str(),
+                                     old_loan_msg)
                 }
-            }
+            };
 
             match new_loan.cause {
                 euv::ClosureCapture(span) => {
-                    self.bccx.span_note(
+                    err.span_note(
                         span,
                         &format!("borrow occurs due to use of `{}` in closure",
                                 nl));
@@ -553,15 +553,15 @@ pub fn report_error_if_loan_conflicts_with_restriction(&self,
                 }
             };
 
-            self.bccx.span_note(
+            err.span_note(
                 old_loan.span,
                 &format!("{}; {}", borrow_summary, rule_summary));
 
             let old_loan_span = self.tcx().map.span(
                 old_loan.kill_scope.node_id(&self.tcx().region_maps));
-            self.bccx.span_end_note(old_loan_span,
-                                    "previous borrow ends here");
-
+            err.span_end_note(old_loan_span,
+                              "previous borrow ends here");
+            err.emit();
             return false;
         }
 
@@ -616,14 +616,14 @@ fn check_for_copy_of_frozen_path(&self,
         match self.analyze_restrictions_on_use(id, copy_path, ty::ImmBorrow) {
             UseOk => { }
             UseWhileBorrowed(loan_path, loan_span) => {
-                span_err!(self.bccx, span, E0503,
-                          "cannot use `{}` because it was mutably borrowed",
-                          &self.bccx.loan_path_to_string(copy_path));
-                self.bccx.span_note(
-                    loan_span,
-                    &format!("borrow of `{}` occurs here",
-                            &self.bccx.loan_path_to_string(&*loan_path))
-                    );
+                struct_span_err!(self.bccx, span, E0503,
+                                 "cannot use `{}` because it was mutably borrowed",
+                                 &self.bccx.loan_path_to_string(copy_path))
+                    .span_note(loan_span,
+                               &format!("borrow of `{}` occurs here",
+                                       &self.bccx.loan_path_to_string(&*loan_path))
+                               )
+                    .emit();
             }
         }
     }
@@ -639,24 +639,25 @@ fn check_for_move_of_borrowed_path(&self,
         match self.analyze_restrictions_on_use(id, move_path, ty::MutBorrow) {
             UseOk => { }
             UseWhileBorrowed(loan_path, loan_span) => {
-                match move_kind {
+                let mut err = match move_kind {
                     move_data::Captured =>
-                        span_err!(self.bccx, span, E0504,
-                                  "cannot move `{}` into closure because it is borrowed",
-                                  &self.bccx.loan_path_to_string(move_path)),
+                        struct_span_err!(self.bccx, span, E0504,
+                                         "cannot move `{}` into closure because it is borrowed",
+                                         &self.bccx.loan_path_to_string(move_path)),
                     move_data::Declared |
                     move_data::MoveExpr |
                     move_data::MovePat =>
-                        span_err!(self.bccx, span, E0505,
-                                  "cannot move out of `{}` because it is borrowed",
-                                  &self.bccx.loan_path_to_string(move_path))
+                        struct_span_err!(self.bccx, span, E0505,
+                                         "cannot move out of `{}` because it is borrowed",
+                                         &self.bccx.loan_path_to_string(move_path))
                 };
 
-                self.bccx.span_note(
+                err.span_note(
                     loan_span,
                     &format!("borrow of `{}` occurs here",
                             &self.bccx.loan_path_to_string(&*loan_path))
                     );
+                err.emit();
             }
         }
     }
@@ -818,12 +819,12 @@ pub fn report_illegal_mutation(&self,
                                    span: Span,
                                    loan_path: &LoanPath<'tcx>,
                                    loan: &Loan) {
-        span_err!(self.bccx, span, E0506,
-                  "cannot assign to `{}` because it is borrowed",
-                  self.bccx.loan_path_to_string(loan_path));
-        self.bccx.span_note(
-            loan.span,
-            &format!("borrow of `{}` occurs here",
-                    self.bccx.loan_path_to_string(loan_path)));
+        struct_span_err!(self.bccx, span, E0506,
+                         "cannot assign to `{}` because it is borrowed",
+                         self.bccx.loan_path_to_string(loan_path))
+            .span_note(loan.span,
+                       &format!("borrow of `{}` occurs here",
+                               self.bccx.loan_path_to_string(loan_path)))
+            .emit();
     }
 }
index a56a03174f609af1c5e3c83534eca65b40774836..4cb9673785ecb36303ffd689cec92dd222c5ce2a 100644 (file)
@@ -15,6 +15,7 @@
 use rustc::middle::ty;
 use syntax::ast;
 use syntax::codemap;
+use syntax::errors::DiagnosticBuilder;
 use rustc_front::hir;
 
 pub struct MoveErrorCollector<'tcx> {
@@ -68,13 +69,14 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                 errors: &Vec<MoveError<'tcx>>) {
     let grouped_errors = group_errors_with_same_origin(errors);
     for error in &grouped_errors {
-        report_cannot_move_out_of(bccx, error.move_from.clone());
+        let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
         let mut is_first_note = true;
         for move_to in &error.move_to_places {
-            note_move_destination(bccx, move_to.span,
+            note_move_destination(&mut err, move_to.span,
                                   move_to.name, is_first_note);
             is_first_note = false;
         }
+        err.emit();
     }
 }
 
@@ -112,24 +114,28 @@ fn append_to_grouped_errors<'tcx>(grouped_errors: &mut Vec<GroupedMoveErrors<'tc
 
 // (keep in sync with gather_moves::check_and_get_illegal_move_origin )
 fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
-                                       move_from: mc::cmt<'tcx>) {
+                                       move_from: mc::cmt<'tcx>)
+                                       -> DiagnosticBuilder<'a> {
     match move_from.cat {
         Categorization::Deref(_, _, mc::BorrowedPtr(..)) |
         Categorization::Deref(_, _, mc::Implicit(..)) |
         Categorization::Deref(_, _, mc::UnsafePtr(..)) |
         Categorization::StaticItem => {
-            span_err!(bccx, move_from.span, E0507,
-                      "cannot move out of {}",
-                      move_from.descriptive_string(bccx.tcx));
+            struct_span_err!(bccx, move_from.span, E0507,
+                             "cannot move out of {}",
+                             move_from.descriptive_string(bccx.tcx))
         }
 
         Categorization::Interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
             let expr = bccx.tcx.map.expect_expr(move_from.id);
             if let hir::ExprIndex(..) = expr.node {
-                span_err!(bccx, move_from.span, E0508,
-                          "cannot move out of type `{}`, \
-                           a non-copy fixed-size array",
-                          b.ty);
+                struct_span_err!(bccx, move_from.span, E0508,
+                                 "cannot move out of type `{}`, \
+                                  a non-copy fixed-size array",
+                                 b.ty)
+            } else {
+                bccx.span_bug(move_from.span, "this path should not cause illegal move");
+                unreachable!();
             }
         }
 
@@ -138,39 +144,41 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
             match b.ty.sty {
                 ty::TyStruct(def, _) |
                 ty::TyEnum(def, _) if def.has_dtor() => {
-                    span_err!(bccx, move_from.span, E0509,
-                              "cannot move out of type `{}`, \
-                               which defines the `Drop` trait",
-                              b.ty);
+                    struct_span_err!(bccx, move_from.span, E0509,
+                                     "cannot move out of type `{}`, \
+                                      which defines the `Drop` trait",
+                                     b.ty)
                 },
                 _ => {
-                    bccx.span_bug(move_from.span, "this path should not cause illegal move")
+                    bccx.span_bug(move_from.span, "this path should not cause illegal move");
+                    unreachable!();
                 }
             }
         }
         _ => {
-            bccx.span_bug(move_from.span, "this path should not cause illegal move")
+            bccx.span_bug(move_from.span, "this path should not cause illegal move");
+            unreachable!();
         }
     }
 }
 
-fn note_move_destination(bccx: &BorrowckCtxt,
+fn note_move_destination(err: &mut DiagnosticBuilder,
                          move_to_span: codemap::Span,
                          pat_name: ast::Name,
                          is_first_note: bool) {
     if is_first_note {
-        bccx.span_note(
+        err.span_note(
             move_to_span,
             "attempting to move value to here");
-        bccx.fileline_help(
+        err.fileline_help(
             move_to_span,
             &format!("to prevent the move, \
-                     use `ref {0}` or `ref mut {0}` to capture value by \
-                     reference",
-                    pat_name));
+                      use `ref {0}` or `ref mut {0}` to capture value by \
+                      reference",
+                     pat_name));
     } else {
-        bccx.span_note(move_to_span,
-                       &format!("and here (use `ref {0}` or `ref mut {0}`)",
+        err.span_note(move_to_span,
+                      &format!("and here (use `ref {0}` or `ref mut {0}`)",
                                pat_name));
     }
 }
index 38ec728e9c16f0af2e12d95bc454dc74752dda68..0a2586755cef429dc6f5444e223cf342fba473b4 100644 (file)
@@ -40,6 +40,7 @@
 use std::rc::Rc;
 use syntax::ast;
 use syntax::codemap::Span;
+use syntax::errors::DiagnosticBuilder;
 
 use rustc_front::hir;
 use rustc_front::hir::{FnDecl, Block};
@@ -591,10 +592,11 @@ pub fn report(&self, err: BckError<'tcx>) {
         }
 
         // General fallback.
-        self.span_err(
+        let mut db = self.struct_span_err(
             err.span,
             &self.bckerr_to_string(&err));
-        self.note_and_explain_bckerr(err);
+        self.note_and_explain_bckerr(&mut db, err);
+        db.emit();
     }
 
     pub fn report_use_of_moved_value<'b>(&self,
@@ -609,16 +611,17 @@ pub fn report_use_of_moved_value<'b>(&self,
             MovedInCapture => "capture",
         };
 
-        let (ol, moved_lp_msg) = match the_move.kind {
+        let (ol, moved_lp_msg, mut err) = match the_move.kind {
             move_data::Declared => {
-                span_err!(
+                let err = struct_span_err!(
                     self.tcx.sess, use_span, E0381,
                     "{} of possibly uninitialized variable: `{}`",
                     verb,
                     self.loan_path_to_string(lp));
 
                 (self.loan_path_to_string(moved_lp),
-                 String::new())
+                 String::new(),
+                 err)
             }
             _ => {
                 // If moved_lp is something like `x.a`, and lp is something like `x.b`, we would
@@ -653,11 +656,11 @@ pub fn report_use_of_moved_value<'b>(&self,
                 let msg = if !has_fork && partial { "partially " }
                           else if has_fork && !has_common { "collaterally "}
                           else { "" };
-                span_err!(
+                let err = struct_span_err!(
                     self.tcx.sess, use_span, E0382,
                     "{} of {}moved value: `{}`",
                     verb, msg, nl);
-                (ol, moved_lp_msg)
+                (ol, moved_lp_msg, err)
             }
         };
 
@@ -684,7 +687,7 @@ pub fn report_use_of_moved_value<'b>(&self,
                 // multiple times. Avoid printing the same span and adjust the wording so it makes
                 // more sense that it's from multiple evalutations.
                 if expr_span == use_span {
-                    self.tcx.sess.note(
+                    err.note(
                         &format!("`{}` was previously moved here{} because it has type `{}`, \
                                   which is {}",
                                  ol,
@@ -692,7 +695,7 @@ pub fn report_use_of_moved_value<'b>(&self,
                                  expr_ty,
                                  suggestion));
                 } else {
-                    self.tcx.sess.span_note(
+                    err.span_note(
                         expr_span,
                         &format!("`{}` moved here{} because it has type `{}`, which is {}",
                                  ol,
@@ -705,7 +708,7 @@ pub fn report_use_of_moved_value<'b>(&self,
             move_data::MovePat => {
                 let pat_ty = self.tcx.node_id_to_type(the_move.id);
                 let span = self.tcx.map.span(the_move.id);
-                self.tcx.sess.span_note(span,
+                err.span_note(span,
                     &format!("`{}` moved here{} because it has type `{}`, \
                              which is moved by default",
                             ol,
@@ -713,14 +716,14 @@ pub fn report_use_of_moved_value<'b>(&self,
                             pat_ty));
                 match self.tcx.sess.codemap().span_to_snippet(span) {
                     Ok(string) => {
-                        self.tcx.sess.span_suggestion(
+                        err.span_suggestion(
                             span,
                             &format!("if you would like to borrow the value instead, \
                                       use a `ref` binding as shown:"),
                             format!("ref {}", string));
                     },
                     Err(_) => {
-                        self.tcx.sess.fileline_help(span,
+                        err.fileline_help(span,
                             "use `ref` to override");
                     },
                 }
@@ -746,7 +749,7 @@ pub fn report_use_of_moved_value<'b>(&self,
                                     expr_ty,
                                     ("moved by default",
                                      "make a copy and capture that instead to override"));
-                self.tcx.sess.span_note(
+                err.span_note(
                     expr_span,
                     &format!("`{}` moved into closure environment here{} because it \
                             has type `{}`, which is {}",
@@ -754,9 +757,10 @@ pub fn report_use_of_moved_value<'b>(&self,
                             moved_lp_msg,
                             moved_lp.ty,
                             suggestion));
-                self.tcx.sess.fileline_help(expr_span, help);
+                err.fileline_help(expr_span, help);
             }
         }
+        err.emit();
 
         fn move_suggestion<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>,
                                     span: Span,
@@ -791,35 +795,36 @@ pub fn report_reassigned_immutable_variable(&self,
                                                 lp: &LoanPath<'tcx>,
                                                 assign:
                                                 &move_data::Assignment) {
-        span_err!(
+        struct_span_err!(
             self.tcx.sess, span, E0384,
             "re-assignment of immutable variable `{}`",
-            self.loan_path_to_string(lp));
-        self.tcx.sess.span_note(assign.span, "prior assignment occurs here");
+            self.loan_path_to_string(lp))
+            .span_note(assign.span, "prior assignment occurs here")
+            .emit();
     }
 
     pub fn span_err(&self, s: Span, m: &str) {
         self.tcx.sess.span_err(s, m);
     }
 
-    pub fn span_err_with_code(&self, s: Span, msg: &str, code: &str) {
-        self.tcx.sess.span_err_with_code(s, msg, code);
+    pub fn struct_span_err(&self, s: Span, m: &str) -> DiagnosticBuilder<'a> {
+        self.tcx.sess.struct_span_err(s, m)
     }
 
-    pub fn span_bug(&self, s: Span, m: &str) {
-        self.tcx.sess.span_bug(s, m);
-    }
-
-    pub fn span_note(&self, s: Span, m: &str) {
-        self.tcx.sess.span_note(s, m);
+    pub fn struct_span_err_with_code(&self,
+                                     s: Span,
+                                     msg: &str,
+                                     code: &str)
+                                     -> DiagnosticBuilder<'a> {
+        self.tcx.sess.struct_span_err_with_code(s, msg, code)
     }
 
-    pub fn span_end_note(&self, s: Span, m: &str) {
-        self.tcx.sess.span_end_note(s, m);
+    pub fn span_err_with_code(&self, s: Span, msg: &str, code: &str) {
+        self.tcx.sess.span_err_with_code(s, msg, code);
     }
 
-    pub fn fileline_help(&self, s: Span, m: &str) {
-        self.tcx.sess.fileline_help(s, m);
+    pub fn span_bug(&self, s: Span, m: &str) {
+        self.tcx.sess.span_bug(s, m);
     }
 
     pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String {
@@ -913,19 +918,19 @@ pub fn report_aliasability_violation(&self,
             }
         };
 
-        match cause {
+        let mut err = match cause {
             mc::AliasableOther => {
-                span_err!(
+                struct_span_err!(
                     self.tcx.sess, span, E0385,
-                    "{} in an aliasable location", prefix);
+                    "{} in an aliasable location", prefix)
             }
             mc::AliasableReason::UnaliasableImmutable => {
-                span_err!(
+                struct_span_err!(
                     self.tcx.sess, span, E0386,
-                    "{} in an immutable container", prefix);
+                    "{} in an immutable container", prefix)
             }
             mc::AliasableClosure(id) => {
-                span_err!(
+                let mut err = struct_span_err!(
                     self.tcx.sess, span, E0387,
                     "{} in a captured outer variable in an `Fn` closure", prefix);
                 if let BorrowViolation(euv::ClosureCapture(_)) = kind {
@@ -933,31 +938,32 @@ pub fn report_aliasability_violation(&self,
                     // happen for nested closures, so we know the enclosing
                     // closure incorrectly accepts an `Fn` while it needs to
                     // be `FnMut`.
-                    span_help!(self.tcx.sess, self.tcx.map.span(id),
+                    span_help!(&mut err, self.tcx.map.span(id),
                            "consider changing this to accept closures that implement `FnMut`");
                 } else {
-                    span_help!(self.tcx.sess, self.tcx.map.span(id),
+                    span_help!(&mut err, self.tcx.map.span(id),
                            "consider changing this closure to take self by mutable reference");
                 }
+                err
             }
             mc::AliasableStatic |
             mc::AliasableStaticMut => {
-                span_err!(
+                struct_span_err!(
                     self.tcx.sess, span, E0388,
-                    "{} in a static location", prefix);
+                    "{} in a static location", prefix)
             }
             mc::AliasableBorrowed => {
-                span_err!(
+                struct_span_err!(
                     self.tcx.sess, span, E0389,
-                    "{} in a `&` reference", prefix);
+                    "{} in a `&` reference", prefix)
             }
-        }
+        };
 
         if is_closure {
-            self.tcx.sess.fileline_help(
-                span,
-                "closures behind references must be called via `&mut`");
+            err.fileline_help(span,
+                              "closures behind references must be called via `&mut`");
         }
+        err.emit();
     }
 
     fn report_out_of_scope_escaping_closure_capture(&self,
@@ -966,34 +972,30 @@ fn report_out_of_scope_escaping_closure_capture(&self,
     {
         let cmt_path_or_string = self.cmt_to_path_or_string(&err.cmt);
 
-        span_err!(
-            self.tcx.sess, err.span, E0373,
-            "closure may outlive the current function, \
-             but it borrows {}, \
-             which is owned by the current function",
-            cmt_path_or_string);
-
-        self.tcx.sess.span_note(
-            capture_span,
-            &format!("{} is borrowed here",
-                     cmt_path_or_string));
-
         let suggestion =
             match self.tcx.sess.codemap().span_to_snippet(err.span) {
                 Ok(string) => format!("move {}", string),
                 Err(_) => format!("move |<args>| <body>")
             };
 
-        self.tcx.sess.span_suggestion(
-            err.span,
-            &format!("to force the closure to take ownership of {} \
-                      (and any other referenced variables), \
-                      use the `move` keyword, as shown:",
-                     cmt_path_or_string),
-            suggestion);
+        struct_span_err!(self.tcx.sess, err.span, E0373,
+                         "closure may outlive the current function, \
+                          but it borrows {}, \
+                          which is owned by the current function",
+                         cmt_path_or_string)
+            .span_note(capture_span,
+                       &format!("{} is borrowed here",
+                                cmt_path_or_string))
+            .span_suggestion(err.span,
+                             &format!("to force the closure to take ownership of {} \
+                                       (and any other referenced variables), \
+                                       use the `move` keyword, as shown:",
+                                      cmt_path_or_string),
+                             suggestion)
+            .emit();
     }
 
-    pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
+    pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>) {
         let code = err.code;
         match code {
             err_mutbl => {
@@ -1007,7 +1009,7 @@ pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
                             _ => unreachable!()
                         };
                         if kind == ty::FnClosureKind {
-                            self.tcx.sess.span_help(
+                            db.span_help(
                                 self.tcx.map.span(upvar_id.closure_expr_id),
                                 "consider changing this closure to take \
                                  self by mutable reference");
@@ -1017,7 +1019,7 @@ pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
                         if let Categorization::Local(local_id) = err.cmt.cat {
                             let span = self.tcx.map.span(local_id);
                             if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
-                                self.tcx.sess.span_suggestion(
+                                db.span_suggestion(
                                     span,
                                     &format!("to make the {} mutable, use `mut` as shown:",
                                              self.cmt_to_string(&err.cmt)),
@@ -1030,16 +1032,18 @@ pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
 
             err_out_of_scope(super_scope, sub_scope) => {
                 self.tcx.note_and_explain_region(
+                    db,
                     "reference must be valid for ",
                     sub_scope,
                     "...");
                 self.tcx.note_and_explain_region(
+                    db,
                     "...but borrowed value is only valid for ",
                     super_scope,
                     "");
                 if let Some(span) = statement_scope_span(self.tcx, super_scope) {
-                    self.tcx.sess.span_help(span,
-                        "consider using a `let` binding to increase its lifetime");
+                    db.span_help(span,
+                                 "consider using a `let` binding to increase its lifetime");
                 }
             }
 
@@ -1051,11 +1055,13 @@ pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
                     None => self.cmt_to_string(&*err.cmt),
                 };
                 self.tcx.note_and_explain_region(
+                    db,
                     &format!("{} would have to be valid for ",
                             descr),
                     loan_scope,
                     "...");
                 self.tcx.note_and_explain_region(
+                    db,
                     &format!("...but {} is only valid for ", descr),
                     ptr_scope,
                     "");
index 1ac1b5978cfb609cacc6bd9ccf055e9e635ab35b..27740b8fc5cf9a390145da6a5c7f8482078b3d02 100644 (file)
@@ -1001,8 +1001,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
                              None
                          }
                          _ => {
-                             session.span_err(a.span, "`crate_type` requires a value");
-                             session.note("for example: `#![crate_type=\"lib\"]`");
+                             session.struct_span_err(a.span, "`crate_type` requires a value")
+                                 .note("for example: `#![crate_type=\"lib\"]`")
+                                 .emit();
                              None
                          }
                      }
index 50a672a4b69e700414629c453f10dd460010a89b..7bcf3276da7a450693eb3994a5d628b66d838536 100644 (file)
@@ -60,7 +60,7 @@ struct ExpectErrorEmitter {
 fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
     match lvl {
         Level::Bug | Level::Fatal | Level::Error => {}
-        Level::Warning | Level::Note | Level::Help => {
+        _ => {
             return;
         }
     }
index f99cdd39da2a8d5ad5f1b83767ecb3212971964a..81d3367ab00dc97ccccb3b2c2ff564315b51c477 100644 (file)
@@ -319,9 +319,9 @@ pub fn lower_path_parameters(lctx: &LoweringContext,
                              path_parameters: &PathParameters)
                              -> hir::PathParameters {
     match *path_parameters {
-        AngleBracketedParameters(ref data) =>
+        PathParameters::AngleBracketed(ref data) =>
             hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)),
-        ParenthesizedParameters(ref data) =>
+        PathParameters::Parenthesized(ref data) =>
             hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)),
     }
 }
index f27cc629791ed5f1849adbb5eab6e1f95a2d7aab..09e6f454fb4f51c5ffaccba9fdccff42e83da4b7 100644 (file)
@@ -752,19 +752,19 @@ fn check_fn(&mut self, cx: &LateContext, fn_kind: FnKind, _: &hir::FnDecl,
         // no break */ }`) shouldn't be linted unless it actually
         // recurs.
         if !reached_exit_without_self_call && !self_call_spans.is_empty() {
-            cx.span_lint(UNCONDITIONAL_RECURSION, sp,
-                         "function cannot return without recurring");
+            let mut db = cx.struct_span_lint(UNCONDITIONAL_RECURSION, sp,
+                                             "function cannot return without recurring");
 
             // FIXME #19668: these could be span_lint_note's instead of this manual guard.
             if cx.current_level(UNCONDITIONAL_RECURSION) != Level::Allow {
-                let sess = cx.sess();
                 // offer some help to the programmer.
                 for call in &self_call_spans {
-                    sess.span_note(*call, "recursive call site")
+                    db.span_note(*call, "recursive call site");
                 }
-                sess.fileline_help(sp, "a `loop` may express intention \
-                                        better if this is on purpose")
+                db.fileline_help(sp, "a `loop` may express intention \
+                                      better if this is on purpose");
             }
+            db.emit();
         }
 
         // all done
index 4420da5f9b87dfd3f7d77fcb18f73d24381e1b27..9122148a8cc05ff9dc37f7927feb4fb742e3bc16 100644 (file)
@@ -35,6 +35,7 @@
 use syntax::parse;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
+use syntax::errors::FatalError;
 use syntax::parse::token::InternedString;
 use syntax::util::small_vector::SmallVector;
 use rustc_front::intravisit::Visitor;
@@ -504,7 +505,10 @@ pub fn read_exported_macros(&mut self, item: &ast::Item) -> Vec<ast::MacroDef> {
                 let lo = p.span.lo;
                 let body = match p.parse_all_token_trees() {
                     Ok(body) => body,
-                    Err(err) => panic!(err),
+                    Err(mut err) => {
+                        err.emit();
+                        panic!(FatalError);
+                    }
                 };
                 let span = mk_sp(lo, p.last_span.hi);
                 p.abort_if_errors();
index 8126970759e6dcc7e0adaaf3c202126fa0820422..29fe9bc759ddece4164284ffe37daea4c7e9519b 100644 (file)
@@ -884,12 +884,12 @@ fn get_mutability(ch: u8) -> hir::Mutability {
 
     let explicit_self_kind = string.as_bytes()[0];
     match explicit_self_kind as char {
-        's' => ty::StaticExplicitSelfCategory,
-        'v' => ty::ByValueExplicitSelfCategory,
-        '~' => ty::ByBoxExplicitSelfCategory,
+        's' => ty::ExplicitSelfCategory::Static,
+        'v' => ty::ExplicitSelfCategory::ByValue,
+        '~' => ty::ExplicitSelfCategory::ByBox,
         // FIXME(#4846) expl. region
         '&' => {
-            ty::ByReferenceExplicitSelfCategory(
+            ty::ExplicitSelfCategory::ByReference(
                 ty::ReEmpty,
                 get_mutability(string.as_bytes()[1]))
         }
@@ -923,7 +923,7 @@ pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
     let doc = cdata.lookup_item(id);
     match item_sort(doc) {
         Some('r') | Some('p') => {
-            get_explicit_self(doc) == ty::StaticExplicitSelfCategory
+            get_explicit_self(doc) == ty::ExplicitSelfCategory::Static
         }
         _ => false
     }
index cd70172e8fa2112500da97662a9d337d2cd87451..f1c5d47df8889789f64535efc03960c156d6d980 100644 (file)
@@ -498,16 +498,16 @@ fn encode_explicit_self(rbml_w: &mut Encoder,
 
     // Encode the base self type.
     match *explicit_self {
-        ty::StaticExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::Static => {
             rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
         }
-        ty::ByValueExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::ByValue => {
             rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
         }
-        ty::ByBoxExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::ByBox => {
             rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
         }
-        ty::ByReferenceExplicitSelfCategory(_, m) => {
+        ty::ExplicitSelfCategory::ByReference(_, m) => {
             // FIXME(#4846) encode custom lifetime
             let ch = encode_mutability(m);
             rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
@@ -675,7 +675,7 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
     encode_visibility(rbml_w, method_ty.vis);
     encode_explicit_self(rbml_w, &method_ty.explicit_self);
     match method_ty.explicit_self {
-        ty::StaticExplicitSelfCategory => {
+        ty::ExplicitSelfCategory::Static => {
             encode_family(rbml_w, STATIC_METHOD_FAMILY);
         }
         _ => encode_family(rbml_w, METHOD_FAMILY)
@@ -1340,7 +1340,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                 path.clone().chain(Some(elem)));
 
                     match method_ty.explicit_self {
-                        ty::StaticExplicitSelfCategory => {
+                        ty::ExplicitSelfCategory::Static => {
                             encode_family(rbml_w,
                                           STATIC_METHOD_FAMILY);
                         }
@@ -1353,7 +1353,7 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                                     ecx.local_id(method_def_id));
 
                     is_nonstatic_method = method_ty.explicit_self !=
-                        ty::StaticExplicitSelfCategory;
+                        ty::ExplicitSelfCategory::Static;
                 }
                 ty::TypeTraitItem(associated_type) => {
                     encode_name(rbml_w, associated_type.name);
index d1892b87f8bcc3b7d8d734f6bf76da960a64974d..40665beaa5ac2698b08c92e6107ad139cef5ff17 100644 (file)
 use rustc_llvm::{False, ObjectFile, mk_section_iter};
 use rustc_llvm::archive_ro::ArchiveRO;
 use syntax::codemap::Span;
-use syntax::errors::Handler;
+use syntax::errors::DiagnosticBuilder;
 use rustc_back::target::Target;
 
 use std::cmp;
@@ -315,38 +315,38 @@ pub fn report_load_errs(&mut self) {
             &Some(ref r) => format!(" which `{}` depends on",
                                     r.ident)
         };
-        if !self.rejected_via_hash.is_empty() {
-            span_err!(self.sess, self.span, E0460,
-                      "found possibly newer version of crate `{}`{}",
-                      self.ident, add);
+        let mut err = if !self.rejected_via_hash.is_empty() {
+            struct_span_err!(self.sess, self.span, E0460,
+                             "found possibly newer version of crate `{}`{}",
+                             self.ident, add)
         } else if !self.rejected_via_triple.is_empty() {
-            span_err!(self.sess, self.span, E0461,
-                      "couldn't find crate `{}` with expected target triple {}{}",
-                      self.ident, self.triple, add);
+            struct_span_err!(self.sess, self.span, E0461,
+                             "couldn't find crate `{}` with expected target triple {}{}",
+                             self.ident, self.triple, add)
         } else if !self.rejected_via_kind.is_empty() {
-            span_err!(self.sess, self.span, E0462,
-                      "found staticlib `{}` instead of rlib or dylib{}",
-                      self.ident, add);
+            struct_span_err!(self.sess, self.span, E0462,
+                             "found staticlib `{}` instead of rlib or dylib{}",
+                             self.ident, add)
         } else {
-            span_err!(self.sess, self.span, E0463,
-                      "can't find crate for `{}`{}",
-                      self.ident, add);
-        }
+            struct_span_err!(self.sess, self.span, E0463,
+                             "can't find crate for `{}`{}",
+                             self.ident, add)
+        };
 
         if !self.rejected_via_triple.is_empty() {
             let mismatches = self.rejected_via_triple.iter();
             for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() {
-                self.sess.fileline_note(self.span,
+                err.fileline_note(self.span,
                     &format!("crate `{}`, path #{}, triple {}: {}",
                             self.ident, i+1, got, path.display()));
             }
         }
         if !self.rejected_via_hash.is_empty() {
-            self.sess.span_note(self.span, "perhaps this crate needs \
+            err.span_note(self.span, "perhaps this crate needs \
                                             to be recompiled?");
             let mismatches = self.rejected_via_hash.iter();
             for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
-                self.sess.fileline_note(self.span,
+                err.fileline_note(self.span,
                     &format!("crate `{}` path #{}: {}",
                             self.ident, i+1, path.display()));
             }
@@ -354,7 +354,7 @@ pub fn report_load_errs(&mut self) {
                 &None => {}
                 &Some(ref r) => {
                     for (i, path) in r.paths().iter().enumerate() {
-                        self.sess.fileline_note(self.span,
+                        err.fileline_note(self.span,
                             &format!("crate `{}` path #{}: {}",
                                     r.ident, i+1, path.display()));
                     }
@@ -362,15 +362,17 @@ pub fn report_load_errs(&mut self) {
             }
         }
         if !self.rejected_via_kind.is_empty() {
-            self.sess.fileline_help(self.span, "please recompile this crate using \
-                                            --crate-type lib");
+            err.fileline_help(self.span, "please recompile this crate using \
+                                          --crate-type lib");
             let mismatches = self.rejected_via_kind.iter();
             for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
-                self.sess.fileline_note(self.span,
-                                        &format!("crate `{}` path #{}: {}",
-                                                 self.ident, i+1, path.display()));
+                err.fileline_note(self.span,
+                                  &format!("crate `{}` path #{}: {}",
+                                           self.ident, i+1, path.display()));
             }
         }
+
+        err.emit();
         self.sess.abort_if_errors();
     }
 
@@ -480,29 +482,30 @@ fn find_library_crate(&mut self) -> Option<Library> {
             0 => None,
             1 => Some(libraries.into_iter().next().unwrap()),
             _ => {
-                span_err!(self.sess, self.span, E0464,
-                          "multiple matching crates for `{}`",
-                          self.crate_name);
-                self.sess.note("candidates:");
+                let mut err = struct_span_err!(self.sess, self.span, E0464,
+                                               "multiple matching crates for `{}`",
+                                               self.crate_name);
+                err.note("candidates:");
                 for lib in &libraries {
                     match lib.dylib {
                         Some((ref p, _)) => {
-                            self.sess.note(&format!("path: {}",
-                                                   p.display()));
+                            err.note(&format!("path: {}",
+                                              p.display()));
                         }
                         None => {}
                     }
                     match lib.rlib {
                         Some((ref p, _)) => {
-                            self.sess.note(&format!("path: {}",
-                                                    p.display()));
+                            err.note(&format!("path: {}",
+                                              p.display()));
                         }
                         None => {}
                     }
                     let data = lib.metadata.as_slice();
                     let name = decoder::get_crate_name(data);
-                    note_crate_name(self.sess.diagnostic(), &name);
+                    note_crate_name(&mut err, &name);
                 }
+                err.emit();
                 None
             }
         }
@@ -533,6 +536,7 @@ fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str,
             }
         }
 
+        let mut err: Option<DiagnosticBuilder> = None;
         for (lib, kind) in m {
             info!("{} reading metadata from: {}", flavor, lib.display());
             let metadata = match get_metadata_section(self.target, &lib) {
@@ -555,27 +559,37 @@ fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str,
             // candidates have the same hash, so they're not actually
             // duplicates that we should warn about.
             if ret.is_some() && self.hash.is_none() {
-                span_err!(self.sess, self.span, E0465,
-                          "multiple {} candidates for `{}` found",
-                          flavor, self.crate_name);
-                self.sess.span_note(self.span,
-                                    &format!(r"candidate #1: {}",
-                                            ret.as_ref().unwrap().0
-                                               .display()));
+                let mut e = struct_span_err!(self.sess, self.span, E0465,
+                                             "multiple {} candidates for `{}` found",
+                                             flavor, self.crate_name);
+                e.span_note(self.span,
+                            &format!(r"candidate #1: {}",
+                                     ret.as_ref().unwrap().0
+                                        .display()));
+                if let Some(ref mut e) = err {
+                    e.emit();
+                }
+                err = Some(e);
                 error = 1;
                 ret = None;
             }
             if error > 0 {
                 error += 1;
-                self.sess.span_note(self.span,
-                                    &format!(r"candidate #{}: {}", error,
-                                            lib.display()));
+                err.as_mut().unwrap().span_note(self.span,
+                                                &format!(r"candidate #{}: {}", error,
+                                                         lib.display()));
                 continue
             }
             *slot = Some(metadata);
             ret = Some((lib, kind));
         }
-        return if error > 0 {None} else {ret}
+
+        if error > 0 {
+            err.unwrap().emit();
+            None
+        } else {
+            ret
+        }
     }
 
     fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> bool {
@@ -662,10 +676,11 @@ fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
                         return true
                     }
                 }
-                sess.err(&format!("extern location for {} is of an unknown type: {}",
-                                 self.crate_name, loc.display()));
-                sess.help(&format!("file name should be lib*.rlib or {}*.{}",
-                                   dylibname.0, dylibname.1));
+                sess.struct_err(&format!("extern location for {} is of an unknown type: {}",
+                                         self.crate_name, loc.display()))
+                    .help(&format!("file name should be lib*.rlib or {}*.{}",
+                                   dylibname.0, dylibname.1))
+                    .emit();
                 false
             });
 
@@ -699,8 +714,8 @@ fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
     }
 }
 
-pub fn note_crate_name(diag: &Handler, name: &str) {
-    diag.note(&format!("crate name: {}", name));
+pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) {
+    err.note(&format!("crate name: {}", name));
 }
 
 impl ArchiveMetadata {
index 476425a75c22df73bb61953d0bf6cb2a124130bf..5adde4304f57c9541b56f76523f0be4655863cb1 100644 (file)
@@ -46,10 +46,11 @@ pub fn find_plugin_registrar(diagnostic: &errors::Handler,
             Some(node_id)
         },
         _ => {
-            diagnostic.err("multiple plugin registration functions found");
+            let mut e = diagnostic.struct_err("multiple plugin registration functions found");
             for &(_, span) in &finder.registrars {
-                diagnostic.span_note(span, "one is here");
+                e.span_note(span, "one is here");
             }
+            e.emit();
             diagnostic.abort_if_errors();
             unreachable!();
         }
index d1a894c61f7e205feacf8ca75c08a0932addda84..1cc2482a39e2787c957fd0762cf45cd5990d5cc1 100644 (file)
@@ -597,13 +597,11 @@ fn report_error(&self, result: CheckResult) -> bool {
         match result {
             None => true,
             Some((span, msg, note)) => {
-                self.tcx.sess.span_err(span, &msg[..]);
-                match note {
-                    Some((span, msg)) => {
-                        self.tcx.sess.span_note(span, &msg[..])
-                    }
-                    None => {},
+                let mut err = self.tcx.sess.struct_span_err(span, &msg[..]);
+                if let Some((span, msg)) = note {
+                    err.span_note(span, &msg[..]);
                 }
+                err.emit();
                 false
             },
         }
@@ -1028,10 +1026,12 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
     fn check_sane_privacy(&self, item: &hir::Item) {
         let check_inherited = |sp, vis, note: &str| {
             if vis != hir::Inherited {
-                span_err!(self.tcx.sess, sp, E0449, "unnecessary visibility qualifier");
+                let mut err = struct_span_err!(self.tcx.sess, sp, E0449,
+                                               "unnecessary visibility qualifier");
                 if !note.is_empty() {
-                    self.tcx.sess.span_note(sp, note);
+                    err.span_note(sp, note);
                 }
+                err.emit();
             }
         };
 
index 11d09fa3e9a6b841d4ba85c6fc650c6651f721e8..1d3f2b79844ea0094120458537cc139239d58055 100644 (file)
@@ -24,7 +24,7 @@
 use ParentLink::{self, ModuleParentLink, BlockParentLink};
 use Resolver;
 use resolve_imports::Shadowable;
-use {resolve_error, ResolutionError};
+use {resolve_error, resolve_struct_error, ResolutionError};
 
 use self::DuplicateCheckingMode::*;
 
@@ -137,12 +137,16 @@ fn add_child(&self,
 
                 // Record an error here by looking up the namespace that had the duplicate
                 let ns_str = match ns { TypeNS => "type or module", ValueNS => "value" };
-                resolve_error(self, sp, ResolutionError::DuplicateDefinition(ns_str, name));
+                let mut err = resolve_struct_error(self,
+                                                   sp,
+                                                   ResolutionError::DuplicateDefinition(ns_str,
+                                                                                        name));
 
                 if let Some(sp) = child[ns].span() {
                     let note = format!("first definition of {} `{}` here", ns_str, name);
-                    self.session.span_note(sp, &note);
+                    err.span_note(sp, &note);
                 }
+                err.emit();
                 child
             }
         }
@@ -253,13 +257,13 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
                                                     })
                                                     .collect::<Vec<Span>>();
                         if mod_spans.len() > 1 {
-                            resolve_error(self,
+                            let mut e = resolve_struct_error(self,
                                           mod_spans[0],
                                           ResolutionError::SelfImportCanOnlyAppearOnceInTheList);
                             for other_span in mod_spans.iter().skip(1) {
-                                self.session
-                                    .span_note(*other_span, "another `self` import appears here");
+                                e.span_note(*other_span, "another `self` import appears here");
                             }
+                            e.emit();
                         }
 
                         for source_item in source_items {
index 3647fd5ce190abca72bf3c9ab7f20dab7e359cda..5a17f2528c85b1aec723b921324e8c195a8ba41d 100644 (file)
@@ -63,8 +63,9 @@
 use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64};
 use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32};
 use syntax::attr::AttrMetaMethods;
-use syntax::parse::token::{self, special_names, special_idents};
 use syntax::codemap::{self, Span, Pos};
+use syntax::errors::DiagnosticBuilder;
+use syntax::parse::token::{self, special_names, special_idents};
 use syntax::util::lev_distance::find_best_match_for_name;
 
 use rustc_front::intravisit::{self, FnKind, Visitor};
@@ -215,210 +216,221 @@ pub enum UnresolvedNameContext {
 fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                                        span: syntax::codemap::Span,
                                        resolution_error: ResolutionError<'b>) {
+    resolve_struct_error(resolver, span, resolution_error).emit();
+}
+
+fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
+                                              span: syntax::codemap::Span,
+                                              resolution_error: ResolutionError<'b>)
+                                              -> DiagnosticBuilder<'a> {
     if !resolver.emit_errors {
-        return;
+        return resolver.session.diagnostic().struct_dummy();
     }
+
     match resolution_error {
         ResolutionError::TypeParametersFromOuterFunction => {
-            span_err!(resolver.session,
-                      span,
-                      E0401,
-                      "can't use type parameters from outer function; try using a local type \
-                       parameter instead");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0401,
+                             "can't use type parameters from outer function; try using a local \
+                              type parameter instead")
         }
         ResolutionError::OuterTypeParameterContext => {
-            span_err!(resolver.session,
-                      span,
-                      E0402,
-                      "cannot use an outer type parameter in this context");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0402,
+                             "cannot use an outer type parameter in this context")
         }
         ResolutionError::NameAlreadyUsedInTypeParameterList(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0403,
-                      "the name `{}` is already used for a type parameter in this type parameter \
-                       list",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0403,
+                             "the name `{}` is already used for a type parameter in this type \
+                              parameter list",
+                             name)
         }
         ResolutionError::IsNotATrait(name) => {
-            span_err!(resolver.session, span, E0404, "`{}` is not a trait", name);
+            struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
         }
         ResolutionError::UndeclaredTraitName(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0405,
-                      "use of undeclared trait name `{}`",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0405,
+                             "use of undeclared trait name `{}`",
+                             name)
         }
         ResolutionError::UndeclaredAssociatedType => {
-            span_err!(resolver.session, span, E0406, "undeclared associated type");
+            struct_span_err!(resolver.session, span, E0406, "undeclared associated type")
         }
         ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
-            span_err!(resolver.session,
-                      span,
-                      E0407,
-                      "method `{}` is not a member of trait `{}`",
-                      method,
-                      trait_);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0407,
+                             "method `{}` is not a member of trait `{}`",
+                             method,
+                             trait_)
         }
         ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
-            span_err!(resolver.session,
-                      span,
-                      E0437,
-                      "type `{}` is not a member of trait `{}`",
-                      type_,
-                      trait_);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0437,
+                             "type `{}` is not a member of trait `{}`",
+                             type_,
+                             trait_)
         }
         ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
-            span_err!(resolver.session,
-                      span,
-                      E0438,
-                      "const `{}` is not a member of trait `{}`",
-                      const_,
-                      trait_);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0438,
+                             "const `{}` is not a member of trait `{}`",
+                             const_,
+                             trait_)
         }
         ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
-            span_err!(resolver.session,
-                      span,
-                      E0408,
-                      "variable `{}` from pattern #1 is not bound in pattern #{}",
-                      variable_name,
-                      pattern_number);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0408,
+                             "variable `{}` from pattern #1 is not bound in pattern #{}",
+                             variable_name,
+                             pattern_number)
         }
         ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
-            span_err!(resolver.session,
-                      span,
-                      E0409,
-                      "variable `{}` is bound with different mode in pattern #{} than in pattern \
-                       #1",
-                      variable_name,
-                      pattern_number);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0409,
+                             "variable `{}` is bound with different mode in pattern #{} than in \
+                              pattern #1",
+                             variable_name,
+                             pattern_number)
         }
         ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
-            span_err!(resolver.session,
-                      span,
-                      E0410,
-                      "variable `{}` from pattern #{} is not bound in pattern #1",
-                      variable_name,
-                      pattern_number);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0410,
+                             "variable `{}` from pattern #{} is not bound in pattern #1",
+                             variable_name,
+                             pattern_number)
         }
         ResolutionError::SelfUsedOutsideImplOrTrait => {
-            span_err!(resolver.session,
-                      span,
-                      E0411,
-                      "use of `Self` outside of an impl or trait");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0411,
+                             "use of `Self` outside of an impl or trait")
         }
         ResolutionError::UseOfUndeclared(kind, name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0412,
-                      "use of undeclared {} `{}`",
-                      kind,
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0412,
+                             "use of undeclared {} `{}`",
+                             kind,
+                             name)
         }
         ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0413,
-                      "declaration of `{}` shadows an enum variant or unit-like struct in scope",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0413,
+                             "declaration of `{}` shadows an enum variant \
+                              or unit-like struct in scope",
+                             name)
         }
         ResolutionError::OnlyIrrefutablePatternsAllowedHere(did, name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0414,
-                      "only irrefutable patterns allowed here");
-            resolver.session.span_note(span,
-                                       "there already is a constant in scope sharing the same \
-                                        name as this pattern");
+            let mut err = struct_span_err!(resolver.session,
+                                           span,
+                                           E0414,
+                                           "only irrefutable patterns allowed here");
+            err.span_note(span,
+                          "there already is a constant in scope sharing the same \
+                           name as this pattern");
             if let Some(sp) = resolver.ast_map.span_if_local(did) {
-                resolver.session.span_note(sp, "constant defined here");
+                err.span_note(sp, "constant defined here");
             }
             if let Some(directive) = resolver.current_module
                                              .import_resolutions
                                              .borrow()
                                              .get(&name) {
                 let item = resolver.ast_map.expect_item(directive.value_ns.id);
-                resolver.session.span_note(item.span, "constant imported here");
+                err.span_note(item.span, "constant imported here");
             }
+            err
         }
         ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
-            span_err!(resolver.session,
-                      span,
-                      E0415,
-                      "identifier `{}` is bound more than once in this parameter list",
-                      identifier);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0415,
+                             "identifier `{}` is bound more than once in this parameter list",
+                             identifier)
         }
         ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
-            span_err!(resolver.session,
-                      span,
-                      E0416,
-                      "identifier `{}` is bound more than once in the same pattern",
-                      identifier);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0416,
+                             "identifier `{}` is bound more than once in the same pattern",
+                             identifier)
         }
         ResolutionError::StaticVariableReference => {
-            span_err!(resolver.session,
-                      span,
-                      E0417,
-                      "static variables cannot be referenced in a pattern, use a `const` instead");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0417,
+                             "static variables cannot be referenced in a pattern, use a \
+                              `const` instead")
         }
         ResolutionError::NotAnEnumVariantStructOrConst(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0418,
-                      "`{}` is not an enum variant, struct or const",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0418,
+                             "`{}` is not an enum variant, struct or const",
+                             name)
         }
         ResolutionError::UnresolvedEnumVariantStructOrConst(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0419,
-                      "unresolved enum variant, struct or const `{}`",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0419,
+                             "unresolved enum variant, struct or const `{}`",
+                             name)
         }
         ResolutionError::NotAnAssociatedConst(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0420,
-                      "`{}` is not an associated const",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0420,
+                             "`{}` is not an associated const",
+                             name)
         }
         ResolutionError::UnresolvedAssociatedConst(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0421,
-                      "unresolved associated const `{}`",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0421,
+                             "unresolved associated const `{}`",
+                             name)
         }
         ResolutionError::DoesNotNameAStruct(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0422,
-                      "`{}` does not name a structure",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0422,
+                             "`{}` does not name a structure",
+                             name)
         }
         ResolutionError::StructVariantUsedAsFunction(path_name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0423,
-                      "`{}` is the name of a struct or struct variant, but this expression uses \
-                       it like a function name",
-                      path_name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0423,
+                             "`{}` is the name of a struct or struct variant, but this expression \
+                             uses it like a function name",
+                             path_name)
         }
         ResolutionError::SelfNotAvailableInStaticMethod => {
-            span_err!(resolver.session,
-                      span,
-                      E0424,
-                      "`self` is not available in a static method. Maybe a `self` argument is \
-                       missing?");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0424,
+                             "`self` is not available in a static method. Maybe a `self` \
+                             argument is missing?")
         }
         ResolutionError::UnresolvedName(path, msg, context) => {
-            span_err!(resolver.session,
-                      span,
-                      E0425,
-                      "unresolved name `{}`{}",
-                      path,
-                      msg);
+            let mut err = struct_span_err!(resolver.session,
+                                           span,
+                                           E0425,
+                                           "unresolved name `{}`{}",
+                                           path,
+                                           msg);
 
             match context {
                 UnresolvedNameContext::Other => {} // no help available
@@ -448,75 +460,77 @@ fn resolve_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
                     }
 
                     if !help_msg.is_empty() {
-                        resolver.session.fileline_help(span, &help_msg);
+                        err.fileline_help(span, &help_msg);
                     }
                 }
             }
+            err
         }
         ResolutionError::UndeclaredLabel(name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0426,
-                      "use of undeclared label `{}`",
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0426,
+                             "use of undeclared label `{}`",
+                             name)
         }
         ResolutionError::CannotUseRefBindingModeWith(descr) => {
-            span_err!(resolver.session,
-                      span,
-                      E0427,
-                      "cannot use `ref` binding mode with {}",
-                      descr);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0427,
+                             "cannot use `ref` binding mode with {}",
+                             descr)
         }
         ResolutionError::DuplicateDefinition(namespace, name) => {
-            span_err!(resolver.session,
-                      span,
-                      E0428,
-                      "duplicate definition of {} `{}`",
-                      namespace,
-                      name);
+            struct_span_err!(resolver.session,
+                             span,
+                             E0428,
+                             "duplicate definition of {} `{}`",
+                             namespace,
+                             name)
         }
         ResolutionError::SelfImportsOnlyAllowedWithin => {
-            span_err!(resolver.session,
-                      span,
-                      E0429,
-                      "{}",
-                      "`self` imports are only allowed within a { } list");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0429,
+                             "{}",
+                             "`self` imports are only allowed within a { } list")
         }
         ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
-            span_err!(resolver.session,
-                      span,
-                      E0430,
-                      "`self` import can only appear once in the list");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0430,
+                             "`self` import can only appear once in the list")
         }
         ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
-            span_err!(resolver.session,
-                      span,
-                      E0431,
-                      "`self` import can only appear in an import list with a non-empty prefix");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0431,
+                             "`self` import can only appear in an import list with a \
+                              non-empty prefix")
         }
         ResolutionError::UnresolvedImport(name) => {
             let msg = match name {
                 Some((n, p)) => format!("unresolved import `{}`{}", n, p),
                 None => "unresolved import".to_owned(),
             };
-            span_err!(resolver.session, span, E0432, "{}", msg);
+            struct_span_err!(resolver.session, span, E0432, "{}", msg)
         }
         ResolutionError::FailedToResolve(msg) => {
-            span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg);
+            struct_span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg)
         }
         ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
-            span_err!(resolver.session,
-                      span,
-                      E0434,
-                      "{}",
-                      "can't capture dynamic environment in a fn item; use the || { ... } \
-                       closure form instead");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0434,
+                             "{}",
+                             "can't capture dynamic environment in a fn item; use the || { ... } \
+                              closure form instead")
         }
         ResolutionError::AttemptToUseNonConstantValueInConstant => {
-            span_err!(resolver.session,
-                      span,
-                      E0435,
-                      "attempt to use a non-constant value in a constant");
+            struct_span_err!(resolver.session,
+                             span,
+                             E0435,
+                             "attempt to use a non-constant value in a constant")
         }
     }
 }
@@ -2180,16 +2194,18 @@ fn resolve_trait_reference(&mut self,
                 debug!("(resolving trait) found trait def: {:?}", path_res);
                 Ok(path_res)
             } else {
-                resolve_error(self,
-                              trait_path.span,
-                              ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
-                                                                                  path_depth)));
+                let mut err =
+                    resolve_struct_error(self,
+                                  trait_path.span,
+                                  ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
+                                                                                      path_depth)));
 
                 // If it's a typedef, give a note
                 if let DefTy(..) = path_res.base_def {
-                    self.session
-                        .span_note(trait_path.span, "`type` aliases cannot be used for traits");
+                    err.span_note(trait_path.span,
+                                  "`type` aliases cannot be used for traits");
                 }
+                err.emit();
                 Err(())
             }
         } else {
@@ -3470,17 +3486,18 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     if let DefVariant(_, _, true) = path_res.base_def {
                         let path_name = path_names_to_string(path, 0);
 
-                        resolve_error(self,
-                                      expr.span,
-                                      ResolutionError::StructVariantUsedAsFunction(&*path_name));
+                        let mut err = resolve_struct_error(self,
+                                        expr.span,
+                                        ResolutionError::StructVariantUsedAsFunction(&*path_name));
 
                         let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                           path_name);
                         if self.emit_errors {
-                            self.session.fileline_help(expr.span, &msg);
+                            err.fileline_help(expr.span, &msg);
                         } else {
-                            self.session.span_help(expr.span, &msg);
+                            err.span_help(expr.span, &msg);
                         }
+                        err.emit();
                         self.record_def(expr.id, err_path_resolution());
                     } else {
                         // Write the result into the def map.
@@ -3510,20 +3527,18 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     self.record_def(expr.id, err_path_resolution());
                     match type_res.map(|r| r.base_def) {
                         Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
-                            resolve_error(
-                                    self,
-                                    expr.span,
-                                    ResolutionError::StructVariantUsedAsFunction(
-                                        &*path_name)
-                                );
+                            let mut err = resolve_struct_error(self,
+                                expr.span,
+                                ResolutionError::StructVariantUsedAsFunction(&*path_name));
 
                             let msg = format!("did you mean to write: `{} {{ /* fields */ }}`?",
                                               path_name);
                             if self.emit_errors {
-                                self.session.fileline_help(expr.span, &msg);
+                                err.fileline_help(expr.span, &msg);
                             } else {
-                                self.session.span_help(expr.span, &msg);
+                                err.span_help(expr.span, &msg);
                             }
+                            err.emit();
                         }
                         _ => {
                             // Keep reporting some errors even if they're ignored above.
index 8b35f4d68df3bffb478353a3ebbcfcc5a071dce0..40bf55efde645eb31e8d45c8fe733015a46d066a 100644 (file)
@@ -454,8 +454,9 @@ fn resolve_single_import(&mut self,
                         let note_msg = format!("Consider marking `{}` as `pub` in the imported \
                                                 module",
                                                source);
-                        span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
-                        self.resolver.session.span_note(directive.span, &note_msg);
+                        struct_span_err!(self.resolver.session, directive.span, E0364, "{}", &msg)
+                            .span_note(directive.span, &note_msg)
+                            .emit();
                         pub_err = true;
                     }
                     if directive.is_public && child_name_bindings.value_ns.
@@ -479,8 +480,9 @@ fn resolve_single_import(&mut self,
                         let msg = format!("`{}` is private, and cannot be reexported", source);
                         let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
                                                source);
-                        span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
-                        self.resolver.session.span_note(directive.span, &note_msg);
+                        struct_span_err!(self.resolver.session, directive.span, E0365, "{}", &msg)
+                            .span_note(directive.span, &note_msg)
+                            .emit();
                     }
                     if !pub_err && directive.is_public && child_name_bindings.type_ns.
                                                     defined_with(DefModifiers::PRIVATE_VARIANT) {
@@ -959,19 +961,20 @@ fn check_for_conflicting_import(&mut self,
                     }
                     ValueNS => "value",
                 };
-                span_err!(self.resolver.session,
-                          import_span,
-                          E0252,
-                          "a {} named `{}` has already been imported in this module",
-                          ns_word,
-                          name);
                 let use_id = import_resolution[namespace].id;
                 let item = self.resolver.ast_map.expect_item(use_id);
-                // item is syntax::ast::Item;
-                span_note!(self.resolver.session,
+                let mut err = struct_span_err!(self.resolver.session,
+                                               import_span,
+                                               E0252,
+                                               "a {} named `{}` has already been imported \
+                                                in this module",
+                                               ns_word,
+                                               name);
+                span_note!(&mut err,
                            item.span,
                            "previous import of `{}` here",
                            name);
+                err.emit();
             }
             Some(_) | None => {}
         }
@@ -1022,14 +1025,16 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
         match import.value_ns.target {
             Some(ref target) if target.shadowable != Shadowable::Always => {
                 if let Some(ref value) = *name_bindings.value_ns.borrow() {
-                    span_err!(self.resolver.session,
-                              import_span,
-                              E0255,
-                              "import `{}` conflicts with value in this module",
-                              name);
+                    let mut err = struct_span_err!(self.resolver.session,
+                                                   import_span,
+                                                   E0255,
+                                                   "import `{}` conflicts with \
+                                                    value in this module",
+                                                   name);
                     if let Some(span) = value.span {
-                        self.resolver.session.span_note(span, "conflicting value here");
+                        err.span_note(span, "conflicting value here");
                     }
+                    err.emit();
                 }
             }
             Some(_) | None => {}
@@ -1045,15 +1050,16 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
                             ("trait in this module", "note conflicting trait here"),
                         _ => ("type in this module", "note conflicting type here"),
                     };
-                    span_err!(self.resolver.session,
-                              import_span,
-                              E0256,
-                              "import `{}` conflicts with {}",
-                              name,
-                              what);
+                    let mut err = struct_span_err!(self.resolver.session,
+                                                   import_span,
+                                                   E0256,
+                                                   "import `{}` conflicts with {}",
+                                                   name,
+                                                   what);
                     if let Some(span) = ty.span {
-                        self.resolver.session.span_note(span, note);
+                        err.span_note(span, note);
                     }
+                    err.emit();
                 }
             }
             Some(_) | None => {}
index f5431554a75642547f975b38cd8237908199ef9d..850608588234cf3ee7ccb9cc4587a5d51092cc1c 100644 (file)
@@ -406,11 +406,12 @@ fn run(&self, cwd: Option<&Path>, action: Action) -> Output {
             Ok(prog) => {
                 let o = prog.wait_with_output().unwrap();
                 if !o.status.success() {
-                    sess.err(&format!("{:?} failed with: {}", cmd, o.status));
-                    sess.note(&format!("stdout ---\n{}",
-                                       str::from_utf8(&o.stdout).unwrap()));
-                    sess.note(&format!("stderr ---\n{}",
-                                       str::from_utf8(&o.stderr).unwrap()));
+                    sess.struct_err(&format!("{:?} failed with: {}", cmd, o.status))
+                        .note(&format!("stdout ---\n{}",
+                                       str::from_utf8(&o.stdout).unwrap()))
+                        .note(&format!("stderr ---\n{}",
+                                       str::from_utf8(&o.stderr).unwrap()))
+                        .emit();
                     sess.abort_if_errors();
                 }
                 o
index 1e5bac85ffc068bbf6aaba83915126601de3139e..8446db65a4ccb3aab6d81aa72573aa8f2b5254c7 100644 (file)
@@ -817,10 +817,10 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
     ab.build();
 
     if !all_native_libs.is_empty() {
-        sess.note("link against the following native artifacts when linking against \
-                  this static library");
-        sess.note("the order and any duplication can be significant on some platforms, \
-                  and so may need to be preserved");
+        sess.note_without_error("link against the following native artifacts when linking against \
+                                 this static library");
+        sess.note_without_error("the order and any duplication can be significant on some \
+                                 platforms, and so may need to be preserved");
     }
 
     for &(kind, ref lib) in &all_native_libs {
@@ -829,7 +829,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
             NativeLibraryKind::NativeUnknown => "library",
             NativeLibraryKind::NativeFramework => "framework",
         };
-        sess.note(&format!("{}: {}", name, *lib));
+        sess.note_without_error(&format!("{}: {}", name, *lib));
     }
 }
 
@@ -902,13 +902,14 @@ fn escape_string(s: &[u8]) -> String {
                     })
             }
             if !prog.status.success() {
-                sess.err(&format!("linking with `{}` failed: {}",
-                                 pname,
-                                 prog.status));
-                sess.note(&format!("{:?}", &cmd));
                 let mut output = prog.stderr.clone();
                 output.extend_from_slice(&prog.stdout);
-                sess.note(&*escape_string(&output[..]));
+                sess.struct_err(&format!("linking with `{}` failed: {}",
+                                         pname,
+                                         prog.status))
+                    .note(&format!("{:?}", &cmd))
+                    .note(&*escape_string(&output[..]))
+                    .emit();
                 sess.abort_if_errors();
             }
             info!("linker stderr:\n{}", escape_string(&prog.stderr[..]));
index 8505c3968ee15ea761187821777340880c96416d..85419a072503a59ccfeb260813d13352f8c99f5d 100644 (file)
@@ -29,8 +29,9 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
            name_extra: &str,
            output_names: &config::OutputFilenames) {
     if sess.opts.cg.prefer_dynamic {
-        sess.err("cannot prefer dynamic linking when performing LTO");
-        sess.note("only 'staticlib' and 'bin' outputs are supported with LTO");
+        sess.struct_err("cannot prefer dynamic linking when performing LTO")
+            .note("only 'staticlib' and 'bin' outputs are supported with LTO")
+            .emit();
         sess.abort_if_errors();
     }
 
index 67eff1ca19fbc1957764576c1e213aa9245142fa..9d0a83fe3635046e7828db0f438209356d3c74b3 100644 (file)
@@ -359,8 +359,9 @@ struct HandlerFreeVars<'a> {
         }
 
         None => {
-            cgcx.handler.err(msg);
-            cgcx.handler.note("build without -C codegen-units for more exact errors");
+            cgcx.handler.struct_err(msg)
+                        .note("build without -C codegen-units for more exact errors")
+                        .emit();
         }
     }
 }
@@ -397,11 +398,11 @@ struct HandlerFreeVars<'a> {
 
             if enabled {
                 let loc = llvm::debug_loc_to_string(llcx, opt.debug_loc);
-                cgcx.handler.note(&format!("optimization {} for {} at {}: {}",
-                                           opt.kind.describe(),
-                                           pass_name,
-                                           if loc.is_empty() { "[unknown]" } else { &*loc },
-                                           llvm::twine_to_string(opt.message)));
+                cgcx.handler.note_without_error(&format!("optimization {} for {} at {}: {}",
+                                                opt.kind.describe(),
+                                                pass_name,
+                                                if loc.is_empty() { "[unknown]" } else { &*loc },
+                                                llvm::twine_to_string(opt.message)));
             }
         }
 
@@ -931,13 +932,15 @@ pub fn run_assembler(sess: &Session, outputs: &OutputFilenames) {
     match cmd.output() {
         Ok(prog) => {
             if !prog.status.success() {
-                sess.err(&format!("linking with `{}` failed: {}",
-                                 pname,
-                                 prog.status));
-                sess.note(&format!("{:?}", &cmd));
                 let mut note = prog.stderr.clone();
                 note.extend_from_slice(&prog.stdout);
-                sess.note(str::from_utf8(&note[..]).unwrap());
+
+                sess.struct_err(&format!("linking with `{}` failed: {}",
+                                         pname,
+                                         prog.status))
+                    .note(&format!("{:?}", &cmd))
+                    .note(str::from_utf8(&note[..]).unwrap())
+                    .emit();
                 sess.abort_if_errors();
             }
         },
index 9c6b54e13796de6b9e2682a0a9c50978b841db8e..c34013a7bbbb1b56d8955e44954e748ec32ba02d 100644 (file)
@@ -682,7 +682,7 @@ fn process_path(&mut self, id: NodeId, path: &ast::Path, ref_kind: Option<record
             def::DefMethod(did) => {
                 let ti = self.tcx.impl_or_trait_item(did);
                 if let ty::MethodTraitItem(m) = ti {
-                    if m.explicit_self == ty::StaticExplicitSelfCategory {
+                    if m.explicit_self == ty::ExplicitSelfCategory::Static {
                         self.write_sub_path_trait_truncated(path);
                     }
                 }
index 838a5435d4feee8b4a9c0e42b15e737a7cefc405..996e72bdad3250e55adc87a102e26125c5c13f9f 100644 (file)
@@ -2181,17 +2181,20 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span,
             }
     );
 
+    // FIXME(#30505) Should use logging for this.
     if print_info {
         let llty = type_of::sizing_type_of(ccx, ty);
 
         let sess = &ccx.tcx().sess;
-        sess.span_note(sp, &*format!("total size: {} bytes", llsize_of_real(ccx, llty)));
+        sess.span_note_without_error(sp,
+                                     &*format!("total size: {} bytes", llsize_of_real(ccx, llty)));
         match *avar {
             adt::General(..) => {
                 for (i, var) in enum_def.variants.iter().enumerate() {
                     ccx.tcx()
                        .sess
-                       .span_note(var.span, &*format!("variant data: {} bytes", sizes[i]));
+                       .span_note_without_error(var.span,
+                                                &*format!("variant data: {} bytes", sizes[i]));
                 }
             }
             _ => {}
@@ -2203,16 +2206,16 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &hir::EnumDef, sp: Span,
     if !is_allow && largest > slargest * 3 && slargest > 0 {
         // Use lint::raw_emit_lint rather than sess.add_lint because the lint-printing
         // pass for the latter already ran.
-        lint::raw_emit_lint(&ccx.tcx().sess,
-                            lint::builtin::VARIANT_SIZE_DIFFERENCES,
-                            *lvlsrc.unwrap(),
-                            Some(sp),
-                            &format!("enum variant is more than three times larger ({} bytes) \
-                                      than the next largest (ignoring padding)",
-                                     largest));
-
-        ccx.sess().span_note(enum_def.variants[largest_index].span,
-                             "this variant is the largest");
+        lint::raw_struct_lint(&ccx.tcx().sess,
+                              lint::builtin::VARIANT_SIZE_DIFFERENCES,
+                              *lvlsrc.unwrap(),
+                              Some(sp),
+                              &format!("enum variant is more than three times larger ({} bytes) \
+                                        than the next largest (ignoring padding)",
+                                       largest))
+            .span_note(enum_def.variants[largest_index].span,
+                       "this variant is the largest")
+            .emit();
     }
 }
 
@@ -2489,9 +2492,10 @@ fn create_entry_fn(ccx: &CrateContext,
         let llfty = Type::func(&[ccx.int_type(), Type::i8p(ccx).ptr_to()], &ccx.int_type());
 
         let llfn = declare::define_cfn(ccx, "main", llfty, ccx.tcx().mk_nil()).unwrap_or_else(|| {
-            ccx.sess().span_err(sp, "entry symbol `main` defined multiple times");
             // FIXME: We should be smart and show a better diagnostic here.
-            ccx.sess().help("did you use #[no_mangle] on `fn main`? Use #[start] instead");
+            ccx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times")
+                      .help("did you use #[no_mangle] on `fn main`? Use #[start] instead")
+                      .emit();
             ccx.sess().abort_if_errors();
             panic!();
         });
index 9012ecaa2134fe5cde58e5e2dc7edc5fc4b55c6c..e6ad5ac4f063a90b7a86a933254245f05b992dfc 100644 (file)
@@ -460,12 +460,13 @@ fn gate_simd_ffi(tcx: &ty::ctxt, decl: &hir::FnDecl, ty: &ty::BareFnTy) {
     if !tcx.sess.features.borrow().simd_ffi {
         let check = |ast_ty: &hir::Ty, ty: ty::Ty| {
             if ty.is_simd() {
-                tcx.sess.span_err(ast_ty.span,
+                tcx.sess.struct_span_err(ast_ty.span,
                               &format!("use of SIMD type `{}` in FFI is highly experimental and \
                                         may result in invalid code",
-                                       pprust::ty_to_string(ast_ty)));
-                tcx.sess.fileline_help(ast_ty.span,
-                                   "add #![feature(simd_ffi)] to the crate attributes to enable");
+                                       pprust::ty_to_string(ast_ty)))
+                    .fileline_help(ast_ty.span,
+                                   "add #![feature(simd_ffi)] to the crate attributes to enable")
+                    .emit();
             }
         };
         let sig = &ty.sig.0;
index 5fbcb687f0968da1dcac5ae6f1fe57de7b979ff4..b57d3b107fb45c058f5a8a83beb682185c956333 100644 (file)
@@ -10,6 +10,7 @@
 
 use llvm::ValueRef;
 use rustc::middle::ty::{self, Ty};
+use middle::ty::cast::{CastTy, IntTy};
 use rustc::mir::repr as mir;
 
 use trans::asm;
@@ -199,7 +200,89 @@ pub fn trans_rvalue_operand(&mut self,
                             }
                         }
                     }
-                    mir::CastKind::Misc => unimplemented!()
+                    mir::CastKind::Misc if common::type_is_immediate(bcx.ccx(), operand.ty) => {
+                        debug_assert!(common::type_is_immediate(bcx.ccx(), cast_ty));
+                        let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
+                        let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
+                        let ll_t_in = type_of::arg_type_of(bcx.ccx(), operand.ty);
+                        let ll_t_out = type_of::arg_type_of(bcx.ccx(), cast_ty);
+                        let (llval, ll_t_in, signed) = if let CastTy::Int(IntTy::CEnum) = r_t_in {
+                            let repr = adt::represent_type(bcx.ccx(), operand.ty);
+                            let llval = operand.immediate();
+                            let discr = adt::trans_get_discr(bcx, &*repr, llval, None);
+                            (discr, common::val_ty(discr), adt::is_discr_signed(&*repr))
+                        } else {
+                            (operand.immediate(), ll_t_in, operand.ty.is_signed())
+                        };
+
+                        let newval = match (r_t_in, r_t_out) {
+                            (CastTy::Int(_), CastTy::Int(_)) => {
+                                let srcsz = ll_t_in.int_width();
+                                let dstsz = ll_t_out.int_width();
+                                if srcsz == dstsz {
+                                    build::BitCast(bcx, llval, ll_t_out)
+                                } else if srcsz > dstsz {
+                                    build::Trunc(bcx, llval, ll_t_out)
+                                } else if signed {
+                                    build::SExt(bcx, llval, ll_t_out)
+                                } else {
+                                    build::ZExt(bcx, llval, ll_t_out)
+                                }
+                            }
+                            (CastTy::Float, CastTy::Float) => {
+                                let srcsz = ll_t_in.float_width();
+                                let dstsz = ll_t_out.float_width();
+                                if dstsz > srcsz {
+                                    build::FPExt(bcx, llval, ll_t_out)
+                                } else if srcsz > dstsz {
+                                    build::FPTrunc(bcx, llval, ll_t_out)
+                                } else {
+                                    llval
+                                }
+                            }
+                            (CastTy::Ptr(_), CastTy::Ptr(_)) |
+                            (CastTy::FnPtr, CastTy::Ptr(_)) |
+                            (CastTy::RPtr(_), CastTy::Ptr(_)) =>
+                                build::PointerCast(bcx, llval, ll_t_out),
+                            (CastTy::Ptr(_), CastTy::Int(_)) |
+                            (CastTy::FnPtr, CastTy::Int(_)) =>
+                                build::PtrToInt(bcx, llval, ll_t_out),
+                            (CastTy::Int(_), CastTy::Ptr(_)) =>
+                                build::IntToPtr(bcx, llval, ll_t_out),
+                            (CastTy::Int(_), CastTy::Float) if signed =>
+                                build::SIToFP(bcx, llval, ll_t_out),
+                            (CastTy::Int(_), CastTy::Float) =>
+                                build::UIToFP(bcx, llval, ll_t_out),
+                            (CastTy::Float, CastTy::Int(IntTy::I)) =>
+                                build::FPToSI(bcx, llval, ll_t_out),
+                            (CastTy::Float, CastTy::Int(_)) =>
+                                build::FPToUI(bcx, llval, ll_t_out),
+                            _ => bcx.ccx().sess().bug(
+                                &format!("unsupported cast: {:?} to {:?}", operand.ty, cast_ty)
+                            )
+                        };
+                        OperandValue::Immediate(newval)
+                    }
+                    mir::CastKind::Misc => { // Casts from a fat-ptr.
+                        let ll_cast_ty = type_of::arg_type_of(bcx.ccx(), cast_ty);
+                        let ll_from_ty = type_of::arg_type_of(bcx.ccx(), operand.ty);
+                        if let OperandValue::FatPtr(data_ptr, meta_ptr) = operand.val {
+                            if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
+                                let ll_cft = ll_cast_ty.field_types();
+                                let ll_fft = ll_from_ty.field_types();
+                                let data_cast = build::PointerCast(bcx, data_ptr, ll_cft[0]);
+                                assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
+                                OperandValue::FatPtr(data_cast, meta_ptr)
+                            } else { // cast to thin-ptr
+                                // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
+                                // pointer-cast of that pointer to desired pointer type.
+                                let llval = build::PointerCast(bcx, data_ptr, ll_cast_ty);
+                                OperandValue::Immediate(llval)
+                            }
+                        } else {
+                            panic!("Unexpected non-FatPtr operand")
+                        }
+                    }
                 };
                 (bcx, OperandRef {
                     val: val,
index 95d85964044da7be0ef5175ed104128ecf6d213a..607daa823744405471502480d70a12b32675e1e4 100644 (file)
@@ -68,6 +68,7 @@
 
 use syntax::{abi, ast};
 use syntax::codemap::{Span, Pos};
+use syntax::errors::DiagnosticBuilder;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::parse::token;
 
@@ -195,7 +196,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &hir::Lifetime)
 }
 
 fn report_elision_failure(
-    tcx: &ty::ctxt,
+    db: &mut DiagnosticBuilder,
     default_span: Span,
     params: Vec<ElisionFailureInfo>)
 {
@@ -233,26 +234,26 @@ fn report_elision_failure(
     }
 
     if len == 0 {
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "this function's return type contains a borrowed value, but \
                         there is no value for it to be borrowed from");
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "consider giving it a 'static lifetime");
     } else if !any_lifetimes {
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "this function's return type contains a borrowed value with \
                         an elided lifetime, but the lifetime cannot be derived from \
                         the arguments");
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "consider giving it an explicit bounded or 'static \
                         lifetime");
     } else if len == 1 {
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "this function's return type contains a borrowed value, but \
                         the signature does not say which {} it is borrowed from",
                        m);
     } else {
-        fileline_help!(tcx.sess, default_span,
+        fileline_help!(db, default_span,
                        "this function's return type contains a borrowed value, but \
                         the signature does not say whether it is borrowed from {}",
                        m);
@@ -273,11 +274,12 @@ pub fn opt_ast_region_to_region<'tcx>(
         None => match rscope.anon_regions(default_span, 1) {
             Ok(rs) => rs[0],
             Err(params) => {
-                span_err!(this.tcx().sess, default_span, E0106,
-                          "missing lifetime specifier");
+                let mut err = struct_span_err!(this.tcx().sess, default_span, E0106,
+                                               "missing lifetime specifier");
                 if let Some(params) = params {
-                    report_elision_failure(this.tcx(), default_span, params);
+                    report_elision_failure(&mut err, default_span, params);
                 }
+                err.emit();
                 ty::ReStatic
             }
         }
@@ -1044,9 +1046,9 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
             }
         }
         _ => {
-            span_err!(this.tcx().sess, ty.span, E0178,
-                      "expected a path on the left-hand side of `+`, not `{}`",
-                      pprust::ty_to_string(ty));
+            let mut err = struct_span_err!(this.tcx().sess, ty.span, E0178,
+                                           "expected a path on the left-hand side of `+`, not `{}`",
+                                           pprust::ty_to_string(ty));
             let hi = bounds.iter().map(|x| match *x {
                 hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
                 hir::RegionTyParamBound(ref r) => r.span.hi,
@@ -1059,29 +1061,28 @@ fn ast_ty_to_trait_ref<'tcx>(this: &AstConv<'tcx>,
             match (&ty.node, full_span) {
                 (&hir::TyRptr(None, ref mut_ty), Some(full_span)) => {
                     let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
-                    this.tcx().sess
-                        .span_suggestion(full_span, "try adding parentheses (per RFC 438):",
-                                         format!("&{}({} +{})",
-                                                 mutbl_str,
-                                                 pprust::ty_to_string(&*mut_ty.ty),
-                                                 pprust::bounds_to_string(bounds)));
+                    err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
+                                        format!("&{}({} +{})",
+                                                mutbl_str,
+                                                pprust::ty_to_string(&*mut_ty.ty),
+                                                pprust::bounds_to_string(bounds)));
                 }
                 (&hir::TyRptr(Some(ref lt), ref mut_ty), Some(full_span)) => {
                     let mutbl_str = if mut_ty.mutbl == hir::MutMutable { "mut " } else { "" };
-                    this.tcx().sess
-                        .span_suggestion(full_span, "try adding parentheses (per RFC 438):",
-                                         format!("&{} {}({} +{})",
-                                                 pprust::lifetime_to_string(lt),
-                                                 mutbl_str,
-                                                 pprust::ty_to_string(&*mut_ty.ty),
-                                                 pprust::bounds_to_string(bounds)));
+                    err.span_suggestion(full_span, "try adding parentheses (per RFC 438):",
+                                        format!("&{} {}({} +{})",
+                                                pprust::lifetime_to_string(lt),
+                                                mutbl_str,
+                                                pprust::ty_to_string(&*mut_ty.ty),
+                                                pprust::bounds_to_string(bounds)));
                 }
 
                 _ => {
-                    fileline_help!(this.tcx().sess, ty.span,
+                    fileline_help!(&mut err, ty.span,
                                "perhaps you forgot parentheses? (per RFC 438)");
                 }
             }
+            err.emit();
             Err(ErrorReported)
         }
     }
@@ -1134,7 +1135,8 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>,
         traits::astconv_object_safety_violations(tcx, principal.def_id());
     if !object_safety_violations.is_empty() {
         traits::report_object_safety_error(
-            tcx, span, principal.def_id(), object_safety_violations);
+            tcx, span, principal.def_id(), object_safety_violations)
+            .emit();
         return tcx.types.err;
     }
 
@@ -1235,17 +1237,18 @@ fn one_bound_for_assoc_type<'tcx>(tcx: &ty::ctxt<'tcx>,
     }
 
     if bounds.len() > 1 {
-        span_err!(tcx.sess, span, E0221,
-                  "ambiguous associated type `{}` in bounds of `{}`",
-                  assoc_name,
-                  ty_param_name);
+        let mut err = struct_span_err!(tcx.sess, span, E0221,
+                                       "ambiguous associated type `{}` in bounds of `{}`",
+                                       assoc_name,
+                                       ty_param_name);
 
         for bound in &bounds {
-            span_note!(tcx.sess, span,
+            span_note!(&mut err, span,
                        "associated type `{}` could derive from `{}`",
                        ty_param_name,
                        bound);
         }
+        err.emit();
     }
 
     Ok(bounds[0].clone())
@@ -1707,12 +1710,13 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                     }
                 }
                 Err(ref r) => {
-                    span_err!(tcx.sess, r.span, E0250,
-                              "array length constant evaluation error: {}",
-                              r.description());
+                    let mut err = struct_span_err!(tcx.sess, r.span, E0250,
+                                                   "array length constant evaluation error: {}",
+                                                   r.description());
                     if !ast_ty.span.contains(r.span) {
-                        span_note!(tcx.sess, ast_ty.span, "for array length here")
+                        span_note!(&mut err, ast_ty.span, "for array length here")
                     }
+                    err.emit();
                     this.tcx().types.err
                 }
             }
@@ -1815,7 +1819,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx>(this: &AstConv<'tcx>,
     // reference) in the arguments, then any anonymous regions in the output
     // have that lifetime.
     let implied_output_region = match explicit_self_category {
-        Some(ty::ByReferenceExplicitSelfCategory(region, _)) => Ok(region),
+        Some(ty::ExplicitSelfCategory::ByReference(region, _)) => Ok(region),
         _ => find_implied_output_region(this.tcx(), &arg_tys, arg_pats)
     };
 
@@ -1846,9 +1850,9 @@ fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
 {
     let self_ty = self_info.untransformed_self_ty;
     return match self_info.explicit_self.node {
-        hir::SelfStatic => (None, Some(ty::StaticExplicitSelfCategory)),
+        hir::SelfStatic => (None, Some(ty::ExplicitSelfCategory::Static)),
         hir::SelfValue(_) => {
-            (Some(self_ty), Some(ty::ByValueExplicitSelfCategory))
+            (Some(self_ty), Some(ty::ExplicitSelfCategory::ByValue))
         }
         hir::SelfRegion(ref lifetime, mutability, _) => {
             let region =
@@ -1862,7 +1866,7 @@ fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
                     ty: self_ty,
                     mutbl: mutability
                 })),
-             Some(ty::ByReferenceExplicitSelfCategory(region, mutability)))
+             Some(ty::ExplicitSelfCategory::ByReference(region, mutability)))
         }
         hir::SelfExplicit(ref ast_type, _) => {
             let explicit_type = ast_ty_to_ty(this, rscope, &**ast_type);
@@ -1878,12 +1882,12 @@ fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
             // ```
             // impl Foo for &T {
             //     // Legal declarations:
-            //     fn method1(self: &&T); // ByReferenceExplicitSelfCategory
-            //     fn method2(self: &T); // ByValueExplicitSelfCategory
-            //     fn method3(self: Box<&T>); // ByBoxExplicitSelfCategory
+            //     fn method1(self: &&T); // ExplicitSelfCategory::ByReference
+            //     fn method2(self: &T); // ExplicitSelfCategory::ByValue
+            //     fn method3(self: Box<&T>); // ExplicitSelfCategory::ByBox
             //
             //     // Invalid cases will be caught later by `check_method_self_type`:
-            //     fn method_err1(self: &mut T); // ByReferenceExplicitSelfCategory
+            //     fn method_err1(self: &mut T); // ExplicitSelfCategory::ByReference
             // }
             // ```
             //
@@ -1894,7 +1898,7 @@ fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
             // call it by-ref, by-box as appropriate. For method1, for
             // example, the impl type has one modifier, but the method
             // type has two, so we end up with
-            // ByReferenceExplicitSelfCategory.
+            // ExplicitSelfCategory::ByReference.
 
             let impl_modifiers = count_modifiers(self_info.untransformed_self_ty);
             let method_modifiers = count_modifiers(explicit_type);
@@ -1908,12 +1912,12 @@ fn determine_self_type<'a, 'tcx>(this: &AstConv<'tcx>,
                    method_modifiers);
 
             let category = if impl_modifiers >= method_modifiers {
-                ty::ByValueExplicitSelfCategory
+                ty::ExplicitSelfCategory::ByValue
             } else {
                 match explicit_type.sty {
-                    ty::TyRef(r, mt) => ty::ByReferenceExplicitSelfCategory(*r, mt.mutbl),
-                    ty::TyBox(_) => ty::ByBoxExplicitSelfCategory,
-                    _ => ty::ByValueExplicitSelfCategory,
+                    ty::TyRef(r, mt) => ty::ExplicitSelfCategory::ByReference(*r, mt.mutbl),
+                    ty::TyBox(_) => ty::ExplicitSelfCategory::ByBox,
+                    _ => ty::ExplicitSelfCategory::ByValue,
                 }
             };
 
index efcc08c69f8246f83e9321b7bbe43a528db707c5..588dee57c520e9f2dd5aab098d3698ccbbef3f67 100644 (file)
@@ -700,7 +700,9 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 if !is_special_case {
                     return
                 } else {
-                    span_note!(tcx.sess, pat.span,
+                    // Boo! Too painful to attach this to the actual warning,
+                    // it should go away at some point though.
+                    tcx.sess.span_note_without_error(pat.span,
                         "this warning will become a HARD ERROR in a future release. \
                         See RFC 218 for details.");
                 }
@@ -786,12 +788,13 @@ pub fn check_struct_pat_fields<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     for &Spanned { node: ref field, span } in fields {
         let field_ty = match used_fields.entry(field.name) {
             Occupied(occupied) => {
-                span_err!(tcx.sess, span, E0025,
-                    "field `{}` bound multiple times in the pattern",
-                    field.name);
-                span_note!(tcx.sess, *occupied.get(),
-                    "field `{}` previously bound here",
-                    field.name);
+                let mut err = struct_span_err!(tcx.sess, span, E0025,
+                                               "field `{}` bound multiple times in the pattern",
+                                               field.name);
+                span_note!(&mut err, *occupied.get(),
+                           "field `{}` previously bound here",
+                           field.name);
+                err.emit();
                 tcx.types.err
             }
             Vacant(vacant) => {
index 1e20cd3985467f45284d72c82229e9f875b5c21b..a1b378d84d0010faf8f9a1fbbb3a4c1c612d748f 100644 (file)
@@ -61,11 +61,12 @@ pub fn check_legal_trait_for_method_call(ccx: &CrateCtxt, span: Span, trait_id:
             return // not a closure method, everything is OK.
         };
 
-        span_err!(tcx.sess, span, E0174,
-                  "explicit use of unboxed closure method `{}` is experimental",
-                  method);
-        fileline_help!(tcx.sess, span,
-                   "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+        struct_span_err!(tcx.sess, span, E0174,
+                         "explicit use of unboxed closure method `{}` is experimental",
+                         method)
+            .fileline_help(span, "add `#![feature(unboxed_closures)]` to the crate \
+                                  attributes to enable")
+            .emit();
     }
 }
 
@@ -228,7 +229,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
             sig
         }
         _ => {
-            fcx.type_error_message(call_expr.span, |actual| {
+            let mut err = fcx.type_error_struct(call_expr.span, |actual| {
                 format!("expected function, found `{}`", actual)
             }, callee_ty, None);
 
@@ -237,12 +238,14 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                 if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
                     if pr.depth == 0 && pr.base_def != def::DefErr {
                         if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
-                            tcx.sess.span_note(span, "defined here")
+                            err.span_note(span, "defined here");
                         }
                     }
                 }
             }
 
+            err.emit();
+
             // This is the "default" function signature, used in case of error.
             // In that case, we check each argument against "error" in order to
             // set up all the node type bindings.
index 13e5e46ed27002fe4109908a6976a6a5a7af164d..90e67944ef90481474fb4f1caf713b6c2aa8348e 100644 (file)
@@ -127,23 +127,25 @@ fn report_cast_error<'a>(&self, fcx: &FnCtxt<'a, 'tcx>,
             CastError::NeedViaThinPtr |
             CastError::NeedViaInt |
             CastError::NeedViaUsize => {
-                fcx.type_error_message(self.span, |actual| {
+                fcx.type_error_struct(self.span, |actual| {
                     format!("casting `{}` as `{}` is invalid",
                             actual,
                             fcx.infcx().ty_to_string(self.cast_ty))
-                }, self.expr_ty, None);
-                fcx.ccx.tcx.sess.fileline_help(self.span,
-                    &format!("cast through {} first", match e {
-                        CastError::NeedViaPtr => "a raw pointer",
-                        CastError::NeedViaThinPtr => "a thin pointer",
-                        CastError::NeedViaInt => "an integer",
-                        CastError::NeedViaUsize => "a usize",
-                        _ => unreachable!()
-                }));
+                }, self.expr_ty, None)
+                    .fileline_help(self.span,
+                        &format!("cast through {} first", match e {
+                            CastError::NeedViaPtr => "a raw pointer",
+                            CastError::NeedViaThinPtr => "a thin pointer",
+                            CastError::NeedViaInt => "an integer",
+                            CastError::NeedViaUsize => "a usize",
+                            _ => unreachable!()
+                        }))
+                    .emit();
             }
             CastError::CastToBool => {
-                span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`");
-                fcx.ccx.tcx.sess.fileline_help(self.span, "compare with zero instead");
+                struct_span_err!(fcx.tcx().sess, self.span, E0054, "cannot cast as `bool`")
+                    .fileline_help(self.span, "compare with zero instead")
+                    .emit();
             }
             CastError::CastToChar => {
                 fcx.type_error_message(self.span, |actual| {
@@ -165,12 +167,13 @@ fn report_cast_error<'a>(&self, fcx: &FnCtxt<'a, 'tcx>,
                 }, self.expr_ty, None);
             }
             CastError::DifferingKinds => {
-                fcx.type_error_message(self.span, |actual| {
+                fcx.type_error_struct(self.span, |actual| {
                     format!("casting `{}` as `{}` is invalid",
                             actual,
                             fcx.infcx().ty_to_string(self.cast_ty))
-                }, self.expr_ty, None);
-                fcx.ccx.tcx.sess.fileline_note(self.span, "vtable kinds may not match");
+                }, self.expr_ty, None)
+                    .fileline_note(self.span, "vtable kinds may not match")
+                    .emit();
             }
         }
     }
index d28a673f748c07c46157d74a253d9d386a908b5a..554424a36b19af688259725a2efaf3ad87e5642a 100644 (file)
@@ -55,9 +55,9 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     // inscrutable, particularly for cases where one method has no
     // self.
     match (&trait_m.explicit_self, &impl_m.explicit_self) {
-        (&ty::StaticExplicitSelfCategory,
-         &ty::StaticExplicitSelfCategory) => {}
-        (&ty::StaticExplicitSelfCategory, _) => {
+        (&ty::ExplicitSelfCategory::Static,
+         &ty::ExplicitSelfCategory::Static) => {}
+        (&ty::ExplicitSelfCategory::Static, _) => {
             span_err!(tcx.sess, impl_m_span, E0185,
                 "method `{}` has a `{}` declaration in the impl, \
                         but not in the trait",
@@ -65,7 +65,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                         impl_m.explicit_self);
             return;
         }
-        (_, &ty::StaticExplicitSelfCategory) => {
+        (_, &ty::ExplicitSelfCategory::Static) => {
             span_err!(tcx.sess, impl_m_span, E0186,
                 "method `{}` has a `{}` declaration in the trait, \
                         but not in the impl",
index 59025346ce3bd029b3cce2d000a306cf1bd4712c..0cf552b6efecb9165a4f9ba8f9ff75c324f5fdf4 100644 (file)
@@ -95,12 +95,13 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
 
     if let Err(_) = infer::mk_eqty(&infcx, true, infer::TypeOrigin::Misc(drop_impl_span),
                                    named_type, fresh_impl_self_ty) {
-        span_err!(tcx.sess, drop_impl_span, E0366,
-                  "Implementations of Drop cannot be specialized");
         let item_span = tcx.map.span(self_type_node_id);
-        tcx.sess.span_note(item_span,
-                           "Use same sequence of generic type and region \
-                            parameters that is on the struct/enum definition");
+        struct_span_err!(tcx.sess, drop_impl_span, E0366,
+                         "Implementations of Drop cannot be specialized")
+            .span_note(item_span,
+                       "Use same sequence of generic type and region \
+                        parameters that is on the struct/enum definition")
+            .emit();
         return Err(());
     }
 
@@ -197,11 +198,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
 
         if !assumptions_in_impl_context.contains(&predicate) {
             let item_span = tcx.map.span(self_type_node_id);
-            span_err!(tcx.sess, drop_impl_span, E0367,
-                      "The requirement `{}` is added only by the Drop impl.", predicate);
-            tcx.sess.span_note(item_span,
-                               "The same requirement must be part of \
-                                the struct/enum definition");
+            struct_span_err!(tcx.sess, drop_impl_span, E0367,
+                             "The requirement `{}` is added only by the Drop impl.", predicate)
+                .span_note(item_span,
+                           "The same requirement must be part of \
+                            the struct/enum definition")
+                .emit();
         }
     }
 
@@ -289,8 +291,8 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
         Ok(()) => {}
         Err(Error::Overflow(ref ctxt, ref detected_on_typ)) => {
             let tcx = rcx.tcx();
-            span_err!(tcx.sess, span, E0320,
-                      "overflow while adding drop-check rules for {}", typ);
+            let mut err = struct_span_err!(tcx.sess, span, E0320,
+                                           "overflow while adding drop-check rules for {}", typ);
             match *ctxt {
                 TypeContext::Root => {
                     // no need for an additional note if the overflow
@@ -311,7 +313,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
                         format!("`{}`", field)
                     };
                     span_note!(
-                        rcx.tcx().sess,
+                        &mut err,
                         span,
                         "overflowed on {} field {} type: {}",
                         variant_name,
@@ -319,6 +321,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
                         detected_on_typ);
                 }
             }
+            err.emit();
         }
     }
 }
index e0ad51b4ea1b54532dd56d0fe0d763d7aa5ab9ed..a961268c6c49bd8244e5072f6828c1c3a72a063c 100644 (file)
@@ -274,13 +274,13 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                    method_ty.explicit_self);
 
             match method_ty.explicit_self {
-                ty::ByValueExplicitSelfCategory => {
+                ty::ExplicitSelfCategory::ByValue => {
                     // Trait method is fn(self), no transformation needed.
                     assert!(!unsize);
                     fcx.write_autoderef_adjustment(self_expr.id, autoderefs);
                 }
 
-                ty::ByReferenceExplicitSelfCategory(..) => {
+                ty::ExplicitSelfCategory::ByReference(..) => {
                     // Trait method is fn(&self) or fn(&mut self), need an
                     // autoref. Pull the region etc out of the type of first argument.
                     match transformed_self_ty.sty {
index ed819d46041e60ce45c5db274a6501b725a64003..3bf24aba62467d21652501118268abe9d2695818 100644 (file)
@@ -1144,10 +1144,10 @@ fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {
         match *item {
             ty::ImplOrTraitItem::MethodTraitItem(ref method) =>
                 match method.explicit_self {
-                    ty::StaticExplicitSelfCategory => self.mode == Mode::Path,
-                    ty::ByValueExplicitSelfCategory |
-                    ty::ByReferenceExplicitSelfCategory(..) |
-                    ty::ByBoxExplicitSelfCategory => true,
+                    ty::ExplicitSelfCategory::Static => self.mode == Mode::Path,
+                    ty::ExplicitSelfCategory::ByValue |
+                    ty::ExplicitSelfCategory::ByReference(..) |
+                    ty::ExplicitSelfCategory::ByBox => true,
                 },
             ty::ImplOrTraitItem::ConstTraitItem(..) => self.mode == Mode::Path,
             _ => false,
index 955bc92a8f31e89bf1a9c982c4b98371ab793798..65b0d5892756c2790735810db1a975f6daace4a3 100644 (file)
@@ -27,6 +27,7 @@
 
 use syntax::ast;
 use syntax::codemap::Span;
+use syntax::errors::DiagnosticBuilder;
 use rustc_front::print::pprust;
 use rustc_front::hir;
 
@@ -55,7 +56,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                            mode }) => {
             let cx = fcx.tcx();
 
-            fcx.type_error_message(
+            let mut err = fcx.type_error_struct(
                 span,
                 |actual| {
                     format!("no {} named `{}` found for type `{}` \
@@ -78,17 +79,21 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                         // snippet
                     };
 
-                    let span_stored_function = || {
-                        cx.sess.span_note(span,
+                    macro_rules! span_stored_function {
+                        () => {
+                            err.span_note(span,
                                           &format!("use `({0}.{1})(...)` if you meant to call \
                                                     the function stored in the `{1}` field",
                                                    expr_string, item_name));
-                    };
+                        }
+                    }
 
-                    let span_did_you_mean = || {
-                        cx.sess.span_note(span, &format!("did you mean to write `{0}.{1}`?",
+                    macro_rules! span_did_you_mean {
+                        () => {
+                            err.span_note(span, &format!("did you mean to write `{0}.{1}`?",
                                                          expr_string, item_name));
-                    };
+                        }
+                    }
 
                     // Determine if the field can be used as a function in some way
                     let field_ty = field.ty(cx, substs);
@@ -96,19 +101,22 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                     match field_ty.sty {
                         // Not all of these (e.g. unsafe fns) implement FnOnce
                         // so we look for these beforehand
-                        ty::TyClosure(..) | ty::TyBareFn(..) => span_stored_function(),
+                        ty::TyClosure(..) | ty::TyBareFn(..) => {
+                            span_stored_function!();
+                        }
                         // If it's not a simple function, look for things which implement FnOnce
                         _ => {
                             if let Ok(fn_once_trait_did) =
                                     cx.lang_items.require(FnOnceTraitLangItem) {
                                 let infcx = fcx.infcx();
                                 infcx.probe(|_| {
-                                    let fn_once_substs = Substs::new_trait(vec![
-                                                                            infcx.next_ty_var()],
-                                                                           Vec::new(),
-                                                                           field_ty);
-                                    let trait_ref = ty::TraitRef::new(fn_once_trait_did,
-                                                                      cx.mk_substs(fn_once_substs));
+                                    let fn_once_substs =
+                                        Substs::new_trait(vec![infcx.next_ty_var()],
+                                                          Vec::new(),
+                                                          field_ty);
+                                    let trait_ref =
+                                      ty::TraitRef::new(fn_once_trait_did,
+                                                        cx.mk_substs(fn_once_substs));
                                     let poly_trait_ref = trait_ref.to_poly_trait_ref();
                                     let obligation = Obligation::misc(span,
                                                                       fcx.body_id,
@@ -117,13 +125,13 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                     let mut selcx = SelectionContext::new(infcx);
 
                                     if selcx.evaluate_obligation(&obligation) {
-                                        span_stored_function();
+                                        span_stored_function!();
                                     } else {
-                                        span_did_you_mean();
+                                        span_did_you_mean!();
                                     }
                                 });
                             } else {
-                                span_did_you_mean()
+                                span_did_you_mean!();
                             }
                         }
                     }
@@ -131,11 +139,11 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             }
 
             if !static_sources.is_empty() {
-                cx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     "found defined static methods, maybe a `self` is missing?");
 
-                report_candidates(fcx, span, item_name, static_sources);
+                report_candidates(fcx, &mut err, span, item_name, static_sources);
             }
 
             if !unsatisfied_predicates.is_empty() {
@@ -145,7 +153,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      p))
                     .collect::<Vec<_>>()
                     .join(", ");
-                cx.sess.fileline_note(
+                err.fileline_note(
                     span,
                     &format!("the method `{}` exists but the \
                              following trait bounds were not satisfied: {}",
@@ -153,15 +161,17 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              bound_list));
             }
 
-            suggest_traits_to_import(fcx, span, rcvr_ty, item_name,
-                                     rcvr_expr, out_of_scope_traits)
+            suggest_traits_to_import(fcx, &mut err, span, rcvr_ty, item_name,
+                                     rcvr_expr, out_of_scope_traits);
+            err.emit();
         }
 
         MethodError::Ambiguity(sources) => {
-            span_err!(fcx.sess(), span, E0034,
-                      "multiple applicable items in scope");
+            let mut err = struct_span_err!(fcx.sess(), span, E0034,
+                                           "multiple applicable items in scope");
 
-            report_candidates(fcx, span, item_name, sources);
+            report_candidates(fcx, &mut err, span, item_name, sources);
+            err.emit();
         }
 
         MethodError::ClosureAmbiguity(trait_def_id) => {
@@ -181,6 +191,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     }
 
     fn report_candidates(fcx: &FnCtxt,
+                         err: &mut DiagnosticBuilder,
                          span: Span,
                          item_name: ast::Name,
                          mut sources: Vec<CandidateSource>) {
@@ -213,7 +224,7 @@ fn report_candidates(fcx: &FnCtxt,
                         }
                     };
 
-                    span_note!(fcx.sess(), item_span,
+                    span_note!(err, item_span,
                                "candidate #{} is defined in an impl{} for the type `{}`",
                                idx + 1,
                                insertion,
@@ -222,7 +233,7 @@ fn report_candidates(fcx: &FnCtxt,
                 CandidateSource::TraitSource(trait_did) => {
                     let item = trait_item(fcx.tcx(), trait_did, item_name).unwrap();
                     let item_span = fcx.tcx().map.def_id_span(item.def_id(), span);
-                    span_note!(fcx.sess(), item_span,
+                    span_note!(err, item_span,
                                "candidate #{} is defined in the trait `{}`",
                                idx + 1,
                                fcx.tcx().item_path_str(trait_did));
@@ -236,6 +247,7 @@ fn report_candidates(fcx: &FnCtxt,
 pub type AllTraitsVec = Vec<TraitInfo>;
 
 fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                      err: &mut DiagnosticBuilder,
                                       span: Span,
                                       rcvr_ty: Ty<'tcx>,
                                       item_name: ast::Name,
@@ -255,14 +267,13 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             traits_are = if candidates.len() == 1 {"trait is"} else {"traits are"},
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"});
 
-        fcx.sess().fileline_help(span, &msg[..]);
+        err.fileline_help(span, &msg[..]);
 
         for (i, trait_did) in candidates.iter().enumerate() {
-            fcx.sess().fileline_help(span,
-                                     &*format!("candidate #{}: use `{}`",
-                                               i + 1,
-                                               fcx.tcx().item_path_str(*trait_did)))
-
+            err.fileline_help(span,
+                              &*format!("candidate #{}: use `{}`",
+                                        i + 1,
+                                        fcx.tcx().item_path_str(*trait_did)));
         }
         return
     }
@@ -301,13 +312,13 @@ fn suggest_traits_to_import<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             one_of_them = if candidates.len() == 1 {"it"} else {"one of them"},
             name = item_name);
 
-        fcx.sess().fileline_help(span, &msg[..]);
+        err.fileline_help(span, &msg[..]);
 
         for (i, trait_info) in candidates.iter().enumerate() {
-            fcx.sess().fileline_help(span,
-                                     &*format!("candidate #{}: `{}`",
-                                               i + 1,
-                                               fcx.tcx().item_path_str(trait_info.def_id)))
+            err.fileline_help(span,
+                              &*format!("candidate #{}: `{}`",
+                                        i + 1,
+                                        fcx.tcx().item_path_str(trait_info.def_id)));
         }
     }
 }
index 72d0e5b53321e243190b1e779033cdd134c41ef4..ca2db8c3deffb50727b9df1a52addf920c71f5b1 100644 (file)
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::{self, Span, Spanned};
+use syntax::errors::DiagnosticBuilder;
 use syntax::parse::token::{self, InternedString};
 use syntax::ptr::P;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -702,11 +703,12 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
             for item in &m.items {
                 let pty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(item.id));
                 if !pty.generics.types.is_empty() {
-                    span_err!(ccx.tcx.sess, item.span, E0044,
+                    let mut err = struct_span_err!(ccx.tcx.sess, item.span, E0044,
                         "foreign items may not have type parameters");
-                    span_help!(ccx.tcx.sess, item.span,
+                    span_help!(&mut err, item.span,
                         "consider using specialization instead of \
                         type parameters");
+                    err.emit();
                 }
 
                 if let hir::ForeignItemFn(ref fn_decl, _) = item.node {
@@ -1037,7 +1039,7 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          t_expr: Ty<'tcx>,
                                          id: ast::NodeId) {
     let tstr = fcx.infcx().ty_to_string(t_cast);
-    fcx.type_error_message(span, |actual| {
+    let mut err = fcx.type_error_struct(span, |actual| {
         format!("cast to unsized type: `{}` as `{}`", actual, tstr)
     }, t_expr, None);
     match t_expr.sty {
@@ -1049,16 +1051,16 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             if t_cast.is_trait() {
                 match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
                     Ok(s) => {
-                        fcx.tcx().sess.span_suggestion(t_span,
-                                                       "try casting to a reference instead:",
-                                                       format!("&{}{}", mtstr, s));
+                        err.span_suggestion(t_span,
+                                            "try casting to a reference instead:",
+                                            format!("&{}{}", mtstr, s));
                     },
                     Err(_) =>
-                        span_help!(fcx.tcx().sess, t_span,
+                        span_help!(err, t_span,
                                    "did you mean `&{}{}`?", mtstr, tstr),
                 }
             } else {
-                span_help!(fcx.tcx().sess, span,
+                span_help!(err, span,
                            "consider using an implicit coercion to `&{}{}` instead",
                            mtstr, tstr);
             }
@@ -1066,19 +1068,20 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         ty::TyBox(..) => {
             match fcx.tcx().sess.codemap().span_to_snippet(t_span) {
                 Ok(s) => {
-                    fcx.tcx().sess.span_suggestion(t_span,
-                                                   "try casting to a `Box` instead:",
-                                                   format!("Box<{}>", s));
+                    err.span_suggestion(t_span,
+                                                          "try casting to a `Box` instead:",
+                                                           format!("Box<{}>", s));
                 },
                 Err(_) =>
-                    span_help!(fcx.tcx().sess, t_span, "did you mean `Box<{}>`?", tstr),
+                    span_help!(err, t_span, "did you mean `Box<{}>`?", tstr),
             }
         }
         _ => {
-            span_help!(fcx.tcx().sess, e_span,
+            span_help!(err, e_span,
                        "consider using a box or reference as appropriate");
         }
     }
+    err.emit();
     fcx.write_error(id);
 }
 
@@ -1443,10 +1446,12 @@ pub fn def_struct_variant(&self,
             Some((adt, variant))
         } else if var_kind == ty::VariantKind::Unit {
             if !self.tcx().sess.features.borrow().braced_empty_structs {
-                self.tcx().sess.span_err(span, "empty structs and enum variants \
-                                                with braces are unstable");
-                fileline_help!(self.tcx().sess, span, "add #![feature(braced_empty_structs)] to \
-                                                       the crate features to enable");
+                let mut err = self.tcx().sess.struct_span_err(span,
+                                                              "empty structs and enum variants \
+                                                               with braces are unstable");
+                fileline_help!(&mut err, span, "add #![feature(braced_empty_structs)] to \
+                                                the crate features to enable");
+                err.emit();
             }
 
              Some((adt, variant))
@@ -1614,12 +1619,23 @@ pub fn type_error_message<M>(&self,
                                  sp: Span,
                                  mk_msg: M,
                                  actual_ty: Ty<'tcx>,
-                                 err: Option<&TypeError<'tcx>>) where
-        M: FnOnce(String) -> String,
+                                 err: Option<&TypeError<'tcx>>)
+        where M: FnOnce(String) -> String,
     {
         self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
     }
 
+    pub fn type_error_struct<M>(&self,
+                                sp: Span,
+                                mk_msg: M,
+                                actual_ty: Ty<'tcx>,
+                                err: Option<&TypeError<'tcx>>)
+                                -> DiagnosticBuilder<'tcx>
+        where M: FnOnce(String) -> String,
+    {
+        self.infcx().type_error_struct(sp, mk_msg, actual_ty, err)
+    }
+
     pub fn report_mismatched_types(&self,
                                    sp: Span,
                                    e: Ty<'tcx>,
@@ -2913,7 +2929,6 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                             lvalue_pref: LvaluePreference,
                             base: &'tcx hir::Expr,
                             field: &Spanned<ast::Name>) {
-        let tcx = fcx.ccx.tcx;
         check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
         let expr_t = structurally_resolved_type(fcx, expr.span,
                                                 fcx.expr_ty(base));
@@ -2945,19 +2960,18 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         }
 
         if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
-            fcx.type_error_message(
-                field.span,
-                |actual| {
-                    format!("attempted to take value of method `{}` on type \
-                            `{}`", field.node, actual)
-                },
-                expr_t, None);
-
-            tcx.sess.fileline_help(field.span,
+            fcx.type_error_struct(field.span,
+                                  |actual| {
+                                       format!("attempted to take value of method `{}` on type \
+                                               `{}`", field.node, actual)
+                                   },
+                                   expr_t, None)
+                .fileline_help(field.span,
                                "maybe a `()` to call it is missing? \
-                               If not, try an anonymous function");
+                               If not, try an anonymous function")
+                .emit();
         } else {
-            fcx.type_error_message(
+            let mut err = fcx.type_error_struct(
                 expr.span,
                 |actual| {
                     format!("attempted access of field `{}` on \
@@ -2968,17 +2982,18 @@ fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                 },
                 expr_t, None);
             if let ty::TyStruct(def, _) = expr_t.sty {
-                suggest_field_names(def.struct_variant(), field, tcx, vec![]);
+                suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
             }
+            err.emit();
         }
 
         fcx.write_error(expr.id);
     }
 
     // displays hints about the closest matches in field names
-    fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
+    fn suggest_field_names<'tcx>(err: &mut DiagnosticBuilder,
+                                 variant: ty::VariantDef<'tcx>,
                                  field: &Spanned<ast::Name>,
-                                 tcx: &ty::ctxt<'tcx>,
                                  skip : Vec<InternedString>) {
         let name = field.node.as_str();
         let names = variant.fields
@@ -2995,8 +3010,8 @@ fn suggest_field_names<'tcx>(variant: ty::VariantDef<'tcx>,
 
         // only find fits with at least one matching letter
         if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
-            tcx.sess.span_help(field.span,
-                &format!("did you mean `{}`?", name));
+            err.span_help(field.span,
+                          &format!("did you mean `{}`?", name));
         }
     }
 
@@ -3071,7 +3086,7 @@ fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                       variant: ty::VariantDef<'tcx>,
                                       field: &hir::Field,
                                       skip_fields: &[hir::Field]) {
-        fcx.type_error_message(
+        let mut err = fcx.type_error_struct(
             field.name.span,
             |actual| if let ty::TyEnum(..) = ty.sty {
                 format!("struct variant `{}::{}` has no field named `{}`",
@@ -3084,7 +3099,8 @@ fn report_unknown_field<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             None);
         // prevent all specified fields from being suggested
         let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
-        suggest_field_names(variant, &field.name, fcx.tcx(), skip_fields.collect());
+        suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
+        err.emit();
     }
 
     fn check_expr_struct_fields<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -4146,9 +4162,9 @@ pub fn check_representable(tcx: &ty::ctxt,
     // caught by case 1.
     match rty.is_representable(tcx, sp) {
         Representability::SelfRecursive => {
-            span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation);
-            tcx.sess.fileline_help(
-                sp, "wrap the inner value in a box to make it representable");
+            struct_span_err!(tcx.sess, sp, E0072, "invalid recursive {} type", designation)
+                .fileline_help(sp, "wrap the inner value in a box to make it representable")
+                .emit();
             return false
         }
         Representability::Representable | Representability::ContainsRecursive => (),
@@ -4245,11 +4261,12 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             // Check for duplicate discriminant values
             match disr_vals.iter().position(|&x| x == current_disr_val) {
                 Some(i) => {
-                    span_err!(ccx.tcx.sess, v.span, E0081,
+                    let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0081,
                         "discriminant value `{}` already exists", disr_vals[i]);
                     let variant_i_node_id = ccx.tcx.map.as_local_node_id(variants[i].did).unwrap();
-                    span_note!(ccx.tcx.sess, ccx.tcx.map.span(variant_i_node_id),
-                        "conflicting discriminant here")
+                    span_note!(&mut err, ccx.tcx.map.span(variant_i_node_id),
+                        "conflicting discriminant here");
+                    err.emit();
                 }
                 None => {}
             }
@@ -4258,10 +4275,11 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 attr::ReprAny | attr::ReprExtern => (),
                 attr::ReprInt(sp, ity) => {
                     if !disr_in_range(ccx, ity, current_disr_val) {
-                        span_err!(ccx.tcx.sess, v.span, E0082,
+                        let mut err = struct_span_err!(ccx.tcx.sess, v.span, E0082,
                             "discriminant value outside specified type");
-                        span_note!(ccx.tcx.sess, sp,
+                        span_note!(&mut err, sp,
                             "discriminant type specified here");
+                        err.emit();
                     }
                 }
                 attr::ReprSimd => {
index 0c65f68f02e3e8fac792447de3f95495271511d6..c5a36fb4ada256d96cfad9da7ef91282329d320c 100644 (file)
@@ -187,10 +187,10 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                               hir_util::binop_to_string(op.node),
                               lhs_ty);
                 } else {
-                    span_err!(fcx.tcx().sess, lhs_expr.span, E0369,
-                              "binary operation `{}` cannot be applied to type `{}`",
-                              hir_util::binop_to_string(op.node),
-                              lhs_ty);
+                    let mut err = struct_span_err!(fcx.tcx().sess, lhs_expr.span, E0369,
+                        "binary operation `{}` cannot be applied to type `{}`",
+                        hir_util::binop_to_string(op.node),
+                        lhs_ty);
                     let missing_trait = match op.node {
                         hir::BiAdd    => Some("std::ops::Add"),
                         hir::BiSub    => Some("std::ops::Sub"),
@@ -208,10 +208,11 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                     };
 
                     if let Some(missing_trait) = missing_trait {
-                        span_note!(fcx.tcx().sess, lhs_expr.span,
+                        span_note!(&mut err, lhs_expr.span,
                                    "an implementation of `{}` might be missing for `{}`",
                                     missing_trait, lhs_ty);
                     }
+                    err.emit();
                 }
             }
             fcx.tcx().types.err
index 230422b7044cd5d366463efc59d885daf57eec84..4f3f716c20d61c76a67572db3972e51d6889d372 100644 (file)
@@ -23,6 +23,7 @@
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::codemap::{Span};
+use syntax::errors::DiagnosticBuilder;
 use syntax::parse::token::{special_idents};
 use rustc_front::intravisit::{self, Visitor};
 use rustc_front::hir;
@@ -398,15 +399,15 @@ fn check_method_receiver<'fcx>(&mut self,
                method.name, method.explicit_self, self_ty, sig);
 
         let rcvr_ty = match method.explicit_self {
-            ty::StaticExplicitSelfCategory => return,
-            ty::ByValueExplicitSelfCategory => self_ty,
-            ty::ByReferenceExplicitSelfCategory(region, mutability) => {
+            ty::ExplicitSelfCategory::Static => return,
+            ty::ExplicitSelfCategory::ByValue => self_ty,
+            ty::ExplicitSelfCategory::ByReference(region, mutability) => {
                 fcx.tcx().mk_ref(fcx.tcx().mk_region(region), ty::TypeAndMut {
                     ty: self_ty,
                     mutbl: mutability
                 })
             }
-            ty::ByBoxExplicitSelfCategory => fcx.tcx().mk_box(self_ty)
+            ty::ExplicitSelfCategory::ByBox => fcx.tcx().mk_box(self_ty)
         };
         let rcvr_ty = fcx.instantiate_type_scheme(span, free_substs, &rcvr_ty);
         let rcvr_ty = fcx.tcx().liberate_late_bound_regions(free_id_outlive,
@@ -496,12 +497,12 @@ fn report_bivariance(&self,
                          span: Span,
                          param_name: ast::Name)
     {
-        error_392(self.tcx(), span, param_name);
+        let mut err = error_392(self.tcx(), span, param_name);
 
         let suggested_marker_id = self.tcx().lang_items.phantom_data();
         match suggested_marker_id {
             Some(def_id) => {
-                self.tcx().sess.fileline_help(
+                err.fileline_help(
                     span,
                     &format!("consider removing `{}` or using a marker such as `{}`",
                              param_name,
@@ -511,6 +512,7 @@ fn report_bivariance(&self,
                 // no lang items, no help!
             }
         }
+        err.emit();
     }
 }
 
@@ -621,9 +623,10 @@ pub fn error_380<'ccx,'tcx>(ccx: &'ccx CrateCtxt<'ccx, 'tcx>, span: Span) {
                Trait for ..`) must have no methods or associated items")
 }
 
-pub fn error_392<'tcx>(tcx: &ty::ctxt<'tcx>, span: Span, param_name: ast::Name)  {
-    span_err!(tcx.sess, span, E0392,
-              "parameter `{}` is never used", param_name);
+pub fn error_392<'tcx>(tcx: &ty::ctxt<'tcx>, span: Span, param_name: ast::Name)
+                       -> DiagnosticBuilder<'tcx> {
+    struct_span_err!(tcx.sess, span, E0392,
+                     "parameter `{}` is never used", param_name)
 }
 
 pub fn error_194<'tcx>(tcx: &ty::ctxt<'tcx>, span: Span, name: ast::Name) {
index c24a416a0109c7a52e789d1d9d14e6f4dd66e024..1536f13a1d51aa21bd49ed50fca219bb93e3b44b 100644 (file)
@@ -129,13 +129,13 @@ fn fix_scalar_binary_expr(&mut self, e: &hir::Expr) {
                             !self.fcx.expr_ty(lhs).references_error() &&
                             !self.fcx.expr_ty(rhs).references_error()
                         {
-                            tcx.sess.span_err(
-                                e.span,
-                                "overloaded augmented assignments are not stable");
-                            fileline_help!(
-                                tcx.sess, e.span,
-                                "add #![feature(augmented_assignments)] to the crate root \
-                                 to enable");
+                            tcx.sess.struct_span_err(e.span,
+                                                     "overloaded augmented assignments \
+                                                      are not stable")
+                                .fileline_help(e.span,
+                                               "add #![feature(augmented_assignments)] to the \
+                                                crate root to enable")
+                                .emit()
                         }
                     }
                 }
index 37bbfb4e967f7c70e8cc64286e6f6b70947ed98d..02be74a590661ff4eb48940d7d36519f42863b5d 100644 (file)
@@ -502,9 +502,14 @@ fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id:
     } else {
         return // everything OK
     };
-    span_err!(tcx.sess, sp, E0183, "manual implementations of `{}` are experimental", trait_name);
-    fileline_help!(tcx.sess, sp,
-               "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+    let mut err = struct_span_err!(tcx.sess,
+                                   sp,
+                                   E0183,
+                                   "manual implementations of `{}` are experimental",
+                                   trait_name);
+    fileline_help!(&mut err, sp,
+                   "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+    err.emit();
 }
 
 pub fn check_coherence(crate_context: &CrateCtxt) {
index 411e1a4e480fc4833fbbc31f86c4248f3d08f640..76be04bb1741a13f52580cde53c56d7e08f6f2b0 100644 (file)
@@ -48,11 +48,11 @@ fn check_primitive_impl(&self,
         match lang_def_id {
             Some(lang_def_id) if lang_def_id == impl_def_id => { /* OK */ },
             _ => {
-                span_err!(self.tcx.sess, span, E0390,
+                struct_span_err!(self.tcx.sess, span, E0390,
                           "only a single inherent implementation marked with `#[lang = \"{}\"]` \
-                           is allowed for the `{}` primitive", lang, ty);
-                span_help!(self.tcx.sess, span,
-                           "consider using a trait to implement these methods");
+                           is allowed for the `{}` primitive", lang, ty)
+                    .span_help(span, "consider using a trait to implement these methods")
+                    .emit();
             }
         }
     }
index 7d1f71967a2d5a524a8d5bb2b3953726b3bc2087..beb409f7f0f23b63ac0aecc49d0e8a41474da3c1 100644 (file)
@@ -150,18 +150,19 @@ fn report_overlap_error(&self,
             }).unwrap_or(String::new())
         };
 
-        span_err!(self.tcx.sess, self.span_of_impl(impl1), E0119,
-                  "conflicting implementations of trait `{}`{}:",
-                  trait_ref,
-                  self_type);
+        let mut err = struct_span_err!(self.tcx.sess, self.span_of_impl(impl1), E0119,
+                                       "conflicting implementations of trait `{}`{}:",
+                                       trait_ref,
+                                       self_type);
 
         if impl2.is_local() {
-            span_note!(self.tcx.sess, self.span_of_impl(impl2),
+            span_note!(&mut err, self.span_of_impl(impl2),
                        "conflicting implementation is here:");
         } else {
             let cname = self.tcx.sess.cstore.crate_name(impl2.krate);
-            self.tcx.sess.note(&format!("conflicting implementation in crate `{}`", cname));
+            err.note(&format!("conflicting implementation in crate `{}`", cname));
         }
+        err.emit();
     }
 
     fn span_of_impl(&self, impl_did: DefId) -> Span {
index b7ce91d331723a572220c211d2ac8e70ca9dae5b..eaaa2c773791e8c24776d5f4d09fca35e533bb8e 100644 (file)
@@ -225,24 +225,24 @@ fn report_cycle(&self,
         assert!(!cycle.is_empty());
         let tcx = self.tcx;
 
-        span_err!(tcx.sess, span, E0391,
+        let mut err = struct_span_err!(tcx.sess, span, E0391,
             "unsupported cyclic reference between types/traits detected");
 
         match cycle[0] {
             AstConvRequest::GetItemTypeScheme(def_id) |
             AstConvRequest::GetTraitDef(def_id) => {
-                tcx.sess.note(
+                err.note(
                     &format!("the cycle begins when processing `{}`...",
                              tcx.item_path_str(def_id)));
             }
             AstConvRequest::EnsureSuperPredicates(def_id) => {
-                tcx.sess.note(
+                err.note(
                     &format!("the cycle begins when computing the supertraits of `{}`...",
                              tcx.item_path_str(def_id)));
             }
             AstConvRequest::GetTypeParameterBounds(id) => {
                 let def = tcx.type_parameter_def(id);
-                tcx.sess.note(
+                err.note(
                     &format!("the cycle begins when computing the bounds \
                               for type parameter `{}`...",
                              def.name));
@@ -253,18 +253,18 @@ fn report_cycle(&self,
             match *request {
                 AstConvRequest::GetItemTypeScheme(def_id) |
                 AstConvRequest::GetTraitDef(def_id) => {
-                    tcx.sess.note(
+                    err.note(
                         &format!("...which then requires processing `{}`...",
                                  tcx.item_path_str(def_id)));
                 }
                 AstConvRequest::EnsureSuperPredicates(def_id) => {
-                    tcx.sess.note(
+                    err.note(
                         &format!("...which then requires computing the supertraits of `{}`...",
                                  tcx.item_path_str(def_id)));
                 }
                 AstConvRequest::GetTypeParameterBounds(id) => {
                     let def = tcx.type_parameter_def(id);
-                    tcx.sess.note(
+                    err.note(
                         &format!("...which then requires computing the bounds \
                                   for type parameter `{}`...",
                                  def.name));
@@ -275,24 +275,25 @@ fn report_cycle(&self,
         match cycle[0] {
             AstConvRequest::GetItemTypeScheme(def_id) |
             AstConvRequest::GetTraitDef(def_id) => {
-                tcx.sess.note(
+                err.note(
                     &format!("...which then again requires processing `{}`, completing the cycle.",
                              tcx.item_path_str(def_id)));
             }
             AstConvRequest::EnsureSuperPredicates(def_id) => {
-                tcx.sess.note(
+                err.note(
                     &format!("...which then again requires computing the supertraits of `{}`, \
                               completing the cycle.",
                              tcx.item_path_str(def_id)));
             }
             AstConvRequest::GetTypeParameterBounds(id) => {
                 let def = tcx.type_parameter_def(id);
-                tcx.sess.note(
+                err.note(
                     &format!("...which then again requires computing the bounds \
                               for type parameter `{}`, completing the cycle.",
                              def.name));
             }
         }
+        err.emit();
     }
 
     /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
@@ -1012,10 +1013,11 @@ fn convert_struct_variant<'tcx>(tcx: &ty::ctxt<'tcx>,
             hir::NamedField(name, vis) => {
                 let dup_span = seen_fields.get(&name).cloned();
                 if let Some(prev_span) = dup_span {
-                    span_err!(tcx.sess, f.span, E0124,
-                              "field `{}` is already declared",
-                              name);
-                    span_note!(tcx.sess, prev_span, "previously declared here");
+                    let mut err = struct_span_err!(tcx.sess, f.span, E0124,
+                                                   "field `{}` is already declared",
+                                                   name);
+                    span_note!(&mut err, prev_span, "previously declared here");
+                    err.emit();
                 } else {
                     seen_fields.insert(name, f.span);
                 }
@@ -1080,12 +1082,13 @@ fn evaluate_disr_expr<'tcx>(tcx: &ty::ctxt<'tcx>,
                 None
             },
             Err(err) => {
-                span_err!(tcx.sess, err.span, E0080,
-                          "constant evaluation error: {}",
-                          err.description());
+                let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
+                                                "constant evaluation error: {}",
+                                                err.description());
                 if !e.span.contains(err.span) {
-                    tcx.sess.span_note(e.span, "for enum discriminant here");
+                    diag.span_note(e.span, "for enum discriminant here");
                 }
+                diag.emit();
                 None
             }
         }
@@ -1254,13 +1257,14 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
     let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
     if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
-        ccx.tcx.sess.span_err(
+        let mut err = ccx.tcx.sess.struct_span_err(
             it.span,
             "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
              which traits can use parenthetical notation");
-        fileline_help!(ccx.tcx.sess, it.span,
+        fileline_help!(&mut err, it.span,
                    "add `#![feature(unboxed_closures)]` to \
                     the crate attributes to use it");
+        err.emit();
     }
 
     let substs = ccx.tcx.mk_substs(mk_trait_substs(ccx, generics));
index 70c6d6f05c66ae34a93dee290cbec5a3a0b010e7..bf890f3e50709b9295b6a240a0cc86e52b0d00c0 100644 (file)
@@ -203,8 +203,9 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
     match result {
         Ok(_) => true,
         Err(ref terr) => {
-            span_err!(tcx.sess, span, E0211, "{}: {}", msg(), terr);
-            tcx.note_and_explain_type_err(terr, span);
+            let mut err = struct_span_err!(tcx.sess, span, E0211, "{}: {}", msg(), terr);
+            tcx.note_and_explain_type_err(&mut err, terr, span);
+            err.emit();
             false
         }
     }
index 675eef637b10b7626a83b476ae79a084b7df973b..d2a5fd457d2fba4cdc9183f06796ad1d05ee037b 100644 (file)
@@ -1306,16 +1306,16 @@ fn clean(&self, cx: &DocContext) -> Item {
 impl<'tcx> Clean<Item> for ty::Method<'tcx> {
     fn clean(&self, cx: &DocContext) -> Item {
         let (self_, sig) = match self.explicit_self {
-            ty::StaticExplicitSelfCategory => (hir::SelfStatic.clean(cx),
-                                               self.fty.sig.clone()),
+            ty::ExplicitSelfCategory::Static => (hir::SelfStatic.clean(cx),
+                                                 self.fty.sig.clone()),
             s => {
                 let sig = ty::Binder(ty::FnSig {
                     inputs: self.fty.sig.0.inputs[1..].to_vec(),
                     ..self.fty.sig.0.clone()
                 });
                 let s = match s {
-                    ty::ByValueExplicitSelfCategory => SelfValue,
-                    ty::ByReferenceExplicitSelfCategory(..) => {
+                    ty::ExplicitSelfCategory::ByValue => SelfValue,
+                    ty::ExplicitSelfCategory::ByReference(..) => {
                         match self.fty.sig.0.inputs[0].sty {
                             ty::TyRef(r, mt) => {
                                 SelfBorrowed(r.clean(cx), mt.mutbl.clean(cx))
@@ -1323,10 +1323,10 @@ fn clean(&self, cx: &DocContext) -> Item {
                             _ => unreachable!(),
                         }
                     }
-                    ty::ByBoxExplicitSelfCategory => {
+                    ty::ExplicitSelfCategory::ByBox => {
                         SelfExplicit(self.fty.sig.0.inputs[0].clean(cx))
                     }
-                    ty::StaticExplicitSelfCategory => unreachable!(),
+                    ty::ExplicitSelfCategory::Static => unreachable!(),
                 };
                 (s, sig)
             }
index 4d805e17a76648193a410f5ab1c25fac7840ef78..41001153c3cc47e7de8c0036b9cc873a87e83435 100644 (file)
@@ -132,6 +132,7 @@ mod tests {
     #[cfg_attr(any(windows,
                    target_os = "android",  // FIXME #10379
                    target_env = "musl"), ignore)]
+    #[allow(deprecated)]
     fn test_loading_cosine() {
         // The math library does not need to be loaded since it is already
         // statically linked in
@@ -164,6 +165,7 @@ fn test_loading_cosine() {
               target_os = "bitrig",
               target_os = "netbsd",
               target_os = "openbsd"))]
+    #[allow(deprecated)]
     fn test_errors_do_not_crash() {
         // Open /dev/null as a library to get an error, and make sure
         // that only causes an error, and not a crash.
index 715749f50d4e4c4c57b66ca590b3d800905d2402..66e4c6013a45ce949fe4c0b6aac0266bcd418083 100644 (file)
@@ -1281,7 +1281,6 @@ mod tests {
     use io::{ErrorKind, SeekFrom};
     use path::PathBuf;
     use path::Path as Path2;
-    use os;
     use rand::{self, StdRng, Rng};
     use str;
 
@@ -1410,8 +1409,8 @@ fn file_test_io_seek_and_tell_smoke_test() {
         let message = "ten-four";
         let mut read_mem = [0; 4];
         let set_cursor = 4 as u64;
-        let mut tell_pos_pre_read;
-        let mut tell_pos_post_read;
+        let tell_pos_pre_read;
+        let tell_pos_post_read;
         let tmpdir = tmpdir();
         let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
         {
index 79eedbeda2c727375b9c93bc2aa6d5d80245e550..16ce05ef2dcaf72497b171796eda90357dc1b624 100644 (file)
@@ -791,7 +791,7 @@ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
 mod tests {
     use prelude::v1::*;
     use io::prelude::*;
-    use io::{self, BufReader, BufWriter, Cursor, LineWriter, SeekFrom};
+    use io::{self, BufReader, BufWriter, LineWriter, SeekFrom};
     use test;
 
     /// A dummy reader intended at testing short-reads propagation.
index 1dd96f5ddfc0169af67bac30d21479c7097999b4..e3f17c839f135be9c4ef4c26848f9bde3d89a071 100644 (file)
@@ -377,7 +377,7 @@ fn test_downcasting() {
         struct TestError;
 
         impl fmt::Display for TestError {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+            fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
                 Ok(())
             }
         }
index 7be0f467ac9ff8b4b39c6bd90c47608bf7529846..2ad45e80dd153e68e82cf9769bcba032b4e2d130 100644 (file)
@@ -1983,7 +1983,7 @@ fn bench_read_to_end(b: &mut test::Bencher) {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
             let mut vec = Vec::with_capacity(1024);
-            super::read_to_end(&mut lr, &mut vec);
+            super::read_to_end(&mut lr, &mut vec)
         });
     }
 }
index 120e56d8079a74223f9f5f1037da6fa63059e589..863e84be093d2d011fdcb717c9896c382f615a38 100644 (file)
@@ -133,14 +133,17 @@ fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
 /// A handle to the standard input stream of a process.
 ///
 /// Each handle is a shared reference to a global buffer of input data to this
-/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
+/// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
 /// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
 /// to other writes.
 ///
 /// This handle implements the `Read` trait, but beware that concurrent reads
 /// of `Stdin` must be executed with care.
 ///
-/// Created by the function `io::stdin()`.
+/// Created by the [`io::stdin`] method.
+///
+/// [`io::stdin`]: fn.stdin.html
+/// [`BufRead`]: trait.BufRead.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdin {
     inner: Arc<Mutex<BufReader<Maybe<StdinRaw>>>>,
@@ -148,8 +151,12 @@ pub struct Stdin {
 
 /// A locked reference to the `Stdin` handle.
 ///
-/// This handle implements both the `Read` and `BufRead` traits and is
-/// constructed via the `lock` method on `Stdin`.
+/// This handle implements both the [`Read`] and [`BufRead`] traits, and
+/// is constructed via the [`Stdin::lock`] method.
+///
+/// [`Read`]: trait.Read.html
+/// [`BufRead`]: trait.BufRead.html
+/// [`Stdin::lock`]: struct.Stdin.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
@@ -159,7 +166,7 @@ pub struct StdinLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [lock() method][lock].
+/// locking, see the [`lock() method`][lock].
 ///
 /// [lock]: struct.Stdin.html#method.lock
 ///
@@ -221,8 +228,11 @@ impl Stdin {
     /// guard.
     ///
     /// The lock is released when the returned lock goes out of scope. The
-    /// returned guard also implements the `Read` and `BufRead` traits for
+    /// returned guard also implements the [`Read`] and [`BufRead`] traits for
     /// accessing the underlying data.
+    ///
+    /// [Read]: trait.Read.html
+    /// [BufRead]: trait.BufRead.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -231,7 +241,9 @@ pub fn lock(&self) -> StdinLock {
     /// Locks this handle and reads a line of input into the specified buffer.
     ///
     /// For detailed semantics of this method, see the documentation on
-    /// `BufRead::read_line`.
+    /// [`BufRead::read_line`].
+    ///
+    /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
     ///
     /// # Examples
     ///
@@ -314,7 +326,9 @@ fn consume(&mut self, n: usize) { self.inner.consume(n) }
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the `lock` method.
 ///
-/// Created by the function `io::stdout()`.
+/// Created by the [`io::stdout`] method.
+///
+/// [`io::stdout`]: fn.stdout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
     // FIXME: this should be LineWriter or BufWriter depending on the state of
@@ -325,8 +339,11 @@ pub struct Stdout {
 
 /// A locked reference to the `Stdout` handle.
 ///
-/// This handle implements the `Write` trait and is constructed via the `lock`
-/// method on `Stdout`.
+/// This handle implements the [`Write`] trait, and is constructed via
+/// the [`Stdout::lock`] method.
+///
+/// [`Write`]: trait.Write.html
+/// [`Stdout::lock`]: struct.Stdout.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>,
@@ -336,9 +353,9 @@ pub struct StdoutLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [lock() method][lock].
+/// locking, see the [Stdout::lock] method.
 ///
-/// [lock]: struct.Stdout.html#method.lock
+/// [Stdout::lock]: struct.Stdout.html#method.lock
 ///
 /// # Examples
 ///
@@ -424,7 +441,9 @@ fn flush(&mut self) -> io::Result<()> {
 
 /// A handle to the standard error stream of a process.
 ///
-/// For more information, see `stderr`
+/// For more information, see the [`io::stderr`] method.
+///
+/// [`io::stderr`]: fn.stderr.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stderr {
     inner: Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>>,
@@ -432,8 +451,10 @@ pub struct Stderr {
 
 /// A locked reference to the `Stderr` handle.
 ///
-/// This handle implements the `Write` trait and is constructed via the `lock`
-/// method on `Stderr`.
+/// This handle implements the `Write` trait and is constructed via
+/// the [`Stderr::lock`] method.
+///
+/// [`Stderr::lock`]: struct.Stderr.html#method.lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StderrLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>,
index 07a9548224aca8c8508166c03eddd896ce8a8e72..e05a0d577ff895b6c366c5c7f8d577c7e56d8e8b 100644 (file)
@@ -199,6 +199,7 @@ fn take_some_bytes() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn tee() {
         let mut buf = [0; 10];
         {
@@ -209,6 +210,7 @@ fn tee() {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn broadcast() {
         let mut buf1 = [0; 10];
         let mut buf2 = [0; 10];
index 9c4e2b1a54c30c17664bb5e1f18aa553ef89d271..74d308dbf0cf5b117890ef55dc5a70cebe36345f 100644 (file)
@@ -468,9 +468,7 @@ fn to_socket_addrs(&self) -> io::Result<T::Iter> {
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use io;
     use net::*;
-    use net::Ipv6MulticastScope::*;
     use net::test::{tsa, sa6, sa4};
 
     #[test]
index 00be17f7383561ff03319478176b551b6ef1dcc5..808cf5cc031be7604ace9967acb8d74e9666a670 100644 (file)
@@ -527,7 +527,6 @@ fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
-    use io;
     use net::*;
     use net::Ipv6MulticastScope::*;
     use net::test::{tsa, sa6, sa4};
index f54d4f804806de63309373fcea235e4e9a59e11d..f9c38c38458475661a87e298266849114991d7e7 100644 (file)
@@ -319,7 +319,7 @@ mod tests {
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
     use sys_common::AsInner;
-    use time::Duration;
+    use time::{Instant, Duration};
     use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr)) {
@@ -929,6 +929,7 @@ fn timeouts() {
 
         t!(stream.set_write_timeout(None));
         assert_eq!(None, t!(stream.write_timeout()));
+        drop(listener);
     }
 
     #[test]
@@ -940,11 +941,11 @@ fn test_read_timeout() {
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         let mut buf = [0; 10];
-        let wait = Duration::span(|| {
-            let kind = stream.read(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.read(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
+        drop(listener);
     }
 
     #[test]
@@ -962,10 +963,10 @@ fn test_read_with_timeout() {
         t!(stream.read(&mut buf));
         assert_eq!(b"hello world", &buf[..]);
 
-        let wait = Duration::span(|| {
-            let kind = stream.read(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.read(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
+        drop(listener);
     }
 }
index b212d4d32aadfcfa55e6034c8da055f83fb5ff73..29ac991a547dc9b4925b854c0b1ea1a0a316c96f 100644 (file)
 /// use std::net::UdpSocket;
 ///
 /// # fn foo() -> std::io::Result<()> {
-/// let mut socket = try!(UdpSocket::bind("127.0.0.1:34254"));
+/// {
+///     let mut socket = try!(UdpSocket::bind("127.0.0.1:34254"));
 ///
-/// let mut buf = [0; 10];
-/// let (amt, src) = try!(socket.recv_from(&mut buf));
+///     // read from the socket
+///     let mut buf = [0; 10];
+///     let (amt, src) = try!(socket.recv_from(&mut buf));
 ///
-/// // Send a reply to the socket we received data from
-/// let buf = &mut buf[..amt];
-/// buf.reverse();
-/// try!(socket.send_to(buf, &src));
-///
-/// drop(socket); // close the socket
-/// # Ok(())
+///     // send a reply to the socket we received data from
+///     let buf = &mut buf[..amt];
+///     buf.reverse();
+///     try!(socket.send_to(buf, &src));
+///     # Ok(())
+/// } // the socket is closed here
 /// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -169,7 +170,7 @@ mod tests {
     use net::test::{next_test_ip4, next_test_ip6};
     use sync::mpsc::channel;
     use sys_common::AsInner;
-    use time::Duration;
+    use time::{Instant, Duration};
     use thread;
 
     fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
@@ -370,22 +371,22 @@ fn timeouts() {
     fn test_read_timeout() {
         let addr = next_test_ip4();
 
-        let mut stream = t!(UdpSocket::bind(&addr));
+        let stream = t!(UdpSocket::bind(&addr));
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         let mut buf = [0; 10];
-        let wait = Duration::span(|| {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+
+        let start = Instant::now();
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
     }
 
     #[test]
     fn test_read_with_timeout() {
         let addr = next_test_ip4();
 
-        let mut stream = t!(UdpSocket::bind(&addr));
+        let stream = t!(UdpSocket::bind(&addr));
         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
 
         t!(stream.send_to(b"hello world", &addr));
@@ -394,10 +395,9 @@ fn test_read_with_timeout() {
         t!(stream.recv_from(&mut buf));
         assert_eq!(b"hello world", &buf[..]);
 
-        let wait = Duration::span(|| {
-            let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
-            assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
-        });
-        assert!(wait > Duration::from_millis(400));
+        let start = Instant::now();
+        let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
+        assert!(start.elapsed() > Duration::from_millis(400));
     }
 }
index 30bee80fbf658859f5585f2d8d96be8a14598481..1cd258a5a728b46bd9042a8556a490f0a211bd4c 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(not(test))]
 use core::num;
+#[cfg(not(test))]
 use intrinsics;
+#[cfg(not(test))]
 use libc::c_int;
+#[cfg(not(test))]
 use num::FpCategory;
 
+
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
 #[stable(feature = "rust1", since = "1.0.0")]
index d444b2594453cef35bca319adc7a86fcc210cfc0..b6a85ee0e9f586d017ede8f78a48d660af2314bb 100644 (file)
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(not(test))]
 use core::num;
+#[cfg(not(test))]
 use intrinsics;
+#[cfg(not(test))]
 use libc::c_int;
+#[cfg(not(test))]
 use num::FpCategory;
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 8e207f5e6cfc5e5f4c002b5e3263f974921c8d2c..faaff494cab51133329e52d3bf99d1162e8ecf23 100644 (file)
@@ -47,11 +47,6 @@ pub fn test_num<T>(ten: T, two: T) where
 #[cfg(test)]
 mod tests {
     use super::*;
-    use i8;
-    use i16;
-    use i32;
-    use i64;
-    use isize;
     use u8;
     use u16;
     use u32;
index 17d6b2605c62831c7300491b4a824f3f90bb79cd..3bc063f4269206eef6cf7e3a4217f5b6e46d9e3c 100644 (file)
@@ -88,7 +88,8 @@ fn same() {
             c_longlong c_ulonglong c_float c_double);
     }
 
-    #[cfg(unix)]
+    #[cfg(all(unix, not(target_os = "android")))]
+    #[test]
     fn unix() {
         {
             use os::unix::raw;
@@ -101,6 +102,7 @@ fn unix() {
     }
 
     #[cfg(windows)]
+    #[test]
     fn windows() {
         use os::windows::raw;
     }
index 45c29e83b39243027932633574bfdc1cbc11a03b..0ba0e01ce29102d03968deb06915a4ac07b2a5cb 100644 (file)
@@ -377,8 +377,6 @@ fn drop(&mut self) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use sync::mpsc::channel;
     use rand::Rng;
     use super::OsRng;
index 36adf44cd3a3ea2913dbc72980fc97167641b677..08bc809ed4d4632ac29dc8f5422487ce2dacfa1a 100644 (file)
@@ -63,8 +63,6 @@ fn fill_bytes(&mut self, mut v: &mut [u8]) {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
-
     use super::ReaderRng;
     use rand::Rng;
 
index 63fb9b561ff32fc6fcf93c7c4ba6bbdde405eb0f..fcd827e2a8b722e9b4e18d17299d90cf12192ee0 100644 (file)
             issue = "0")]
 #![doc(hidden)]
 
-use borrow::ToOwned;
-use mem;
-use panic;
-use sys;
-use sys_common::thread_info::{self, NewThread};
-use sys_common;
-use thread::Thread;
+
 
 // Reexport some of our utilities which are expected by other crates.
 pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt};
 #[cfg(not(test))]
 #[lang = "start"]
 fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
+    use borrow::ToOwned;
+    use mem;
+    use panic;
+    use sys;
+    use sys_common;
+    use sys_common::thread_info::{self, NewThread};
+    use thread::Thread;
+
     sys::init();
 
     let failed = unsafe {
index d817a261f7c9493c53a2d20f361942a65d689b68..1f7fe820bf86a37c7edd5dbdd240afabce4df954 100644 (file)
@@ -510,15 +510,15 @@ fn wait_timeout_ms() {
         static M: StaticMutex = StaticMutex::new();
 
         let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout_ms(g, 1).unwrap();
+        let (g, _no_timeout) = C.wait_timeout(g, Duration::from_millis(1)).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
         let _t = thread::spawn(move || {
             let _g = M.lock().unwrap();
             C.notify_one();
         });
-        let (g, no_timeout) = C.wait_timeout_ms(g, u32::MAX).unwrap();
-        assert!(no_timeout);
+        let (g, timeout_res) = C.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
+        assert!(!timeout_res.timed_out());
         drop(g);
         unsafe { C.destroy(); M.destroy(); }
     }
index 151d853fc9f7e033576df32ea0a093db9a0412c5..9f2f0df3a64705577537e4eaf90e7249924baa13 100644 (file)
@@ -133,7 +133,7 @@ fn bench_uninitialized(b: &mut test::Bencher) {
         b.iter(|| {
             let mut lr = repeat(1).take(10000000);
             let mut vec = Vec::with_capacity(1024);
-            unsafe { read_to_end_uninitialized(&mut lr, &mut vec) };
+            unsafe { read_to_end_uninitialized(&mut lr, &mut vec) }
         });
     }
 }
index f3f21e47a14066d76c37c1f0342b8a601f10faf7..31caa68c4b7ea70bcd89871e305a68076738eebf 100644 (file)
@@ -167,7 +167,6 @@ mod tests {
     use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
     use cell::RefCell;
     use sync::Arc;
-    use boxed;
     use thread;
 
     #[test]
@@ -208,13 +207,13 @@ fn is_mutex() {
     fn trylock_works() {
         let m = Arc::new(ReentrantMutex::new(()));
         let m2 = m.clone();
-        let lock = m.try_lock().unwrap();
-        let lock2 = m.try_lock().unwrap();
+        let _lock = m.try_lock().unwrap();
+        let _lock2 = m.try_lock().unwrap();
         thread::spawn(move || {
             let lock = m2.try_lock();
             assert!(lock.is_err());
         }).join().unwrap();
-        let lock3 = m.try_lock().unwrap();
+        let _lock3 = m.try_lock().unwrap();
     }
 
     pub struct Answer<'a>(pub ReentrantMutexGuard<'a, RefCell<u32>>);
@@ -233,9 +232,8 @@ fn poison_works() {
             *lock.borrow_mut() = 1;
             let lock2 = mc.lock().unwrap();
             *lock.borrow_mut() = 2;
-            let answer = Answer(lock2);
+            let _answer = Answer(lock2);
             panic!("What the answer to my lifetimes dilemma is?");
-            drop(answer);
         }).join();
         assert!(result.is_err());
         let r = m.lock().err().unwrap().into_inner();
index 2e092d5f770c52c250ad4c52b9214fedd79b98e9..bc997af3a27e46ae2e8edd61d0b74876652bac28 100644 (file)
@@ -1067,7 +1067,7 @@ fn wtf8buf_as_slice() {
     #[test]
     fn wtf8buf_show_str() {
         let text = "a\té ðŸ’©\r";
-        let mut string = Wtf8Buf::from_str(text);
+        let string = Wtf8Buf::from_str(text);
         assert_eq!(format!("{:?}", text), format!("{:?}", string));
     }
 
index 68b0c3d6b0ee7392ce9d81919e3f1bd1e4d6c0e5..929fd2fb0c38b8a0c3dc146d634c1fb63e5b396f 100644 (file)
@@ -45,7 +45,7 @@
 pub mod time;
 pub mod stdio;
 
-#[cfg(not(target_os = "nacl"))]
+#[cfg(not(any(target_os = "nacl", test)))]
 pub fn init() {
     use libc::signal;
     // By default, some platforms will send a *signal* when an EPIPE error
@@ -59,7 +59,8 @@ pub fn init() {
         assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
     }
 }
-#[cfg(target_os = "nacl")]
+
+#[cfg(all(target_os = "nacl", not(test)))]
 pub fn init() { }
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
index 407fcb0a1b8f176eecc3c945cddb79d251907141..495f45f5c7e224346f26e0ac06ead4b70738aad1 100644 (file)
@@ -462,8 +462,7 @@ mod tests {
     use mem;
     use ptr;
     use libc;
-    use slice;
-    use sys::{self, cvt, pipe};
+    use sys::{self, cvt};
 
     macro_rules! t {
         ($e:expr) => {
@@ -482,6 +481,8 @@ macro_rules! t {
 
     #[cfg(target_os = "android")]
     unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
+        use slice;
+
         let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
         let bit = (signum - 1) as usize;
         raw[bit / 8] |= 1 << (bit % 8);
index 9a7f98d24cd5df733617cc416f13f7223e1e7aff..776acd20b069bbc0598eb417c4f10dd78d1d6ca6 100644 (file)
@@ -7,11 +7,13 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+#![cfg_attr(test, allow(dead_code))]
 
 use libc;
 use self::imp::{make_handler, drop_handler};
 
-pub use self::imp::{init, cleanup};
+pub use self::imp::cleanup;
+pub use self::imp::init;
 
 pub struct Handler {
     _data: *mut libc::c_void
@@ -40,12 +42,11 @@ fn drop(&mut self) {
           target_os = "openbsd"))]
 mod imp {
     use super::Handler;
-    use sys_common::util::report_overflow;
     use mem;
     use ptr;
+    use libc::{sigaltstack, SIGSTKSZ};
     use libc::{sigaction, SIGBUS, SIG_DFL,
-               SA_SIGINFO, SA_ONSTACK, sigaltstack,
-               SIGSTKSZ, sighandler_t};
+               SA_SIGINFO, SA_ONSTACK, sighandler_t};
     use libc;
     use libc::{mmap, munmap};
     use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
@@ -94,6 +95,8 @@ unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void {
     unsafe extern fn signal_handler(signum: libc::c_int,
                                     info: *mut libc::siginfo_t,
                                     _data: *mut libc::c_void) {
+        use sys_common::util::report_overflow;
+
         let guard = thread_info::stack_guard().unwrap_or(0);
         let addr = siginfo_si_addr(info) as usize;
 
index 0e525f394216c9bdadef5d415f8e40e54fd16a9b..116cd5da2ce7b273a4cfc8ad07d0154e43b84dc0 100644 (file)
@@ -830,14 +830,14 @@ fn test_try_panic_message_unit_struct() {
     fn test_park_timeout_unpark_before() {
         for _ in 0..10 {
             thread::current().unpark();
-            thread::park_timeout_ms(u32::MAX);
+            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
         }
     }
 
     #[test]
     fn test_park_timeout_unpark_not_called() {
         for _ in 0..10 {
-            thread::park_timeout_ms(10);
+            thread::park_timeout(Duration::from_millis(10));
         }
     }
 
@@ -847,17 +847,17 @@ fn test_park_timeout_unpark_called_other_thread() {
             let th = thread::current();
 
             let _guard = thread::spawn(move || {
-                super::sleep_ms(50);
+                super::sleep(Duration::from_millis(50));
                 th.unpark();
             });
 
-            thread::park_timeout_ms(u32::MAX);
+            thread::park_timeout(Duration::from_millis(u32::MAX as u64));
         }
     }
 
     #[test]
     fn sleep_ms_smoke() {
-        thread::sleep_ms(2);
+        thread::sleep(Duration::from_millis(2));
     }
 
     // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due
index 0981a8c4a5bf33198d403aacf809a19f6e197c73..ad1be82d6d8422a9a28b1b14481c0961a8847056 100644 (file)
@@ -173,7 +173,6 @@ fn div(self, rhs: u32) -> Duration {
 
 #[cfg(test)]
 mod tests {
-    use prelude::v1::*;
     use super::Duration;
 
     #[test]
index 0ad655ce00bb93e5be2ff0b976cef363599ad688..9617ae6bae54c9cf29a46ef2ec74e846db7ae7bb 100644 (file)
@@ -250,14 +250,14 @@ pub struct PathSegment {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum PathParameters {
     /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>`
-    AngleBracketedParameters(AngleBracketedParameterData),
+    AngleBracketed(AngleBracketedParameterData),
     /// The `(A,B)` and `C` in `Foo(A,B) -> C`
-    ParenthesizedParameters(ParenthesizedParameterData),
+    Parenthesized(ParenthesizedParameterData),
 }
 
 impl PathParameters {
     pub fn none() -> PathParameters {
-        AngleBracketedParameters(AngleBracketedParameterData {
+        PathParameters::AngleBracketed(AngleBracketedParameterData {
             lifetimes: Vec::new(),
             types: P::empty(),
             bindings: P::empty(),
@@ -266,25 +266,25 @@ pub fn none() -> PathParameters {
 
     pub fn is_empty(&self) -> bool {
         match *self {
-            AngleBracketedParameters(ref data) => data.is_empty(),
+            PathParameters::AngleBracketed(ref data) => data.is_empty(),
 
             // Even if the user supplied no types, something like
             // `X()` is equivalent to `X<(),()>`.
-            ParenthesizedParameters(..) => false,
+            PathParameters::Parenthesized(..) => false,
         }
     }
 
     pub fn has_lifetimes(&self) -> bool {
         match *self {
-            AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(),
-            ParenthesizedParameters(_) => false,
+            PathParameters::AngleBracketed(ref data) => !data.lifetimes.is_empty(),
+            PathParameters::Parenthesized(_) => false,
         }
     }
 
     pub fn has_types(&self) -> bool {
         match *self {
-            AngleBracketedParameters(ref data) => !data.types.is_empty(),
-            ParenthesizedParameters(..) => true,
+            PathParameters::AngleBracketed(ref data) => !data.types.is_empty(),
+            PathParameters::Parenthesized(..) => true,
         }
     }
 
@@ -292,10 +292,10 @@ pub fn has_types(&self) -> bool {
     /// parameters in the parenthesized case.
     pub fn types(&self) -> Vec<&P<Ty>> {
         match *self {
-            AngleBracketedParameters(ref data) => {
+            PathParameters::AngleBracketed(ref data) => {
                 data.types.iter().collect()
             }
-            ParenthesizedParameters(ref data) => {
+            PathParameters::Parenthesized(ref data) => {
                 data.inputs.iter()
                     .chain(data.output.iter())
                     .collect()
@@ -305,10 +305,10 @@ pub fn types(&self) -> Vec<&P<Ty>> {
 
     pub fn lifetimes(&self) -> Vec<&Lifetime> {
         match *self {
-            AngleBracketedParameters(ref data) => {
+            PathParameters::AngleBracketed(ref data) => {
                 data.lifetimes.iter().collect()
             }
-            ParenthesizedParameters(_) => {
+            PathParameters::Parenthesized(_) => {
                 Vec::new()
             }
         }
@@ -316,10 +316,10 @@ pub fn lifetimes(&self) -> Vec<&Lifetime> {
 
     pub fn bindings(&self) -> Vec<&P<TypeBinding>> {
         match *self {
-            AngleBracketedParameters(ref data) => {
+            PathParameters::AngleBracketed(ref data) => {
                 data.bindings.iter().collect()
             }
-            ParenthesizedParameters(_) => {
+            PathParameters::Parenthesized(_) => {
                 Vec::new()
             }
         }
index 70561b1eb551dce71563391c6629881e51ce4447..ba4d1e2193e5f0f49be54071dd73dca53783f282 100644 (file)
@@ -40,7 +40,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path {
         segments: vec!(
             ast::PathSegment {
                 identifier: identifier,
-                parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+                parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
                     lifetimes: Vec::new(),
                     types: P::empty(),
                     bindings: P::empty(),
index 26662605ba87fb68abab4d729ac722f7d669c3a9..96d0052cf180125b659fd5ce4157960ea0b4f616 100644 (file)
@@ -305,8 +305,10 @@ pub fn find_export_name_attr(diag: &Handler, attrs: &[Attribute]) -> Option<Inte
             if let s@Some(_) = attr.value_str() {
                 s
             } else {
-                diag.span_err(attr.span, "export_name attribute has invalid format");
-                diag.help("use #[export_name=\"*\"]");
+                diag.struct_span_err(attr.span,
+                                     "export_name attribute has invalid format")
+                    .help("use #[export_name=\"*\"]")
+                    .emit();
                 None
             }
         } else {
index 3c8347f8a8e0e165b3852e1c52cf95df903188e5..95a74d875545fcfeac1fd6ef15e10dbe06ab238a 100644 (file)
@@ -30,6 +30,14 @@ macro_rules! span_err {
     })
 }
 
+#[macro_export]
+macro_rules! span_warn {
+    ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
+        __diagnostic_used!($code);
+        $session.span_warn_with_code($span, &format!($($message)*), stringify!($code))
+    })
+}
+
 #[macro_export]
 macro_rules! span_err_or_warn {
     ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
@@ -43,31 +51,59 @@ macro_rules! span_err_or_warn {
 }
 
 #[macro_export]
-macro_rules! span_warn {
+macro_rules! struct_span_fatal {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
         __diagnostic_used!($code);
-        $session.span_warn_with_code($span, &format!($($message)*), stringify!($code))
+        $session.struct_span_fatal_with_code($span, &format!($($message)*), stringify!($code))
+    })
+}
+
+#[macro_export]
+macro_rules! struct_span_err {
+    ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
+        __diagnostic_used!($code);
+        $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code))
+    })
+}
+
+#[macro_export]
+macro_rules! struct_span_warn {
+    ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
+        __diagnostic_used!($code);
+        $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code))
+    })
+}
+
+#[macro_export]
+macro_rules! struct_span_err_or_warn {
+    ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
+        __diagnostic_used!($code);
+        if $is_warning {
+            $session.struct_span_warn_with_code($span, &format!($($message)*), stringify!($code))
+        } else {
+            $session.struct_span_err_with_code($span, &format!($($message)*), stringify!($code))
+        }
     })
 }
 
 #[macro_export]
 macro_rules! span_note {
-    ($session:expr, $span:expr, $($message:tt)*) => ({
-        ($session).span_note($span, &format!($($message)*))
+    ($err:expr, $span:expr, $($message:tt)*) => ({
+        ($err).span_note($span, &format!($($message)*));
     })
 }
 
 #[macro_export]
 macro_rules! span_help {
-    ($session:expr, $span:expr, $($message:tt)*) => ({
-        ($session).span_help($span, &format!($($message)*))
+    ($err:expr, $span:expr, $($message:tt)*) => ({
+        ($err).span_help($span, &format!($($message)*));
     })
 }
 
 #[macro_export]
 macro_rules! fileline_help {
-    ($session:expr, $span:expr, $($message:tt)*) => ({
-        ($session).fileline_help($span, &format!($($message)*))
+    ($err:expr, $span:expr, $($message:tt)*) => ({
+        ($err).fileline_help($span, &format!($($message)*));
     })
 }
 
index be0d5729c7009fe738158e39765379f73e6c46f1..d17ca3892dc684746c2e3f379b28447834940ff8 100644 (file)
@@ -62,10 +62,10 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt,
         match diagnostics.get_mut(&code.name) {
             // Previously used errors.
             Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => {
-                ecx.span_warn(span, &format!(
+                ecx.struct_span_warn(span, &format!(
                     "diagnostic code {} already used", code
-                ));
-                ecx.span_note(previous_span, "previous invocation");
+                )).span_note(previous_span, "previous invocation")
+                  .emit();
             }
             // Newly used errors.
             Some(ref mut info) => {
index 7fef85a833e251224f3456ed46da1a11a8d270b4..a7bfdedf71813d0fd70ef99033069f1927598008 100644 (file)
@@ -13,7 +13,7 @@
 use codemap::{self, COMMAND_LINE_SP, COMMAND_LINE_EXPN, Pos, Span};
 use diagnostics;
 
-use errors::{Level, RenderSpan};
+use errors::{Level, RenderSpan, DiagnosticBuilder};
 use errors::RenderSpan::*;
 use errors::Level::*;
 
 pub trait Emitter {
     fn emit(&mut self, span: Option<Span>, msg: &str, code: Option<&str>, lvl: Level);
     fn custom_emit(&mut self, sp: RenderSpan, msg: &str, lvl: Level);
+
+    /// Emit a structured diagnostic.
+    fn emit_struct(&mut self, db: &DiagnosticBuilder) {
+        self.emit(db.span, &db.message, db.code.as_ref().map(|s| &**s), db.level);
+        for child in &db.children {
+            match child.render_span {
+                Some(ref sp) => self.custom_emit(sp.clone(), &child.message, child.level),
+                None => self.emit(child.span, &child.message, None, child.level),
+            }
+        }
+    }
 }
 
 /// maximum number of lines we will print for each error; arbitrary.
@@ -49,8 +60,8 @@ fn use_color(&self) -> bool {
     }
 }
 
-// A basic emitter for when we don't have access to a codemap or registry. Used
-// for reporting very early errors, etc.
+/// A basic emitter for when we don't have access to a codemap or registry. Used
+/// for reporting very early errors, etc.
 pub struct BasicEmitter {
     dst: Destination,
 }
@@ -111,9 +122,8 @@ fn custom_emit(&mut self,
                    sp: RenderSpan,
                    msg: &str,
                    lvl: Level) {
-        match self.emit_(sp, msg, None, lvl) {
-            Ok(()) => {}
-            Err(e) => panic!("failed to print diagnostics: {:?}", e),
+        if let Err(e) = self.emit_(sp, msg, None, lvl) {
+            panic!("failed to print diagnostics: {:?}", e);
         }
     }
 }
index f2e61090ba23cfc86b1d72a3e9d2b9fe97b9dc1e..a2fae975148f953e913d96b878babf75fcd01ae8 100644 (file)
@@ -98,6 +98,171 @@ fn description(&self) -> &str {
     }
 }
 
+/// Used for emitting structured error messages and other diagnostic information.
+#[must_use]
+pub struct DiagnosticBuilder<'a> {
+    emitter: &'a RefCell<Box<Emitter>>,
+    level: Level,
+    message: String,
+    code: Option<String>,
+    span: Option<Span>,
+    children: Vec<SubDiagnostic>,
+}
+
+/// For example a note attached to an error.
+struct SubDiagnostic {
+    level: Level,
+    message: String,
+    span: Option<Span>,
+    render_span: Option<RenderSpan>,
+}
+
+impl<'a> DiagnosticBuilder<'a> {
+    /// Emit the diagnostic.
+    pub fn emit(&mut self) {
+        if self.cancelled() {
+            return;
+        }
+
+        self.emitter.borrow_mut().emit_struct(&self);
+        self.cancel();
+
+        // if self.is_fatal() {
+        //     panic!(FatalError);
+        // }
+    }
+
+    /// Cancel the diagnostic (a structured diagnostic must either be emitted or
+    /// cancelled or it will panic when dropped).
+    /// BEWARE: if this DiagnosticBuilder is an error, then creating it will
+    /// bump the error count on the Handler and cancelling it won't undo that.
+    /// If you want to decrement the error count you should use `Handler::cancel`.
+    pub fn cancel(&mut self) {
+        self.level = Level::Cancelled;
+    }
+
+    pub fn cancelled(&self) -> bool {
+        self.level == Level::Cancelled
+    }
+
+    pub fn is_fatal(&self) -> bool {
+        self.level == Level::Fatal
+    }
+
+    pub fn note(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Note, msg, None, None);
+        self
+    }
+    pub fn span_note(&mut self ,
+                     sp: Span,
+                     msg: &str)
+                     -> &mut DiagnosticBuilder<'a> {
+        self.sub(Level::Note, msg, Some(sp), None);
+        self
+    }
+    pub fn help(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Help, msg, None, None);
+        self
+    }
+    pub fn span_help(&mut self ,
+                     sp: Span,
+                     msg: &str)
+                     -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Help, msg, Some(sp), None);
+        self
+    }
+    /// Prints out a message with a suggested edit of the code.
+    ///
+    /// See `diagnostic::RenderSpan::Suggestion` for more information.
+    pub fn span_suggestion(&mut self ,
+                           sp: Span,
+                           msg: &str,
+                           suggestion: String)
+                           -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Help, msg, Some(sp), Some(Suggestion(sp, suggestion)));
+        self
+    }
+    pub fn span_end_note(&mut self ,
+                         sp: Span,
+                         msg: &str)
+                         -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Note, msg, Some(sp), Some(EndSpan(sp)));
+        self
+    }
+    pub fn fileline_note(&mut self ,
+                         sp: Span,
+                         msg: &str)
+                         -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Note, msg, Some(sp), Some(FileLine(sp)));
+        self
+    }
+    pub fn fileline_help(&mut self ,
+                         sp: Span,
+                         msg: &str)
+                         -> &mut DiagnosticBuilder<'a>  {
+        self.sub(Level::Help, msg, Some(sp), Some(FileLine(sp)));
+        self
+    }
+
+    pub fn span(&mut self, sp: Span) -> &mut Self {
+        self.span = Some(sp);
+        self
+    }
+
+    pub fn code(&mut self, s: String) -> &mut Self {
+        self.code = Some(s);
+        self
+    }
+
+    /// Convenience function for internal use, clients should use one of the
+    /// struct_* methods on Handler.
+    fn new(emitter: &'a RefCell<Box<Emitter>>,
+           level: Level,
+           message: &str) -> DiagnosticBuilder<'a>  {
+        DiagnosticBuilder {
+            emitter: emitter,
+            level: level,
+            message: message.to_owned(),
+            code: None,
+            span: None,
+            children: vec![],
+        }
+    }
+
+    /// Convenience function for internal use, clients should use one of the
+    /// public methods above.
+    fn sub(&mut self,
+           level: Level,
+           message: &str,
+           span: Option<Span>,
+           render_span: Option<RenderSpan>) {
+        let sub = SubDiagnostic {
+            level: level,
+            message: message.to_owned(),
+            span: span,
+            render_span: render_span,
+        };
+        self.children.push(sub);
+    }
+}
+
+impl<'a> fmt::Debug for DiagnosticBuilder<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.message.fmt(f)
+    }
+}
+
+/// Destructor bomb - a DiagnosticBuilder must be either emitted or cancelled or
+/// we emit a bug.
+impl<'a> Drop for DiagnosticBuilder<'a> {
+    fn drop(&mut self) {
+        if !self.cancelled() {
+            self.emitter.borrow_mut().emit(None, "Error constructed but not emitted", None, Bug);
+            panic!();
+        }
+    }
+}
+
 /// A handler deals with errors; certain errors
 /// (fatal, bug, unimpl) may cause immediate exit,
 /// others log errors for later reporting.
@@ -132,11 +297,104 @@ pub fn with_emitter(can_emit_warnings: bool,
         }
     }
 
+    pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> {
+        DiagnosticBuilder::new(&self.emit, Level::Cancelled, "")
+    }
+
+    pub fn struct_span_warn<'a>(&'a self,
+                                sp: Span,
+                                msg: &str)
+                                -> DiagnosticBuilder<'a> {
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
+        result.span(sp);
+        if !self.can_emit_warnings {
+            result.cancel();
+        }
+        result
+    }
+    pub fn struct_span_warn_with_code<'a>(&'a self,
+                                          sp: Span,
+                                          msg: &str,
+                                          code: &str)
+                                          -> DiagnosticBuilder<'a> {
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
+        result.span(sp);
+        result.code(code.to_owned());
+        if !self.can_emit_warnings {
+            result.cancel();
+        }
+        result
+    }
+    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Warning, msg);
+        if !self.can_emit_warnings {
+            result.cancel();
+        }
+        result
+    }
+    pub fn struct_span_err<'a>(&'a self,
+                               sp: Span,
+                               msg: &str)
+                               -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg);
+        result.span(sp);
+        result
+    }
+    pub fn struct_span_err_with_code<'a>(&'a self,
+                                         sp: Span,
+                                         msg: &str,
+                                         code: &str)
+                                         -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Error, msg);
+        result.span(sp);
+        result.code(code.to_owned());
+        result
+    }
+    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        DiagnosticBuilder::new(&self.emit, Level::Error, msg)
+    }
+    pub fn struct_span_fatal<'a>(&'a self,
+                                 sp: Span,
+                                 msg: &str)
+                                 -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg);
+        result.span(sp);
+        result
+    }
+    pub fn struct_span_fatal_with_code<'a>(&'a self,
+                                           sp: Span,
+                                           msg: &str,
+                                           code: &str)
+                                           -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        let mut result = DiagnosticBuilder::new(&self.emit, Level::Fatal, msg);
+        result.span(sp);
+        result.code(code.to_owned());
+        result
+    }
+    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
+        self.bump_err_count();
+        DiagnosticBuilder::new(&self.emit, Level::Fatal, msg)
+    }
+
+    pub fn cancel(&mut self, err: &mut DiagnosticBuilder) {
+        if err.level == Level::Error || err.level == Level::Fatal {
+            assert!(self.has_errors());
+            self.err_count.set(self.err_count.get() + 1);
+        }
+        err.cancel();
+    }
+
     pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError {
         if self.treat_err_as_bug {
             self.span_bug(sp, msg);
         }
         self.emit(Some(sp), msg, Fatal);
+        self.bump_err_count();
         return FatalError;
     }
     pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> FatalError {
@@ -144,6 +402,7 @@ pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> FatalErro
             self.span_bug(sp, msg);
         }
         self.emit_with_code(Some(sp), msg, code, Fatal);
+        self.bump_err_count();
         return FatalError;
     }
     pub fn span_err(&self, sp: Span, msg: &str) {
@@ -166,27 +425,6 @@ pub fn span_warn(&self, sp: Span, msg: &str) {
     pub fn span_warn_with_code(&self, sp: Span, msg: &str, code: &str) {
         self.emit_with_code(Some(sp), msg, code, Warning);
     }
-    pub fn span_note(&self, sp: Span, msg: &str) {
-        self.emit(Some(sp), msg, Note);
-    }
-    pub fn span_end_note(&self, sp: Span, msg: &str) {
-        self.custom_emit(EndSpan(sp), msg, Note);
-    }
-    pub fn span_help(&self, sp: Span, msg: &str) {
-        self.emit(Some(sp), msg, Help);
-    }
-    /// Prints out a message with a suggested edit of the code.
-    ///
-    /// See `diagnostic::RenderSpan::Suggestion` for more information.
-    pub fn span_suggestion(&self, sp: Span, msg: &str, suggestion: String) {
-        self.custom_emit(Suggestion(sp, suggestion), msg, Help);
-    }
-    pub fn fileline_note(&self, sp: Span, msg: &str) {
-        self.custom_emit(FileLine(sp), msg, Note);
-    }
-    pub fn fileline_help(&self, sp: Span, msg: &str) {
-        self.custom_emit(FileLine(sp), msg, Help);
-    }
     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
         self.emit(Some(sp), msg, Bug);
         panic!(ExplicitBug);
@@ -199,6 +437,9 @@ pub fn span_bug_no_panic(&self, sp: Span, msg: &str) {
         self.emit(Some(sp), msg, Bug);
         self.bump_err_count();
     }
+    pub fn span_note_without_error(&self, sp: Span, msg: &str) {
+        self.emit.borrow_mut().emit(Some(sp), msg, None, Note);
+    }
     pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
         self.span_bug(sp, &format!("unimplemented {}", msg));
     }
@@ -207,6 +448,7 @@ pub fn fatal(&self, msg: &str) -> FatalError {
             self.bug(msg);
         }
         self.emit.borrow_mut().emit(None, msg, None, Fatal);
+        self.bump_err_count();
         FatalError
     }
     pub fn err(&self, msg: &str) {
@@ -219,12 +461,9 @@ pub fn err(&self, msg: &str) {
     pub fn warn(&self, msg: &str) {
         self.emit.borrow_mut().emit(None, msg, None, Warning);
     }
-    pub fn note(&self, msg: &str) {
+    pub fn note_without_error(&self, msg: &str) {
         self.emit.borrow_mut().emit(None, msg, None, Note);
     }
-    pub fn help(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, None, Help);
-    }
     pub fn bug(&self, msg: &str) -> ! {
         self.emit.borrow_mut().emit(None, msg, None, Bug);
         panic!(ExplicitBug);
@@ -266,7 +505,7 @@ pub fn abort_if_errors(&self) {
             }
         }
 
-        panic!(self.fatal(&s[..]));
+        panic!(self.fatal(&s));
     }
 
     pub fn emit(&self,
@@ -301,6 +540,7 @@ pub enum Level {
     Warning,
     Note,
     Help,
+    Cancelled,
 }
 
 impl fmt::Display for Level {
@@ -313,6 +553,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             Warning => "warning".fmt(f),
             Note => "note".fmt(f),
             Help => "help".fmt(f),
+            Cancelled => unreachable!(),
         }
     }
 }
@@ -324,6 +565,7 @@ fn color(self) -> term::color::Color {
             Warning => term::color::BRIGHT_YELLOW,
             Note => term::color::BRIGHT_GREEN,
             Help => term::color::BRIGHT_CYAN,
+            Cancelled => unreachable!(),
         }
     }
 }
index f616420218e1aff1427f4d66c2562a251c6338b0..fc0f1925207ae45dbaeaa2866852e41dca8f7fa0 100644 (file)
@@ -14,6 +14,7 @@
 use ast::Name;
 use codemap;
 use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
+use errors::DiagnosticBuilder;
 use ext;
 use ext::expand;
 use ext::tt::macro_rules;
@@ -678,6 +679,25 @@ pub fn insert_macro(&mut self, def: ast::MacroDef) {
         }
     }
 
+    pub fn struct_span_warn(&self,
+                            sp: Span,
+                            msg: &str)
+                            -> DiagnosticBuilder<'a> {
+        self.parse_sess.span_diagnostic.struct_span_warn(sp, msg)
+    }
+    pub fn struct_span_err(&self,
+                           sp: Span,
+                           msg: &str)
+                           -> DiagnosticBuilder<'a> {
+        self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
+    }
+    pub fn struct_span_fatal(&self,
+                             sp: Span,
+                             msg: &str)
+                             -> DiagnosticBuilder<'a> {
+        self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg)
+    }
+
     /// Emit `msg` attached to `sp`, and stop compilation immediately.
     ///
     /// `span_err` should be strongly preferred where-ever possible:
@@ -710,15 +730,6 @@ pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! {
     pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
         self.parse_sess.span_diagnostic.span_bug(sp, msg);
     }
-    pub fn span_note(&self, sp: Span, msg: &str) {
-        self.parse_sess.span_diagnostic.span_note(sp, msg);
-    }
-    pub fn span_help(&self, sp: Span, msg: &str) {
-        self.parse_sess.span_diagnostic.span_help(sp, msg);
-    }
-    pub fn fileline_help(&self, sp: Span, msg: &str) {
-        self.parse_sess.span_diagnostic.fileline_help(sp, msg);
-    }
     pub fn bug(&self, msg: &str) -> ! {
         self.parse_sess.span_diagnostic.bug(msg);
     }
@@ -743,10 +754,13 @@ pub fn name_of(&self, st: &str) -> ast::Name {
         token::intern(st)
     }
 
-    pub fn suggest_macro_name(&mut self, name: &str, span: Span) {
+    pub fn suggest_macro_name(&mut self,
+                              name: &str,
+                              span: Span,
+                              err: &mut DiagnosticBuilder<'a>) {
         let names = &self.syntax_env.names;
         if let Some(suggestion) = find_best_match_for_name(names.iter(), name, None) {
-            self.fileline_help(span, &format!("did you mean `{}!`?", suggestion));
+            err.fileline_help(span, &format!("did you mean `{}!`?", suggestion));
         }
     }
 }
index 8c19a10b4b147aa65b0241c6944fb80aea4e9829..a74c2340cecb8621ae1d3ce2034bec3c43f75594 100644 (file)
@@ -328,7 +328,7 @@ fn path_all(&self,
         }).collect();
         segments.push(ast::PathSegment {
             identifier: last_identifier,
-            parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+            parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
                 types: P::from_vec(types),
                 bindings: P::from_vec(bindings),
@@ -366,7 +366,7 @@ fn qpath_all(&self,
         let mut path = trait_path;
         path.segments.push(ast::PathSegment {
             identifier: ident,
-            parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+            parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
                 lifetimes: lifetimes,
                 types: P::from_vec(types),
                 bindings: P::from_vec(bindings),
index 743bcda18def441507ef0cd3a3f1ca4a2995b32e..5f27bdfc98a41bac1f9ff0b814ab89e49a515cbc 100644 (file)
@@ -201,11 +201,12 @@ fn expand_mac_invoc<T, F, G>(mac: ast::Mac,
     let extname = pth.segments[0].identifier.name;
     match fld.cx.syntax_env.find(extname) {
         None => {
-            fld.cx.span_err(
+            let mut err = fld.cx.struct_span_err(
                 pth.span,
                 &format!("macro undefined: '{}!'",
                         &extname));
-            fld.cx.suggest_macro_name(&extname.as_str(), pth.span);
+            fld.cx.suggest_macro_name(&extname.as_str(), pth.span, &mut err);
+            err.emit();
 
             // let compilation continue
             None
@@ -334,11 +335,15 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool
     for attr in attrs {
         let mut is_use = attr.check_name("macro_use");
         if attr.check_name("macro_escape") {
-            fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use");
+            let mut err =
+                fld.cx.struct_span_warn(attr.span,
+                                        "macro_escape is a deprecated synonym for macro_use");
             is_use = true;
             if let ast::AttrStyle::Inner = attr.node.style {
-                fld.cx.fileline_help(attr.span, "consider an outer attribute, \
-                                             #[macro_use] mod ...");
+                err.fileline_help(attr.span, "consider an outer attribute, \
+                                              #[macro_use] mod ...").emit();
+            } else {
+                err.emit();
             }
         };
 
index 0c3a8b05fba1e6d76ae91f16fba2d2a2f7ff677a..7a1a207a562a1dd23200ef4d0d54d8220bb80b2f 100644 (file)
@@ -802,7 +802,7 @@ fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[TokenTree])
 
     let cx_expr = panictry!(p.parse_expr());
     if !panictry!(p.eat(&token::Comma)) {
-        panic!(p.fatal("expected token `,`"));
+        let _ = p.diagnostic().fatal("expected token `,`");
     }
 
     let tts = panictry!(p.parse_all_token_trees());
index 7899e170ecf195f322da65a4af938fa55be0fec0..f00224bacdd2d13459933750ef81c7d5076bd6a4 100644 (file)
@@ -117,11 +117,9 @@ fn make_items(mut self: Box<ExpandResult<'a>>)
             while self.p.token != token::Eof {
                 match panictry!(self.p.parse_item()) {
                     Some(item) => ret.push(item),
-                    None => panic!(self.p.span_fatal(
-                        self.p.span,
-                        &format!("expected item, found `{}`",
-                                 self.p.this_token_to_string())
-                    ))
+                    None => panic!(self.p.diagnostic().span_fatal(self.p.span,
+                                                           &format!("expected item, found `{}`",
+                                                                    self.p.this_token_to_string())))
                 }
             }
             Some(ret)
index fb09118035c7e3cea4d962cb7f87689005ebe555..166d32a8cc62faa3f0e20a9e288f732b29470bcb 100644 (file)
@@ -82,6 +82,7 @@
 use ast::{TokenTree, Name, Ident};
 use codemap::{BytePos, mk_sp, Span, Spanned};
 use codemap;
+use errors::FatalError;
 use parse::lexer::*; //resolve bug?
 use parse::ParseSess;
 use parse::parser::{LifetimeAndTypesWithoutColons, Parser};
@@ -499,11 +500,12 @@ pub fn parse(sess: &ParseSess,
     }
 }
 
-pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
+pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
     match name {
         "tt" => {
             p.quote_depth += 1; //but in theory, non-quoted tts might be useful
-            let res = token::NtTT(P(panictry!(p.parse_token_tree())));
+            let res: ::parse::PResult<'a, _> = p.parse_token_tree();
+            let res = token::NtTT(P(panictry!(res)));
             p.quote_depth -= 1;
             return res;
         }
@@ -514,12 +516,18 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
     match name {
         "item" => match panictry!(p.parse_item()) {
             Some(i) => token::NtItem(i),
-            None => panic!(p.fatal("expected an item keyword"))
+            None => {
+                p.fatal("expected an item keyword").emit();
+                panic!(FatalError);
+            }
         },
         "block" => token::NtBlock(panictry!(p.parse_block())),
         "stmt" => match panictry!(p.parse_stmt()) {
             Some(s) => token::NtStmt(s),
-            None => panic!(p.fatal("expected a statement"))
+            None => {
+                p.fatal("expected a statement").emit();
+                panic!(FatalError);
+            }
         },
         "pat" => token::NtPat(panictry!(p.parse_pat())),
         "expr" => token::NtExpr(panictry!(p.parse_expr())),
@@ -532,8 +540,9 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
             }
             _ => {
                 let token_str = pprust::token_to_string(&p.token);
-                panic!(p.fatal(&format!("expected ident, found {}",
-                                 &token_str[..])))
+                p.fatal(&format!("expected ident, found {}",
+                                 &token_str[..])).emit();
+                panic!(FatalError)
             }
         },
         "path" => {
@@ -541,11 +550,12 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
         },
         "meta" => token::NtMeta(panictry!(p.parse_meta_item())),
         _ => {
-            panic!(p.span_fatal_help(sp,
-                            &format!("invalid fragment specifier `{}`", name),
-                            "valid fragment specifiers are `ident`, `block`, \
-                             `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
-                             and `item`"))
+            p.span_fatal_help(sp,
+                              &format!("invalid fragment specifier `{}`", name),
+                              "valid fragment specifiers are `ident`, `block`, \
+                               `stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
+                               and `item`").emit();
+            panic!(FatalError);
         }
     }
 }
index fae60d28032931feb075aed89b3d0c9b230a5577..fd0bbf7a0723e95d71f6438d2a6918c21b854fc8 100644 (file)
@@ -55,12 +55,12 @@ fn ensure_complete_parse(&self, allow_semi: bool, context: &str) {
                                following",
                               token_str);
             let span = parser.span;
-            parser.span_err(span, &msg[..]);
-
+            let mut err = parser.diagnostic().struct_span_err(span, &msg[..]);
             let msg = format!("caused by the macro expansion here; the usage \
                                of `{}!` is likely invalid in {} context",
                                self.macro_ident, context);
-            parser.span_note(self.site_span, &msg[..]);
+            err.span_note(self.site_span, &msg[..])
+               .emit();
         }
     }
 }
@@ -111,7 +111,10 @@ fn make_stmts(self: Box<ParserAnyMacro<'a>>)
                         Some(stmt) => ret.push(stmt),
                         None => (),
                     },
-                    Err(_) => break,
+                    Err(mut e) => {
+                        e.emit();
+                        break;
+                    }
                 }
             }
         }
index 4ea0fd76fea4a6c38868651b0a34eb188f4aa4ae..a23dc3b8871fadb89bf7ba92d64e34b8ed95d7d0 100644 (file)
@@ -725,17 +725,21 @@ pub fn emit_feature_err(diag: &Handler, feature: &str, span: Span, issue: GateIs
         GateIssue::Library(lib) => lib,
     };
 
-    if let Some(n) = issue {
-        diag.span_err(span, &format!("{} (see issue #{})", explain, n));
+    let mut err = if let Some(n) = issue {
+        diag.struct_span_err(span, &format!("{} (see issue #{})", explain, n))
     } else {
-        diag.span_err(span, explain);
-    }
+        diag.struct_span_err(span, explain)
+    };
 
     // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
-    if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; }
-    diag.fileline_help(span, &format!("add #![feature({})] to the \
-                                   crate attributes to enable",
-                                  feature));
+    if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() {
+        err.emit();
+        return;
+    }
+    err.fileline_help(span, &format!("add #![feature({})] to the \
+                                      crate attributes to enable",
+                                     feature));
+    err.emit();
 }
 
 pub const EXPLAIN_ASM: &'static str =
@@ -942,11 +946,13 @@ fn visit_variant_data(&mut self, s: &'v ast::VariantData, _: ast::Ident,
                 self.gate_feature("braced_empty_structs", span,
                                   "empty structs and enum variants with braces are unstable");
             } else if s.is_tuple() {
-                self.context.span_handler.span_err(span, "empty tuple structs and enum variants \
-                                                          are not allowed, use unit structs and \
-                                                          enum variants instead");
-                self.context.span_handler.span_help(span, "remove trailing `()` to make a unit \
-                                                           struct or unit enum variant");
+                self.context.span_handler.struct_span_err(span, "empty tuple structs and enum \
+                                                                 variants are not allowed, use \
+                                                                 unit structs and enum variants \
+                                                                 instead")
+                                         .span_help(span, "remove trailing `()` to make a unit \
+                                                           struct or unit enum variant")
+                                         .emit();
             }
         }
         visit::walk_struct_def(self, s)
index cb467f9016b6f5f6496635b6fd5bcf2a505bb586..1de6d6c002f065d60033eb3f0d9cc4228ff575bd 100644 (file)
@@ -469,10 +469,10 @@ pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld
                                             -> PathParameters
 {
     match path_parameters {
-        AngleBracketedParameters(data) =>
-            AngleBracketedParameters(fld.fold_angle_bracketed_parameter_data(data)),
-        ParenthesizedParameters(data) =>
-            ParenthesizedParameters(fld.fold_parenthesized_parameter_data(data)),
+        PathParameters::AngleBracketed(data) =>
+            PathParameters::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data)),
+        PathParameters::Parenthesized(data) =>
+            PathParameters::Parenthesized(fld.fold_parenthesized_parameter_data(data)),
     }
 }
 
index c09e35f1077a53fca990cf05ee447ac2ab1369d2..795f4044f6eb1be35c1bb8b74a49093b813be9c9 100644 (file)
 
 extern crate serialize as rustc_serialize; // used by deriving
 
-// A variant of 'try!' that panics on Err(FatalError). This is used as a
-// crutch on the way towards a non-panic!-prone parser. It should be used
-// for fatal parsing errors; eventually we plan to convert all code using
-// panictry to just use normal try
+// A variant of 'try!' that panics on an Err. This is used as a crutch on the
+// way towards a non-panic!-prone parser. It should be used for fatal parsing
+// errors; eventually we plan to convert all code using panictry to just use
+// normal try.
+// Exported for syntax_ext, not meant for general use.
+#[macro_export]
 macro_rules! panictry {
     ($e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use errors::FatalError;
+        use $crate::errors::FatalError;
         match $e {
             Ok(e) => e,
-            Err(FatalError) => panic!(FatalError)
+            Err(mut e) => {
+                e.emit();
+                panic!(FatalError);
+            }
         }
     })
 }
index 5df2478d4875809c8fe5c6e381ba44658952913f..35ec3dcb0fd5f2a540ebaa924aaa26ab3e752af9 100644 (file)
@@ -19,7 +19,7 @@
 
 impl<'a> Parser<'a> {
     /// Parse attributes that appear before an item
-    pub fn parse_outer_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
+    pub fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
         loop {
             debug!("parse_outer_attributes: self.token={:?}",
@@ -51,7 +51,7 @@ pub fn parse_outer_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
     ///
     /// If permit_inner is true, then a leading `!` indicates an inner
     /// attribute
-    pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute> {
+    pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> {
         debug!("parse_attributes: permit_inner={:?} self.token={:?}",
                permit_inner, self.token);
         let (span, value, mut style) = match self.token {
@@ -64,11 +64,13 @@ pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute>
                     try!(self.bump());
                     if !permit_inner {
                         let span = self.span;
-                        self.span_err(span,
-                                      "an inner attribute is not permitted in \
-                                       this context");
-                        self.fileline_help(span,
-                                       "place inner attribute at the top of the module or block");
+                        self.diagnostic().struct_span_err(span,
+                                                          "an inner attribute is not permitted in \
+                                                           this context")
+                                         .fileline_help(span,
+                                                        "place inner attribute at the top of \
+                                                         the module or block")
+                                         .emit()
                     }
                     ast::AttrStyle::Inner
                 } else {
@@ -111,7 +113,7 @@ pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<ast::Attribute>
     /// terminated by a semicolon.
 
     /// matches inner_attrs*
-    pub fn parse_inner_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
+    pub fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
             match self.token {
@@ -146,7 +148,7 @@ pub fn parse_inner_attributes(&mut self) -> PResult<Vec<ast::Attribute>> {
     /// matches meta_item = IDENT
     /// | IDENT = lit
     /// | IDENT meta_seq
-    pub fn parse_meta_item(&mut self) -> PResult<P<ast::MetaItem>> {
+    pub fn parse_meta_item(&mut self) -> PResult<'a, P<ast::MetaItem>> {
         let nt_meta = match self.token {
             token::Interpolated(token::NtMeta(ref e)) => {
                 Some(e.clone())
@@ -195,10 +197,10 @@ pub fn parse_meta_item(&mut self) -> PResult<P<ast::MetaItem>> {
     }
 
     /// matches meta_seq = ( COMMASEP(meta_item) )
-    fn parse_meta_seq(&mut self) -> PResult<Vec<P<ast::MetaItem>>> {
+    fn parse_meta_seq(&mut self) -> PResult<'a, Vec<P<ast::MetaItem>>> {
         self.parse_unspanned_seq(&token::OpenDelim(token::Paren),
                                  &token::CloseDelim(token::Paren),
                                  seq_sep_trailing_allowed(token::Comma),
-                                 |p| p.parse_meta_item())
+                                 |p: &mut Parser<'a>| p.parse_meta_item())
     }
 }
index 4619410ada7274c44cefe8f08032684bff346d78..3d8f3bcd5268fa174c9df7084c8faf8aff340305 100644 (file)
@@ -11,7 +11,7 @@
 use ast;
 use codemap::{BytePos, CharPos, CodeMap, Pos, Span};
 use codemap;
-use errors::{FatalError, Handler};
+use errors::{FatalError, Handler, DiagnosticBuilder};
 use ext::tt::transcribe::tt_next_token;
 use parse::token::str_to_ident;
 use parse::token;
@@ -173,10 +173,6 @@ pub fn err_span(&self, sp: Span, m: &str) {
         self.span_diagnostic.span_err(sp, m)
     }
 
-    /// Suggest some help with a given span.
-    pub fn help_span(&self, sp: Span, m: &str) {
-        self.span_diagnostic.span_help(sp, m)
-    }
 
     /// Report a fatal error spanning [`from_pos`, `to_pos`).
     fn fatal_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) -> FatalError {
@@ -188,11 +184,6 @@ fn err_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
         self.err_span(codemap::mk_sp(from_pos, to_pos), m)
     }
 
-    /// Suggest some help spanning [`from_pos`, `to_pos`).
-    fn help_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) {
-        self.help_span(codemap::mk_sp(from_pos, to_pos), m)
-    }
-
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
     /// escaped character to the error message
     fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError {
@@ -201,6 +192,17 @@ fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char)
         for c in c.escape_default() { m.push(c) }
         self.fatal_span_(from_pos, to_pos, &m[..])
     }
+    fn struct_fatal_span_char(&self,
+                              from_pos: BytePos,
+                              to_pos: BytePos,
+                              m: &str,
+                              c: char)
+                              -> DiagnosticBuilder<'a>  {
+        let mut m = m.to_string();
+        m.push_str(": ");
+        for c in c.escape_default() { m.push(c) }
+        self.span_diagnostic.struct_span_fatal(codemap::mk_sp(from_pos, to_pos), &m[..])
+    }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
     /// escaped character to the error message
@@ -210,6 +212,17 @@ fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
         for c in c.escape_default() { m.push(c) }
         self.err_span_(from_pos, to_pos, &m[..]);
     }
+    fn struct_err_span_char(&self,
+                            from_pos: BytePos,
+                            to_pos: BytePos,
+                            m: &str,
+                            c: char)
+                            -> DiagnosticBuilder<'a>  {
+        let mut m = m.to_string();
+        m.push_str(": ");
+        for c in c.escape_default() { m.push(c) }
+        self.span_diagnostic.struct_span_err(codemap::mk_sp(from_pos, to_pos), &m[..])
+    }
 
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending the
     /// offending string to the error message
@@ -746,10 +759,12 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                                 let valid = if self.curr_is('{') {
                                     self.scan_unicode_escape(delim) && !ascii_only
                                 } else {
-                                    self.err_span_(start, self.last_pos,
-                                        "incorrect unicode escape sequence");
-                                    self.help_span_(start, self.last_pos,
-                                        "format of unicode escape sequences is `\\u{…}`");
+                                    let span = codemap::mk_sp(start, self.last_pos);
+                                    self.span_diagnostic.struct_span_err(span,
+                                        "incorrect unicode escape sequence")
+                                        .span_help(span,
+                                        "format of unicode escape sequences is `\\u{…}`")
+                                        .emit();
                                     false
                                 };
                                 if ascii_only {
@@ -771,21 +786,22 @@ fn scan_char_or_byte(&mut self, start: BytePos, first_source_char: char,
                             }
                             c => {
                                 let last_pos = self.last_pos;
-                                self.err_span_char(
+                                let mut err = self.struct_err_span_char(
                                     escaped_pos, last_pos,
                                     if ascii_only { "unknown byte escape" }
                                     else { "unknown character escape" },
                                     c);
                                 if e == '\r' {
-                                    self.help_span_(escaped_pos, last_pos,
+                                    err.span_help(codemap::mk_sp(escaped_pos, last_pos),
                                         "this is an isolated carriage return; consider checking \
-                                         your editor and version control settings")
+                                         your editor and version control settings");
                                 }
                                 if (e == '{' || e == '}') && !ascii_only {
-                                    self.help_span_(escaped_pos, last_pos,
+                                    err.span_help(codemap::mk_sp(escaped_pos, last_pos),
                                         "if used in a formatting string, \
-                                        curly braces are escaped with `{{` and `}}`")
+                                        curly braces are escaped with `{{` and `}}`");
                                 }
+                                err.emit();
                                 false
                             }
                         }
@@ -1224,8 +1240,13 @@ fn next_token_inner(&mut self) -> token::Token {
           c => {
               let last_bpos = self.last_pos;
               let bpos = self.pos;
-              unicode_chars::check_for_substitution(&self, c);
-              panic!(self.fatal_span_char(last_bpos, bpos, "unknown start of token", c))
+              let mut err = self.struct_fatal_span_char(last_bpos,
+                                                        bpos,
+                                                        "unknown start of token",
+                                                        c);
+              unicode_chars::check_for_substitution(&self, c, &mut err);
+              err.emit();
+              panic!(FatalError);
           }
         }
     }
index a2f37426210e92fafe5bc1ad38ff52748b339b22..1d32dd4973127432562f15c14cadeb2f9ab49696 100644 (file)
@@ -12,6 +12,7 @@
 // http://www.unicode.org/Public/security/revision-06/confusables.txt
 
 use codemap::mk_sp as make_span;
+use errors::DiagnosticBuilder;
 use super::StringReader;
 
 const UNICODE_ARRAY: &'static [(char, &'static str, char)] = &[
     ('=', "Equals Sign"),
     ('>', "Greater-Than Sign"), ];
 
-pub fn check_for_substitution(reader: &StringReader, ch: char) {
+pub fn check_for_substitution<'a>(reader: &StringReader<'a>,
+                                  ch: char,
+                                  err: &mut DiagnosticBuilder<'a>) {
     UNICODE_ARRAY
     .iter()
     .find(|&&(c, _, _)| c == ch)
@@ -190,7 +193,7 @@ pub fn check_for_substitution(reader: &StringReader, ch: char) {
                 let msg =
                     format!("unicode character '{}' ({}) looks much like '{}' ({}), but it's not",
                             ch, u_name, ascii_char, ascii_name);
-                reader.help_span(span, &msg);
+                err.span_help(span, &msg);
             },
             None => {
                 reader
index 6951d6319acafa50343afaa469db433acc7ea930..efbde0f85a6b5426d99d61fd34d4e16812617623 100644 (file)
@@ -12,7 +12,7 @@
 
 use ast;
 use codemap::{self, Span, CodeMap, FileMap};
-use errors::{Handler, ColorConfig, FatalError};
+use errors::{Handler, ColorConfig, DiagnosticBuilder};
 use parse::parser::Parser;
 use parse::token::InternedString;
 use ptr::P;
@@ -25,7 +25,7 @@
 use std::rc::Rc;
 use std::str;
 
-pub type PResult<T> = Result<T, FatalError>;
+pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
 #[macro_use]
 pub mod parser;
@@ -76,8 +76,8 @@ pub fn parse_crate_from_file(
     cfg: ast::CrateConfig,
     sess: &ParseSess
 ) -> ast::Crate {
-    panictry!(new_parser_from_file(sess, cfg, input).parse_crate_mod())
-    // why is there no p.abort_if_errors here?
+    let mut parser = new_parser_from_file(sess, cfg, input);
+    abort_if_errors(parser.parse_crate_mod(), &parser)
 }
 
 pub fn parse_crate_attrs_from_file(
@@ -85,8 +85,8 @@ pub fn parse_crate_attrs_from_file(
     cfg: ast::CrateConfig,
     sess: &ParseSess
 ) -> Vec<ast::Attribute> {
-    // FIXME: maybe_aborted?
-    panictry!(new_parser_from_file(sess, cfg, input).parse_inner_attributes())
+    let mut parser = new_parser_from_file(sess, cfg, input);
+    abort_if_errors(parser.parse_inner_attributes(), &parser)
 }
 
 pub fn parse_crate_from_source_str(name: String,
@@ -271,6 +271,20 @@ pub fn maybe_aborted<T>(result: T, p: Parser) -> T {
     result
 }
 
+fn abort_if_errors<'a, T>(result: PResult<'a, T>, p: &Parser) -> T {
+    match result {
+        Ok(c) => {
+            p.abort_if_errors();
+            c
+        }
+        Err(mut e) => {
+            e.emit();
+            p.abort_if_errors();
+            unreachable!();
+        }
+    }
+}
+
 /// Parse a string representing a character literal into its final form.
 /// Rather than just accepting/rejecting a given literal, unescapes it as
 /// well. Can take any slice prefixed by a character escape. Returns the
@@ -449,11 +463,13 @@ fn filtered_float_lit(data: token::InternedString, suffix: Option<&str>,
         Some(suf) => {
             if suf.len() >= 2 && looks_like_width_suffix(&['f'], suf) {
                 // if it looks like a width, lets try to be helpful.
-                sd.span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..]));
-                sd.fileline_help(sp, "valid widths are 32 and 64");
+                sd.struct_span_err(sp, &format!("invalid width `{}` for float literal", &suf[1..]))
+                 .fileline_help(sp, "valid widths are 32 and 64")
+                 .emit();
             } else {
-                sd.span_err(sp, &format!("invalid suffix `{}` for float literal", suf));
-                sd.fileline_help(sp, "valid suffixes are `f32` and `f64`");
+                sd.struct_span_err(sp, &format!("invalid suffix `{}` for float literal", suf))
+                  .fileline_help(sp, "valid suffixes are `f32` and `f64`")
+                  .emit();
             }
 
             ast::LitFloatUnsuffixed(data)
@@ -622,13 +638,15 @@ pub fn integer_lit(s: &str,
                 // i<digits> and u<digits> look like widths, so lets
                 // give an error message along those lines
                 if looks_like_width_suffix(&['i', 'u'], suf) {
-                    sd.span_err(sp, &format!("invalid width `{}` for integer literal",
-                                             &suf[1..]));
-                    sd.fileline_help(sp, "valid widths are 8, 16, 32 and 64");
+                    sd.struct_span_err(sp, &format!("invalid width `{}` for integer literal",
+                                             &suf[1..]))
+                      .fileline_help(sp, "valid widths are 8, 16, 32 and 64")
+                      .emit();
                 } else {
-                    sd.span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf));
-                    sd.fileline_help(sp, "the suffix must be one of the integral types \
-                                      (`u32`, `isize`, etc)");
+                    sd.struct_span_err(sp, &format!("invalid suffix `{}` for numeric literal", suf))
+                      .fileline_help(sp, "the suffix must be one of the integral types \
+                                      (`u32`, `isize`, etc)")
+                      .emit();
                 }
 
                 ty
index 5dba1e189ab156dcb8ca3c0a65c17a01ad883de7..75f1ac49c9acc92956446f5db7d56edab98e57b7 100644 (file)
@@ -59,18 +59,17 @@ fn report(&mut self,
               kind_str: &str,
               desc: &str,
               error: bool) {
-        if error {
-            self.span_err(sp, &format!("obsolete syntax: {}", kind_str));
+        let mut err = if error {
+            self.diagnostic().struct_span_err(sp, &format!("obsolete syntax: {}", kind_str))
         } else {
-            self.span_warn(sp, &format!("obsolete syntax: {}", kind_str));
-        }
+            self.diagnostic().struct_span_warn(sp, &format!("obsolete syntax: {}", kind_str))
+        };
 
         if !self.obsolete_set.contains(&kind) &&
             (error || self.sess.span_diagnostic.can_emit_warnings) {
-            self.sess
-                .span_diagnostic
-                .note(&format!("{}", desc));
+            err.note(&format!("{}", desc));
             self.obsolete_set.insert(kind);
         }
+        err.emit();
     }
 }
index dbd34b49f7d9e7ad13380592353429ffe362beaf..db746af998d9f91f8799b564c7115a6acca61753 100644 (file)
 use ast;
 use ast_util::{self, ident_to_path};
 use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap};
-use errors::{self, FatalError};
+use errors::{self, DiagnosticBuilder};
 use ext::tt::macro_parser;
 use parse;
 use parse::classify;
 use parse::common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed};
 use parse::lexer::{Reader, TokenAndSpan};
 use parse::obsolete::{ParserObsoleteMethods, ObsoleteSyntax};
-use parse::token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString};
+use parse::token::{self, intern, MatchNt, SubstNt, SpecialVarNt, InternedString};
 use parse::token::{keywords, special_idents, SpecialMacroVar};
 use parse::{new_sub_parser_from_file, ParseSess};
 use util::parser::{AssocOp, Fixity};
@@ -392,14 +392,14 @@ pub fn this_token_to_string(&self) -> String {
         Parser::token_to_string(&self.token)
     }
 
-    pub fn unexpected_last(&self, t: &token::Token) -> FatalError {
+    pub fn unexpected_last(&self, t: &token::Token) -> DiagnosticBuilder<'a> {
         let token_str = Parser::token_to_string(t);
         let last_span = self.last_span;
         self.span_fatal(last_span, &format!("unexpected token: `{}`",
                                                 token_str))
     }
 
-    pub fn unexpected(&mut self) -> FatalError {
+    pub fn unexpected(&mut self) -> DiagnosticBuilder<'a> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => e,
             Ok(_) => unreachable!()
@@ -408,7 +408,7 @@ pub fn unexpected(&mut self) -> FatalError {
 
     /// Expect and consume the token t. Signal an error if
     /// the next token is not t.
-    pub fn expect(&mut self, t: &token::Token) -> PResult<()> {
+    pub fn expect(&mut self, t: &token::Token) -> PResult<'a,  ()> {
         if self.expected_tokens.is_empty() {
             if self.token == *t {
                 self.bump()
@@ -429,7 +429,7 @@ pub fn expect(&mut self, t: &token::Token) -> PResult<()> {
     /// anything.  Signal a fatal error if next token is unexpected.
     pub fn expect_one_of(&mut self,
                          edible: &[token::Token],
-                         inedible: &[token::Token]) -> PResult<()>{
+                         inedible: &[token::Token]) -> PResult<'a,  ()>{
         fn tokens_to_string(tokens: &[TokenType]) -> String {
             let mut i = tokens.iter();
             // This might be a sign we need a connect method on Iterator.
@@ -484,7 +484,7 @@ fn tokens_to_string(tokens: &[TokenType]) -> String {
     /// true if and only if input was consumed for recovery.
     pub fn check_for_erroneous_unit_struct_expecting(&mut self,
                                                      expected: &[token::Token])
-                                                     -> PResult<bool> {
+                                                     -> PResult<'a, bool> {
         if self.token == token::OpenDelim(token::Brace)
             && expected.iter().all(|t| *t != token::OpenDelim(token::Brace))
             && self.look_ahead(1, |t| *t == token::CloseDelim(token::Brace)) {
@@ -504,7 +504,7 @@ pub fn check_for_erroneous_unit_struct_expecting(&mut self,
     /// followed by some token from the set edible + inedible.  Recover
     /// from anticipated input errors, discarding erroneous characters.
     pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token],
-                       inedible: &[token::Token]) -> PResult<()> {
+                       inedible: &[token::Token]) -> PResult<'a, ()> {
         debug!("commit_expr {:?}", e);
         if let ExprPath(..) = e.node {
             // might be unit-struct construction; check for recoverableinput error.
@@ -517,7 +517,7 @@ pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token],
         self.expect_one_of(edible, inedible)
     }
 
-    pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResult<()> {
+    pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResult<'a, ()> {
         self.commit_expr(e, &[edible], &[])
     }
 
@@ -525,7 +525,7 @@ pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResu
     /// followed by some token from the set edible + inedible.  Check
     /// for recoverable input errors, discarding erroneous characters.
     pub fn commit_stmt(&mut self, edible: &[token::Token],
-                       inedible: &[token::Token]) -> PResult<()> {
+                       inedible: &[token::Token]) -> PResult<'a, ()> {
         if self.last_token
                .as_ref()
                .map_or(false, |t| t.is_ident() || t.is_path()) {
@@ -538,11 +538,11 @@ pub fn commit_stmt(&mut self, edible: &[token::Token],
         self.expect_one_of(edible, inedible)
     }
 
-    pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<()> {
+    pub fn commit_stmt_expecting(&mut self, edible: token::Token) -> PResult<'a, ()> {
         self.commit_stmt(&[edible], &[])
     }
 
-    pub fn parse_ident(&mut self) -> PResult<ast::Ident> {
+    pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
         self.check_strict_keywords();
         try!(self.check_reserved_keywords());
         match self.token {
@@ -561,7 +561,7 @@ pub fn parse_ident(&mut self) -> PResult<ast::Ident> {
         }
     }
 
-    pub fn parse_ident_or_self_type(&mut self) -> PResult<ast::Ident> {
+    pub fn parse_ident_or_self_type(&mut self) -> PResult<'a, ast::Ident> {
         if self.is_self_type_ident() {
             self.expect_self_type_ident()
         } else {
@@ -569,7 +569,7 @@ pub fn parse_ident_or_self_type(&mut self) -> PResult<ast::Ident> {
         }
     }
 
-    pub fn parse_path_list_item(&mut self) -> PResult<ast::PathListItem> {
+    pub fn parse_path_list_item(&mut self) -> PResult<'a, ast::PathListItem> {
         let lo = self.span.lo;
         let node = if try!(self.eat_keyword(keywords::SelfValue)) {
             let rename = try!(self.parse_rename());
@@ -595,7 +595,7 @@ pub fn check(&mut self, tok: &token::Token) -> bool {
 
     /// Consume token 'tok' if it exists. Returns true if the given
     /// token was present, false otherwise.
-    pub fn eat(&mut self, tok: &token::Token) -> PResult<bool> {
+    pub fn eat(&mut self, tok: &token::Token) -> PResult<'a, bool> {
         let is_present = self.check(tok);
         if is_present { try!(self.bump())}
         Ok(is_present)
@@ -608,7 +608,7 @@ pub fn check_keyword(&mut self, kw: keywords::Keyword) -> bool {
 
     /// If the next token is the given keyword, eat it and return
     /// true. Otherwise, return false.
-    pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<bool> {
+    pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> {
         if self.check_keyword(kw) {
             try!(self.bump());
             Ok(true)
@@ -617,7 +617,7 @@ pub fn eat_keyword(&mut self, kw: keywords::Keyword) -> PResult<bool> {
         }
     }
 
-    pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<bool> {
+    pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<'a, bool> {
         if self.token.is_keyword(kw) {
             try!(self.bump());
             Ok(true)
@@ -629,7 +629,7 @@ pub fn eat_keyword_noexpect(&mut self, kw: keywords::Keyword) -> PResult<bool> {
     /// If the given word is not a keyword, signal an error.
     /// If the next token is not the given word, signal an error.
     /// Otherwise, eat it.
-    pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<()> {
+    pub fn expect_keyword(&mut self, kw: keywords::Keyword) -> PResult<'a, ()> {
         if !try!(self.eat_keyword(kw) ){
             self.expect_one_of(&[], &[])
         } else {
@@ -649,11 +649,10 @@ pub fn check_strict_keywords(&mut self) {
     }
 
     /// Signal an error if the current token is a reserved keyword
-    pub fn check_reserved_keywords(&mut self) -> PResult<()>{
+    pub fn check_reserved_keywords(&mut self) -> PResult<'a, ()>{
         if self.token.is_reserved_keyword() {
             let token_str = self.this_token_to_string();
-            Err(self.fatal(&format!("`{}` is a reserved keyword",
-                               token_str)))
+            Err(self.fatal(&format!("`{}` is a reserved keyword", token_str)))
         } else {
             Ok(())
         }
@@ -661,7 +660,7 @@ pub fn check_reserved_keywords(&mut self) -> PResult<()>{
 
     /// Expect and consume an `&`. If `&&` is seen, replace it with a single
     /// `&` and continue. If an `&` is not seen, signal an error.
-    fn expect_and(&mut self) -> PResult<()> {
+    fn expect_and(&mut self) -> PResult<'a, ()> {
         self.expected_tokens.push(TokenType::Token(token::BinOp(token::And)));
         match self.token {
             token::BinOp(token::And) => self.bump(),
@@ -693,7 +692,7 @@ pub fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>)
     ///
     /// This is meant to be used when parsing generics on a path to get the
     /// starting token.
-    fn eat_lt(&mut self) -> PResult<bool> {
+    fn eat_lt(&mut self) -> PResult<'a, bool> {
         self.expected_tokens.push(TokenType::Token(token::Lt));
         match self.token {
             token::Lt => { try!(self.bump()); Ok(true)}
@@ -707,7 +706,7 @@ fn eat_lt(&mut self) -> PResult<bool> {
         }
     }
 
-    fn expect_lt(&mut self) -> PResult<()> {
+    fn expect_lt(&mut self) -> PResult<'a, ()> {
         if !try!(self.eat_lt()) {
             self.expect_one_of(&[], &[])
         } else {
@@ -718,7 +717,7 @@ fn expect_lt(&mut self) -> PResult<()> {
     /// Expect and consume a GT. if a >> is seen, replace it
     /// with a single > and continue. If a GT is not seen,
     /// signal an error.
-    pub fn expect_gt(&mut self) -> PResult<()> {
+    pub fn expect_gt(&mut self) -> PResult<'a, ()> {
         self.expected_tokens.push(TokenType::Token(token::Gt));
         match self.token {
             token::Gt => self.bump(),
@@ -750,8 +749,8 @@ pub fn expect_gt(&mut self) -> PResult<()> {
     pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
                                                   sep: Option<token::Token>,
                                                   mut f: F)
-                                                  -> PResult<(P<[T]>, bool)> where
-        F: FnMut(&mut Parser) -> PResult<Option<T>>,
+                                                  -> PResult<'a, (P<[T]>, bool)>
+        where F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
     {
         let mut v = Vec::new();
         // This loop works by alternating back and forth between parsing types
@@ -788,8 +787,8 @@ pub fn parse_seq_to_before_gt_or_return<T, F>(&mut self,
     pub fn parse_seq_to_before_gt<T, F>(&mut self,
                                         sep: Option<token::Token>,
                                         mut f: F)
-                                        -> PResult<P<[T]>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                        -> PResult<'a, P<[T]>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
         let (result, returned) = try!(self.parse_seq_to_before_gt_or_return(sep,
                                                     |p| Ok(Some(try!(f(p))))));
@@ -800,8 +799,8 @@ pub fn parse_seq_to_before_gt<T, F>(&mut self,
     pub fn parse_seq_to_gt<T, F>(&mut self,
                                  sep: Option<token::Token>,
                                  f: F)
-                                 -> PResult<P<[T]>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                 -> PResult<'a, P<[T]>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     {
         let v = try!(self.parse_seq_to_before_gt(sep, f));
         try!(self.expect_gt());
@@ -811,8 +810,8 @@ pub fn parse_seq_to_gt<T, F>(&mut self,
     pub fn parse_seq_to_gt_or_return<T, F>(&mut self,
                                            sep: Option<token::Token>,
                                            f: F)
-                                           -> PResult<(P<[T]>, bool)> where
-        F: FnMut(&mut Parser) -> PResult<Option<T>>,
+                                           -> PResult<'a, (P<[T]>, bool)> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a, Option<T>>,
     {
         let (v, returned) = try!(self.parse_seq_to_before_gt_or_return(sep, f));
         if !returned {
@@ -828,8 +827,8 @@ pub fn parse_seq_to_end<T, F>(&mut self,
                                   ket: &token::Token,
                                   sep: SeqSep,
                                   f: F)
-                                  -> PResult<Vec<T>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                  -> PResult<'a, Vec<T>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
     {
         let val = try!(self.parse_seq_to_before_end(ket, sep, f));
         try!(self.bump());
@@ -843,8 +842,8 @@ pub fn parse_seq_to_before_end<T, F>(&mut self,
                                          ket: &token::Token,
                                          sep: SeqSep,
                                          mut f: F)
-                                         -> PResult<Vec<T>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                         -> PResult<'a, Vec<T>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
     {
         let mut first: bool = true;
         let mut v = vec!();
@@ -870,8 +869,8 @@ pub fn parse_unspanned_seq<T, F>(&mut self,
                                      ket: &token::Token,
                                      sep: SeqSep,
                                      f: F)
-                                     -> PResult<Vec<T>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                     -> PResult<'a, Vec<T>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
     {
         try!(self.expect(bra));
         let result = try!(self.parse_seq_to_before_end(ket, sep, f));
@@ -886,8 +885,8 @@ pub fn parse_enum_variant_seq<T, F>(&mut self,
                                         ket: &token::Token,
                                         sep: SeqSep,
                                         f: F)
-                                        -> PResult<Vec<T>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                                        -> PResult<'a, Vec<T>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
     {
         let result = try!(self.parse_unspanned_seq(bra, ket, sep, f));
         if result.is_empty() {
@@ -905,8 +904,8 @@ pub fn parse_seq<T, F>(&mut self,
                            ket: &token::Token,
                            sep: SeqSep,
                            f: F)
-                           -> PResult<Spanned<Vec<T>>> where
-        F: FnMut(&mut Parser) -> PResult<T>,
+                           -> PResult<'a, Spanned<Vec<T>>> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
     {
         let lo = self.span.lo;
         try!(self.expect(bra));
@@ -917,7 +916,7 @@ pub fn parse_seq<T, F>(&mut self,
     }
 
     /// Advance the parser by one token
-    pub fn bump(&mut self) -> PResult<()> {
+    pub fn bump(&mut self) -> PResult<'a,  ()> {
         self.last_span = self.span;
         // Stash token for error recovery (sometimes; clone is not necessarily cheap).
         self.last_token = if self.token.is_ident() ||
@@ -950,7 +949,7 @@ pub fn bump(&mut self) -> PResult<()> {
     }
 
     /// Advance the parser by one token and return the bumped token.
-    pub fn bump_and_get(&mut self) -> PResult<token::Token> {
+    pub fn bump_and_get(&mut self) -> PResult<'a, token::Token> {
         let old_token = mem::replace(&mut self.token, token::Underscore);
         try!(self.bump());
         Ok(old_token)
@@ -981,28 +980,16 @@ pub fn look_ahead<R, F>(&mut self, distance: usize, f: F) -> R where
         }
         f(&self.buffer[((self.buffer_start + dist - 1) & 3) as usize].tok)
     }
-    pub fn fatal(&self, m: &str) -> errors::FatalError {
-        self.sess.span_diagnostic.span_fatal(self.span, m)
+    pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> {
+        self.sess.span_diagnostic.struct_span_fatal(self.span, m)
     }
-    pub fn span_fatal(&self, sp: Span, m: &str) -> errors::FatalError {
-        self.sess.span_diagnostic.span_fatal(sp, m)
+    pub fn span_fatal(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> {
+        self.sess.span_diagnostic.struct_span_fatal(sp, m)
     }
-    pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> errors::FatalError {
-        self.span_err(sp, m);
-        self.fileline_help(sp, help);
-        errors::FatalError
-    }
-    pub fn span_note(&self, sp: Span, m: &str) {
-        self.sess.span_diagnostic.span_note(sp, m)
-    }
-    pub fn span_help(&self, sp: Span, m: &str) {
-        self.sess.span_diagnostic.span_help(sp, m)
-    }
-    pub fn span_suggestion(&self, sp: Span, m: &str, n: String) {
-        self.sess.span_diagnostic.span_suggestion(sp, m, n)
-    }
-    pub fn fileline_help(&self, sp: Span, m: &str) {
-        self.sess.span_diagnostic.fileline_help(sp, m)
+    pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> {
+        let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m);
+        err.fileline_help(sp, help);
+        err
     }
     pub fn bug(&self, m: &str) -> ! {
         self.sess.span_diagnostic.span_bug(self.span, m)
@@ -1023,6 +1010,10 @@ pub fn abort_if_errors(&self) {
         self.sess.span_diagnostic.abort_if_errors();
     }
 
+    pub fn diagnostic(&self) -> &'a errors::Handler {
+        &self.sess.span_diagnostic
+    }
+
     pub fn id_to_interned_str(&mut self, id: Ident) -> InternedString {
         id.name.as_str()
     }
@@ -1042,7 +1033,7 @@ pub fn get_lifetime(&mut self) -> ast::Ident {
         }
     }
 
-    pub fn parse_for_in_type(&mut self) -> PResult<Ty_> {
+    pub fn parse_for_in_type(&mut self) -> PResult<'a, Ty_> {
         /*
         Parses whatever can come after a `for` keyword in a type.
         The `for` has already been consumed.
@@ -1085,12 +1076,12 @@ pub fn parse_for_in_type(&mut self) -> PResult<Ty_> {
         }
     }
 
-    pub fn parse_ty_path(&mut self) -> PResult<Ty_> {
+    pub fn parse_ty_path(&mut self) -> PResult<'a, Ty_> {
         Ok(TyPath(None, try!(self.parse_path(LifetimeAndTypesWithoutColons))))
     }
 
     /// parse a TyBareFn type:
-    pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> PResult<Ty_> {
+    pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> PResult<'a, Ty_> {
         /*
 
         [unsafe] [extern "ABI"] fn <'lt> (S) -> T
@@ -1127,7 +1118,7 @@ pub fn parse_ty_bare_fn(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> PRes
     }
 
     /// Parses an obsolete closure kind (`&:`, `&mut:`, or `:`).
-    pub fn parse_obsolete_closure_kind(&mut self) -> PResult<()> {
+    pub fn parse_obsolete_closure_kind(&mut self) -> PResult<'a, ()> {
          let lo = self.span.lo;
         if
             self.check(&token::BinOp(token::And)) &&
@@ -1156,7 +1147,7 @@ pub fn parse_obsolete_closure_kind(&mut self) -> PResult<()> {
         Ok(())
     }
 
-    pub fn parse_unsafety(&mut self) -> PResult<Unsafety> {
+    pub fn parse_unsafety(&mut self) -> PResult<'a, Unsafety> {
         if try!(self.eat_keyword(keywords::Unsafe)) {
             return Ok(Unsafety::Unsafe);
         } else {
@@ -1165,12 +1156,12 @@ pub fn parse_unsafety(&mut self) -> PResult<Unsafety> {
     }
 
     /// Parse the items in a trait declaration
-    pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
+    pub fn parse_trait_items(&mut self) -> PResult<'a,  Vec<P<TraitItem>>> {
         self.parse_unspanned_seq(
             &token::OpenDelim(token::Brace),
             &token::CloseDelim(token::Brace),
             seq_sep_none(),
-            |p| -> PResult<P<TraitItem>> {
+            |p| -> PResult<'a, P<TraitItem>> {
             maybe_whole!(no_clone p, NtTraitItem);
             let mut attrs = try!(p.parse_outer_attributes());
             let lo = p.span.lo;
@@ -1200,7 +1191,7 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
                 let ident = try!(p.parse_ident());
                 let mut generics = try!(p.parse_generics());
 
-                let (explicit_self, d) = try!(p.parse_fn_decl_with_self(|p|{
+                let (explicit_self, d) = try!(p.parse_fn_decl_with_self(|p: &mut Parser<'a>|{
                     // This is somewhat dubious; We don't want to allow
                     // argument names to be left off if there is a
                     // definition...
@@ -1251,14 +1242,14 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
     }
 
     /// Parse a possibly mutable type
-    pub fn parse_mt(&mut self) -> PResult<MutTy> {
+    pub fn parse_mt(&mut self) -> PResult<'a, MutTy> {
         let mutbl = try!(self.parse_mutability());
         let t = try!(self.parse_ty());
         Ok(MutTy { ty: t, mutbl: mutbl })
     }
 
     /// Parse optional return type [ -> TY ] in function decl
-    pub fn parse_ret_ty(&mut self) -> PResult<FunctionRetTy> {
+    pub fn parse_ret_ty(&mut self) -> PResult<'a, FunctionRetTy> {
         if try!(self.eat(&token::RArrow) ){
             if try!(self.eat(&token::Not) ){
                 Ok(NoReturn(self.last_span))
@@ -1272,7 +1263,7 @@ pub fn parse_ret_ty(&mut self) -> PResult<FunctionRetTy> {
     }
 
     /// Parse a type in a context where `T1+T2` is allowed.
-    pub fn parse_ty_sum(&mut self) -> PResult<P<Ty>> {
+    pub fn parse_ty_sum(&mut self) -> PResult<'a, P<Ty>> {
         let lo = self.span.lo;
         let lhs = try!(self.parse_ty());
 
@@ -1297,7 +1288,7 @@ pub fn parse_ty_sum(&mut self) -> PResult<P<Ty>> {
     }
 
     /// Parse a type.
-    pub fn parse_ty(&mut self) -> PResult<P<Ty>> {
+    pub fn parse_ty(&mut self) -> PResult<'a, P<Ty>> {
         maybe_whole!(no_clone self, NtTy);
 
         let lo = self.span.lo;
@@ -1397,7 +1388,7 @@ pub fn parse_ty(&mut self) -> PResult<P<Ty>> {
         Ok(P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp}))
     }
 
-    pub fn parse_borrowed_pointee(&mut self) -> PResult<Ty_> {
+    pub fn parse_borrowed_pointee(&mut self) -> PResult<'a, Ty_> {
         // look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
         let opt_lifetime = try!(self.parse_opt_lifetime());
 
@@ -1405,7 +1396,7 @@ pub fn parse_borrowed_pointee(&mut self) -> PResult<Ty_> {
         return Ok(TyRptr(opt_lifetime, mt));
     }
 
-    pub fn parse_ptr(&mut self) -> PResult<MutTy> {
+    pub fn parse_ptr(&mut self) -> PResult<'a, MutTy> {
         let mutbl = if try!(self.eat_keyword(keywords::Mut) ){
             MutMutable
         } else if try!(self.eat_keyword(keywords::Const) ){
@@ -1443,7 +1434,7 @@ pub fn is_named_argument(&mut self) -> bool {
 
     /// This version of parse arg doesn't necessarily require
     /// identifier names.
-    pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<Arg> {
+    pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> {
         maybe_whole!(no_clone self, NtArg);
 
         let pat = if require_name || self.is_named_argument() {
@@ -1470,12 +1461,12 @@ pub fn parse_arg_general(&mut self, require_name: bool) -> PResult<Arg> {
     }
 
     /// Parse a single function argument
-    pub fn parse_arg(&mut self) -> PResult<Arg> {
+    pub fn parse_arg(&mut self) -> PResult<'a, Arg> {
         self.parse_arg_general(true)
     }
 
     /// Parse an argument in a lambda header e.g. |arg, arg|
-    pub fn parse_fn_block_arg(&mut self) -> PResult<Arg> {
+    pub fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
         let pat = try!(self.parse_pat());
         let t = if try!(self.eat(&token::Colon) ){
             try!(self.parse_ty_sum())
@@ -1493,7 +1484,7 @@ pub fn parse_fn_block_arg(&mut self) -> PResult<Arg> {
         })
     }
 
-    pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<Option<P<ast::Expr>>> {
+    pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
         if self.check(&token::Semi) {
             try!(self.bump());
             Ok(Some(try!(self.parse_expr())))
@@ -1503,7 +1494,7 @@ pub fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<Option<P<ast::Expr>
     }
 
     /// Matches token_lit = LIT_INTEGER | ...
-    pub fn lit_from_token(&self, tok: &token::Token) -> PResult<Lit_> {
+    pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, Lit_> {
         match *tok {
             token::Interpolated(token::NtExpr(ref v)) => {
                 match v.node {
@@ -1562,7 +1553,7 @@ pub fn lit_from_token(&self, tok: &token::Token) -> PResult<Lit_> {
     }
 
     /// Matches lit = true | false | token_lit
-    pub fn parse_lit(&mut self) -> PResult<Lit> {
+    pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
         let lo = self.span.lo;
         let lit = if try!(self.eat_keyword(keywords::True) ){
             LitBool(true)
@@ -1577,7 +1568,7 @@ pub fn parse_lit(&mut self) -> PResult<Lit> {
     }
 
     /// matches '-' lit | lit
-    pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<P<Expr>> {
+    pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
         let minus_lo = self.span.lo;
         let minus_present = try!(self.eat(&token::BinOp(token::Minus)));
         let lo = self.span.lo;
@@ -1610,7 +1601,7 @@ pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<P<Expr>> {
     /// `<T as U>::a`
     /// `<T as U>::F::a::<S>`
     pub fn parse_qualified_path(&mut self, mode: PathParsingMode)
-                                -> PResult<(QSelf, ast::Path)> {
+                                -> PResult<'a, (QSelf, ast::Path)> {
         let span = self.last_span;
         let self_type = try!(self.parse_ty_sum());
         let mut path = if try!(self.eat_keyword(keywords::As)) {
@@ -1653,7 +1644,7 @@ pub fn parse_qualified_path(&mut self, mode: PathParsingMode)
     /// mode. The `mode` parameter determines whether lifetimes, types, and/or
     /// bounds are permitted and whether `::` must precede type parameter
     /// groups.
-    pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<ast::Path> {
+    pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<'a, ast::Path> {
         // Check for a whole path...
         let found = match self.token {
             token::Interpolated(token::NtPath(_)) => Some(try!(self.bump_and_get())),
@@ -1696,7 +1687,7 @@ pub fn parse_path(&mut self, mode: PathParsingMode) -> PResult<ast::Path> {
     /// - `a::b<T,U>::c<V,W>`
     /// - `a::b<T,U>::c(V) -> W`
     /// - `a::b<T,U>::c(V)`
-    pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSegment>> {
+    pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
@@ -1706,7 +1697,7 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSeg
             let parameters = if try!(self.eat_lt() ){
                 let (lifetimes, types, bindings) = try!(self.parse_generic_values_after_lt());
 
-                ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
+                ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
                     lifetimes: lifetimes,
                     types: P::from_vec(types),
                     bindings: P::from_vec(bindings),
@@ -1727,7 +1718,7 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSeg
 
                 let hi = self.last_span.hi;
 
-                ast::ParenthesizedParameters(ast::ParenthesizedParameterData {
+                ast::PathParameters::Parenthesized(ast::ParenthesizedParameterData {
                     span: mk_sp(lo, hi),
                     inputs: inputs,
                     output: output_ty,
@@ -1749,7 +1740,7 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<Vec<ast::PathSeg
 
     /// Examples:
     /// - `a::b::<T,U>::c`
-    pub fn parse_path_segments_with_colons(&mut self) -> PResult<Vec<ast::PathSegment>> {
+    pub fn parse_path_segments_with_colons(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
@@ -1768,13 +1759,14 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<Vec<ast::PathSegmen
             if try!(self.eat_lt() ){
                 // Consumed `a::b::<`, go look for types
                 let (lifetimes, types, bindings) = try!(self.parse_generic_values_after_lt());
+                let parameters = ast::AngleBracketedParameterData {
+                    lifetimes: lifetimes,
+                    types: P::from_vec(types),
+                    bindings: P::from_vec(bindings),
+                };
                 segments.push(ast::PathSegment {
                     identifier: identifier,
-                    parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
-                        lifetimes: lifetimes,
-                        types: P::from_vec(types),
-                        bindings: P::from_vec(bindings),
-                    }),
+                    parameters: ast::PathParameters::AngleBracketed(parameters),
                 });
 
                 // Consumed `a::b::<T,U>`, check for `::` before proceeding
@@ -1794,7 +1786,7 @@ pub fn parse_path_segments_with_colons(&mut self) -> PResult<Vec<ast::PathSegmen
 
     /// Examples:
     /// - `a::b::c`
-    pub fn parse_path_segments_without_types(&mut self) -> PResult<Vec<ast::PathSegment>> {
+    pub fn parse_path_segments_without_types(&mut self) -> PResult<'a, Vec<ast::PathSegment>> {
         let mut segments = Vec::new();
         loop {
             // First, parse an identifier.
@@ -1814,7 +1806,7 @@ pub fn parse_path_segments_without_types(&mut self) -> PResult<Vec<ast::PathSegm
     }
 
     /// parses 0 or 1 lifetime
-    pub fn parse_opt_lifetime(&mut self) -> PResult<Option<ast::Lifetime>> {
+    pub fn parse_opt_lifetime(&mut self) -> PResult<'a, Option<ast::Lifetime>> {
         match self.token {
             token::Lifetime(..) => {
                 Ok(Some(try!(self.parse_lifetime())))
@@ -1827,7 +1819,7 @@ pub fn parse_opt_lifetime(&mut self) -> PResult<Option<ast::Lifetime>> {
 
     /// Parses a single lifetime
     /// Matches lifetime = LIFETIME
-    pub fn parse_lifetime(&mut self) -> PResult<ast::Lifetime> {
+    pub fn parse_lifetime(&mut self) -> PResult<'a, ast::Lifetime> {
         match self.token {
             token::Lifetime(i) => {
                 let span = self.span;
@@ -1846,7 +1838,7 @@ pub fn parse_lifetime(&mut self) -> PResult<ast::Lifetime> {
 
     /// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def  =
     /// lifetime [':' lifetimes]`
-    pub fn parse_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> {
+    pub fn parse_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
 
         let mut res = Vec::new();
         loop {
@@ -1889,7 +1881,7 @@ pub fn parse_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> {
     /// Parses zero or more comma separated lifetimes. Expects each lifetime to be followed by
     /// either a comma or `>`.  Used when parsing type parameter lists, where we expect something
     /// like `<'a, 'b, T>`.
-    pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<Vec<ast::Lifetime>> {
+    pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<'a, Vec<ast::Lifetime>> {
 
         let mut res = Vec::new();
         loop {
@@ -1911,7 +1903,7 @@ pub fn parse_lifetimes(&mut self, sep: token::Token) -> PResult<Vec<ast::Lifetim
     }
 
     /// Parse mutability declaration (mut/const/imm)
-    pub fn parse_mutability(&mut self) -> PResult<Mutability> {
+    pub fn parse_mutability(&mut self) -> PResult<'a, Mutability> {
         if try!(self.eat_keyword(keywords::Mut) ){
             Ok(MutMutable)
         } else {
@@ -1920,7 +1912,7 @@ pub fn parse_mutability(&mut self) -> PResult<Mutability> {
     }
 
     /// Parse ident COLON expr
-    pub fn parse_field(&mut self) -> PResult<Field> {
+    pub fn parse_field(&mut self) -> PResult<'a, Field> {
         let lo = self.span.lo;
         let i = try!(self.parse_ident());
         let hi = self.last_span.hi;
@@ -2012,7 +2004,7 @@ pub fn mk_lit_u32(&mut self, i: u32, attrs: ThinAttributes) -> P<Expr> {
         })
     }
 
-    fn expect_open_delim(&mut self) -> PResult<token::DelimToken> {
+    fn expect_open_delim(&mut self) -> PResult<'a, token::DelimToken> {
         self.expected_tokens.push(TokenType::Token(token::Gt));
         match self.token {
             token::OpenDelim(delim) => {
@@ -2030,7 +2022,7 @@ fn expect_open_delim(&mut self) -> PResult<token::DelimToken> {
     /// NB: This does not parse outer attributes,
     ///     and is private because it only works
     ///     correctly if called from parse_dot_or_call_expr().
-    fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> {
+    fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
         maybe_whole_expr!(self);
 
         // Outer attributes are already parsed and will be
@@ -2294,7 +2286,7 @@ fn parse_bottom_expr(&mut self) -> PResult<P<Expr>> {
 
     fn parse_or_use_outer_attributes(&mut self,
                                      already_parsed_attrs: Option<ThinAttributes>)
-                                     -> PResult<ThinAttributes> {
+                                     -> PResult<'a, ThinAttributes> {
         if let Some(attrs) = already_parsed_attrs {
             Ok(attrs)
         } else {
@@ -2305,7 +2297,7 @@ fn parse_or_use_outer_attributes(&mut self,
     /// Parse a block or unsafe block
     pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode,
                             attrs: ThinAttributes)
-                            -> PResult<P<Expr>> {
+                            -> PResult<'a, P<Expr>> {
 
         let outer_attrs = attrs;
         try!(self.expect(&token::OpenDelim(token::Brace)));
@@ -2320,7 +2312,7 @@ pub fn parse_block_expr(&mut self, lo: BytePos, blk_mode: BlockCheckMode,
     /// parse a.b or a(13) or a[4] or just a
     pub fn parse_dot_or_call_expr(&mut self,
                                   already_parsed_attrs: Option<ThinAttributes>)
-                                  -> PResult<P<Expr>> {
+                                  -> PResult<'a, P<Expr>> {
         let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
 
         let b = try!(self.parse_bottom_expr());
@@ -2330,7 +2322,7 @@ pub fn parse_dot_or_call_expr(&mut self,
     pub fn parse_dot_or_call_expr_with(&mut self,
                                        e0: P<Expr>,
                                        attrs: ThinAttributes)
-                                       -> PResult<P<Expr>> {
+                                       -> PResult<'a, P<Expr>> {
         // Stitch the list of outer attributes onto the return value.
         // A little bit ugly, but the best way given the current code
         // structure
@@ -2356,7 +2348,7 @@ pub fn parse_dot_or_call_expr_with(&mut self,
         )
     }
 
-    fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<P<Expr>> {
+    fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<'a, P<Expr>> {
         let mut e = e0;
         let lo = e.span.lo;
         let mut hi;
@@ -2437,18 +2429,19 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<P<Expr>> {
                     try!(self.bump());
                     let last_span = self.last_span;
                     let fstr = n.as_str();
-                    self.span_err(last_span,
-                                  &format!("unexpected token: `{}`", n.as_str()));
+                    let mut err = self.diagnostic().struct_span_err(last_span,
+                        &format!("unexpected token: `{}`", n.as_str()));
                     if fstr.chars().all(|x| "0123456789.".contains(x)) {
                         let float = match fstr.parse::<f64>().ok() {
                             Some(f) => f,
                             None => continue,
                         };
-                        self.fileline_help(last_span,
+                        err.fileline_help(last_span,
                             &format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
                                     float.trunc() as usize,
                                     format!(".{}", fstr.splitn(2, ".").last().unwrap())));
                     }
+                    err.emit();
                     self.abort_if_errors();
 
                   }
@@ -2489,7 +2482,7 @@ fn parse_dot_or_call_expr_with_(&mut self, e0: P<Expr>) -> PResult<P<Expr>> {
     }
 
     // Parse unquoted tokens after a `$` in a token tree
-    fn parse_unquoted(&mut self) -> PResult<TokenTree> {
+    fn parse_unquoted(&mut self) -> PResult<'a, TokenTree> {
         let mut sp = self.span;
         let (name, namep) = match self.token {
             token::Dollar => {
@@ -2541,7 +2534,7 @@ fn parse_unquoted(&mut self) -> PResult<TokenTree> {
         }
     }
 
-    pub fn check_unknown_macro_variable(&mut self) -> PResult<()> {
+    pub fn check_unknown_macro_variable(&mut self) -> PResult<'a, ()> {
         if self.quote_depth == 0 {
             match self.token {
                 token::SubstNt(name, _) =>
@@ -2555,8 +2548,9 @@ pub fn check_unknown_macro_variable(&mut self) -> PResult<()> {
 
     /// Parse an optional separator followed by a Kleene-style
     /// repetition token (+ or *).
-    pub fn parse_sep_and_kleene_op(&mut self) -> PResult<(Option<token::Token>, ast::KleeneOp)> {
-        fn parse_kleene_op(parser: &mut Parser) -> PResult<Option<ast::KleeneOp>> {
+    pub fn parse_sep_and_kleene_op(&mut self)
+                                   -> PResult<'a, (Option<token::Token>, ast::KleeneOp)> {
+        fn parse_kleene_op<'a>(parser: &mut Parser<'a>) -> PResult<'a,  Option<ast::KleeneOp>> {
             match parser.token {
                 token::BinOp(token::Star) => {
                     try!(parser.bump());
@@ -2583,7 +2577,7 @@ fn parse_kleene_op(parser: &mut Parser) -> PResult<Option<ast::KleeneOp>> {
     }
 
     /// parse a single token tree from the input.
-    pub fn parse_token_tree(&mut self) -> PResult<TokenTree> {
+    pub fn parse_token_tree(&mut self) -> PResult<'a, TokenTree> {
         // FIXME #6994: currently, this is too eager. It
         // parses token trees but also identifies TokenType::Sequence's
         // and token::SubstNt's; it's too early to know yet
@@ -2596,20 +2590,20 @@ pub fn parse_token_tree(&mut self) -> PResult<TokenTree> {
         // not an EOF, and not the desired right-delimiter (if
         // it were, parse_seq_to_before_end would have prevented
         // reaching this point.
-        fn parse_non_delim_tt_tok(p: &mut Parser) -> PResult<TokenTree> {
+        fn parse_non_delim_tt_tok<'b>(p: &mut Parser<'b>) -> PResult<'b,  TokenTree> {
             maybe_whole!(deref p, NtTT);
             match p.token {
                 token::CloseDelim(_) => {
+                    let token_str = p.this_token_to_string();
+                    let mut err = p.fatal(
+                        &format!("incorrect close delimiter: `{}`", token_str));
                     // This is a conservative error: only report the last unclosed delimiter. The
                     // previous unclosed delimiters could actually be closed! The parser just hasn't
                     // gotten to them yet.
-                    match p.open_braces.last() {
-                        None => {}
-                        Some(&sp) => p.span_note(sp, "unclosed delimiter"),
+                    if let Some(&sp) = p.open_braces.last() {
+                        err.span_note(sp, "unclosed delimiter");
                     };
-                    let token_str = p.this_token_to_string();
-                    Err(p.fatal(&format!("incorrect close delimiter: `{}`",
-                                    token_str)))
+                    Err(err)
                 },
                 /* we ought to allow different depths of unquotation */
                 token::Dollar | token::SubstNt(..) if p.quote_depth > 0 => {
@@ -2624,12 +2618,12 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> PResult<TokenTree> {
         match self.token {
             token::Eof => {
                 let open_braces = self.open_braces.clone();
+                let mut err: DiagnosticBuilder<'a> =
+                    self.fatal("this file contains an un-closed delimiter");
                 for sp in &open_braces {
-                    self.span_help(*sp, "did you mean to close this delimiter?");
+                    err.span_help(*sp, "did you mean to close this delimiter?");
                 }
-                // There shouldn't really be a span, but it's easier for the test runner
-                // if we give it one
-                return Err(self.fatal("this file contains an un-closed delimiter "));
+                return Err(err);
             },
             token::OpenDelim(delim) => {
                 // The span for beginning of the delimited section
@@ -2668,7 +2662,7 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> PResult<TokenTree> {
 
     // parse a stream of tokens into a list of TokenTree's,
     // up to EOF.
-    pub fn parse_all_token_trees(&mut self) -> PResult<Vec<TokenTree>> {
+    pub fn parse_all_token_trees(&mut self) -> PResult<'a, Vec<TokenTree>> {
         let mut tts = Vec::new();
         while self.token != token::Eof {
             tts.push(try!(self.parse_token_tree()));
@@ -2679,7 +2673,7 @@ pub fn parse_all_token_trees(&mut self) -> PResult<Vec<TokenTree>> {
     /// Parse a prefix-unary-operator expr
     pub fn parse_prefix_expr(&mut self,
                              already_parsed_attrs: Option<ThinAttributes>)
-                             -> PResult<P<Expr>> {
+                             -> PResult<'a, P<Expr>> {
         let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
         let lo = self.span.lo;
         let hi;
@@ -2740,7 +2734,7 @@ pub fn parse_prefix_expr(&mut self,
     /// the expression.
     pub fn parse_assoc_expr(&mut self,
                             already_parsed_attrs: Option<ThinAttributes>)
-                            -> PResult<P<Expr>> {
+                            -> PResult<'a, P<Expr>> {
         self.parse_assoc_expr_with(0, already_parsed_attrs.into())
     }
 
@@ -2748,7 +2742,7 @@ pub fn parse_assoc_expr(&mut self,
     pub fn parse_assoc_expr_with(&mut self,
                                  min_prec: usize,
                                  lhs: LhsExpr)
-                                 -> PResult<P<Expr>> {
+                                 -> PResult<'a, P<Expr>> {
         let mut lhs = if let LhsExpr::AlreadyParsed(expr) = lhs {
             expr
         } else {
@@ -2815,16 +2809,25 @@ pub fn parse_assoc_expr_with(&mut self,
             }
 
             let rhs = try!(match op.fixity() {
-                Fixity::Right => self.with_res(restrictions, |this|{
-                    this.parse_assoc_expr_with(op.precedence(), LhsExpr::NotYetParsed)
+                Fixity::Right => self.with_res(
+                    restrictions - Restrictions::RESTRICTION_STMT_EXPR,
+                    |this| {
+                        this.parse_assoc_expr_with(op.precedence(),
+                            LhsExpr::NotYetParsed)
                 }),
-                Fixity::Left => self.with_res(restrictions, |this|{
-                    this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed)
+                Fixity::Left => self.with_res(
+                    restrictions - Restrictions::RESTRICTION_STMT_EXPR,
+                    |this| {
+                        this.parse_assoc_expr_with(op.precedence() + 1,
+                            LhsExpr::NotYetParsed)
                 }),
                 // We currently have no non-associative operators that are not handled above by
                 // the special cases. The code is here only for future convenience.
-                Fixity::None => self.with_res(restrictions, |this|{
-                    this.parse_assoc_expr_with(op.precedence() + 1, LhsExpr::NotYetParsed)
+                Fixity::None => self.with_res(
+                    restrictions - Restrictions::RESTRICTION_STMT_EXPR,
+                    |this| {
+                        this.parse_assoc_expr_with(op.precedence() + 1,
+                            LhsExpr::NotYetParsed)
                 }),
             });
 
@@ -2879,12 +2882,13 @@ fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
             ExprBinary(op, _, _) if op.node.is_comparison() => {
                 // respan to include both operators
                 let op_span = mk_sp(op.span.lo, self.span.hi);
-                self.span_err(op_span,
+                let mut err = self.diagnostic().struct_span_err(op_span,
                     "chained comparison operators require parentheses");
                 if op.node == BiLt && *outer_op == AssocOp::Greater {
-                    self.fileline_help(op_span,
+                    err.fileline_help(op_span,
                         "use `::<...>` instead of `<...>` if you meant to specify type arguments");
                 }
+                err.emit();
             }
             _ => {}
         }
@@ -2893,7 +2897,7 @@ fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: &AssocOp) {
     /// Parse prefix-forms of range notation: `..expr` and `..`
     fn parse_prefix_range_expr(&mut self,
                                already_parsed_attrs: Option<ThinAttributes>)
-                               -> PResult<P<Expr>> {
+                               -> PResult<'a, P<Expr>> {
         debug_assert!(self.token == token::DotDot);
         let attrs = try!(self.parse_or_use_outer_attributes(already_parsed_attrs));
         let lo = self.span.lo;
@@ -2928,7 +2932,7 @@ fn is_at_start_of_range_notation_rhs(&self) -> bool {
     }
 
     /// Parse an 'if' or 'if let' expression ('if' token already eaten)
-    pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> {
+    pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         if self.check_keyword(keywords::Let) {
             return self.parse_if_let_expr(attrs);
         }
@@ -2947,7 +2951,7 @@ pub fn parse_if_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> {
 
     /// Parse an 'if let' expression ('if' token already eaten)
     pub fn parse_if_let_expr(&mut self, attrs: ThinAttributes)
-                             -> PResult<P<Expr>> {
+                             -> PResult<'a, P<Expr>> {
         let lo = self.last_span.lo;
         try!(self.expect_keyword(keywords::Let));
         let pat = try!(self.parse_pat());
@@ -2967,7 +2971,7 @@ pub fn parse_if_let_expr(&mut self, attrs: ThinAttributes)
     pub fn parse_lambda_expr(&mut self, lo: BytePos,
                              capture_clause: CaptureClause,
                              attrs: ThinAttributes)
-                             -> PResult<P<Expr>>
+                             -> PResult<'a, P<Expr>>
     {
         let decl = try!(self.parse_fn_block_decl());
         let body = match decl.output {
@@ -2997,7 +3001,7 @@ pub fn parse_lambda_expr(&mut self, lo: BytePos,
     }
 
     // `else` token already eaten
-    pub fn parse_else_expr(&mut self) -> PResult<P<Expr>> {
+    pub fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
         if try!(self.eat_keyword(keywords::If) ){
             return self.parse_if_expr(None);
         } else {
@@ -3009,7 +3013,7 @@ pub fn parse_else_expr(&mut self) -> PResult<P<Expr>> {
     /// Parse a 'for' .. 'in' expression ('for' token already eaten)
     pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>,
                           span_lo: BytePos,
-                          attrs: ThinAttributes) -> PResult<P<Expr>> {
+                          attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         // Parse: `for <src_pat> in <src_expr> <src_loop_block>`
 
         let pat = try!(self.parse_pat());
@@ -3028,7 +3032,7 @@ pub fn parse_for_expr(&mut self, opt_ident: Option<ast::Ident>,
     /// Parse a 'while' or 'while let' expression ('while' token already eaten)
     pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>,
                             span_lo: BytePos,
-                            attrs: ThinAttributes) -> PResult<P<Expr>> {
+                            attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         if self.token.is_keyword(keywords::Let) {
             return self.parse_while_let_expr(opt_ident, span_lo, attrs);
         }
@@ -3043,7 +3047,7 @@ pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>,
     /// Parse a 'while let' expression ('while' token already eaten)
     pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>,
                                 span_lo: BytePos,
-                                attrs: ThinAttributes) -> PResult<P<Expr>> {
+                                attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         try!(self.expect_keyword(keywords::Let));
         let pat = try!(self.parse_pat());
         try!(self.expect(&token::Eq));
@@ -3057,7 +3061,7 @@ pub fn parse_while_let_expr(&mut self, opt_ident: Option<ast::Ident>,
     // parse `loop {...}`, `loop` token already eaten
     pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>,
                            span_lo: BytePos,
-                           attrs: ThinAttributes) -> PResult<P<Expr>> {
+                           attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         let (iattrs, body) = try!(self.parse_inner_attrs_and_block());
         let attrs = attrs.append(iattrs.into_thin_attrs());
         let hi = body.span.hi;
@@ -3065,14 +3069,15 @@ pub fn parse_loop_expr(&mut self, opt_ident: Option<ast::Ident>,
     }
 
     // `match` token already eaten
-    fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> {
+    fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Expr>> {
         let match_span = self.last_span;
         let lo = self.last_span.lo;
         let discriminant = try!(self.parse_expr_res(
             Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None));
-        if let Err(e) = self.commit_expr_expecting(&*discriminant, token::OpenDelim(token::Brace)) {
+        if let Err(mut e) = self.commit_expr_expecting(&*discriminant,
+                                                       token::OpenDelim(token::Brace)) {
             if self.token == token::Token::Semi {
-                self.span_note(match_span, "did you mean to remove this `match` keyword?");
+                e.span_note(match_span, "did you mean to remove this `match` keyword?");
             }
             return Err(e)
         }
@@ -3087,7 +3092,7 @@ fn parse_match_expr(&mut self, attrs: ThinAttributes) -> PResult<P<Expr>> {
         return Ok(self.mk_expr(lo, hi, ExprMatch(discriminant, arms), attrs));
     }
 
-    pub fn parse_arm(&mut self) -> PResult<Arm> {
+    pub fn parse_arm(&mut self) -> PResult<'a, Arm> {
         maybe_whole!(no_clone self, NtArm);
 
         let attrs = try!(self.parse_outer_attributes());
@@ -3118,15 +3123,16 @@ pub fn parse_arm(&mut self) -> PResult<Arm> {
     }
 
     /// Parse an expression
-    pub fn parse_expr(&mut self) -> PResult<P<Expr>> {
+    pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
         self.parse_expr_res(Restrictions::empty(), None)
     }
 
     /// Evaluate the closure with restrictions in place.
     ///
     /// After the closure is evaluated, restrictions are reset.
-    pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<P<Expr>>
-    where F: FnOnce(&mut Self) -> PResult<P<Expr>> {
+    pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<'a, P<Expr>>
+        where F: FnOnce(&mut Self) -> PResult<'a,  P<Expr>>
+    {
         let old = self.restrictions;
         self.restrictions = r;
         let r = f(self);
@@ -3138,12 +3144,12 @@ pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<P<Expr>>
     /// Parse an expression, subject to the given restrictions
     pub fn parse_expr_res(&mut self, r: Restrictions,
                           already_parsed_attrs: Option<ThinAttributes>)
-                          -> PResult<P<Expr>> {
+                          -> PResult<'a, P<Expr>> {
         self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs))
     }
 
     /// Parse the RHS of a local variable declaration (e.g. '= 14;')
-    fn parse_initializer(&mut self) -> PResult<Option<P<Expr>>> {
+    fn parse_initializer(&mut self) -> PResult<'a, Option<P<Expr>>> {
         if self.check(&token::Eq) {
             try!(self.bump());
             Ok(Some(try!(self.parse_expr())))
@@ -3153,7 +3159,7 @@ fn parse_initializer(&mut self) -> PResult<Option<P<Expr>>> {
     }
 
     /// Parse patterns, separated by '|' s
-    fn parse_pats(&mut self) -> PResult<Vec<P<Pat>>> {
+    fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
         let mut pats = Vec::new();
         loop {
             pats.push(try!(self.parse_pat()));
@@ -3162,7 +3168,7 @@ fn parse_pats(&mut self) -> PResult<Vec<P<Pat>>> {
         };
     }
 
-    fn parse_pat_tuple_elements(&mut self) -> PResult<Vec<P<Pat>>> {
+    fn parse_pat_tuple_elements(&mut self) -> PResult<'a, Vec<P<Pat>>> {
         let mut fields = vec![];
         if !self.check(&token::CloseDelim(token::Paren)) {
             fields.push(try!(self.parse_pat()));
@@ -3181,7 +3187,7 @@ fn parse_pat_tuple_elements(&mut self) -> PResult<Vec<P<Pat>>> {
 
     fn parse_pat_vec_elements(
         &mut self,
-    ) -> PResult<(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> {
+    ) -> PResult<'a, (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>)> {
         let mut before = Vec::new();
         let mut slice = None;
         let mut after = Vec::new();
@@ -3233,7 +3239,7 @@ fn parse_pat_vec_elements(
     }
 
     /// Parse the fields of a struct-like pattern
-    fn parse_pat_fields(&mut self) -> PResult<(Vec<codemap::Spanned<ast::FieldPat>> , bool)> {
+    fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<codemap::Spanned<ast::FieldPat>> , bool)> {
         let mut fields = Vec::new();
         let mut etc = false;
         let mut first = true;
@@ -3310,7 +3316,7 @@ fn parse_pat_fields(&mut self) -> PResult<(Vec<codemap::Spanned<ast::FieldPat>>
         return Ok((fields, etc));
     }
 
-    fn parse_pat_range_end(&mut self) -> PResult<P<Expr>> {
+    fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
         if self.is_path_start() {
             let lo = self.span.lo;
             let (qself, path) = if try!(self.eat_lt()) {
@@ -3336,7 +3342,7 @@ fn is_path_start(&self) -> bool {
     }
 
     /// Parse a pattern.
-    pub fn parse_pat(&mut self) -> PResult<P<Pat>> {
+    pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
         maybe_whole!(self, NtPat);
 
         let lo = self.span.lo;
@@ -3496,7 +3502,7 @@ pub fn parse_pat(&mut self) -> PResult<P<Pat>> {
     /// error message when parsing mistakes like ref foo(a,b)
     fn parse_pat_ident(&mut self,
                        binding_mode: ast::BindingMode)
-                       -> PResult<ast::Pat_> {
+                       -> PResult<'a, ast::Pat_> {
         if !self.token.is_plain_ident() {
             let span = self.span;
             let tok_str = self.this_token_to_string();
@@ -3529,7 +3535,7 @@ fn parse_pat_ident(&mut self,
     }
 
     /// Parse a local variable declaration
-    fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<P<Local>> {
+    fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Local>> {
         let lo = self.span.lo;
         let pat = try!(self.parse_pat());
 
@@ -3549,7 +3555,7 @@ fn parse_local(&mut self, attrs: ThinAttributes) -> PResult<P<Local>> {
     }
 
     /// Parse a "let" stmt
-    fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<P<Decl>> {
+    fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<'a, P<Decl>> {
         let lo = self.span.lo;
         let local = try!(self.parse_local(attrs));
         Ok(P(spanned(lo, self.last_span.hi, DeclLocal(local))))
@@ -3557,7 +3563,7 @@ fn parse_let(&mut self, attrs: ThinAttributes) -> PResult<P<Decl>> {
 
     /// Parse a structure field
     fn parse_name_and_ty(&mut self, pr: Visibility,
-                         attrs: Vec<Attribute> ) -> PResult<StructField> {
+                         attrs: Vec<Attribute> ) -> PResult<'a, StructField> {
         let lo = match pr {
             Inherited => self.span.lo,
             Public => self.last_span.lo,
@@ -3589,11 +3595,11 @@ fn expected_item_err(&self, attrs: &[Attribute]) {
     }
 
     /// Parse a statement. may include decl.
-    pub fn parse_stmt(&mut self) -> PResult<Option<P<Stmt>>> {
+    pub fn parse_stmt(&mut self) -> PResult<'a, Option<P<Stmt>>> {
         Ok(try!(self.parse_stmt_()).map(P))
     }
 
-    fn parse_stmt_(&mut self) -> PResult<Option<Stmt>> {
+    fn parse_stmt_(&mut self) -> PResult<'a, Option<Stmt>> {
         maybe_whole!(Some deref self, NtStmt);
 
         let attrs = try!(self.parse_outer_attributes());
@@ -3729,7 +3735,7 @@ fn expr_is_complete(&mut self, e: &Expr) -> bool {
     }
 
     /// Parse a block. No inner attrs are allowed.
-    pub fn parse_block(&mut self) -> PResult<P<Block>> {
+    pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         maybe_whole!(no_clone self, NtBlock);
 
         let lo = self.span.lo;
@@ -3746,7 +3752,7 @@ pub fn parse_block(&mut self) -> PResult<P<Block>> {
     }
 
     /// Parse a block. Inner attrs are allowed.
-    fn parse_inner_attrs_and_block(&mut self) -> PResult<(Vec<Attribute>, P<Block>)> {
+    fn parse_inner_attrs_and_block(&mut self) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
         maybe_whole!(pair_empty self, NtBlock);
 
         let lo = self.span.lo;
@@ -3757,7 +3763,7 @@ fn parse_inner_attrs_and_block(&mut self) -> PResult<(Vec<Attribute>, P<Block>)>
 
     /// Parse the rest of a block expression or function body
     /// Precondition: already parsed the '{'.
-    fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<P<Block>> {
+    fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> PResult<'a, P<Block>> {
         let mut stmts = vec![];
         let mut expr = None;
 
@@ -3851,7 +3857,7 @@ fn handle_expression_like_statement(
             e: P<Expr>,
             span: Span,
             stmts: &mut Vec<P<Stmt>>,
-            last_block_expr: &mut Option<P<Expr>>) -> PResult<()> {
+            last_block_expr: &mut Option<P<Expr>>) -> PResult<'a, ()> {
         // expression without semicolon
         if classify::expr_requires_semi_to_be_stmt(&*e) {
             // Just check for errors and recover; do not eat semicolon yet.
@@ -3887,7 +3893,7 @@ fn handle_expression_like_statement(
     // otherwise returns empty list.
     fn parse_colon_then_ty_param_bounds(&mut self,
                                         mode: BoundParsingMode)
-                                        -> PResult<TyParamBounds>
+                                        -> PResult<'a, TyParamBounds>
     {
         if !try!(self.eat(&token::Colon) ){
             Ok(P::empty())
@@ -3902,7 +3908,7 @@ fn parse_colon_then_ty_param_bounds(&mut self,
     // and     bound     = 'region | trait_ref
     fn parse_ty_param_bounds(&mut self,
                              mode: BoundParsingMode)
-                             -> PResult<TyParamBounds>
+                             -> PResult<'a, TyParamBounds>
     {
         let mut result = vec!();
         loop {
@@ -3948,7 +3954,7 @@ fn parse_ty_param_bounds(&mut self,
     }
 
     /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
-    fn parse_ty_param(&mut self) -> PResult<TyParam> {
+    fn parse_ty_param(&mut self) -> PResult<'a, TyParam> {
         let span = self.span;
         let ident = try!(self.parse_ident());
 
@@ -3977,7 +3983,7 @@ fn parse_ty_param(&mut self) -> PResult<TyParam> {
     /// matches generics = ( ) | ( < > ) | ( < typaramseq ( , )? > ) | ( < lifetimes ( , )? > )
     ///                  | ( < lifetimes , typaramseq ( , )? > )
     /// where   typaramseq = ( typaram ) | ( typaram , typaramseq )
-    pub fn parse_generics(&mut self) -> PResult<ast::Generics> {
+    pub fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
         maybe_whole!(self, NtGenerics);
 
         if try!(self.eat(&token::Lt) ){
@@ -4008,7 +4014,7 @@ pub fn parse_generics(&mut self) -> PResult<ast::Generics> {
         }
     }
 
-    fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>,
+    fn parse_generic_values_after_lt(&mut self) -> PResult<'a, (Vec<ast::Lifetime>,
                                                             Vec<P<Ty>>,
                                                             Vec<P<TypeBinding>>)> {
         let span_lo = self.span.lo;
@@ -4025,7 +4031,7 @@ fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>,
             let msg = format!("expected `,` or `>` after lifetime \
                               name, found `{}`",
                               self.this_token_to_string());
-            self.span_err(self.span, &msg);
+            let mut err = self.diagnostic().struct_span_err(self.span, &msg);
 
             let span_hi = self.span.hi;
             let span_hi = if self.parse_ty().is_ok() {
@@ -4037,7 +4043,8 @@ fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>,
             let msg = format!("did you mean a single argument type &'a Type, \
                               or did you mean the comma-separated arguments \
                               'a, Type?");
-            self.span_note(mk_sp(span_lo, span_hi), &msg);
+            err.span_note(mk_sp(span_lo, span_hi), &msg);
+            err.emit();
 
             self.abort_if_errors()
         }
@@ -4085,7 +4092,7 @@ fn parse_generic_values_after_lt(&mut self) -> PResult<(Vec<ast::Lifetime>,
         Ok((lifetimes, types.into_vec(), bindings.into_vec()))
     }
 
-    fn forbid_lifetime(&mut self) -> PResult<()> {
+    fn forbid_lifetime(&mut self) -> PResult<'a, ()> {
         if self.token.is_lifetime() {
             let span = self.span;
             return Err(self.span_fatal(span, "lifetime parameters must be declared \
@@ -4099,7 +4106,7 @@ fn forbid_lifetime(&mut self) -> PResult<()> {
     /// ```ignore
     /// where T : Trait<U, V> + 'b, 'a : 'b
     /// ```
-    pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
+    pub fn parse_where_clause(&mut self) -> PResult<'a, ast::WhereClause> {
         maybe_whole!(self, NtWhereClause);
 
         let mut where_clause = WhereClause {
@@ -4215,7 +4222,7 @@ pub fn parse_where_clause(&mut self) -> PResult<ast::WhereClause> {
     }
 
     fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
-                     -> PResult<(Vec<Arg> , bool)> {
+                     -> PResult<'a, (Vec<Arg> , bool)> {
         let sp = self.span;
         let mut args: Vec<Option<Arg>> =
             try!(self.parse_unspanned_seq(
@@ -4264,7 +4271,7 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
     }
 
     /// Parse the argument list and result type of a function declaration
-    pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<P<FnDecl>> {
+    pub fn parse_fn_decl(&mut self, allow_variadic: bool) -> PResult<'a, P<FnDecl>> {
 
         let (args, variadic) = try!(self.parse_fn_args(true, allow_variadic));
         let ret_ty = try!(self.parse_ret_ty());
@@ -4283,7 +4290,7 @@ fn is_self_ident(&mut self) -> bool {
         }
     }
 
-    fn expect_self_ident(&mut self) -> PResult<ast::Ident> {
+    fn expect_self_ident(&mut self) -> PResult<'a, ast::Ident> {
         match self.token {
             token::Ident(id, token::Plain) if id.name == special_idents::self_.name => {
                 try!(self.bump());
@@ -4304,7 +4311,7 @@ fn is_self_type_ident(&mut self) -> bool {
         }
     }
 
-    fn expect_self_type_ident(&mut self) -> PResult<ast::Ident> {
+    fn expect_self_type_ident(&mut self) -> PResult<'a, ast::Ident> {
         match self.token {
             token::Ident(id, token::Plain) if id.name == special_idents::type_self.name => {
                 try!(self.bump());
@@ -4321,11 +4328,11 @@ fn expect_self_type_ident(&mut self) -> PResult<ast::Ident> {
     /// Parse the argument list and result type of a function
     /// that may have a self type.
     fn parse_fn_decl_with_self<F>(&mut self,
-                                  parse_arg_fn: F) -> PResult<(ExplicitSelf, P<FnDecl>)> where
-        F: FnMut(&mut Parser) -> PResult<Arg>,
+                                  parse_arg_fn: F) -> PResult<'a, (ExplicitSelf, P<FnDecl>)> where
+        F: FnMut(&mut Parser<'a>) -> PResult<'a,  Arg>,
     {
-        fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
-                                              -> PResult<ast::ExplicitSelf_> {
+        fn maybe_parse_borrowed_explicit_self<'b>(this: &mut Parser<'b>)
+                                                  -> PResult<'b,  ast::ExplicitSelf_> {
             // The following things are possible to see here:
             //
             //     fn(&mut self)
@@ -4483,7 +4490,7 @@ macro_rules! parse_remaining_arguments {
     }
 
     // parse the |arg, arg| header on a lambda
-    fn parse_fn_block_decl(&mut self) -> PResult<P<FnDecl>> {
+    fn parse_fn_block_decl(&mut self) -> PResult<'a, P<FnDecl>> {
         let inputs_captures = {
             if try!(self.eat(&token::OrOr) ){
                 Vec::new()
@@ -4509,7 +4516,7 @@ fn parse_fn_block_decl(&mut self) -> PResult<P<FnDecl>> {
     }
 
     /// Parse the name and optional generic types of a function header.
-    fn parse_fn_header(&mut self) -> PResult<(Ident, ast::Generics)> {
+    fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
         let id = try!(self.parse_ident());
         let generics = try!(self.parse_generics());
         Ok((id, generics))
@@ -4533,7 +4540,7 @@ fn parse_item_fn(&mut self,
                      unsafety: Unsafety,
                      constness: Constness,
                      abi: abi::Abi)
-                     -> PResult<ItemInfo> {
+                     -> PResult<'a, ItemInfo> {
         let (ident, mut generics) = try!(self.parse_fn_header());
         let decl = try!(self.parse_fn_decl(false));
         generics.where_clause = try!(self.parse_where_clause());
@@ -4556,7 +4563,8 @@ pub fn is_const_item(&mut self) -> bool {
     /// - `const unsafe fn`
     /// - `extern fn`
     /// - etc
-    pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafety, abi::Abi)> {
+    pub fn parse_fn_front_matter(&mut self)
+                                 -> PResult<'a, (ast::Constness, ast::Unsafety, abi::Abi)> {
         let is_const_fn = try!(self.eat_keyword(keywords::Const));
         let unsafety = try!(self.parse_unsafety());
         let (constness, unsafety, abi) = if is_const_fn {
@@ -4574,7 +4582,7 @@ pub fn parse_fn_front_matter(&mut self) -> PResult<(ast::Constness, ast::Unsafet
     }
 
     /// Parse an impl item.
-    pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
+    pub fn parse_impl_item(&mut self) -> PResult<'a, P<ImplItem>> {
         maybe_whole!(no_clone self, NtImplItem);
 
         let mut attrs = try!(self.parse_outer_attributes());
@@ -4614,9 +4622,22 @@ pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
     fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
         match visa {
             Public => {
-                self.span_err(span, "can't qualify macro invocation with `pub`");
-                self.fileline_help(span, "try adjusting the macro to put `pub` inside \
-                                      the invocation");
+                let is_macro_rules: bool = match self.token {
+                    token::Ident(sid, _) => sid.name == intern("macro_rules"),
+                    _ => false,
+                };
+                if is_macro_rules {
+                    self.diagnostic().struct_span_err(span, "can't qualify macro_rules \
+                                                             invocation with `pub`")
+                                     .fileline_help(span, "did you mean #[macro_export]?")
+                                     .emit();
+                } else {
+                    self.diagnostic().struct_span_err(span, "can't qualify macro \
+                                                             invocation with `pub`")
+                                     .fileline_help(span, "try adjusting the macro to put `pub` \
+                                                           inside the invocation")
+                                     .emit();
+                }
             }
             Inherited => (),
         }
@@ -4624,7 +4645,7 @@ fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
 
     /// Parse a method or a macro invocation in a trait impl.
     fn parse_impl_method(&mut self, vis: Visibility)
-                         -> PResult<(Ident, Vec<ast::Attribute>, ast::ImplItemKind)> {
+                         -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> {
         // code copied from parse_macro_use_or_failure... abstraction!
         if !self.token.is_any_keyword()
             && self.look_ahead(1, |t| *t == token::Not)
@@ -4673,7 +4694,7 @@ fn parse_impl_method(&mut self, vis: Visibility)
     }
 
     /// Parse trait Foo { ... }
-    fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<ItemInfo> {
+    fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
 
         let ident = try!(self.parse_ident());
         let mut tps = try!(self.parse_generics());
@@ -4691,7 +4712,7 @@ fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<ItemInfo> {
     ///    impl<T> Foo { ... }
     ///    impl<T> ToString for &'static T { ... }
     ///    impl Send for .. {}
-    fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<ItemInfo> {
+    fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<'a, ItemInfo> {
         let impl_span = self.span;
 
         // First, parse type parameters if necessary.
@@ -4769,14 +4790,14 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> PResult<ItemInfo> {
     }
 
     /// Parse a::B<String,i32>
-    fn parse_trait_ref(&mut self) -> PResult<TraitRef> {
+    fn parse_trait_ref(&mut self) -> PResult<'a, TraitRef> {
         Ok(ast::TraitRef {
             path: try!(self.parse_path(LifetimeAndTypesWithoutColons)),
             ref_id: ast::DUMMY_NODE_ID,
         })
     }
 
-    fn parse_late_bound_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> {
+    fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<ast::LifetimeDef>> {
         if try!(self.eat_keyword(keywords::For) ){
             try!(self.expect(&token::Lt));
             let lifetime_defs = try!(self.parse_lifetime_defs());
@@ -4788,7 +4809,7 @@ fn parse_late_bound_lifetime_defs(&mut self) -> PResult<Vec<ast::LifetimeDef>> {
     }
 
     /// Parse for<'l> a::B<String,i32>
-    fn parse_poly_trait_ref(&mut self) -> PResult<PolyTraitRef> {
+    fn parse_poly_trait_ref(&mut self) -> PResult<'a, PolyTraitRef> {
         let lo = self.span.lo;
         let lifetime_defs = try!(self.parse_late_bound_lifetime_defs());
 
@@ -4800,7 +4821,7 @@ fn parse_poly_trait_ref(&mut self) -> PResult<PolyTraitRef> {
     }
 
     /// Parse struct Foo { ... }
-    fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
+    fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> {
         let class_name = try!(self.parse_ident());
         let mut generics = try!(self.parse_generics());
 
@@ -4851,7 +4872,9 @@ fn parse_item_struct(&mut self) -> PResult<ItemInfo> {
         Ok((class_name, ItemStruct(vdata, generics), None))
     }
 
-    pub fn parse_record_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<StructField>> {
+    pub fn parse_record_struct_body(&mut self,
+                                    parse_pub: ParsePub)
+                                    -> PResult<'a, Vec<StructField>> {
         let mut fields = Vec::new();
         if try!(self.eat(&token::OpenDelim(token::Brace)) ){
             while self.token != token::CloseDelim(token::Brace) {
@@ -4869,7 +4892,9 @@ pub fn parse_record_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<S
         Ok(fields)
     }
 
-    pub fn parse_tuple_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<StructField>> {
+    pub fn parse_tuple_struct_body(&mut self,
+                                   parse_pub: ParsePub)
+                                   -> PResult<'a, Vec<StructField>> {
         // This is the case where we find `struct Foo<T>(T) where T: Copy;`
         // Unit like structs are handled in parse_item_struct function
         let fields = try!(self.parse_unspanned_seq(
@@ -4901,7 +4926,7 @@ pub fn parse_tuple_struct_body(&mut self, parse_pub: ParsePub) -> PResult<Vec<St
     pub fn parse_single_struct_field(&mut self,
                                      vis: Visibility,
                                      attrs: Vec<Attribute> )
-                                     -> PResult<StructField> {
+                                     -> PResult<'a, StructField> {
         let a_var = try!(self.parse_name_and_ty(vis, attrs));
         match self.token {
             token::Comma => {
@@ -4921,7 +4946,7 @@ pub fn parse_single_struct_field(&mut self,
     }
 
     /// Parse an element of a struct definition
-    fn parse_struct_decl_field(&mut self, parse_pub: ParsePub) -> PResult<StructField> {
+    fn parse_struct_decl_field(&mut self, parse_pub: ParsePub) -> PResult<'a, StructField> {
 
         let attrs = try!(self.parse_outer_attributes());
 
@@ -4937,13 +4962,13 @@ fn parse_struct_decl_field(&mut self, parse_pub: ParsePub) -> PResult<StructFiel
     }
 
     /// Parse visibility: PUB or nothing
-    fn parse_visibility(&mut self) -> PResult<Visibility> {
+    fn parse_visibility(&mut self) -> PResult<'a, Visibility> {
         if try!(self.eat_keyword(keywords::Pub)) { Ok(Public) }
         else { Ok(Inherited) }
     }
 
     /// Given a termination token, parse all of the items in a module
-    fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult<Mod> {
+    fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult<'a, Mod> {
         let mut items = vec![];
         while let Some(item) = try!(self.parse_item()) {
             items.push(item);
@@ -4966,7 +4991,7 @@ fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> PResult
         })
     }
 
-    fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<ItemInfo> {
+    fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
         let id = try!(self.parse_ident());
         try!(self.expect(&token::Colon));
         let ty = try!(self.parse_ty_sum());
@@ -4981,7 +5006,7 @@ fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<ItemInfo> {
     }
 
     /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
-    fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<ItemInfo> {
+    fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
         let id_span = self.span;
         let id = try!(self.parse_ident());
         if self.check(&token::Semi) {
@@ -5060,7 +5085,7 @@ pub fn default_submod_path(id: ast::Ident, dir_path: &Path, codemap: &CodeMap) -
     fn submod_path(&mut self,
                    id: ast::Ident,
                    outer_attrs: &[ast::Attribute],
-                   id_sp: Span) -> PResult<ModulePathSuccess> {
+                   id_sp: Span) -> PResult<'a, ModulePathSuccess> {
         let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span));
         prefix.pop();
         let mut dir_path = prefix;
@@ -5075,21 +5100,23 @@ fn submod_path(&mut self,
         let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap());
 
         if !self.owns_directory {
-            self.span_err(id_sp, "cannot declare a new module at this location");
+            let mut err = self.diagnostic().struct_span_err(id_sp,
+                "cannot declare a new module at this location");
             let this_module = match self.mod_path_stack.last() {
                 Some(name) => name.to_string(),
                 None => self.root_module_name.as_ref().unwrap().clone(),
             };
-            self.span_note(id_sp,
-                           &format!("maybe move this module `{0}` to its own directory \
+            err.span_note(id_sp,
+                          &format!("maybe move this module `{0}` to its own directory \
                                      via `{0}/mod.rs`",
                                     this_module));
             if paths.path_exists {
-                self.span_note(id_sp,
-                               &format!("... or maybe `use` the module `{}` instead \
-                                         of possibly redeclaring it",
-                                        paths.name));
+                err.span_note(id_sp,
+                              &format!("... or maybe `use` the module `{}` instead \
+                                        of possibly redeclaring it",
+                                       paths.name));
             }
+            err.emit();
             self.abort_if_errors();
         }
 
@@ -5104,7 +5131,7 @@ fn eval_src_mod(&mut self,
                     id: ast::Ident,
                     outer_attrs: &[ast::Attribute],
                     id_sp: Span)
-                    -> PResult<(ast::Item_, Vec<ast::Attribute> )> {
+                    -> PResult<'a, (ast::Item_, Vec<ast::Attribute> )> {
         let ModulePathSuccess { path, owns_directory } = try!(self.submod_path(id,
                                                                                outer_attrs,
                                                                                id_sp));
@@ -5119,7 +5146,7 @@ fn eval_src_mod_from_path(&mut self,
                               path: PathBuf,
                               owns_directory: bool,
                               name: String,
-                              id_sp: Span) -> PResult<(ast::Item_, Vec<ast::Attribute> )> {
+                              id_sp: Span) -> PResult<'a, (ast::Item_, Vec<ast::Attribute> )> {
         let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
         match included_mod_stack.iter().position(|p| *p == path) {
             Some(i) => {
@@ -5152,7 +5179,7 @@ fn eval_src_mod_from_path(&mut self,
 
     /// Parse a function declaration from a foreign module
     fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: BytePos,
-                             attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> {
+                             attrs: Vec<Attribute>) -> PResult<'a, P<ForeignItem>> {
         try!(self.expect_keyword(keywords::Fn));
 
         let (ident, mut generics) = try!(self.parse_fn_header());
@@ -5172,7 +5199,7 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility, lo: BytePos,
 
     /// Parse a static item from a foreign module
     fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: BytePos,
-                                 attrs: Vec<Attribute>) -> PResult<P<ForeignItem>> {
+                                 attrs: Vec<Attribute>) -> PResult<'a, P<ForeignItem>> {
         try!(self.expect_keyword(keywords::Static));
         let mutbl = try!(self.eat_keyword(keywords::Mut));
 
@@ -5201,7 +5228,7 @@ fn parse_item_extern_crate(&mut self,
                                lo: BytePos,
                                visibility: Visibility,
                                attrs: Vec<Attribute>)
-                                -> PResult<P<Item>> {
+                                -> PResult<'a, P<Item>> {
 
         let crate_name = try!(self.parse_ident());
         let (maybe_path, ident) = if let Some(ident) = try!(self.parse_rename()) {
@@ -5242,7 +5269,7 @@ fn parse_item_foreign_mod(&mut self,
                               opt_abi: Option<abi::Abi>,
                               visibility: Visibility,
                               mut attrs: Vec<Attribute>)
-                              -> PResult<P<Item>> {
+                              -> PResult<'a, P<Item>> {
         try!(self.expect(&token::OpenDelim(token::Brace)));
 
         let abi = opt_abi.unwrap_or(abi::C);
@@ -5269,7 +5296,7 @@ fn parse_item_foreign_mod(&mut self,
     }
 
     /// Parse type Foo = Bar;
-    fn parse_item_type(&mut self) -> PResult<ItemInfo> {
+    fn parse_item_type(&mut self) -> PResult<'a, ItemInfo> {
         let ident = try!(self.parse_ident());
         let mut tps = try!(self.parse_generics());
         tps.where_clause = try!(self.parse_where_clause());
@@ -5280,7 +5307,7 @@ fn parse_item_type(&mut self) -> PResult<ItemInfo> {
     }
 
     /// Parse the part of an "enum" decl following the '{'
-    fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
+    fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
         let mut variants = Vec::new();
         let mut all_nullary = true;
         let mut any_disr = None;
@@ -5330,7 +5357,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<EnumDef> {
     }
 
     /// Parse an "enum" declaration
-    fn parse_item_enum(&mut self) -> PResult<ItemInfo> {
+    fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
         let id = try!(self.parse_ident());
         let mut generics = try!(self.parse_generics());
         generics.where_clause = try!(self.parse_where_clause());
@@ -5342,7 +5369,7 @@ fn parse_item_enum(&mut self) -> PResult<ItemInfo> {
 
     /// Parses a string as an ABI spec on an extern type or module. Consumes
     /// the `extern` keyword, if one is found.
-    fn parse_opt_abi(&mut self) -> PResult<Option<abi::Abi>> {
+    fn parse_opt_abi(&mut self) -> PResult<'a, Option<abi::Abi>> {
         match self.token {
             token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => {
                 let sp = self.span;
@@ -5371,7 +5398,7 @@ fn parse_opt_abi(&mut self) -> PResult<Option<abi::Abi>> {
     /// NB: this function no longer parses the items inside an
     /// extern crate.
     fn parse_item_(&mut self, attrs: Vec<Attribute>,
-                   macros_allowed: bool, attributes_allowed: bool) -> PResult<Option<P<Item>>> {
+                   macros_allowed: bool, attributes_allowed: bool) -> PResult<'a, Option<P<Item>>> {
         let nt_item = match self.token {
             token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
@@ -5474,8 +5501,9 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             // CONST ITEM
             if try!(self.eat_keyword(keywords::Mut) ){
                 let last_span = self.last_span;
-                self.span_err(last_span, "const globals cannot be mutable");
-                self.fileline_help(last_span, "did you mean to declare a static?");
+                self.diagnostic().struct_span_err(last_span, "const globals cannot be mutable")
+                                 .fileline_help(last_span, "did you mean to declare a static?")
+                                 .emit();
             }
             let (ident, item_, extra_attrs) = try!(self.parse_item_const(None));
             let last_span = self.last_span;
@@ -5633,7 +5661,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
     }
 
     /// Parse a foreign item.
-    fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
+    fn parse_foreign_item(&mut self) -> PResult<'a, Option<P<ForeignItem>>> {
         let attrs = try!(self.parse_outer_attributes());
         let lo = self.span.lo;
         let visibility = try!(self.parse_visibility());
@@ -5664,7 +5692,7 @@ fn parse_macro_use_or_failure(
         attributes_allowed: bool,
         lo: BytePos,
         visibility: Visibility
-    ) -> PResult<Option<P<Item>>> {
+    ) -> PResult<'a, Option<P<Item>>> {
         if macros_allowed && !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| t.is_plain_ident())
@@ -5736,7 +5764,7 @@ fn parse_macro_use_or_failure(
         Ok(None)
     }
 
-    pub fn parse_item(&mut self) -> PResult<Option<P<Item>>> {
+    pub fn parse_item(&mut self) -> PResult<'a, Option<P<Item>>> {
         let attrs = try!(self.parse_outer_attributes());
         self.parse_item_(attrs, true, false)
     }
@@ -5747,7 +5775,7 @@ pub fn parse_item(&mut self) -> PResult<Option<P<Item>>> {
     /// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
     /// | MOD? non_global_path MOD_SEP STAR
     /// | MOD? non_global_path
-    fn parse_view_path(&mut self) -> PResult<P<ViewPath>> {
+    fn parse_view_path(&mut self) -> PResult<'a, P<ViewPath>> {
         let lo = self.span.lo;
 
         // Allow a leading :: because the paths are absolute either way.
@@ -5843,7 +5871,7 @@ fn parse_view_path(&mut self) -> PResult<P<ViewPath>> {
         Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path))))
     }
 
-    fn parse_rename(&mut self) -> PResult<Option<Ident>> {
+    fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
         if try!(self.eat_keyword(keywords::As)) {
             self.parse_ident().map(Some)
         } else {
@@ -5853,7 +5881,7 @@ fn parse_rename(&mut self) -> PResult<Option<Ident>> {
 
     /// Parses a source module as a crate. This is the main
     /// entry point for the parser.
-    pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
+    pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
         let lo = self.span.lo;
         Ok(ast::Crate {
             attrs: try!(self.parse_inner_attributes()),
@@ -5865,7 +5893,7 @@ pub fn parse_crate_mod(&mut self) -> PResult<Crate> {
     }
 
     pub fn parse_optional_str(&mut self)
-                              -> PResult<Option<(InternedString,
+                              -> PResult<'a, Option<(InternedString,
                                                  ast::StrStyle,
                                                  Option<ast::Name>)>> {
         let ret = match self.token {
@@ -5881,7 +5909,7 @@ pub fn parse_optional_str(&mut self)
         Ok(Some(ret))
     }
 
-    pub fn parse_str(&mut self) -> PResult<(InternedString, StrStyle)> {
+    pub fn parse_str(&mut self) -> PResult<'a, (InternedString, StrStyle)> {
         match try!(self.parse_optional_str()) {
             Some((s, style, suf)) => {
                 let sp = self.last_span;
index becccbf3d2421fcc054d45cea4b558396a325f1a..67817ee0740e6d38a0f5bbdba768d778e31b79bb 100644 (file)
@@ -2403,7 +2403,7 @@ fn print_path_parameters(&mut self,
         }
 
         match *parameters {
-            ast::AngleBracketedParameters(ref data) => {
+            ast::PathParameters::AngleBracketed(ref data) => {
                 try!(word(&mut self.s, "<"));
 
                 let mut comma = false;
@@ -2440,7 +2440,7 @@ fn print_path_parameters(&mut self,
                 try!(word(&mut self.s, ">"))
             }
 
-            ast::ParenthesizedParameters(ref data) => {
+            ast::PathParameters::Parenthesized(ref data) => {
                 try!(word(&mut self.s, "("));
                 try!(self.commasep(
                     Inconsistent,
index 014c7b2a68f4f36935f96b38b726a1e6086d82c0..5e3cd0773aa45df290384225020a9b4f9902f7f7 100644 (file)
@@ -47,21 +47,21 @@ struct ShowSpanVisitor<'a> {
 impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
     fn visit_expr(&mut self, e: &ast::Expr) {
         if let Mode::Expression = self.mode {
-            self.span_diagnostic.span_note(e.span, "expression");
+            self.span_diagnostic.span_warn(e.span, "expression");
         }
         visit::walk_expr(self, e);
     }
 
     fn visit_pat(&mut self, p: &ast::Pat) {
         if let Mode::Pattern = self.mode {
-            self.span_diagnostic.span_note(p.span, "pattern");
+            self.span_diagnostic.span_warn(p.span, "pattern");
         }
         visit::walk_pat(self, p);
     }
 
     fn visit_ty(&mut self, t: &ast::Ty) {
         if let Mode::Type = self.mode {
-            self.span_diagnostic.span_note(t.span, "type");
+            self.span_diagnostic.span_warn(t.span, "type");
         }
         visit::walk_ty(self, t);
     }
index a462dbeb6e4edb7412b6d8f54c3a6614735fc53d..454b925a4945e7133930276e1fe53d6c27edd57e 100644 (file)
@@ -30,10 +30,9 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a>
                                source_str)
 }
 
-fn with_error_checking_parse<T, F>(s: String, f: F) -> T where
-    F: FnOnce(&mut Parser) -> PResult<T>,
+fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where
+    F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
 {
-    let ps = ParseSess::new();
     let mut p = string_to_parser(&ps, s);
     let x = panictry!(f(&mut p));
     p.abort_if_errors();
@@ -42,28 +41,32 @@ fn with_error_checking_parse<T, F>(s: String, f: F) -> T where
 
 /// Parse a string, return a crate.
 pub fn string_to_crate (source_str : String) -> ast::Crate {
-    with_error_checking_parse(source_str, |p| {
+    let ps = ParseSess::new();
+    with_error_checking_parse(source_str, &ps, |p| {
         p.parse_crate_mod()
     })
 }
 
 /// Parse a string, return an expr
 pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
-    with_error_checking_parse(source_str, |p| {
+    let ps = ParseSess::new();
+    with_error_checking_parse(source_str, &ps, |p| {
         p.parse_expr()
     })
 }
 
 /// Parse a string, return an item
 pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
-    with_error_checking_parse(source_str, |p| {
+    let ps = ParseSess::new();
+    with_error_checking_parse(source_str, &ps, |p| {
         p.parse_item()
     })
 }
 
 /// Parse a string, return a stmt
 pub fn string_to_stmt(source_str : String) -> Option<P<ast::Stmt>> {
-    with_error_checking_parse(source_str, |p| {
+    let ps = ParseSess::new();
+    with_error_checking_parse(source_str, &ps, |p| {
         p.parse_stmt()
     })
 }
@@ -71,7 +74,8 @@ pub fn string_to_stmt(source_str : String) -> Option<P<ast::Stmt>> {
 /// Parse a string, return a pat. Uses "irrefutable"... which doesn't
 /// (currently) affect parsing.
 pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
-    with_error_checking_parse(source_str, |p| {
+    let ps = ParseSess::new();
+    with_error_checking_parse(source_str, &ps, |p| {
         p.parse_pat()
     })
 }
index b8dd54790ce51ecb21cad8c15fbcf74e8308b4bb..9b102cd99f305faac1e88a662cd0284c27bcd63c 100644 (file)
@@ -399,12 +399,12 @@ pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
                                                 _path_span: Span,
                                                 path_parameters: &'v PathParameters) {
     match *path_parameters {
-        AngleBracketedParameters(ref data) => {
+        PathParameters::AngleBracketed(ref data) => {
             walk_list!(visitor, visit_ty, &data.types);
             walk_list!(visitor, visit_lifetime, &data.lifetimes);
             walk_list!(visitor, visit_assoc_type_binding, &data.bindings);
         }
-        ParenthesizedParameters(ref data) => {
+        PathParameters::Parenthesized(ref data) => {
             walk_list!(visitor, visit_ty, &data.inputs);
             walk_list!(visitor, visit_ty, &data.output);
         }
index 24094f797e6c272895305c5a18213e830ca99c1e..78e7f7462f31742f9a90929291f2ad84e90a54bb 100644 (file)
@@ -130,10 +130,11 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
             match names.get(name) {
                 None => {}
                 Some(prev) => {
-                    ecx.span_err(e.span,
-                                 &format!("duplicate argument named `{}`",
-                                         name));
-                    ecx.parse_sess.span_diagnostic.span_note(prev.span, "previously here");
+                    ecx.struct_span_err(e.span,
+                                        &format!("duplicate argument named `{}`",
+                                                 name))
+                       .span_note(prev.span, "previously here")
+                       .emit();
                     continue
                 }
             }
index a032666595ebeb300069db0660d02aa366ca6a75..0f049fa9792553a8992a0e05d2b42f2b5a909f97 100644 (file)
 #![feature(str_char)]
 
 extern crate fmt_macros;
+#[macro_use]
 extern crate syntax;
 
 use syntax::ext::base::{MacroExpanderFn, NormalTT};
 use syntax::ext::base::{SyntaxEnv, SyntaxExtension};
 use syntax::parse::token::intern;
 
-// A variant of 'try!' that panics on Err(FatalError). This is used as a
-// crutch on the way towards a non-panic!-prone parser. It should be used
-// for fatal parsing errors; eventually we plan to convert all code using
-// panictry to just use normal try
-macro_rules! panictry {
-    ($e:expr) => ({
-        use std::result::Result::{Ok, Err};
-        use syntax::errors::FatalError;
-        match $e {
-            Ok(e) => e,
-            Err(FatalError) => panic!(FatalError)
-        }
-    })
-}
 
 mod asm;
 mod cfg;
index 34773e1657c2d220f2272648cb4edd9ecb223275..2fa540012816ef1bf0dfb33c961516d0491ff219 100644 (file)
@@ -1,4 +1,7 @@
 S 2015-12-18 3391630
+  bitrig-x86_64 6476e1562df02389b55553b4c88b1f4fd121cd40
+  freebsd-i386 7e624c50494402e1feb14c743d659fbd71b448f5
+  freebsd-x86_64 91724d4e655807a2a2e940ac50992ebeaac16ea9
   linux-i386 a09c4a4036151d0cb28e265101669731600e01f2
   linux-x86_64 97e2a5eb8904962df8596e95d6e5d9b574d73bf4
   macos-i386 ca52d2d3ba6497ed007705ee3401cf7efc136ca1
diff --git a/src/test/compile-fail/pub-item-macro.rs b/src/test/compile-fail/pub-item-macro.rs
deleted file mode 100644 (file)
index 8809e9a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Issue #14660
-
-macro_rules! priv_x { () => {
-    static x: u32 = 0;
-}}
-
-macro_rules! pub_x { () => {
-    pub priv_x!(); //~ ERROR can't qualify macro invocation with `pub`
-    //~^ HELP try adjusting the macro to put `pub` inside the invocation
-}}
-
-mod foo {
-    pub_x!();
-}
-
-fn main() {
-    let y: u32 = foo::x;
-}
diff --git a/src/test/compile-fail/pub-method-macro.rs b/src/test/compile-fail/pub-method-macro.rs
deleted file mode 100644 (file)
index 198fa5b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Issue #18317
-
-mod bleh {
-    macro_rules! defn {
-        ($n:ident) => (
-            fn $n (&self) -> i32 {
-                println!("{}", stringify!($n));
-                1
-            }
-        )
-    }
-
-    #[derive(Copy, Clone)]
-    pub struct S;
-
-    impl S {
-        pub defn!(f); //~ ERROR can't qualify macro invocation with `pub`
-        //~^ HELP try adjusting the macro to put `pub` inside the invocation
-    }
-}
-
-fn main() {
-    bleh::S.f();
-}
diff --git a/src/test/parse-fail/assoc-oddities-3.rs b/src/test/parse-fail/assoc-oddities-3.rs
deleted file mode 100644 (file)
index 0d4f21f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-fn that_odd_parse() {
-    // see assoc-oddities-1 for explanation
-    x + if c { a } else { b }[n]; //~ ERROR expected one of
-}
diff --git a/src/test/parse-fail/pub-item-macro.rs b/src/test/parse-fail/pub-item-macro.rs
new file mode 100644 (file)
index 0000000..8809e9a
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue #14660
+
+macro_rules! priv_x { () => {
+    static x: u32 = 0;
+}}
+
+macro_rules! pub_x { () => {
+    pub priv_x!(); //~ ERROR can't qualify macro invocation with `pub`
+    //~^ HELP try adjusting the macro to put `pub` inside the invocation
+}}
+
+mod foo {
+    pub_x!();
+}
+
+fn main() {
+    let y: u32 = foo::x;
+}
diff --git a/src/test/parse-fail/pub-macro-rules.rs b/src/test/parse-fail/pub-macro-rules.rs
new file mode 100644 (file)
index 0000000..93b992f
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[macro_use] mod bleh {
+    pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation with `pub`
+    //~^ HELP did you mean #[macro_export]?
+        ($n:ident) => (
+            fn $n () -> i32 {
+                1
+            }
+        )
+    }
+
+}
+
+foo!(meh);
+
+fn main() {
+    println!("{}", meh());
+}
diff --git a/src/test/parse-fail/pub-method-macro.rs b/src/test/parse-fail/pub-method-macro.rs
new file mode 100644 (file)
index 0000000..198fa5b
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Issue #18317
+
+mod bleh {
+    macro_rules! defn {
+        ($n:ident) => (
+            fn $n (&self) -> i32 {
+                println!("{}", stringify!($n));
+                1
+            }
+        )
+    }
+
+    #[derive(Copy, Clone)]
+    pub struct S;
+
+    impl S {
+        pub defn!(f); //~ ERROR can't qualify macro invocation with `pub`
+        //~^ HELP try adjusting the macro to put `pub` inside the invocation
+    }
+}
+
+fn main() {
+    bleh::S.f();
+}
index 7c1a45d020b22d61c84a280965eeffd773b31e3e..b64e5778d90336ec989304a8e72110010deca8a7 100644 (file)
@@ -37,34 +37,36 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a>
                                source_str)
 }
 
-fn with_error_checking_parse<T, F>(s: String, f: F) -> PResult<T> where
-    F: FnOnce(&mut Parser) -> PResult<T>,
+fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where
+    F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
 {
-    let ps = ParseSess::new();
     let mut p = string_to_parser(&ps, s);
     let x = f(&mut p);
 
     if ps.span_diagnostic.has_errors() || p.token != token::Eof {
+        if let Err(mut e) = x {
+            e.cancel();
+        }
         return Err(p.fatal("parse error"));
     }
 
     x
 }
 
-fn expr(s: &str) -> PResult<P<ast::Expr>> {
-    with_error_checking_parse(s.to_string(), |p| {
+fn expr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P<ast::Expr>> {
+    with_error_checking_parse(s.to_string(), ps, |p| {
         p.parse_expr()
     })
 }
 
-fn stmt(s: &str) -> PResult<P<ast::Stmt>> {
-    with_error_checking_parse(s.to_string(), |p| {
+fn stmt<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, P<ast::Stmt>> {
+    with_error_checking_parse(s.to_string(), ps, |p| {
         p.parse_stmt().map(|s| s.unwrap())
     })
 }
 
-fn attr(s: &str) -> PResult<ast::Attribute> {
-    with_error_checking_parse(s.to_string(), |p| {
+fn attr<'a>(s: &str, ps: &'a ParseSess) -> PResult<'a, ast::Attribute> {
+    with_error_checking_parse(s.to_string(), ps, |p| {
         p.parse_attribute(true)
     })
 }
@@ -79,29 +81,39 @@ fn str_compare<T, F: Fn(&T) -> String>(e: &str, expected: &[T], actual: &[T], f:
 }
 
 fn check_expr_attrs(es: &str, expected: &[&str]) {
-    let e = expr(es).expect("parse error");
+    let ps = ParseSess::new();
+    let e = expr(es, &ps).expect("parse error");
     let actual = &e.attrs;
     str_compare(es,
-                &expected.iter().map(|r| attr(r).unwrap()).collect::<Vec<_>>(),
+                &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
                 actual.as_attr_slice(),
                 pprust::attribute_to_string);
 }
 
 fn check_stmt_attrs(es: &str, expected: &[&str]) {
-    let e = stmt(es).expect("parse error");
+    let ps = ParseSess::new();
+    let e = stmt(es, &ps).expect("parse error");
     let actual = e.node.attrs();
     str_compare(es,
-                &expected.iter().map(|r| attr(r).unwrap()).collect::<Vec<_>>(),
+                &expected.iter().map(|r| attr(r, &ps).unwrap()).collect::<Vec<_>>(),
                 actual,
                 pprust::attribute_to_string);
 }
 
 fn reject_expr_parse(es: &str) {
-    assert!(expr(es).is_err(), "parser did not reject `{}`", es);
+    let ps = ParseSess::new();
+    match expr(es, &ps) {
+        Ok(_) => panic!("parser did not reject `{}`", es),
+        Err(mut e) => e.cancel(),
+    };
 }
 
 fn reject_stmt_parse(es: &str) {
-    assert!(stmt(es).is_err(), "parser did not reject `{}`", es);
+    let ps = ParseSess::new();
+    match stmt(es, &ps) {
+        Ok(_) => panic!("parser did not reject `{}`", es),
+        Err(mut e) => e.cancel(),
+    };
 }
 
 fn main() {
diff --git a/src/test/run-pass/assoc-oddities-3.rs b/src/test/run-pass/assoc-oddities-3.rs
new file mode 100644 (file)
index 0000000..4913816
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn that_odd_parse(c: bool, n: usize) -> u32 {
+    let x = 2;
+    let a = [1, 2, 3, 4];
+    let b = [5, 6, 7, 7];
+    x + if c { a } else { b }[n]
+}
+
+fn main() {
+    assert_eq!(4, that_odd_parse(true, 1));
+    assert_eq!(8, that_odd_parse(false, 1));
+}
diff --git a/src/test/run-pass/issue-28777.rs b/src/test/run-pass/issue-28777.rs
new file mode 100644 (file)
index 0000000..ea5d4e4
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let v1 = { 1 + {2} * {3} };
+    let v2 =   1 + {2} * {3}  ;
+
+    assert_eq!(7, v1);
+    assert_eq!(7, v2);
+
+    let v3;
+    v3 = { 1 + {2} * {3} };
+    let v4;
+    v4 = 1 + {2} * {3};
+    assert_eq!(7, v3);
+    assert_eq!(7, v4);
+
+    let v5 = { 1 + {2} * 3 };
+    assert_eq!(7, v5);
+
+    let v9 = { 1 + if 1 > 2 {1} else {2} * {3} };
+    assert_eq!(7, v9);
+}
diff --git a/src/test/run-pass/mir_misc_casts.rs b/src/test/run-pass/mir_misc_casts.rs
new file mode 100644 (file)
index 0000000..0799ffe
--- /dev/null
@@ -0,0 +1,349 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(libc, rustc_attrs)]
+
+extern crate libc;
+
+fn func(){}
+
+const STR: &'static str = "hello";
+const BSTR: &'static [u8; 5] = b"hello";
+
+#[rustc_mir]
+fn from_ptr()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, *const ()) {
+    let f = 1_usize as *const libc::FILE;
+    let c1 = f as isize;
+    let c2 = f as usize;
+    let c3 = f as i8;
+    let c4 = f as i16;
+    let c5 = f as i32;
+    let c6 = f as i64;
+    let c7 = f as u8;
+    let c8 = f as u16;
+    let c9 = f as u32;
+    let c10 = f as u64;
+    let c11 = f as *const ();
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11)
+}
+
+#[rustc_mir]
+fn from_1()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1 as isize;
+    let c2 = 1 as usize;
+    let c3 = 1 as i8;
+    let c4 = 1 as i16;
+    let c5 = 1 as i32;
+    let c6 = 1 as i64;
+    let c7 = 1 as u8;
+    let c8 = 1 as u16;
+    let c9 = 1 as u32;
+    let c10 = 1 as u64;
+    let c11 = 1 as f32;
+    let c12 = 1 as f64;
+    let c13 = 1 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1usize()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_usize as isize;
+    let c2 = 1_usize as usize;
+    let c3 = 1_usize as i8;
+    let c4 = 1_usize as i16;
+    let c5 = 1_usize as i32;
+    let c6 = 1_usize as i64;
+    let c7 = 1_usize as u8;
+    let c8 = 1_usize as u16;
+    let c9 = 1_usize as u32;
+    let c10 = 1_usize as u64;
+    let c11 = 1_usize as f32;
+    let c12 = 1_usize as f64;
+    let c13 = 1_usize as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1isize()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_isize as isize;
+    let c2 = 1_isize as usize;
+    let c3 = 1_isize as i8;
+    let c4 = 1_isize as i16;
+    let c5 = 1_isize as i32;
+    let c6 = 1_isize as i64;
+    let c7 = 1_isize as u8;
+    let c8 = 1_isize as u16;
+    let c9 = 1_isize as u32;
+    let c10 = 1_isize as u64;
+    let c11 = 1_isize as f32;
+    let c12 = 1_isize as f64;
+    let c13 = 1_isize as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1u8()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_u8 as isize;
+    let c2 = 1_u8 as usize;
+    let c3 = 1_u8 as i8;
+    let c4 = 1_u8 as i16;
+    let c5 = 1_u8 as i32;
+    let c6 = 1_u8 as i64;
+    let c7 = 1_u8 as u8;
+    let c8 = 1_u8 as u16;
+    let c9 = 1_u8 as u32;
+    let c10 = 1_u8 as u64;
+    let c11 = 1_u8 as f32;
+    let c12 = 1_u8 as f64;
+    let c13 = 1_u8 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1i8()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_i8 as isize;
+    let c2 = 1_i8 as usize;
+    let c3 = 1_i8 as i8;
+    let c4 = 1_i8 as i16;
+    let c5 = 1_i8 as i32;
+    let c6 = 1_i8 as i64;
+    let c7 = 1_i8 as u8;
+    let c8 = 1_i8 as u16;
+    let c9 = 1_i8 as u32;
+    let c10 = 1_i8 as u64;
+    let c11 = 1_i8 as f32;
+    let c12 = 1_i8 as f64;
+    let c13 = 1_i8 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1u16()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_u16 as isize;
+    let c2 = 1_u16 as usize;
+    let c3 = 1_u16 as i8;
+    let c4 = 1_u16 as i16;
+    let c5 = 1_u16 as i32;
+    let c6 = 1_u16 as i64;
+    let c7 = 1_u16 as u8;
+    let c8 = 1_u16 as u16;
+    let c9 = 1_u16 as u32;
+    let c10 = 1_u16 as u64;
+    let c11 = 1_u16 as f32;
+    let c12 = 1_u16 as f64;
+    let c13 = 1_u16 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1i16()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_i16 as isize;
+    let c2 = 1_i16 as usize;
+    let c3 = 1_i16 as i8;
+    let c4 = 1_i16 as i16;
+    let c5 = 1_i16 as i32;
+    let c6 = 1_i16 as i64;
+    let c7 = 1_i16 as u8;
+    let c8 = 1_i16 as u16;
+    let c9 = 1_i16 as u32;
+    let c10 = 1_i16 as u64;
+    let c11 = 1_i16 as f32;
+    let c12 = 1_i16 as f64;
+    let c13 = 1_i16 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1u32()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_u32 as isize;
+    let c2 = 1_u32 as usize;
+    let c3 = 1_u32 as i8;
+    let c4 = 1_u32 as i16;
+    let c5 = 1_u32 as i32;
+    let c6 = 1_u32 as i64;
+    let c7 = 1_u32 as u8;
+    let c8 = 1_u32 as u16;
+    let c9 = 1_u32 as u32;
+    let c10 = 1_u32 as u64;
+    let c11 = 1_u32 as f32;
+    let c12 = 1_u32 as f64;
+    let c13 = 1_u32 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1i32()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_i32 as isize;
+    let c2 = 1_i32 as usize;
+    let c3 = 1_i32 as i8;
+    let c4 = 1_i32 as i16;
+    let c5 = 1_i32 as i32;
+    let c6 = 1_i32 as i64;
+    let c7 = 1_i32 as u8;
+    let c8 = 1_i32 as u16;
+    let c9 = 1_i32 as u32;
+    let c10 = 1_i32 as u64;
+    let c11 = 1_i32 as f32;
+    let c12 = 1_i32 as f64;
+    let c13 = 1_i32 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1u64()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_u64 as isize;
+    let c2 = 1_u64 as usize;
+    let c3 = 1_u64 as i8;
+    let c4 = 1_u64 as i16;
+    let c5 = 1_u64 as i32;
+    let c6 = 1_u64 as i64;
+    let c7 = 1_u64 as u8;
+    let c8 = 1_u64 as u16;
+    let c9 = 1_u64 as u32;
+    let c10 = 1_u64 as u64;
+    let c11 = 1_u64 as f32;
+    let c12 = 1_u64 as f64;
+    let c13 = 1_u64 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_1i64()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, *const libc::FILE) {
+    let c1 = 1_i64 as isize;
+    let c2 = 1_i64 as usize;
+    let c3 = 1_i64 as i8;
+    let c4 = 1_i64 as i16;
+    let c5 = 1_i64 as i32;
+    let c6 = 1_i64 as i64;
+    let c7 = 1_i64 as u8;
+    let c8 = 1_i64 as u16;
+    let c9 = 1_i64 as u32;
+    let c10 = 1_i64 as u64;
+    let c11 = 1_i64 as f32;
+    let c12 = 1_i64 as f64;
+    let c13 = 1_i64 as *const libc::FILE;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13)
+}
+
+#[rustc_mir]
+fn from_bool()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64) {
+    let c1 = true as isize;
+    let c2 = true as usize;
+    let c3 = true as i8;
+    let c4 = true as i16;
+    let c5 = true as i32;
+    let c6 = true as i64;
+    let c7 = true as u8;
+    let c8 = true as u16;
+    let c9 = true as u32;
+    let c10 = true as u64;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10)
+}
+
+#[rustc_mir]
+fn from_1f32()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64) {
+    let c1 = 1.0_f32 as isize;
+    let c2 = 1.0_f32 as usize;
+    let c3 = 1.0_f32 as i8;
+    let c4 = 1.0_f32 as i16;
+    let c5 = 1.0_f32 as i32;
+    let c6 = 1.0_f32 as i64;
+    let c7 = 1.0_f32 as u8;
+    let c8 = 1.0_f32 as u16;
+    let c9 = 1.0_f32 as u32;
+    let c10 = 1.0_f32 as u64;
+    let c11 = 1.0_f32 as f32;
+    let c12 = 1.0_f32 as f64;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
+}
+
+#[rustc_mir]
+fn from_1f64()
+-> (isize, usize, i8, i16, i32, i64, u8, u16, u32, u64, f32, f64) {
+    let c1 = 1.0f64 as isize;
+    let c2 = 1.0f64 as usize;
+    let c3 = 1.0f64 as i8;
+    let c4 = 1.0f64 as i16;
+    let c5 = 1.0f64 as i32;
+    let c6 = 1.0f64 as i64;
+    let c7 = 1.0f64 as u8;
+    let c8 = 1.0f64 as u16;
+    let c9 = 1.0f64 as u32;
+    let c10 = 1.0f64 as u64;
+    let c11 = 1.0f64 as f32;
+    let c12 = 1.0f64 as f64;
+    (c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12)
+}
+
+#[rustc_mir]
+fn other_casts()
+-> (*const u8, *const isize, *const u8, *const u8) {
+    let c1 = func as *const u8;
+    let c2 = c1 as *const isize;
+
+    let r = &42u32;
+    let _ = r as *const u32;
+
+    // fat-ptr -> fat-ptr -> fat-raw-ptr -> thin-ptr
+    let c3 = STR as &str as *const str as *const u8;
+
+    let c4 = BSTR as *const [u8] as *const [u16] as *const u8;
+    (c1, c2, c3, c4)
+}
+
+pub fn assert_eq_13(l: (isize, usize, i8, i16, i32, i64, u8,
+                        u16, u32, u64, f32, f64, *const libc::FILE),
+                    r: (isize, usize, i8, i16, i32, i64, u8,
+                        u16, u32, u64, f32, f64, *const libc::FILE)) -> bool {
+    let (l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13) = l;
+    let (r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13) = r;
+    l1 == r1 && l2 == r2 && l3 == r3 && l4 == r4 && l5 == r5 && l6 == r6 && l7 == r7 &&
+    l8 == r8 && l9 == r9 && l10 == r10 && l11 == r11 && l12 == r12 && l13 == r13
+}
+
+
+pub fn main() {
+    let f = 1_usize as *const libc::FILE;
+    let t13 = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, f);
+    let t12 = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
+    assert_eq_13(from_1(), t13);
+    assert_eq_13(from_1usize(), t13);
+    assert_eq_13(from_1isize(), t13);
+    assert_eq_13(from_1u8(), t13);
+    assert_eq_13(from_1i8(), t13);
+    assert_eq_13(from_1u16(), t13);
+    assert_eq_13(from_1i16(), t13);
+    assert_eq_13(from_1u32(), t13);
+    assert_eq_13(from_1i32(), t13);
+    assert_eq_13(from_1u64(), t13);
+    assert_eq_13(from_1i64(), t13);
+    assert_eq!(from_1f32(), t12);
+    assert_eq!(from_1f64(), t12);
+
+    assert_eq!(from_ptr(), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 as *const ()));
+    assert_eq!(from_bool(), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
+
+    assert_eq!(other_casts(), (func as *const u8, func as *const isize,
+                               STR as *const str as *const u8, BSTR as *const [u8] as *const u8));
+}