]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #35393 - GuillaumeGomez:err_codes2, r=jonathandturner
authorbors <bors@rust-lang.org>
Sat, 6 Aug 2016 19:29:28 +0000 (12:29 -0700)
committerGitHub <noreply@github.com>
Sat, 6 Aug 2016 19:29:28 +0000 (12:29 -0700)
Err codes

r? @jonathandturner

123 files changed:
man/rustc.1
man/rustdoc.1
src/doc/book/guessing-game.md
src/doc/book/the-stack-and-the-heap.md
src/doc/reference.md
src/libcollections/range.rs
src/libcollections/vec.rs
src/libcore/marker.rs
src/libcore/raw.rs
src/librustc/hir/mod.rs
src/librustc/middle/astconv_util.rs
src/librustc/middle/entry.rs
src/librustc/traits/object_safety.rs
src/librustc/ty/util.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_const_eval/check_match.rs
src/librustc_const_eval/eval.rs
src/librustc_passes/ast_validation.rs
src/librustc_passes/consts.rs
src/librustc_passes/diagnostics.rs
src/librustc_passes/lib.rs
src/librustc_passes/loops.rs
src/librustc_passes/no_asm.rs
src/librustc_passes/static_recursion.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/diagnostics.rs
src/librustc_resolve/lib.rs
src/librustc_resolve/resolve_imports.rs
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/intrinsic.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/autoderef.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/lib.rs
src/libstd/ffi/c_str.rs
src/libstd/fs.rs
src/libstd/io/error.rs
src/libstd/io/mod.rs
src/libstd/io/stdio.rs
src/libstd/net/mod.rs
src/libstd/net/tcp.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/windows/fs.rs
src/libstd/thread/mod.rs
src/test/compile-fail/E0055.rs
src/test/compile-fail/E0060.rs
src/test/compile-fail/E0061.rs
src/test/compile-fail/E0062.rs
src/test/compile-fail/E0069.rs
src/test/compile-fail/E0071.rs
src/test/compile-fail/E0079.rs
src/test/compile-fail/E0106.rs
src/test/compile-fail/E0107.rs
src/test/compile-fail/E0109.rs
src/test/compile-fail/E0110.rs
src/test/compile-fail/E0119.rs
src/test/compile-fail/E0120.rs
src/test/compile-fail/E0124.rs
src/test/compile-fail/E0132.rs
src/test/compile-fail/E0137.rs
src/test/compile-fail/E0166.rs
src/test/compile-fail/E0172.rs
src/test/compile-fail/E0178.rs
src/test/compile-fail/E0207.rs
src/test/compile-fail/E0229.rs
src/test/compile-fail/E0253.rs [new file with mode: 0644]
src/test/compile-fail/E0254.rs [new file with mode: 0644]
src/test/compile-fail/E0255.rs [new file with mode: 0644]
src/test/compile-fail/E0259.rs [new file with mode: 0644]
src/test/compile-fail/E0260.rs [new file with mode: 0644]
src/test/compile-fail/E0261.rs [new file with mode: 0644]
src/test/compile-fail/E0262.rs [new file with mode: 0644]
src/test/compile-fail/E0263.rs [new file with mode: 0644]
src/test/compile-fail/E0264.rs [new file with mode: 0644]
src/test/compile-fail/E0267.rs [new file with mode: 0644]
src/test/compile-fail/E0268.rs [new file with mode: 0644]
src/test/compile-fail/E0306.rs
src/test/compile-fail/bad-bang-ann-3.rs
src/test/compile-fail/borrowck/borrowck-escaping-closure-error-1.rs
src/test/compile-fail/borrowck/borrowck-escaping-closure-error-2.rs
src/test/compile-fail/const-fn-mismatch.rs
src/test/compile-fail/const-integer-bool-ops.rs
src/test/compile-fail/const-pattern-irrefutable.rs
src/test/compile-fail/impl-unused-rps-in-assoc-type.rs
src/test/compile-fail/impl-wrong-item-for-trait.rs
src/test/compile-fail/issue-15524.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-22886.rs
src/test/compile-fail/issue-23543.rs
src/test/compile-fail/issue-23544.rs
src/test/compile-fail/issue-27008.rs
src/test/compile-fail/issue-28568.rs
src/test/compile-fail/issue-3044.rs
src/test/compile-fail/issue-31221.rs
src/test/compile-fail/issue-35139.rs
src/test/compile-fail/issue-3907.rs
src/test/compile-fail/issue-4335.rs
src/test/compile-fail/issue-4935.rs
src/test/compile-fail/issue-5035.rs
src/test/compile-fail/issue-5239-1.rs
src/test/compile-fail/lint-unused-imports.rs
src/test/compile-fail/method-call-err-msg.rs
src/test/compile-fail/non-exhaustive-pattern-witness.rs
src/test/compile-fail/not-enough-arguments.rs
src/test/compile-fail/overloaded-calls-bad.rs
src/test/compile-fail/region-borrow-params-issue-29793-small.rs
src/test/compile-fail/regions-nested-fns-2.rs
src/test/compile-fail/repeat_count.rs
src/test/compile-fail/struct-fields-decl-dupe.rs
src/test/compile-fail/trait-as-struct-constructor.rs
src/test/compile-fail/variadic-ffi-3.rs
src/test/run-pass/auxiliary/typeid-intrinsic-aux1.rs
src/test/run-pass/auxiliary/typeid-intrinsic-aux2.rs
src/test/run-pass/type-id-higher-rank-2.rs [new file with mode: 0644]
src/test/run-pass/type-id-higher-rank.rs
src/test/run-pass/typeid-intrinsic.rs
src/test/ui/codemap_tests/two_files.stderr
src/tools/cargotest/main.rs

index fa61afd3be582215f26ea7262452c8c177e56f5b..edbc6cea0266499c582036320c4b954489dd328f 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTC "1" "August 2015" "rustc 1.2.0" "User Commands"
+.TH RUSTC "1" "August 2016" "rustc 1.12.0" "User Commands"
 .SH NAME
 rustc \- The Rust compiler
 .SH SYNOPSIS
@@ -299,7 +299,7 @@ To build an executable with debug info:
 See https://github.com/rust\-lang/rust/issues for issues.
 
 .SH "AUTHOR"
-See \fIAUTHORS.txt\fR in the Rust source distribution.
+See https://github.com/rust\-lang/rust/graphs/contributors or use `git log --all --format='%cN <%cE>' | sort -u` in the rust source distribution.
 
 .SH "COPYRIGHT"
 This work is dual\[hy]licensed under Apache\ 2.0 and MIT terms.
index ae14c9d78287f3833965b734fb4a846c4b163155..3fb5757f4ff24be21f2cac4ea3312fef2d257b23 100644 (file)
@@ -1,4 +1,4 @@
-.TH RUSTDOC "1" "August 2015" "rustdoc 1.2.0" "User Commands"
+.TH RUSTDOC "1" "August 2016" "rustdoc 1.12.0" "User Commands"
 .SH NAME
 rustdoc \- generate documentation from Rust source code
 .SH SYNOPSIS
index 6ce75efd1031d83ce7d372081090542a6091bf9b..22cf6068e4d5a20f79fa61075ed31fa23e10b5b8 100644 (file)
@@ -365,7 +365,7 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`,
 meaning "anything compatible with 0.3.0".
 If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"`
 (note the two equal signs).
-And if we wanted to use the latest version we could use `*`.
+And if we wanted to use the latest version we could use `rand="*"`.
 We could also use a range of versions.
 [Cargo’s documentation][cargodoc] contains more details.
 
index a1f6a065a252bd93d6dabd58e4064b03be525702..aee45299cf22d77369fde008fc9b2cba292f7058 100644 (file)
@@ -26,6 +26,8 @@ The stack is very fast, and is where memory is allocated in Rust by default.
 But the allocation is local to a function call, and is limited in size. The
 heap, on the other hand, is slower, and is explicitly allocated by your
 program. But it’s effectively unlimited in size, and is globally accessible.
+Note this meaning of heap, which allocates arbitrary-sized blocks of memory in arbitrary
+order, is quite different from the heap data structure.  
 
 # The Stack
 
index a461023642afd6130df80eaf0b95de7c0cd32021..f4ffe5774d27cd0f3dd121f42bb89255e0e11da6 100644 (file)
@@ -3049,7 +3049,8 @@ as
 == != < > <= >=
 &&
 ||
-= ..
+.. ...
+=
 ```
 
 Operators at the same precedence level are evaluated left-to-right. [Unary
index 4e39191b472ee8f6a85ec7ea67a21fbc0745c6d7..1badc72aed07c1a9d21eab781c59fd6ef5fed9f9 100644 (file)
@@ -23,6 +23,22 @@ pub trait RangeArgument<T> {
     /// Start index (inclusive)
     ///
     /// Return start value if present, else `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections)]
+    /// #![feature(collections_range)]
+    ///
+    /// extern crate collections;
+    ///
+    /// # fn main() {
+    /// use collections::range::RangeArgument;
+    ///
+    /// assert_eq!((..10).start(), None);
+    /// assert_eq!((3..10).start(), Some(&3));
+    /// # }
+    /// ```
     fn start(&self) -> Option<&T> {
         None
     }
@@ -30,6 +46,22 @@ fn start(&self) -> Option<&T> {
     /// End index (exclusive)
     ///
     /// Return end value if present, else `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections)]
+    /// #![feature(collections_range)]
+    ///
+    /// extern crate collections;
+    ///
+    /// # fn main() {
+    /// use collections::range::RangeArgument;
+    ///
+    /// assert_eq!((3..).end(), None);
+    /// assert_eq!((3..10).end(), Some(&10));
+    /// # }
+    /// ```
     fn end(&self) -> Option<&T> {
         None
     }
index 275f38b2f787d469a8596be0b0d6bcce64fc3b19..8b4fce158de4645d60b1557bde684283d0d21509 100644 (file)
@@ -476,6 +476,25 @@ pub fn shrink_to_fit(&mut self) {
     /// Note that this will drop any excess capacity. Calling this and
     /// converting back to a vector with `into_vec()` is equivalent to calling
     /// `shrink_to_fit()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = vec![1, 2, 3];
+    ///
+    /// let slice = v.into_boxed_slice();
+    /// ```
+    ///
+    /// Any excess capacity is removed:
+    ///
+    /// ```
+    /// let mut vec = Vec::with_capacity(10);
+    /// vec.extend([1, 2, 3].iter().cloned());
+    ///
+    /// assert_eq!(vec.capacity(), 10);
+    /// let slice = vec.into_boxed_slice();
+    /// assert_eq!(slice.into_vec().capacity(), 3);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_boxed_slice(mut self) -> Box<[T]> {
         unsafe {
index c18d230be31af9db758feb8e6f6de9f439d80ba3..894982abaa939879f58e410e03c595ddf17cb684 100644 (file)
@@ -144,6 +144,12 @@ pub trait Unsize<T: ?Sized> {
 /// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
 /// managing some resource besides its own `size_of::<T>()` bytes.
 ///
+/// ## What if I derive `Copy` on a type that can't?
+///
+/// If you try to derive `Copy` on a struct or enum, you will get a compile-time error.
+/// Specifically, with structs you'll get [E0204](https://doc.rust-lang.org/error-index.html#E0204)
+/// and with enums you'll get [E0205](https://doc.rust-lang.org/error-index.html#E0205).
+///
 /// ## When should my type be `Copy`?
 ///
 /// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
index 6b2122451db8fbf164190d84d485a09067229113..a7d0d3899b181d2dd3add95f7bbb46c2bb83ced3 100644 (file)
 /// only designed to be used by unsafe code that needs to manipulate
 /// the low-level details.
 ///
-/// There is no `Repr` implementation for `TraitObject` because there
-/// is no way to refer to all trait objects generically, so the only
+/// There is no way to refer to all trait objects generically, so the only
 /// way to create values of this type is with functions like
-/// `std::mem::transmute`. Similarly, the only way to create a true
+/// [`std::mem::transmute`][transmute]. Similarly, the only way to create a true
 /// trait object from a `TraitObject` value is with `transmute`.
 ///
+/// [transmute]: ../intrinsics/fn.transmute.html
+///
 /// Synthesizing a trait object with mismatched types—one where the
 /// vtable does not correspond to the type of the value to which the
 /// data pointer points—is highly likely to lead to undefined
 /// ```
 /// #![feature(raw)]
 ///
-/// use std::mem;
-/// use std::raw;
+/// use std::{mem, raw};
 ///
 /// // an example trait
 /// trait Foo {
 ///     fn bar(&self) -> i32;
 /// }
+///
 /// impl Foo for i32 {
 ///     fn bar(&self) -> i32 {
 ///          *self + 1
@@ -74,7 +75,6 @@
 /// // the data pointer is the address of `value`
 /// assert_eq!(raw_object.data as *const i32, &value as *const _);
 ///
-///
 /// let other_value: i32 = 456;
 ///
 /// // construct a new object, pointing to a different `i32`, being
 /// let synthesized: &Foo = unsafe {
 ///      mem::transmute(raw::TraitObject {
 ///          data: &other_value as *const _ as *mut (),
-///          vtable: raw_object.vtable
+///          vtable: raw_object.vtable,
 ///      })
 /// };
 ///
-/// // it should work just like we constructed a trait object out of
+/// // it should work just as if we had constructed a trait object out of
 /// // `other_value` directly
 /// assert_eq!(synthesized.bar(), 457);
 /// ```
index 20bf4f7d3edbb68dc88517338e2be124937d8642..9212fda6502532e1ab5fc75e466fac752334ad14 100644 (file)
@@ -36,7 +36,7 @@
 use hir::def_id::DefId;
 use util::nodemap::{NodeMap, FnvHashSet};
 
-use syntax_pos::{mk_sp, Span, ExpnId};
+use syntax_pos::{BytePos, mk_sp, Span, ExpnId};
 use syntax::codemap::{self, respan, Spanned};
 use syntax::abi::Abi;
 use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
@@ -326,6 +326,38 @@ pub fn is_type_parameterized(&self) -> bool {
     pub fn is_parameterized(&self) -> bool {
         self.is_lt_parameterized() || self.is_type_parameterized()
     }
+
+    // Does return a span which includes lifetimes and type parameters,
+    // not where clause.
+    pub fn span(&self) -> Option<Span> {
+        if !self.is_parameterized() {
+            None
+        } else {
+            let mut span: Option<Span> = None;
+            for lifetime in self.lifetimes.iter() {
+                if let Some(ref mut span) = span {
+                    let life_span = lifetime.lifetime.span;
+                    span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi };
+                    span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo };
+                } else {
+                    span = Some(lifetime.lifetime.span.clone());
+                }
+            }
+            for ty_param in self.ty_params.iter() {
+                if let Some(ref mut span) = span {
+                    span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo };
+                    span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi };
+                } else {
+                    span = Some(ty_param.span.clone());
+                }
+            }
+            if let Some(ref mut span) = span {
+                span.lo = span.lo - BytePos(1);
+                span.hi = span.hi + BytePos(1);
+            }
+            span
+        }
+    }
 }
 
 /// A `where` clause in a definition
index e856eb84ff2c3a93f33259acb9504d9dcb793fe7..86422835c8cbd0b8d5f1583827eec4503874b17a 100644 (file)
@@ -24,13 +24,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
         for segment in segments {
             for typ in segment.parameters.types() {
-                span_err!(self.sess, typ.span, E0109,
-                          "type parameters are not allowed on this type");
+                struct_span_err!(self.sess, typ.span, E0109,
+                                 "type parameters are not allowed on this type")
+                    .span_label(typ.span, &format!("type parameter not allowed"))
+                    .emit();
                 break;
             }
             for lifetime in segment.parameters.lifetimes() {
-                span_err!(self.sess, lifetime.span, E0110,
-                          "lifetime parameters are not allowed on this type");
+                struct_span_err!(self.sess, lifetime.span, E0110,
+                                 "lifetime parameters are not allowed on this type")
+                    .span_label(lifetime.span,
+                                &format!("lifetime parameter not allowed on this type"))
+                    .emit();
                 break;
             }
             for binding in segment.parameters.bindings() {
@@ -42,8 +47,9 @@ pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
 
     pub fn prohibit_projection(self, span: Span)
     {
-        span_err!(self.sess, span, E0229,
-                  "associated type bindings are not allowed here");
+        let mut err = struct_span_err!(self.sess, span, E0229,
+                                       "associated type bindings are not allowed here");
+        err.span_label(span, &format!("associate type not allowed here")).emit();
     }
 
     pub fn prim_ty_to_ty(self,
index 23a261400ed076690f3cddaaf93d789e916947eb..0a363fddd53124f6d9cc7218e88d552b94e1469b 100644 (file)
@@ -121,8 +121,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
             if ctxt.attr_main_fn.is_none() {
                 ctxt.attr_main_fn = Some((item.id, item.span));
             } else {
-                span_err!(ctxt.session, item.span, E0137,
-                          "multiple functions with a #[main] attribute");
+                struct_span_err!(ctxt.session, item.span, E0137,
+                          "multiple functions with a #[main] attribute")
+                .span_label(item.span, &format!("additional #[main] function"))
+                .span_label(ctxt.attr_main_fn.unwrap().1, &format!("first #[main] function"))
+                .emit();
             }
         },
         EntryPointType::Start => {
index ffa1530a14e2644043079ab2690a622020e39ec8..93c6dd09e07b83d2c450f2b97f223b6d8c828b29 100644 (file)
@@ -17,7 +17,6 @@
 //!   - not reference the erased type `Self` except for in this receiver;
 //!   - not have generic type parameters
 
-use super::supertraits;
 use super::elaborate_predicates;
 
 use hir::def_id::DefId;
index fadf36471555b7f83a151bffd55c7c6fa020a915..d9ffe36ea47fbe3610cb927d346cdf4d7a3008d0 100644 (file)
@@ -10,7 +10,6 @@
 
 //! misc. type-system utilities too small to deserve their own file
 
-use hir::svh::Svh;
 use hir::def_id::DefId;
 use ty::subst;
 use infer::InferCtxt;
@@ -18,6 +17,7 @@
 use traits::{self, ProjectionMode};
 use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable};
 use ty::{Disr, ParameterEnvironment};
+use ty::fold::TypeVisitor;
 use ty::layout::{Layout, LayoutError};
 use ty::TypeVariants::*;
 
@@ -25,6 +25,7 @@
 
 use std::cmp;
 use std::hash::{Hash, SipHasher, Hasher};
+use std::intrinsics;
 use syntax::ast::{self, Name};
 use syntax::attr::{self, SignedInt, UnsignedInt};
 use syntax_pos::Span;
@@ -350,148 +351,13 @@ pub fn required_region_bounds(self,
 
     /// Creates a hash of the type `Ty` which will be the same no matter what crate
     /// context it's calculated within. This is used by the `type_id` intrinsic.
-    pub fn hash_crate_independent(self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
-        let mut state = SipHasher::new();
-        helper(self, ty, svh, &mut state);
-        return state.finish();
-
-        fn helper<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                                  ty: Ty<'tcx>, svh: &Svh,
-                                  state: &mut SipHasher) {
-            macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
-            macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
-
-            let region = |state: &mut SipHasher, r: ty::Region| {
-                match r {
-                    ty::ReStatic | ty::ReErased => {}
-                    ty::ReLateBound(db, ty::BrAnon(i)) => {
-                        db.hash(state);
-                        i.hash(state);
-                    }
-                    ty::ReEmpty |
-                    ty::ReEarlyBound(..) |
-                    ty::ReLateBound(..) |
-                    ty::ReFree(..) |
-                    ty::ReScope(..) |
-                    ty::ReVar(..) |
-                    ty::ReSkolemized(..) => {
-                        bug!("unexpected region found when hashing a type")
-                    }
-                }
-            };
-            let did = |state: &mut SipHasher, did: DefId| {
-                let h = if did.is_local() {
-                    svh.clone()
-                } else {
-                    tcx.sess.cstore.crate_hash(did.krate)
-                };
-                h.hash(state);
-                did.index.hash(state);
-            };
-            let mt = |state: &mut SipHasher, mt: TypeAndMut| {
-                mt.mutbl.hash(state);
-            };
-            let fn_sig = |state: &mut SipHasher, sig: &ty::Binder<ty::FnSig<'tcx>>| {
-                let sig = tcx.anonymize_late_bound_regions(sig).0;
-                for a in &sig.inputs { helper(tcx, *a, svh, state); }
-                if let ty::FnConverging(output) = sig.output {
-                    helper(tcx, output, svh, state);
-                }
-            };
-            ty.maybe_walk(|ty| {
-                match ty.sty {
-                    TyBool => byte!(2),
-                    TyChar => byte!(3),
-                    TyInt(i) => {
-                        byte!(4);
-                        hash!(i);
-                    }
-                    TyUint(u) => {
-                        byte!(5);
-                        hash!(u);
-                    }
-                    TyFloat(f) => {
-                        byte!(6);
-                        hash!(f);
-                    }
-                    TyStr => {
-                        byte!(7);
-                    }
-                    TyEnum(d, _) => {
-                        byte!(8);
-                        did(state, d.did);
-                    }
-                    TyBox(_) => {
-                        byte!(9);
-                    }
-                    TyArray(_, n) => {
-                        byte!(10);
-                        n.hash(state);
-                    }
-                    TySlice(_) => {
-                        byte!(11);
-                    }
-                    TyRawPtr(m) => {
-                        byte!(12);
-                        mt(state, m);
-                    }
-                    TyRef(r, m) => {
-                        byte!(13);
-                        region(state, *r);
-                        mt(state, m);
-                    }
-                    TyFnDef(def_id, _, _) => {
-                        byte!(14);
-                        hash!(def_id);
-                    }
-                    TyFnPtr(ref b) => {
-                        byte!(15);
-                        hash!(b.unsafety);
-                        hash!(b.abi);
-                        fn_sig(state, &b.sig);
-                        return false;
-                    }
-                    TyTrait(ref data) => {
-                        byte!(17);
-                        did(state, data.principal_def_id());
-                        hash!(data.bounds);
-
-                        let principal = tcx.anonymize_late_bound_regions(&data.principal).0;
-                        for subty in &principal.substs.types {
-                            helper(tcx, subty, svh, state);
-                        }
-
-                        return false;
-                    }
-                    TyStruct(d, _) => {
-                        byte!(18);
-                        did(state, d.did);
-                    }
-                    TyTuple(ref inner) => {
-                        byte!(19);
-                        hash!(inner.len());
-                    }
-                    TyParam(p) => {
-                        byte!(20);
-                        hash!(p.space);
-                        hash!(p.idx);
-                        hash!(p.name.as_str());
-                    }
-                    TyInfer(_) => bug!(),
-                    TyError => byte!(21),
-                    TyClosure(d, _) => {
-                        byte!(22);
-                        did(state, d);
-                    }
-                    TyProjection(ref data) => {
-                        byte!(23);
-                        did(state, data.trait_ref.def_id);
-                        hash!(data.item_name.as_str());
-                    }
-                }
-                true
-            });
-        }
+    pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
+        let mut hasher = TypeIdHasher {
+            tcx: self,
+            state: SipHasher::new()
+        };
+        hasher.visit_ty(ty);
+        hasher.state.finish()
     }
 
     /// Returns true if this ADT is a dtorck type.
@@ -525,6 +391,143 @@ pub fn is_adt_dtorck(self, adt: ty::AdtDef) -> bool {
     }
 }
 
+struct TypeIdHasher<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+    state: SipHasher
+}
+
+impl<'a, 'gcx, 'tcx> TypeIdHasher<'a, 'gcx, 'tcx> {
+    fn hash<T: Hash>(&mut self, x: T) {
+        x.hash(&mut self.state);
+    }
+
+    fn hash_discriminant_u8<T>(&mut self, x: &T) {
+        let v = unsafe {
+            intrinsics::discriminant_value(x)
+        };
+        let b = v as u8;
+        assert_eq!(v, b as u64);
+        self.hash(b)
+    }
+
+    fn def_id(&mut self, did: DefId) {
+        // Hash the crate identification information.
+        let name = self.tcx.crate_name(did.krate);
+        let disambiguator = self.tcx.crate_disambiguator(did.krate);
+        self.hash((name, disambiguator));
+
+        // Hash the item path within that crate.
+        // FIXME(#35379) This should use a deterministic
+        // DefPath hashing mechanism, not the DefIndex.
+        self.hash(did.index);
+    }
+}
+
+impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
+    fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+        // Distinguish between the Ty variants uniformly.
+        self.hash_discriminant_u8(&ty.sty);
+
+        match ty.sty {
+            TyInt(i) => self.hash(i),
+            TyUint(u) => self.hash(u),
+            TyFloat(f) => self.hash(f),
+            TyStruct(d, _) |
+            TyEnum(d, _) => self.def_id(d.did),
+            TyArray(_, n) => self.hash(n),
+            TyRawPtr(m) |
+            TyRef(_, m) => self.hash(m.mutbl),
+            TyClosure(def_id, _) |
+            TyFnDef(def_id, _, _) => self.def_id(def_id),
+            TyFnPtr(f) => {
+                self.hash(f.unsafety);
+                self.hash(f.abi);
+                self.hash(f.sig.variadic());
+            }
+            TyTrait(ref data) => {
+                // Trait objects have a list of projection bounds
+                // that are not guaranteed to be sorted in an order
+                // that gets preserved across crates, so we need
+                // to sort them again by the name, in string form.
+
+                // Hash the whole principal trait ref.
+                self.def_id(data.principal_def_id());
+                data.principal.visit_with(self);
+
+                // Hash region and builtin bounds.
+                data.bounds.region_bound.visit_with(self);
+                self.hash(data.bounds.builtin_bounds);
+
+                // Only projection bounds are left, sort and hash them.
+                let mut projection_bounds: Vec<_> = data.bounds.projection_bounds
+                                                        .iter()
+                                                        .map(|b| (b.item_name().as_str(), b))
+                                                        .collect();
+                projection_bounds.sort_by_key(|&(ref name, _)| name.clone());
+                for (name, bound) in projection_bounds {
+                    self.def_id(bound.0.projection_ty.trait_ref.def_id);
+                    self.hash(name);
+                    bound.visit_with(self);
+                }
+
+                // Bypass super_visit_with, we've visited everything.
+                return false;
+            }
+            TyTuple(tys) => {
+                self.hash(tys.len());
+            }
+            TyParam(p) => {
+                self.hash(p.space);
+                self.hash(p.idx);
+                self.hash(p.name.as_str());
+            }
+            TyProjection(ref data) => {
+                self.def_id(data.trait_ref.def_id);
+                self.hash(data.item_name.as_str());
+            }
+            TyBool |
+            TyChar |
+            TyStr |
+            TyBox(_) |
+            TySlice(_) |
+            TyError => {}
+            TyInfer(_) => bug!()
+        }
+
+        ty.super_visit_with(self)
+    }
+
+    fn visit_region(&mut self, r: ty::Region) -> bool {
+        match r {
+            ty::ReStatic | ty::ReErased => {
+                self.hash::<u32>(0);
+            }
+            ty::ReLateBound(db, ty::BrAnon(i)) => {
+                assert!(db.depth > 0);
+                self.hash::<u32>(db.depth);
+                self.hash(i);
+            }
+            ty::ReEmpty |
+            ty::ReEarlyBound(..) |
+            ty::ReLateBound(..) |
+            ty::ReFree(..) |
+            ty::ReScope(..) |
+            ty::ReVar(..) |
+            ty::ReSkolemized(..) => {
+                bug!("unexpected region found when hashing a type")
+            }
+        }
+        false
+    }
+
+    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, x: &ty::Binder<T>) -> bool {
+        // Anonymize late-bound regions so that, for example:
+        // `for<'a, b> fn(&'a &'b T)` and `for<'a, b> fn(&'b &'a T)`
+        // result in the same TypeId (the two types are equivalent).
+        self.tcx.anonymize_late_bound_regions(x).super_visit_with(self)
+    }
+}
+
 impl<'a, 'tcx> ty::TyS<'tcx> {
     fn impls_bound(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                    param_env: &ParameterEnvironment<'tcx>,
index 1fe47cd4853876ae544d568f32e65ac0481ffab2..9115fd42be870e02aec87792b163d02ca5657720 100644 (file)
@@ -942,9 +942,12 @@ fn report_out_of_scope_escaping_closure_capture(&self,
                           but it borrows {}, \
                           which is owned by the current function",
                          cmt_path_or_string)
-            .span_note(capture_span,
+            .span_label(capture_span,
                        &format!("{} is borrowed here",
                                 cmt_path_or_string))
+            .span_label(err.span,
+                       &format!("may outlive borrowed value {}",
+                                cmt_path_or_string))
             .span_suggestion(err.span,
                              &format!("to force the closure to take ownership of {} \
                                        (and any other referenced variables), \
index d3952de2fbe30eb1088c6cbaf1df0515d5264419..2fe4ae627c1dc7be3ea12168369e8df3cb17939f 100644 (file)
@@ -335,6 +335,7 @@ fn check_arms(cx: &MatchCheckCtxt,
                         hir::MatchSource::Normal => {
                             let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001,
                                                            "unreachable pattern");
+                            err.span_label(pat.span, &format!("this is an unreachable pattern"));
                             // if we had a catchall pattern, hint at that
                             for row in &seen.0 {
                                 if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) {
@@ -423,10 +424,15 @@ fn check_exhaustive<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>,
                             format!("`{}` and {} more", head.join("`, `"), tail.len())
                         }
                     };
-                    span_err!(cx.tcx.sess, sp, E0004,
+
+                    let label_text = match pattern_strings.len(){
+                        1 => format!("pattern {} not covered", joined_patterns),
+                        _ => format!("patterns {} not covered", joined_patterns)
+                    };
+                    struct_span_err!(cx.tcx.sess, sp, E0004,
                         "non-exhaustive patterns: {} not covered",
                         joined_patterns
-                    );
+                    ).span_label(sp, &label_text).emit();
                 },
             }
         }
index d424b57c938411168550c1e229c9ff022fca94bf..43d9725baaf004e9e970fb466452d714186a1c87 100644 (file)
@@ -1337,10 +1337,13 @@ pub fn eval_length<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             Ok(val as usize)
         },
         Ok(const_val) => {
-            span_err!(tcx.sess, count_expr.span, E0306,
-                      "expected usize for {}, found {}",
-                      reason,
-                      const_val.description());
+            struct_span_err!(tcx.sess, count_expr.span, E0306,
+                             "expected `usize` for {}, found {}",
+                             reason,
+                             const_val.description())
+                .span_label(count_expr.span, &format!("expected `usize`"))
+                .emit();
+
             Err(ErrorReported)
         }
         Err(err) => {
index d2cf48eddebac2de42b84571262075df045d4af7..91d2500564fd3b7d246f406fcb8d117fb0fede0b 100644 (file)
@@ -38,16 +38,18 @@ fn check_label(&self, label: Ident, span: Span, id: NodeId) {
             self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
         }
         if label.name.as_str() == "'_" {
-            self.session.add_lint(
-                lint::builtin::LIFETIME_UNDERSCORE, id, span,
-                format!("invalid label name `{}`", label.name)
-            );
+            self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
+                                  id,
+                                  span,
+                                  format!("invalid label name `{}`", label.name));
         }
     }
 
     fn invalid_visibility(&self, vis: &Visibility, span: Span, note: Option<&str>) {
         if vis != &Visibility::Inherited {
-            let mut err = struct_span_err!(self.session, span, E0449,
+            let mut err = struct_span_err!(self.session,
+                                           span,
+                                           E0449,
                                            "unnecessary visibility qualifier");
             if let Some(note) = note {
                 err.span_note(span, note);
@@ -71,10 +73,10 @@ fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err:
 impl<'a> Visitor for AstValidator<'a> {
     fn visit_lifetime(&mut self, lt: &Lifetime) {
         if lt.name.as_str() == "'_" {
-            self.session.add_lint(
-                lint::builtin::LIFETIME_UNDERSCORE, lt.id, lt.span,
-                format!("invalid lifetime name `{}`", lt.name)
-            );
+            self.session.add_lint(lint::builtin::LIFETIME_UNDERSCORE,
+                                  lt.id,
+                                  lt.span,
+                                  format!("invalid lifetime name `{}`", lt.name));
         }
 
         visit::walk_lifetime(self, lt)
@@ -82,9 +84,12 @@ fn visit_lifetime(&mut self, lt: &Lifetime) {
 
     fn visit_expr(&mut self, expr: &Expr) {
         match expr.node {
-            ExprKind::While(_, _, Some(ident)) | ExprKind::Loop(_, Some(ident)) |
-            ExprKind::WhileLet(_, _, _, Some(ident)) | ExprKind::ForLoop(_, _, _, Some(ident)) |
-            ExprKind::Break(Some(ident)) | ExprKind::Continue(Some(ident)) => {
+            ExprKind::While(_, _, Some(ident)) |
+            ExprKind::Loop(_, Some(ident)) |
+            ExprKind::WhileLet(_, _, _, Some(ident)) |
+            ExprKind::ForLoop(_, _, _, Some(ident)) |
+            ExprKind::Break(Some(ident)) |
+            ExprKind::Continue(Some(ident)) => {
                 self.check_label(ident.node, ident.span, expr.id);
             }
             _ => {}
@@ -97,10 +102,13 @@ fn visit_ty(&mut self, ty: &Ty) {
         match ty.node {
             TyKind::BareFn(ref bfty) => {
                 self.check_decl_no_pat(&bfty.decl, |span, _| {
-                    let mut err = struct_span_err!(self.session, span, E0561,
-                                            "patterns aren't allowed in function pointer types");
-                    err.span_note(span, "this is a recent error, see \
-                                         issue #35203 for more details");
+                    let mut err = struct_span_err!(self.session,
+                                                   span,
+                                                   E0561,
+                                                   "patterns aren't allowed in function pointer \
+                                                    types");
+                    err.span_note(span,
+                                  "this is a recent error, see issue #35203 for more details");
                     err.emit();
                 });
             }
@@ -114,10 +122,10 @@ fn visit_path(&mut self, path: &Path, id: NodeId) {
         if path.global && path.segments.len() > 0 {
             let ident = path.segments[0].identifier;
             if token::Ident(ident).is_path_segment_keyword() {
-                self.session.add_lint(
-                    lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH, id, path.span,
-                    format!("global paths cannot start with `{}`", ident)
-                );
+                self.session.add_lint(lint::builtin::SUPER_OR_SELF_IN_GLOBAL_PATH,
+                                      id,
+                                      path.span,
+                                      format!("global paths cannot start with `{}`", ident));
             }
         }
 
@@ -129,8 +137,8 @@ fn visit_item(&mut self, item: &Item) {
             ItemKind::Use(ref view_path) => {
                 let path = view_path.node.path();
                 if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
-                    self.err_handler().span_err(path.span, "type or lifetime parameters \
-                                                            in import path");
+                    self.err_handler()
+                        .span_err(path.span, "type or lifetime parameters in import path");
                 }
             }
             ItemKind::Impl(_, _, _, Some(..), _, ref impl_items) => {
@@ -140,15 +148,18 @@ fn visit_item(&mut self, item: &Item) {
                 }
             }
             ItemKind::Impl(_, _, _, None, _, _) => {
-                self.invalid_visibility(&item.vis, item.span, Some("place qualifiers on individual \
-                                                                    impl items instead"));
+                self.invalid_visibility(&item.vis,
+                                        item.span,
+                                        Some("place qualifiers on individual impl items instead"));
             }
             ItemKind::DefaultImpl(..) => {
                 self.invalid_visibility(&item.vis, item.span, None);
             }
             ItemKind::ForeignMod(..) => {
-                self.invalid_visibility(&item.vis, item.span, Some("place qualifiers on individual \
-                                                                    foreign items instead"));
+                self.invalid_visibility(&item.vis,
+                                        item.span,
+                                        Some("place qualifiers on individual foreign items \
+                                              instead"));
             }
             ItemKind::Enum(ref def, _) => {
                 for variant in &def.variants {
@@ -167,11 +178,14 @@ fn visit_foreign_item(&mut self, fi: &ForeignItem) {
         match fi.node {
             ForeignItemKind::Fn(ref decl, _) => {
                 self.check_decl_no_pat(decl, |span, is_recent| {
-                    let mut err = struct_span_err!(self.session, span, E0130,
-                                        "patterns aren't allowed in foreign function declarations");
+                    let mut err = struct_span_err!(self.session,
+                                                   span,
+                                                   E0130,
+                                                   "patterns aren't allowed in foreign function \
+                                                    declarations");
                     if is_recent {
-                        err.span_note(span, "this is a recent error, see \
-                                             issue #35203 for more details");
+                        err.span_note(span,
+                                      "this is a recent error, see issue #35203 for more details");
                     }
                     err.emit();
                 });
@@ -182,16 +196,21 @@ fn visit_foreign_item(&mut self, fi: &ForeignItem) {
         visit::walk_foreign_item(self, fi)
     }
 
-    fn visit_variant_data(&mut self, vdata: &VariantData, _: Ident,
-                          _: &Generics, _: NodeId, span: Span) {
+    fn visit_variant_data(&mut self,
+                          vdata: &VariantData,
+                          _: Ident,
+                          _: &Generics,
+                          _: NodeId,
+                          span: Span) {
         if vdata.fields().is_empty() {
             if vdata.is_tuple() {
-                self.err_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();
+                self.err_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();
             }
         }
 
@@ -200,10 +219,10 @@ struct or unit enum variant")
 
     fn visit_vis(&mut self, vis: &Visibility) {
         match *vis {
-            Visibility::Restricted{ref path, ..} => {
+            Visibility::Restricted { ref path, .. } => {
                 if !path.segments.iter().all(|segment| segment.parameters.is_empty()) {
-                    self.err_handler().span_err(path.span, "type or lifetime parameters \
-                                                            in visibility path");
+                    self.err_handler()
+                        .span_err(path.span, "type or lifetime parameters in visibility path");
                 }
             }
             _ => {}
index 1030a4b0116de5a07572ffa53fa974d909f4b6b7..fc55118c9f4c518ed0fa989067cf40f95f580f9e 100644 (file)
@@ -25,7 +25,7 @@
 // by borrowck::gather_loans
 
 use rustc::dep_graph::DepNode;
-use rustc::ty::cast::{CastKind};
+use rustc::ty::cast::CastKind;
 use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
 use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
 use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll, Math};
@@ -71,12 +71,12 @@ struct CheckCrateVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     mode: Mode,
     qualif: ConstQualif,
-    rvalue_borrows: NodeMap<hir::Mutability>
+    rvalue_borrows: NodeMap<hir::Mutability>,
 }
 
 impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
-    fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R where
-        F: FnOnce(&mut CheckCrateVisitor<'a, 'gcx>) -> R,
+    fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R
+        where F: FnOnce(&mut CheckCrateVisitor<'a, 'gcx>) -> R
     {
         let (old_mode, old_qualif) = (self.mode, self.qualif);
         self.mode = mode;
@@ -87,17 +87,17 @@ fn with_mode<F, R>(&mut self, mode: Mode, f: F) -> R where
         r
     }
 
-    fn with_euv<F, R>(&mut self, item_id: Option<ast::NodeId>, f: F) -> R where
-        F: for<'b, 'tcx> FnOnce(&mut euv::ExprUseVisitor<'b, 'gcx, 'tcx>) -> R,
+    fn with_euv<F, R>(&mut self, item_id: Option<ast::NodeId>, f: F) -> R
+        where F: for<'b, 'tcx> FnOnce(&mut euv::ExprUseVisitor<'b, 'gcx, 'tcx>) -> R
     {
         let param_env = match item_id {
             Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id),
-            None => self.tcx.empty_parameter_environment()
+            None => self.tcx.empty_parameter_environment(),
         };
 
-        self.tcx.infer_ctxt(None, Some(param_env), ProjectionMode::AnyFinal).enter(|infcx| {
-            f(&mut euv::ExprUseVisitor::new(self, &infcx))
-        })
+        self.tcx
+            .infer_ctxt(None, Some(param_env), ProjectionMode::AnyFinal)
+            .enter(|infcx| f(&mut euv::ExprUseVisitor::new(self, &infcx)))
     }
 
     fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
@@ -111,13 +111,17 @@ fn global_expr(&mut self, mode: Mode, expr: &hir::Expr) -> ConstQualif {
         }
         if let Err(err) = eval_const_expr_partial(self.tcx, expr, ExprTypeChecked, None) {
             match err.kind {
-                UnimplementedConstVal(_) => {},
-                IndexOpFeatureGated => {},
-                ErroneousReferencedConstant(_) => {},
-                _ => self.tcx.sess.add_lint(CONST_ERR, expr.id, expr.span,
-                                         format!("constant evaluation error: {}. This will \
-                                                 become a HARD ERROR in the future",
-                                                 err.description().into_oneline())),
+                UnimplementedConstVal(_) => {}
+                IndexOpFeatureGated => {}
+                ErroneousReferencedConstant(_) => {}
+                _ => {
+                    self.tcx.sess.add_lint(CONST_ERR,
+                                           expr.id,
+                                           expr.span,
+                                           format!("constant evaluation error: {}. This will \
+                                                    become a HARD ERROR in the future",
+                                                   err.description().into_oneline()))
+                }
             }
         }
         self.with_mode(mode, |this| {
@@ -143,9 +147,7 @@ fn fn_like(&mut self,
         }
 
         let mode = match fk {
-            FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => {
-                Mode::ConstFn
-            }
+            FnKind::ItemFn(_, _, _, hir::Constness::Const, _, _, _) => Mode::ConstFn,
             FnKind::Method(_, m, _, _) => {
                 if m.constness == hir::Constness::Const {
                     Mode::ConstFn
@@ -153,7 +155,7 @@ fn fn_like(&mut self,
                     Mode::Var
                 }
             }
-            _ => Mode::Var
+            _ => Mode::Var,
         };
 
         let qualif = self.with_mode(mode, |this| {
@@ -175,11 +177,7 @@ fn add_qualif(&mut self, qualif: ConstQualif) {
     }
 
     /// Returns true if the call is to a const fn or method.
-    fn handle_const_fn_call(&mut self,
-                            _expr: &hir::Expr,
-                            def_id: DefId,
-                            ret_ty: Ty<'gcx>)
-                            -> bool {
+    fn handle_const_fn_call(&mut self, _expr: &hir::Expr, def_id: DefId, ret_ty: Ty<'gcx>) -> bool {
         if let Some(fn_like) = lookup_const_fn_by_id(self.tcx, def_id) {
             let qualif = self.fn_like(fn_like.kind(),
                                       fn_like.decl(),
@@ -285,13 +283,15 @@ fn visit_pat(&mut self, p: &hir::Pat) {
                     Ok(Ordering::Less) |
                     Ok(Ordering::Equal) => {}
                     Ok(Ordering::Greater) => {
-                        span_err!(self.tcx.sess, start.span, E0030,
-                            "lower range bound must be less than or equal to upper");
+                        span_err!(self.tcx.sess,
+                                  start.span,
+                                  E0030,
+                                  "lower range bound must be less than or equal to upper");
                     }
                     Err(ErrorReported) => {}
                 }
             }
-            _ => intravisit::walk_pat(self, p)
+            _ => intravisit::walk_pat(self, p),
         }
     }
 
@@ -301,13 +301,13 @@ fn visit_block(&mut self, block: &hir::Block) {
             match stmt.node {
                 hir::StmtDecl(ref decl, _) => {
                     match decl.node {
-                        hir::DeclLocal(_) => {},
+                        hir::DeclLocal(_) => {}
                         // Item statements are allowed
-                        hir::DeclItem(_) => continue
+                        hir::DeclItem(_) => continue,
                     }
                 }
-                hir::StmtExpr(_, _) => {},
-                hir::StmtSemi(_, _) => {},
+                hir::StmtExpr(_, _) => {}
+                hir::StmtSemi(_, _) => {}
             }
             self.add_qualif(ConstQualif::NOT_CONST);
         }
@@ -340,7 +340,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 // The count is checked elsewhere (typeck).
                 let count = match node_ty.sty {
                     ty::TyArray(_, n) => n,
-                    _ => bug!()
+                    _ => bug!(),
                 };
                 // [element; 0] is always zero-sized.
                 if count == 0 {
@@ -354,7 +354,8 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 for pat in arms.iter().flat_map(|arm| &arm.pats) {
                     let pat_borrow = self.rvalue_borrows.remove(&pat.id);
                     match (borrow, pat_borrow) {
-                        (None, _) | (_, Some(hir::MutMutable)) => {
+                        (None, _) |
+                        (_, Some(hir::MutMutable)) => {
                             borrow = pat_borrow;
                         }
                         _ => {}
@@ -365,7 +366,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
                 }
                 intravisit::walk_expr(self, ex);
             }
-            _ => intravisit::walk_expr(self, ex)
+            _ => intravisit::walk_expr(self, ex),
         }
 
         // Handle borrows on (or inside the autorefs of) this expression.
@@ -405,17 +406,18 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
         if self.mode == Mode::Var && !self.qualif.intersects(ConstQualif::NOT_CONST) {
             match eval_const_expr_partial(self.tcx, ex, ExprTypeChecked, None) {
                 Ok(_) => {}
-                Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
-                Err(ConstEvalErr { kind: MiscCatchAll, ..}) |
-                Err(ConstEvalErr { kind: MiscBinaryOp, ..}) |
-                Err(ConstEvalErr { kind: NonConstPath, ..}) |
-                Err(ConstEvalErr { kind: UnresolvedPath, ..}) |
-                Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), ..}) |
-                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shr)), ..}) |
-                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shl)), ..}) |
-                Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
+                Err(ConstEvalErr { kind: UnimplementedConstVal(_), .. }) |
+                Err(ConstEvalErr { kind: MiscCatchAll, .. }) |
+                Err(ConstEvalErr { kind: MiscBinaryOp, .. }) |
+                Err(ConstEvalErr { kind: NonConstPath, .. }) |
+                Err(ConstEvalErr { kind: UnresolvedPath, .. }) |
+                Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), .. }) |
+                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shr)), .. }) |
+                Err(ConstEvalErr { kind: Math(ConstMathErr::Overflow(Op::Shl)), .. }) |
+                Err(ConstEvalErr { kind: IndexOpFeatureGated, .. }) => {}
                 Err(msg) => {
-                    self.tcx.sess.add_lint(CONST_ERR, ex.id,
+                    self.tcx.sess.add_lint(CONST_ERR,
+                                           ex.id,
                                            msg.span,
                                            msg.description().into_oneline().into_owned())
                 }
@@ -434,8 +436,7 @@ fn visit_expr(&mut self, ex: &hir::Expr) {
 /// every nested expression. If the expression is not part
 /// of a const/static item, it is qualified for promotion
 /// instead of producing errors.
-fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
-                        e: &hir::Expr, node_ty: Ty<'tcx>) {
+fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node_ty: Ty<'tcx>) {
     match node_ty.sty {
         ty::TyStruct(def, _) |
         ty::TyEnum(def, _) if def.has_dtor() => {
@@ -635,12 +636,9 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
         Some(&ty::adjustment::AdjustUnsafeFnPointer) |
         Some(&ty::adjustment::AdjustMutToConstPointer) => {}
 
-        Some(&ty::adjustment::AdjustDerefRef(
-            ty::adjustment::AutoDerefRef { autoderefs, .. }
-        )) => {
-            if (0..autoderefs as u32).any(|autoderef| {
-                    v.tcx.is_overloaded_autoderef(e.id, autoderef)
-            }) {
+        Some(&ty::adjustment::AdjustDerefRef(ty::adjustment::AutoDerefRef { autoderefs, .. })) => {
+            if (0..autoderefs as u32)
+                .any(|autoderef| v.tcx.is_overloaded_autoderef(e.id, autoderef)) {
                 v.add_qualif(ConstQualif::NOT_CONST);
             }
         }
@@ -648,12 +646,13 @@ fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Exp
 }
 
 pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    tcx.visit_all_items_in_krate(DepNode::CheckConst, &mut CheckCrateVisitor {
-        tcx: tcx,
-        mode: Mode::Var,
-        qualif: ConstQualif::NOT_CONST,
-        rvalue_borrows: NodeMap()
-    });
+    tcx.visit_all_items_in_krate(DepNode::CheckConst,
+                                 &mut CheckCrateVisitor {
+                                     tcx: tcx,
+                                     mode: Mode::Var,
+                                     qualif: ConstQualif::NOT_CONST,
+                                     rvalue_borrows: NodeMap(),
+                                 });
     tcx.sess.abort_if_errors();
 }
 
@@ -675,7 +674,7 @@ fn consume(&mut self,
 
                 Categorization::Rvalue(..) |
                 Categorization::Upvar(..) |
-                Categorization::Local(..) => break
+                Categorization::Local(..) => break,
             }
         }
     }
@@ -685,8 +684,7 @@ fn borrow(&mut self,
               cmt: mc::cmt<'tcx>,
               _loan_region: ty::Region,
               bk: ty::BorrowKind,
-              loan_cause: euv::LoanCause)
-    {
+              loan_cause: euv::LoanCause) {
         // Kind of hacky, but we allow Unsafe coercions in constants.
         // These occur when we convert a &T or *T to a *U, as well as
         // when making a thin pointer (e.g., `*T`) into a fat pointer
@@ -695,7 +693,7 @@ fn borrow(&mut self,
             euv::LoanCause::AutoUnsafe => {
                 return;
             }
-            _ => { }
+            _ => {}
         }
 
         let mut cur = &cmt;
@@ -715,7 +713,8 @@ fn borrow(&mut self,
                         // type of the expression.  `&mut [1]` has exactly the
                         // same representation as &mut 1.
                         match cmt.ty.sty {
-                            ty::TyArray(_, _) | ty::TySlice(_) => break,
+                            ty::TyArray(_, _) |
+                            ty::TySlice(_) => break,
                             _ => {}
                         }
                     }
@@ -732,27 +731,20 @@ fn borrow(&mut self,
                 }
 
                 Categorization::Upvar(..) |
-                Categorization::Local(..) => break
+                Categorization::Local(..) => break,
             }
         }
     }
 
-    fn decl_without_init(&mut self,
-                         _id: ast::NodeId,
-                         _span: Span) {}
+    fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) {}
     fn mutate(&mut self,
               _assignment_id: ast::NodeId,
               _assignment_span: Span,
               _assignee_cmt: mc::cmt,
-              _mode: euv::MutateMode) {}
+              _mode: euv::MutateMode) {
+    }
 
-    fn matched_pat(&mut self,
-                   _: &hir::Pat,
-                   _: mc::cmt,
-                   _: euv::MatchMode) {}
+    fn matched_pat(&mut self, _: &hir::Pat, _: mc::cmt, _: euv::MatchMode) {}
 
-    fn consume_pat(&mut self,
-                   _consume_pat: &hir::Pat,
-                   _cmt: mc::cmt,
-                   _mode: euv::ConsumeMode) {}
+    fn consume_pat(&mut self, _consume_pat: &hir::Pat, _cmt: mc::cmt, _mode: euv::ConsumeMode) {}
 }
index 3e2dd477bccf089f0e40b0598246ce9c120b39e2..7049040678e39f706499e9a7cc920dfe89f797aa 100644 (file)
@@ -121,11 +121,11 @@ fn main() {
 
 For example, neither of the following can be sensibly compiled:
 
-```compile_fail
+```compile_fail,E0265
 const X: u32 = X;
 ```
 
-```compile_fail
+```compile_fail,E0265
 const X: u32 = Y;
 const Y: u32 = X;
 ```
@@ -135,7 +135,7 @@ fn main() {
 This error indicates the use of a loop keyword (`break` or `continue`) inside a
 closure but outside of any loop. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0267
 let w = || { break; }; // error: `break` inside of a closure
 ```
 
@@ -159,7 +159,7 @@ fn main() {
 of a loop. Without a loop to break out of or continue in, no sensible action can
 be taken. Erroneous code example:
 
-```compile_fail
+```compile_fail,E0268
 fn some_func() {
     break; // error: `break` outside of loop
 }
index 650613f4844f526facb139225cc39d3a8a46e1e4..e59c4a6fc4186bfbb9664dcf7042a630ce574de9 100644 (file)
 #![feature(rustc_private)]
 
 extern crate core;
-#[macro_use] extern crate rustc;
+#[macro_use]
+extern crate rustc;
 extern crate rustc_const_eval;
 extern crate rustc_const_math;
 
-#[macro_use] extern crate log;
-#[macro_use] extern crate syntax;
+#[macro_use]
+extern crate log;
+#[macro_use]
+extern crate syntax;
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 
index dd0f16baaa395d524e6e91bf2abdcb3dbe5e0d65..4e251793f6917ae645fc6c14c7581aa26c3f658d 100644 (file)
 
 #[derive(Clone, Copy, PartialEq)]
 enum Context {
-    Normal, Loop, Closure
+    Normal,
+    Loop,
+    Closure,
 }
 
 #[derive(Copy, Clone)]
 struct CheckLoopVisitor<'a> {
     sess: &'a Session,
-    cx: Context
+    cx: Context,
 }
 
 pub fn check_crate(sess: &Session, map: &Map) {
     let _task = map.dep_graph.in_task(DepNode::CheckLoops);
     let krate = map.krate();
-    krate.visit_all_items(&mut CheckLoopVisitor { sess: sess, cx: Normal });
+    krate.visit_all_items(&mut CheckLoopVisitor {
+        sess: sess,
+        cx: Normal,
+    });
 }
 
 impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
@@ -53,14 +58,14 @@ fn visit_expr(&mut self, e: &hir::Expr) {
             }
             hir::ExprBreak(_) => self.require_loop("break", e.span),
             hir::ExprAgain(_) => self.require_loop("continue", e.span),
-            _ => intravisit::walk_expr(self, e)
+            _ => intravisit::walk_expr(self, e),
         }
     }
 }
 
 impl<'a> CheckLoopVisitor<'a> {
-    fn with_context<F>(&mut self, cx: Context, f: F) where
-        F: FnOnce(&mut CheckLoopVisitor<'a>),
+    fn with_context<F>(&mut self, cx: Context, f: F)
+        where F: FnOnce(&mut CheckLoopVisitor<'a>)
     {
         let old_cx = self.cx;
         self.cx = cx;
@@ -72,12 +77,10 @@ fn require_loop(&self, name: &str, span: Span) {
         match self.cx {
             Loop => {}
             Closure => {
-                span_err!(self.sess, span, E0267,
-                                   "`{}` inside of a closure", name);
+                span_err!(self.sess, span, E0267, "`{}` inside of a closure", name);
             }
             Normal => {
-                span_err!(self.sess, span, E0268,
-                                   "`{}` outside of loop", name);
+                span_err!(self.sess, span, E0268, "`{}` outside of loop", name);
             }
         }
     }
index 314513a974ecdb826b728523403a5056c635a062..af3065d64e8db08bc7fd8ee36cca33a93971fff3 100644 (file)
 use syntax::visit;
 
 pub fn check_crate(sess: &Session, krate: &ast::Crate) {
-    if sess.target.target.options.allow_asm { return; }
+    if sess.target.target.options.allow_asm {
+        return;
+    }
 
-    visit::walk_crate(&mut CheckNoAsm { sess: sess, }, krate);
+    visit::walk_crate(&mut CheckNoAsm { sess: sess }, krate);
 }
 
 #[derive(Copy, Clone)]
@@ -32,9 +34,13 @@ struct CheckNoAsm<'a> {
 impl<'a> Visitor for CheckNoAsm<'a> {
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
-            ast::ExprKind::InlineAsm(_) => span_err!(self.sess, e.span, E0472,
-                                                     "asm! is unsupported on this target"),
-            _ => {},
+            ast::ExprKind::InlineAsm(_) => {
+                span_err!(self.sess,
+                          e.span,
+                          E0472,
+                          "asm! is unsupported on this target")
+            }
+            _ => {}
         }
         visit::walk_expr(self, e)
     }
index d0938ad09a0da1bced4e17ef57d5c1c1096c97fe..8b2943a33c006aaced7fd7cee377a241ff187467 100644 (file)
 
 use rustc::dep_graph::DepNode;
 use rustc::hir::map as ast_map;
-use rustc::session::{Session, CompileResult};
+use rustc::session::{CompileResult, Session};
 use rustc::hir::def::{Def, DefMap};
 use rustc::util::nodemap::NodeMap;
 
-use syntax::{ast};
+use syntax::ast;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax_pos::Span;
 use rustc::hir::intravisit::{self, Visitor};
@@ -41,18 +41,17 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
         match it.node {
             hir::ItemStatic(..) |
             hir::ItemConst(..) => {
-                let mut recursion_visitor =
-                    CheckItemRecursionVisitor::new(self, &it.span);
+                let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &it.span);
                 recursion_visitor.visit_item(it);
-            },
+            }
             hir::ItemEnum(ref enum_def, ref generics) => {
                 // We could process the whole enum, but handling the variants
                 // with discriminant expressions one by one gives more specific,
                 // less redundant output.
                 for variant in &enum_def.variants {
                     if let Some(_) = variant.node.disr_expr {
-                        let mut recursion_visitor =
-                            CheckItemRecursionVisitor::new(self, &variant.span);
+                        let mut recursion_visitor = CheckItemRecursionVisitor::new(self,
+                                                                                   &variant.span);
                         recursion_visitor.populate_enum_discriminants(enum_def);
                         recursion_visitor.visit_variant(variant, generics, it.id);
                     }
@@ -67,8 +66,7 @@ fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
         match ti.node {
             hir::ConstTraitItem(_, ref default) => {
                 if let Some(_) = *default {
-                    let mut recursion_visitor =
-                        CheckItemRecursionVisitor::new(self, &ti.span);
+                    let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ti.span);
                     recursion_visitor.visit_trait_item(ti);
                 }
             }
@@ -80,8 +78,7 @@ fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
     fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
         match ii.node {
             hir::ImplItemKind::Const(..) => {
-                let mut recursion_visitor =
-                    CheckItemRecursionVisitor::new(self, &ii.span);
+                let mut recursion_visitor = CheckItemRecursionVisitor::new(self, &ii.span);
                 recursion_visitor.visit_impl_item(ii);
             }
             _ => {}
@@ -117,7 +114,8 @@ struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
 }
 
 impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
-    fn new(v: &'a CheckCrateVisitor<'a, 'ast>, span: &'a Span)
+    fn new(v: &'a CheckCrateVisitor<'a, 'ast>,
+           span: &'a Span)
            -> CheckItemRecursionVisitor<'a, 'ast> {
         CheckItemRecursionVisitor {
             root_span: span,
@@ -129,7 +127,8 @@ fn new(v: &'a CheckCrateVisitor<'a, 'ast>, span: &'a Span)
         }
     }
     fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
-          where F: Fn(&mut Self) {
+        where F: Fn(&mut Self)
+    {
         if self.idstack.iter().any(|&x| x == id) {
             let any_static = self.idstack.iter().any(|&x| {
                 if let ast_map::NodeItem(item) = self.ast_map.get(x) {
@@ -146,7 +145,9 @@ fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
                 if !self.sess.features.borrow().static_recursion {
                     emit_feature_err(&self.sess.parse_sess.span_diagnostic,
                                      "static_recursion",
-                                     *self.root_span, GateIssue::Language, "recursive static");
+                                     *self.root_span,
+                                     GateIssue::Language,
+                                     "recursive static");
                 }
             } else {
                 span_err!(self.sess, *self.root_span, E0265, "recursive constant");
@@ -170,7 +171,9 @@ fn populate_enum_discriminants(&self, enum_definition: &'ast hir::EnumDef) {
         // has no variants.
         let mut discriminant_map = self.discriminant_map.borrow_mut();
         match enum_definition.variants.first() {
-            None => { return; }
+            None => {
+                return;
+            }
             Some(variant) if discriminant_map.contains_key(&variant.node.data.id()) => {
                 return;
             }
@@ -203,14 +206,19 @@ fn visit_item(&mut self, it: &'ast hir::Item) {
         self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it));
     }
 
-    fn visit_enum_def(&mut self, enum_definition: &'ast hir::EnumDef,
-                      generics: &'ast hir::Generics, item_id: ast::NodeId, _: Span) {
+    fn visit_enum_def(&mut self,
+                      enum_definition: &'ast hir::EnumDef,
+                      generics: &'ast hir::Generics,
+                      item_id: ast::NodeId,
+                      _: Span) {
         self.populate_enum_discriminants(enum_definition);
         intravisit::walk_enum_def(self, enum_definition, generics, item_id);
     }
 
-    fn visit_variant(&mut self, variant: &'ast hir::Variant,
-                     _: &'ast hir::Generics, _: ast::NodeId) {
+    fn visit_variant(&mut self,
+                     variant: &'ast hir::Variant,
+                     _: &'ast hir::Generics,
+                     _: ast::NodeId) {
         let variant_id = variant.node.data.id();
         let maybe_expr;
         if let Some(get_expr) = self.discriminant_map.borrow().get(&variant_id) {
@@ -246,18 +254,14 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                     Some(Def::Const(def_id)) => {
                         if let Some(node_id) = self.ast_map.as_local_node_id(def_id) {
                             match self.ast_map.get(node_id) {
-                                ast_map::NodeItem(item) =>
-                                    self.visit_item(item),
-                                ast_map::NodeTraitItem(item) =>
-                                    self.visit_trait_item(item),
-                                ast_map::NodeImplItem(item) =>
-                                    self.visit_impl_item(item),
-                                ast_map::NodeForeignItem(_) => {},
+                                ast_map::NodeItem(item) => self.visit_item(item),
+                                ast_map::NodeTraitItem(item) => self.visit_trait_item(item),
+                                ast_map::NodeImplItem(item) => self.visit_impl_item(item),
+                                ast_map::NodeForeignItem(_) => {}
                                 _ => {
-                                    span_bug!(
-                                        e.span,
-                                        "expected item, found {}",
-                                        self.ast_map.node_to_string(node_id));
+                                    span_bug!(e.span,
+                                              "expected item, found {}",
+                                              self.ast_map.node_to_string(node_id));
                                 }
                             }
                         }
@@ -268,9 +272,9 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                     // might be (if any).
                     Some(Def::Variant(enum_id, variant_id)) => {
                         if let Some(enum_node_id) = self.ast_map.as_local_node_id(enum_id) {
-                            if let hir::ItemEnum(ref enum_def, ref generics) =
-                                self.ast_map.expect_item(enum_node_id).node
-                            {
+                            if let hir::ItemEnum(ref enum_def, ref generics) = self.ast_map
+                                .expect_item(enum_node_id)
+                                .node {
                                 self.populate_enum_discriminants(enum_def);
                                 let enum_id = self.ast_map.as_local_node_id(enum_id).unwrap();
                                 let variant_id = self.ast_map.as_local_node_id(variant_id).unwrap();
@@ -283,10 +287,10 @@ fn visit_expr(&mut self, e: &'ast hir::Expr) {
                             }
                         }
                     }
-                    _ => ()
+                    _ => (),
                 }
-            },
-            _ => ()
+            }
+            _ => (),
         }
         intravisit::walk_expr(self, e);
     }
index 5867e48c7ca27b64d5fbea039fffde6a34a6ec8f..116c1b7a6d06f811eb29829e316cfedfe093d1e6 100644 (file)
@@ -16,7 +16,7 @@
 use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
 use Module;
 use Namespace::{self, TypeNS, ValueNS};
-use {NameBinding, NameBindingKind};
+use {NameBinding, NameBindingKind, ToNameBinding};
 use ParentLink::{ModuleParentLink, BlockParentLink};
 use Resolver;
 use {resolve_error, resolve_struct_error, ResolutionError};
 
 use syntax_pos::{Span, DUMMY_SP};
 
-trait ToNameBinding<'a> {
-    fn to_name_binding(self) -> NameBinding<'a>;
-}
-
 impl<'a> ToNameBinding<'a> for (Module<'a>, Span, ty::Visibility) {
     fn to_name_binding(self) -> NameBinding<'a> {
         NameBinding { kind: NameBindingKind::Module(self.0), span: self.1, vis: self.2 }
@@ -68,18 +64,13 @@ pub fn build_reduced_graph(&mut self, krate: &Crate) {
         visit::walk_crate(&mut visitor, krate);
     }
 
-    /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined.
-    fn try_define<T>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
-        where T: ToNameBinding<'b>
-    {
-        let _ = parent.try_define_child(name, ns, def.to_name_binding());
-    }
-
     /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
     /// otherwise, reports an error.
-    fn define<T: ToNameBinding<'b>>(&self, parent: Module<'b>, name: Name, ns: Namespace, def: T) {
+    fn define<T>(&mut self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
+        where T: ToNameBinding<'b>,
+    {
         let binding = def.to_name_binding();
-        if let Err(old_binding) = parent.try_define_child(name, ns, binding.clone()) {
+        if let Err(old_binding) = self.try_define(parent, name, ns, binding.clone()) {
             self.report_conflict(parent, name, ns, old_binding, &binding);
         }
     }
@@ -399,14 +390,14 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
                        name, vis);
                 let parent_link = ModuleParentLink(parent, name);
                 let module = self.new_module(parent_link, Some(def), true);
-                self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
             }
             Def::Variant(_, variant_id) => {
                 debug!("(building reduced graph for external crate) building variant {}", name);
                 // Variants are always treated as importable to allow them to be glob used.
                 // All variants are defined in both type and value namespaces as future-proofing.
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
-                self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
                 if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) {
                     // Not adding fields for variants as they are not accessed with a self receiver
                     self.structs.insert(variant_id, Vec::new());
@@ -419,7 +410,7 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
             Def::Method(..) => {
                 debug!("(building reduced graph for external crate) building value (fn/static) {}",
                        name);
-                self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
             }
             Def::Trait(def_id) => {
                 debug!("(building reduced graph for external crate) building type {}", name);
@@ -441,20 +432,20 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcd
 
                 let parent_link = ModuleParentLink(parent, name);
                 let module = self.new_module(parent_link, Some(def), true);
-                self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
             }
             Def::TyAlias(..) | Def::AssociatedTy(..) => {
                 debug!("(building reduced graph for external crate) building type {}", name);
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
             }
             Def::Struct(def_id)
                 if self.session.cstore.tuple_struct_definition_if_ctor(def_id).is_none() => {
                 debug!("(building reduced graph for external crate) building type and value for {}",
                        name);
-                self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
+                let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
                 if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
                     let def = Def::Struct(ctor_def_id);
-                    self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
+                    let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
                 }
 
                 // Record the def ID and fields of this struct.
index 3e860150a35fdfbe3f2379e81cc727f3783f4778..11ef75ee6a8fc4fcc90596feebccca7687c16fb0 100644 (file)
@@ -146,6 +146,7 @@ pub trait MyTrait {
 }
 
 use foo::MyTrait::do_something;
+// error: `do_something` is not directly importable
 
 fn main() {}
 ```
@@ -153,6 +154,45 @@ fn main() {}
 It's invalid to directly import methods belonging to a trait or concrete type.
 "##,
 
+E0254: r##"
+Attempt was made to import an item whereas an extern crate with this name has
+already been imported.
+
+Erroneous code example:
+
+```compile_fail,E0254
+extern crate collections;
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections; // error: an extern crate named `collections` has already
+                      //        been imported in this module
+
+fn main() {}
+```
+
+To fix issue issue, you have to rename at least one of the two imports.
+Example:
+
+```ignore
+extern crate collections as libcollections; // ok!
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections;
+
+fn main() {}
+```
+"##,
+
 E0255: r##"
 You can't import a value whose name is the same as another value defined in the
 module.
@@ -1237,7 +1277,6 @@ impl Foo for i32 {}
 register_diagnostics! {
 //  E0153, unused error code
 //  E0157, unused error code
-    E0254, // import conflicts with imported crate in this module
 //  E0257,
 //  E0258,
     E0402, // cannot use an outer type parameter in this context
index c1511b29c9e0154f1649e8f49ac0cca04289c170..befe328591121e2bb45b82c28b998c3448e6ea04 100644 (file)
@@ -158,7 +158,7 @@ enum ResolutionError<'a> {
     /// error E0435: attempt to use a non-constant value in a constant
     AttemptToUseNonConstantValueInConstant,
     /// error E0530: X bindings cannot shadow Ys
-    BindingShadowsSomethingUnacceptable(&'a str, &'a str, Name),
+    BindingShadowsSomethingUnacceptable(&'a str, Name, &'a NameBinding<'a>),
     /// error E0531: unresolved pattern path kind `name`
     PatPathUnresolved(&'a str, &'a Path),
     /// error E0532: expected pattern path kind, found another pattern path kind
@@ -219,7 +219,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                              name)
         }
         ResolutionError::IsNotATrait(name) => {
-            struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
+            let mut err = struct_span_err!(resolver.session,
+                                           span,
+                                           E0404,
+                                           "`{}` is not a trait",
+                                           name);
+            err.span_label(span, &format!("not a trait"));
+            err
         }
         ResolutionError::UndeclaredTraitName(name, candidates) => {
             let mut err = struct_span_err!(resolver.session,
@@ -422,17 +428,16 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
                              E0435,
                              "attempt to use a non-constant value in a constant")
         }
-        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, shadows_what, name) => {
+        ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
+            let shadows_what = PathResolution::new(binding.def().unwrap()).kind_name();
             let mut err = struct_span_err!(resolver.session,
                                            span,
                                            E0530,
                                            "{}s cannot shadow {}s", what_binding, shadows_what);
             err.span_label(span, &format!("cannot be named the same as a {}", shadows_what));
-            if let Success(binding) = resolver.current_module.resolve_name(name, ValueNS, true) {
-                let participle = if binding.is_import() { "imported" } else { "defined" };
-                err.span_label(binding.span, &format!("a {} `{}` is {} here",
-                                                      shadows_what, name, participle));
-            }
+            let participle = if binding.is_import() { "imported" } else { "defined" };
+            let msg = &format!("a {} `{}` is {} here", shadows_what, name, participle);
+            err.span_label(binding.span, msg);
             err
         }
         ResolutionError::PatPathUnresolved(expected_what, path) => {
@@ -712,12 +717,16 @@ fn local_def(self) -> LocalDef {
         }
     }
 
-    fn module(self) -> Option<Module<'a>> {
+    fn item(self) -> Option<&'a NameBinding<'a>> {
         match self {
-            LexicalScopeBinding::Item(binding) => binding.module(),
+            LexicalScopeBinding::Item(binding) => Some(binding),
             _ => None,
         }
     }
+
+    fn module(self) -> Option<Module<'a>> {
+        self.item().and_then(NameBinding::module)
+    }
 }
 
 /// The link from a module up to its nearest parent node.
@@ -818,6 +827,16 @@ pub struct NameBinding<'a> {
     vis: ty::Visibility,
 }
 
+pub trait ToNameBinding<'a> {
+    fn to_name_binding(self) -> NameBinding<'a>;
+}
+
+impl<'a> ToNameBinding<'a> for NameBinding<'a> {
+    fn to_name_binding(self) -> NameBinding<'a> {
+        self
+    }
+}
+
 #[derive(Clone, Debug)]
 enum NameBindingKind<'a> {
     Def(Def),
@@ -1197,34 +1216,27 @@ fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec<Rib<'a>> {
         match ns { ValueNS => &mut self.value_ribs, TypeNS => &mut self.type_ribs }
     }
 
-    #[inline]
-    fn record_use(&mut self, name: Name, binding: &'a NameBinding<'a>) {
+    fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
         // track extern crates for unused_extern_crate lint
         if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
             self.used_crates.insert(krate);
         }
 
-        let directive = match binding.kind {
-            NameBindingKind::Import { directive, .. } => directive,
-            _ => return,
-        };
-
-        if !self.make_glob_map {
-            return;
-        }
-        if self.glob_map.contains_key(&directive.id) {
-            self.glob_map.get_mut(&directive.id).unwrap().insert(name);
-            return;
+        if let NameBindingKind::Import { directive, .. } = binding.kind {
+            self.used_imports.insert((directive.id, ns));
+            self.add_to_glob_map(directive.id, name);
         }
+    }
 
-        let mut new_set = FnvHashSet();
-        new_set.insert(name);
-        self.glob_map.insert(directive.id, new_set);
+    fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
+        if self.make_glob_map {
+            self.glob_map.entry(id).or_insert_with(FnvHashSet).insert(name);
+        }
     }
 
-    /// Resolves the given module path from the given root `module_`.
+    /// Resolves the given module path from the given root `search_module`.
     fn resolve_module_path_from_root(&mut self,
-                                     module_: Module<'a>,
+                                     mut search_module: Module<'a>,
                                      module_path: &[Name],
                                      index: usize,
                                      span: Span)
@@ -1241,7 +1253,6 @@ fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
             }
         }
 
-        let mut search_module = module_;
         let mut index = index;
         let module_path_len = module_path.len();
 
@@ -1438,10 +1449,9 @@ fn resolve_ident_in_lexical_scope(&mut self,
     }
 
     /// Returns the nearest normal module parent of the given module.
-    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
-        let mut module_ = module_;
+    fn get_nearest_normal_module_parent(&self, mut module: Module<'a>) -> Option<Module<'a>> {
         loop {
-            match module_.parent_link {
+            match module.parent_link {
                 NoParentLink => return None,
                 ModuleParentLink(new_module, _) |
                 BlockParentLink(new_module, _) => {
@@ -1449,7 +1459,7 @@ fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module
                     if new_module.is_normal() {
                         return Some(new_module);
                     }
-                    module_ = new_module;
+                    module = new_module;
                 }
             }
         }
@@ -1457,12 +1467,12 @@ fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module
 
     /// Returns the nearest normal module parent of the given module, or the
     /// module itself if it is a normal module.
-    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
-        if module_.is_normal() {
-            return module_;
+    fn get_nearest_normal_module_parent_or_self(&self, module: Module<'a>) -> Module<'a> {
+        if module.is_normal() {
+            return module;
         }
-        match self.get_nearest_normal_module_parent(module_) {
-            None => module_,
+        match self.get_nearest_normal_module_parent(module) {
+            None => module,
             Some(new_module) => new_module,
         }
     }
@@ -1479,8 +1489,8 @@ fn resolve_module_prefix(&mut self, module_path: &[Name], span: Span)
             "super" => 0,
             _ => return Success(NoPrefixFound),
         };
-        let module_ = self.current_module;
-        let mut containing_module = self.get_nearest_normal_module_parent_or_self(module_);
+        let mut containing_module =
+            self.get_nearest_normal_module_parent_or_self(self.current_module);
 
         // Now loop through all the `super`s we find.
         while i < module_path.len() && "super" == module_path[i].as_str() {
@@ -1519,10 +1529,7 @@ fn resolve_name_in_module(&mut self,
         self.populate_module_if_necessary(module);
         module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
             if record_used {
-                if let NameBindingKind::Import { directive, .. } = binding.kind {
-                    self.used_imports.insert((directive.id, namespace));
-                }
-                self.record_use(name, binding);
+                self.record_use(name, namespace, binding);
             }
             Success(binding)
         })
@@ -2302,16 +2309,17 @@ fn resolve_pattern(&mut self,
                 PatKind::Ident(bmode, ref ident, ref opt_pat) => {
                     // First try to resolve the identifier as some existing
                     // entity, then fall back to a fresh binding.
-                    let resolution = self.resolve_identifier(ident.node, ValueNS, true)
-                                         .map(|local_def| PathResolution::new(local_def.def))
-                                         .and_then(|resolution| {
+                    let binding = self.resolve_ident_in_lexical_scope(ident.node, ValueNS, false)
+                                      .and_then(LexicalScopeBinding::item);
+                    let resolution = binding.and_then(NameBinding::def).and_then(|def| {
                         let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
                                              bmode != BindingMode::ByValue(Mutability::Immutable);
-                        match resolution.base_def {
+                        match def {
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
                                 // A constant, unit variant, etc pattern.
-                                Some(resolution)
+                                self.record_use(ident.node.name, ValueNS, binding.unwrap());
+                                Some(PathResolution::new(def))
                             }
                             Def::Struct(..) | Def::Variant(..) |
                             Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
@@ -2320,7 +2328,7 @@ fn resolve_pattern(&mut self,
                                     self,
                                     ident.span,
                                     ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), resolution.kind_name(), ident.node.name)
+                                        pat_src.descr(), ident.node.name, binding.unwrap())
                                 );
                                 None
                             }
@@ -3130,10 +3138,10 @@ fn add_trait_info(found_traits: &mut Vec<TraitCandidate>,
                         if let NameBindingKind::Import { directive, .. } = binding.kind {
                             let id = directive.id;
                             this.maybe_unused_trait_imports.insert(id);
+                            this.add_to_glob_map(id, trait_name);
                             import_id = Some(id);
                         }
                         add_trait_info(&mut found_traits, trait_def_id, import_id, name);
-                        this.record_use(trait_name, binding);
                     }
                 }
             };
index fc5e2a48e876ccc2eaf5391dd85a4e399f7ec2ee..6986f99926e1e43d9dd07874d5d25b29a9d4d6df 100644 (file)
@@ -12,7 +12,7 @@
 
 use Module;
 use Namespace::{self, TypeNS, ValueNS};
-use {NameBinding, NameBindingKind, PrivacyError};
+use {NameBinding, NameBindingKind, PrivacyError, ToNameBinding};
 use ResolveResult;
 use ResolveResult::*;
 use Resolver;
@@ -21,7 +21,7 @@
 use {resolve_error, ResolutionError};
 
 use rustc::ty;
-use rustc::lint;
+use rustc::lint::builtin::PRIVATE_IN_PUBLIC;
 use rustc::hir::def::*;
 
 use syntax::ast::{NodeId, Name};
@@ -71,19 +71,6 @@ pub struct ImportDirective<'a> {
 }
 
 impl<'a> ImportDirective<'a> {
-    // Given the binding to which this directive resolves in a particular namespace,
-    // this returns the binding for the name this directive defines in that namespace.
-    fn import(&'a self, binding: &'a NameBinding<'a>) -> NameBinding<'a> {
-        NameBinding {
-            kind: NameBindingKind::Import {
-                binding: binding,
-                directive: self,
-            },
-            span: self.span,
-            vis: self.vis,
-        }
-    }
-
     pub fn is_glob(&self) -> bool {
         match self.subclass { ImportDirectiveSubclass::GlobImport { .. } => true, _ => false }
     }
@@ -137,23 +124,6 @@ fn directive_failed(&mut self) {
 }
 
 impl<'a> NameResolution<'a> {
-    fn try_define(&mut self, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> {
-        if let Some(old_binding) = self.binding {
-            if binding.is_glob_import() {
-                self.duplicate_globs.push(binding);
-            } else if old_binding.is_glob_import() {
-                self.duplicate_globs.push(old_binding);
-                self.binding = Some(binding);
-            } else {
-                return Err(old_binding);
-            }
-        } else {
-            self.binding = Some(binding);
-        }
-
-        Ok(())
-    }
-
     // Returns the binding for the name if it is known or None if it not known.
     fn binding(&self) -> Option<&'a NameBinding<'a>> {
         self.binding.and_then(|binding| match self.single_imports {
@@ -203,24 +173,6 @@ fn try_result(&self, ns: Namespace, allow_private_imports: bool)
 
         self.binding.map(Success)
     }
-
-    fn report_conflicts<F: FnMut(&NameBinding, &NameBinding)>(&self, mut report: F) {
-        let binding = match self.binding {
-            Some(binding) => binding,
-            None => return,
-        };
-
-        for duplicate_glob in self.duplicate_globs.iter() {
-            // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
-            if !binding.is_import() {
-                if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
-                    if binding.is_import() { continue }
-                }
-            }
-
-            report(duplicate_glob, binding);
-        }
-    }
 }
 
 impl<'a> ::ModuleS<'a> {
@@ -261,14 +213,6 @@ pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: boo
         Failed(None)
     }
 
-    // Define the name or return the existing binding if there is a collision.
-    pub fn try_define_child(&self, name: Name, ns: Namespace, binding: NameBinding<'a>)
-                            -> Result<(), &'a NameBinding<'a>> {
-        self.update_resolution(name, ns, |resolution| {
-            resolution.try_define(self.arenas.alloc_name_binding(binding))
-        })
-    }
-
     pub fn add_import_directive(&self,
                                 module_path: Vec<Name>,
                                 subclass: ImportDirectiveSubclass,
@@ -298,19 +242,59 @@ pub fn add_import_directive(&self,
             GlobImport { .. } => self.globs.borrow_mut().push(directive),
         }
     }
+}
+
+impl<'a> Resolver<'a> {
+    // Given a binding and an import directive that resolves to it,
+    // return the corresponding binding defined by the import directive.
+    fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
+              -> NameBinding<'a> {
+        NameBinding {
+            kind: NameBindingKind::Import {
+                binding: binding,
+                directive: directive,
+            },
+            span: directive.span,
+            vis: directive.vis,
+        }
+    }
 
-    // Use `update` to mutate the resolution for the name.
+    // Define the name or return the existing binding if there is a collision.
+    pub fn try_define<T>(&mut self, module: Module<'a>, name: Name, ns: Namespace, binding: T)
+                         -> Result<(), &'a NameBinding<'a>>
+        where T: ToNameBinding<'a>
+    {
+        let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
+        self.update_resolution(module, name, ns, |_, resolution| {
+            if let Some(old_binding) = resolution.binding {
+                if binding.is_glob_import() {
+                    resolution.duplicate_globs.push(binding);
+                } else if old_binding.is_glob_import() {
+                    resolution.duplicate_globs.push(old_binding);
+                    resolution.binding = Some(binding);
+                } else {
+                    return Err(old_binding);
+                }
+            } else {
+                resolution.binding = Some(binding);
+            }
+
+            Ok(())
+        })
+    }
+
+    // Use `f` to mutate the resolution of the name in the module.
     // If the resolution becomes a success, define it in the module's glob importers.
-    fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T
-        where F: FnOnce(&mut NameResolution<'a>) -> T
+    fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namespace, f: F) -> T
+        where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
     {
-        // Ensure that `resolution` isn't borrowed during `define_in_glob_importers`,
-        // where it might end up getting re-defined via a glob cycle.
+        // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
+        // during which the resolution might end up getting re-defined via a glob cycle.
         let (new_binding, t) = {
-            let mut resolution = &mut *self.resolution(name, ns).borrow_mut();
+            let mut resolution = &mut *module.resolution(name, ns).borrow_mut();
             let was_known = resolution.binding().is_some();
 
-            let t = update(resolution);
+            let t = f(self, resolution);
 
             if was_known { return t; }
             match resolution.binding() {
@@ -319,15 +303,15 @@ fn update_resolution<T, F>(&self, name: Name, ns: Namespace, update: F) -> T
             }
         };
 
-        self.define_in_glob_importers(name, ns, new_binding);
-        t
-    }
-
-    fn define_in_glob_importers(&self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>) {
-        if !binding.is_importable() || !binding.is_pseudo_public() { return }
-        for &(importer, directive) in self.glob_importers.borrow_mut().iter() {
-            let _ = importer.try_define_child(name, ns, directive.import(binding));
+        // Define `new_binding` in `module`s glob importers.
+        if new_binding.is_importable() && new_binding.is_pseudo_public() {
+            for &(importer, directive) in module.glob_importers.borrow_mut().iter() {
+                let imported_binding = self.import(new_binding, directive);
+                let _ = self.try_define(importer, name, ns, imported_binding);
+            }
         }
+
+        t
     }
 }
 
@@ -343,6 +327,25 @@ struct ImportResolver<'a, 'b: 'a> {
     resolver: &'a mut Resolver<'b>,
 }
 
+impl<'a, 'b: 'a> ::std::ops::Deref for ImportResolver<'a, 'b> {
+    type Target = Resolver<'b>;
+    fn deref(&self) -> &Resolver<'b> {
+        self.resolver
+    }
+}
+
+impl<'a, 'b: 'a> ::std::ops::DerefMut for ImportResolver<'a, 'b> {
+    fn deref_mut(&mut self) -> &mut Resolver<'b> {
+        self.resolver
+    }
+}
+
+impl<'a, 'b: 'a> ty::NodeIdTree for ImportResolver<'a, 'b> {
+    fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool {
+        self.resolver.is_descendant_of(node, ancestor)
+    }
+}
+
 impl<'a, 'b:'a> ImportResolver<'a, 'b> {
     // Import resolution
     //
@@ -360,31 +363,29 @@ fn resolve_imports(&mut self) {
         let mut errors = Vec::new();
 
         loop {
-            debug!("(resolving imports) iteration {}, {} imports left",
-                   i,
-                   self.resolver.unresolved_imports);
+            debug!("(resolving imports) iteration {}, {} imports left", i, self.unresolved_imports);
 
             // Attempt to resolve imports in all local modules.
-            for module in self.resolver.arenas.local_modules().iter() {
-                self.resolver.current_module = module;
+            for module in self.arenas.local_modules().iter() {
+                self.current_module = module;
                 self.resolve_imports_in_current_module(&mut errors);
             }
 
-            if self.resolver.unresolved_imports == 0 {
+            if self.unresolved_imports == 0 {
                 debug!("(resolving imports) success");
-                for module in self.resolver.arenas.local_modules().iter() {
+                for module in self.arenas.local_modules().iter() {
                     self.finalize_resolutions_in(module, false);
                 }
                 break;
             }
 
-            if self.resolver.unresolved_imports == prev_unresolved_imports {
+            if self.unresolved_imports == prev_unresolved_imports {
                 // resolving failed
                 // Report unresolved imports only if no hard error was already reported
                 // to avoid generating multiple errors on the same import.
                 // Imports that are still indeterminate at this point are actually blocked
                 // by errored imports, so there is no point reporting them.
-                for module in self.resolver.arenas.local_modules().iter() {
+                for module in self.arenas.local_modules().iter() {
                     self.finalize_resolutions_in(module, errors.len() == 0);
                 }
                 for e in errors {
@@ -394,29 +395,31 @@ fn resolve_imports(&mut self) {
             }
 
             i += 1;
-            prev_unresolved_imports = self.resolver.unresolved_imports;
+            prev_unresolved_imports = self.unresolved_imports;
         }
     }
 
     // Define a "dummy" resolution containing a Def::Err as a placeholder for a
     // failed resolution
-    fn import_dummy_binding(&self, source_module: Module<'b>, directive: &'b ImportDirective<'b>) {
+    fn import_dummy_binding(&mut self,
+                            source_module: Module<'b>,
+                            directive: &'b ImportDirective<'b>) {
         if let SingleImport { target, .. } = directive.subclass {
-            let dummy_binding = self.resolver.arenas.alloc_name_binding(NameBinding {
+            let dummy_binding = self.arenas.alloc_name_binding(NameBinding {
                 kind: NameBindingKind::Def(Def::Err),
                 span: DUMMY_SP,
                 vis: ty::Visibility::Public,
             });
-            let dummy_binding = directive.import(dummy_binding);
+            let dummy_binding = self.import(dummy_binding, directive);
 
-            let _ = source_module.try_define_child(target, ValueNS, dummy_binding.clone());
-            let _ = source_module.try_define_child(target, TypeNS, dummy_binding);
+            let _ = self.try_define(source_module, target, ValueNS, dummy_binding.clone());
+            let _ = self.try_define(source_module, target, TypeNS, dummy_binding);
         }
     }
 
     /// Resolves an `ImportResolvingError` into the correct enum discriminant
     /// and passes that on to `resolve_error`.
-    fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
+    fn import_resolving_error(&mut self, e: ImportResolvingError<'b>) {
         // If the error is a single failed import then create a "fake" import
         // resolution for it so that later resolve stages won't complain.
         self.import_dummy_binding(e.source_module, e.import_directive);
@@ -430,7 +433,7 @@ fn import_resolving_error(&self, e: ImportResolvingError<'b>) {
     /// Attempts to resolve imports for the given module only.
     fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolvingError<'b>>) {
         let mut imports = Vec::new();
-        let mut unresolved_imports = self.resolver.current_module.unresolved_imports.borrow_mut();
+        let mut unresolved_imports = self.current_module.unresolved_imports.borrow_mut();
         ::std::mem::swap(&mut imports, &mut unresolved_imports);
 
         for import_directive in imports {
@@ -441,7 +444,7 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
                         None => (import_directive.span, String::new()),
                     };
                     errors.push(ImportResolvingError {
-                        source_module: self.resolver.current_module,
+                        source_module: self.current_module,
                         import_directive: import_directive,
                         span: span,
                         help: help,
@@ -450,8 +453,8 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
                 Indeterminate => unresolved_imports.push(import_directive),
                 Success(()) => {
                     // Decrement the count of unresolved imports.
-                    assert!(self.resolver.unresolved_imports >= 1);
-                    self.resolver.unresolved_imports -= 1;
+                    assert!(self.unresolved_imports >= 1);
+                    self.unresolved_imports -= 1;
                 }
             }
         }
@@ -465,13 +468,13 @@ fn resolve_imports_in_current_module(&mut self, errors: &mut Vec<ImportResolving
     fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResult<()> {
         debug!("(resolving import for module) resolving import `{}::...` in `{}`",
                names_to_string(&directive.module_path),
-               module_to_string(self.resolver.current_module));
+               module_to_string(self.current_module));
 
         let target_module = match directive.target_module.get() {
             Some(module) => module,
-            _ => match self.resolver.resolve_module_path(&directive.module_path,
-                                                         DontUseLexicalScope,
-                                                         directive.span) {
+            _ => match self.resolve_module_path(&directive.module_path,
+                                                DontUseLexicalScope,
+                                                directive.span) {
                 Success(module) => module,
                 Indeterminate => return Indeterminate,
                 Failed(err) => return Failed(err),
@@ -486,38 +489,36 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
         };
 
         // We need to resolve both namespaces for this to succeed.
-        let value_result =
-            self.resolver.resolve_name_in_module(target_module, source, ValueNS, false, true);
-        let type_result =
-            self.resolver.resolve_name_in_module(target_module, source, TypeNS, false, true);
+        let value_result = self.resolve_name_in_module(target_module, source, ValueNS, false, true);
+        let type_result = self.resolve_name_in_module(target_module, source, TypeNS, false, true);
 
-        let module_ = self.resolver.current_module;
+        let module = self.current_module;
         let mut privacy_error = true;
         for &(ns, result, determined) in &[(ValueNS, &value_result, value_determined),
                                            (TypeNS, &type_result, type_determined)] {
             match *result {
                 Failed(..) if !determined.get() => {
                     determined.set(true);
-                    module_.update_resolution(target, ns, |resolution| {
+                    self.update_resolution(module, target, ns, |_, resolution| {
                         resolution.single_imports.directive_failed()
                     });
                 }
                 Success(binding) if !binding.is_importable() => {
                     let msg = format!("`{}` is not directly importable", target);
-                    span_err!(self.resolver.session, directive.span, E0253, "{}", &msg);
+                    span_err!(self.session, directive.span, E0253, "{}", &msg);
                     // Do not import this illegal binding. Import a dummy binding and pretend
                     // everything is fine
-                    self.import_dummy_binding(module_, directive);
+                    self.import_dummy_binding(module, directive);
                     return Success(());
                 }
-                Success(binding) if !self.resolver.is_accessible(binding.vis) => {}
+                Success(binding) if !self.is_accessible(binding.vis) => {}
                 Success(binding) if !determined.get() => {
                     determined.set(true);
-                    let imported_binding = directive.import(binding);
-                    let conflict = module_.try_define_child(target, ns, imported_binding);
+                    let imported_binding = self.import(binding, directive);
+                    let conflict = self.try_define(module, target, ns, imported_binding);
                     if let Err(old_binding) = conflict {
-                        let binding = &directive.import(binding);
-                        self.resolver.report_conflict(module_, target, ns, binding, old_binding);
+                        let binding = &self.import(binding, directive);
+                        self.report_conflict(module, target, ns, binding, old_binding);
                     }
                     privacy_error = false;
                 }
@@ -556,39 +557,35 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
         if privacy_error {
             for &(ns, result) in &[(ValueNS, &value_result), (TypeNS, &type_result)] {
                 let binding = match *result { Success(binding) => binding, _ => continue };
-                self.resolver.privacy_errors.push(PrivacyError(directive.span, source, binding));
-                let _ = module_.try_define_child(target, ns, directive.import(binding));
+                self.privacy_errors.push(PrivacyError(directive.span, source, binding));
+                let imported_binding = self.import(binding, directive);
+                let _ = self.try_define(module, target, ns, imported_binding);
             }
         }
 
         match (&value_result, &type_result) {
-            (&Success(binding), _) if !binding.pseudo_vis()
-                                              .is_at_least(directive.vis, self.resolver) &&
-                                      self.resolver.is_accessible(binding.vis) => {
+            (&Success(binding), _) if !binding.pseudo_vis().is_at_least(directive.vis, self) &&
+                                      self.is_accessible(binding.vis) => {
                 let msg = format!("`{}` is private, and cannot be reexported", source);
                 let note_msg = format!("consider marking `{}` as `pub` in the imported module",
                                         source);
-                struct_span_err!(self.resolver.session, directive.span, E0364, "{}", &msg)
+                struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
                     .span_note(directive.span, &note_msg)
                     .emit();
             }
 
-            (_, &Success(binding)) if !binding.pseudo_vis()
-                                              .is_at_least(directive.vis, self.resolver) &&
-                                      self.resolver.is_accessible(binding.vis) => {
+            (_, &Success(binding)) if !binding.pseudo_vis().is_at_least(directive.vis, self) &&
+                                      self.is_accessible(binding.vis) => {
                 if binding.is_extern_crate() {
                     let msg = format!("extern crate `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring with `pub`",
                                        source);
-                    self.resolver.session.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
-                                                   directive.id,
-                                                   directive.span,
-                                                   msg);
+                    self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
                 } else {
                     let msg = format!("`{}` is private, and cannot be reexported", source);
                     let note_msg =
                         format!("consider declaring type or module `{}` with `pub`", source);
-                    struct_span_err!(self.resolver.session, directive.span, E0365, "{}", &msg)
+                    struct_span_err!(self.session, directive.span, E0365, "{}", &msg)
                         .span_note(directive.span, &note_msg)
                         .emit();
                 }
@@ -605,7 +602,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
             None => value_result.success().and_then(NameBinding::def).unwrap(),
         };
         let path_resolution = PathResolution::new(def);
-        self.resolver.def_map.insert(directive.id, path_resolution);
+        self.def_map.insert(directive.id, path_resolution);
 
         debug!("(resolving single import) successfully resolved import");
         return Success(());
@@ -618,40 +615,41 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> ResolveResul
     fn resolve_glob_import(&mut self, target_module: Module<'b>, directive: &'b ImportDirective<'b>)
                            -> ResolveResult<()> {
         if let Some(Def::Trait(_)) = target_module.def {
-            self.resolver.session.span_err(directive.span, "items in traits are not importable.");
+            self.session.span_err(directive.span, "items in traits are not importable.");
         }
 
-        let module_ = self.resolver.current_module;
-        if module_.def_id() == target_module.def_id() {
+        let module = self.current_module;
+        if module.def_id() == target_module.def_id() {
             // This means we are trying to glob import a module into itself, and it is a no-go
             let msg = "Cannot glob-import a module into itself.".into();
             return Failed(Some((directive.span, msg)));
         }
-        self.resolver.populate_module_if_necessary(target_module);
+        self.populate_module_if_necessary(target_module);
 
         if let GlobImport { is_prelude: true } = directive.subclass {
-            self.resolver.prelude = Some(target_module);
+            self.prelude = Some(target_module);
             return Success(());
         }
 
         // Add to target_module's glob_importers
-        target_module.glob_importers.borrow_mut().push((module_, directive));
+        target_module.glob_importers.borrow_mut().push((module, directive));
 
-        // Ensure that `resolutions` isn't borrowed during `try_define_child`,
+        // Ensure that `resolutions` isn't borrowed during `try_define`,
         // since it might get updated via a glob cycle.
         let bindings = target_module.resolutions.borrow().iter().filter_map(|(name, resolution)| {
             resolution.borrow().binding().map(|binding| (*name, binding))
         }).collect::<Vec<_>>();
         for ((name, ns), binding) in bindings {
             if binding.is_importable() && binding.is_pseudo_public() {
-                let _ = module_.try_define_child(name, ns, directive.import(binding));
+                let imported_binding = self.import(binding, directive);
+                let _ = self.try_define(module, name, ns, imported_binding);
             }
         }
 
         // Record the destination of this import
         if let Some(did) = target_module.def_id() {
             let resolution = PathResolution::new(Def::Mod(did));
-            self.resolver.def_map.insert(directive.id, resolution);
+            self.def_map.insert(directive.id, resolution);
         }
 
         debug!("(resolving glob import) successfully resolved import");
@@ -667,15 +665,23 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_impo
         let mut reexports = Vec::new();
         for (&(name, ns), resolution) in module.resolutions.borrow().iter() {
             let resolution = resolution.borrow();
-            resolution.report_conflicts(|b1, b2| {
-                self.resolver.report_conflict(module, name, ns, b1, b2)
-            });
-
             let binding = match resolution.binding {
                 Some(binding) => binding,
                 None => continue,
             };
 
+            // Report conflicts
+            for duplicate_glob in resolution.duplicate_globs.iter() {
+                // FIXME #31337: We currently allow items to shadow glob-imported re-exports.
+                if !binding.is_import() {
+                    if let NameBindingKind::Import { binding, .. } = duplicate_glob.kind {
+                        if binding.is_import() { continue }
+                    }
+                }
+
+                self.report_conflict(module, name, ns, duplicate_glob, binding);
+            }
+
             if binding.vis == ty::Visibility::Public &&
                (binding.is_import() || binding.is_extern_crate()) {
                 if let Some(def) = binding.def() {
@@ -685,20 +691,19 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>, report_unresolved_impo
 
             if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind {
                 if ns == TypeNS && orig_binding.is_variant() &&
-                   !orig_binding.vis.is_at_least(binding.vis, self.resolver) {
+                   !orig_binding.vis.is_at_least(binding.vis, self) {
                     let msg = format!("variant `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring its enum as `pub`",
                                       name);
-                    let lint = lint::builtin::PRIVATE_IN_PUBLIC;
-                    self.resolver.session.add_lint(lint, directive.id, binding.span, msg);
+                    self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
                 }
             }
         }
 
         if reexports.len() > 0 {
             if let Some(def_id) = module.def_id() {
-                let node_id = self.resolver.definitions.as_local_node_id(def_id).unwrap();
-                self.resolver.export_map.insert(node_id, reexports);
+                let node_id = self.definitions.as_local_node_id(def_id).unwrap();
+                self.export_map.insert(node_id, reexports);
             }
         }
 
index 464c32c3cc725b78992f1bc7ca1844fd6808b01c..f2c7068565ee90d482bfb7471f6f5b0e7f879cbf 100644 (file)
@@ -18,7 +18,7 @@
 use self::namespace::mangled_name_of_item;
 use self::type_names::compute_debuginfo_type_name;
 use self::metadata::{type_metadata, diverging_type_metadata};
-use self::metadata::{file_metadata, scope_metadata, TypeMap};
+use self::metadata::{file_metadata, TypeMap};
 use self::source_loc::InternalDebugLocation::{self, UnknownLocation};
 
 use llvm;
index 2f27aed065d80f17b926d937a1d2ee473c2e1b4e..4980fad0cc37e676f3605bbcfdd667166e1681a7 100644 (file)
@@ -406,9 +406,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
             C_str_slice(ccx, ty_name)
         }
         (_, "type_id") => {
-            let hash = ccx.tcx().hash_crate_independent(*substs.types.get(FnSpace, 0),
-                                                        &ccx.link_meta().crate_hash);
-            C_u64(ccx, hash)
+            C_u64(ccx, ccx.tcx().type_id_hash(*substs.types.get(FnSpace, 0)))
         }
         (_, "init_dropped") => {
             let tp_ty = *substs.types.get(FnSpace, 0);
index 3b2bca4ab391225f9e477195a248be95a9b5eefd..50ffa52e88ba497e5c6833635470a78a7ed6a4b8 100644 (file)
@@ -310,8 +310,12 @@ pub fn opt_ast_region_to_region(&self,
             None => match rscope.anon_regions(default_span, 1) {
                 Ok(rs) => rs[0],
                 Err(params) => {
-                    let mut err = struct_span_err!(self.tcx().sess, default_span, E0106,
-                                                   "missing lifetime specifier");
+                    let ampersand_span = Span { hi: default_span.lo, ..default_span};
+
+                    let mut err = struct_span_err!(self.tcx().sess, ampersand_span, E0106,
+                                                 "missing lifetime specifier");
+                    err.span_label(ampersand_span, &format!("expected lifetime parameter"));
+
                     if let Some(params) = params {
                         report_elision_failure(&mut err, params);
                     }
@@ -1075,8 +1079,10 @@ fn ast_ty_to_trait_ref(&self,
                         Ok((trait_ref, projection_bounds))
                     }
                     _ => {
-                        span_err!(self.tcx().sess, ty.span, E0172,
-                                  "expected a reference to a trait");
+                        struct_span_err!(self.tcx().sess, ty.span, E0172,
+                                  "expected a reference to a trait")
+                            .span_label(ty.span, &format!("expected a trait"))
+                            .emit();
                         Err(ErrorReported)
                     }
                 }
@@ -1086,6 +1092,7 @@ fn ast_ty_to_trait_ref(&self,
                                                "expected a path on the left-hand side \
                                                 of `+`, not `{}`",
                                                pprust::ty_to_string(ty));
+                err.span_label(ty.span, &format!("expected a path"));
                 let hi = bounds.iter().map(|x| match *x {
                     hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
                     hir::RegionTyParamBound(ref r) => r.span.hi,
@@ -2266,9 +2273,25 @@ fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize,
 }
 
 fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected: usize) {
-    span_err!(tcx.sess, span, E0107,
-              "wrong number of lifetime parameters: expected {}, found {}",
-              expected, number);
+    let label = if number < expected {
+        if expected == 1 {
+            format!("expected {} lifetime parameter", expected)
+        } else {
+            format!("expected {} lifetime parameters", expected)
+        }
+    } else {
+        let additional = number - expected;
+        if additional == 1 {
+            "unexpected lifetime parameter".to_string()
+        } else {
+            format!("{} unexpected lifetime parameters", additional)
+        }
+    };
+    struct_span_err!(tcx.sess, span, E0107,
+                     "wrong number of lifetime parameters: expected {}, found {}",
+                     expected, number)
+        .span_label(span, &label)
+        .emit();
 }
 
 // A helper struct for conveniently grouping a set of bounds which we pass to
index 3c176744fca592b0dd766a9a3db378223bd0cfc4..265422468fe2a1c4a18b6ca9f790f005d2f539d5 100644 (file)
@@ -54,9 +54,11 @@ fn next(&mut self) -> Option<Self::Item> {
 
         if self.steps.len() == tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
-            span_err!(tcx.sess, self.span, E0055,
+            struct_span_err!(tcx.sess, self.span, E0055,
                       "reached the recursion limit while auto-dereferencing {:?}",
-                      self.cur_ty);
+                      self.cur_ty)
+                      .span_label(self.span, &format!("deref recursion limit reached"))
+                      .emit();
             return None;
         }
 
index 6062bd048b3d27f8972edfbdce5efa766c448aab..8da061208730fc85dfd52f5d9cc43300495e5e73 100644 (file)
@@ -847,7 +847,9 @@ fn check_trait_fn_not_const<'a,'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             // good
         }
         hir::Constness::Const => {
-            span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const");
+            struct_span_err!(ccx.tcx.sess, span, E0379, "trait fns cannot be declared const")
+                .span_label(span, &format!("trait fns cannot be const"))
+                .emit()
         }
     }
 }
@@ -993,7 +995,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // Check existing impl methods to see if they are both present in trait
     // and compatible with trait signature
     for impl_item in impl_items {
-        let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
+        let ty_impl_item = tcx.impl_or_trait_item(tcx.map.local_def_id(impl_item.id));
         let ty_trait_item = trait_items.iter()
             .find(|ac| ac.name() == ty_impl_item.name());
 
@@ -1014,11 +1016,18 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                            trait_const,
                                            &impl_trait_ref);
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0323,
+                         let mut err = struct_span_err!(tcx.sess, impl_item.span, E0323,
                                   "item `{}` is an associated const, \
                                   which doesn't match its trait `{:?}`",
                                   impl_const.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         // We can only get the spans from local trait definition
+                         // Same for E0324 and E0325
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
                 hir::ImplItemKind::Method(ref sig, ref body) => {
@@ -1037,11 +1046,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                             &trait_method,
                                             &impl_trait_ref);
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0324,
+                        let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324,
                                   "item `{}` is an associated method, \
                                   which doesn't match its trait `{:?}`",
                                   impl_method.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
                 hir::ImplItemKind::Type(_) => {
@@ -1055,11 +1069,16 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                             overridden_associated_type = Some(impl_item);
                         }
                     } else {
-                        span_err!(tcx.sess, impl_item.span, E0325,
+                        let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325,
                                   "item `{}` is an associated type, \
                                   which doesn't match its trait `{:?}`",
                                   impl_type.name,
-                                  impl_trait_ref)
+                                  impl_trait_ref);
+                         err.span_label(impl_item.span, &format!("does not match trait"));
+                         if let Some(trait_span) = tcx.map.span_if_local(ty_trait_item.def_id()) {
+                            err.span_label(trait_span, &format!("original trait requirement"));
+                         }
+                         err.emit()
                     }
                 }
             }
@@ -1251,8 +1270,9 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 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!(&mut err, ccx.tcx.map.span(variant_i_node_id),
-                    "conflicting discriminant here");
+                err.span_label(ccx.tcx.map.span(variant_i_node_id),
+                               &format!("first use of `{}`", disr_vals[i]));
+                err.span_label(v.span , &format!("enum already has `{}`", disr_vals[i]));
                 err.emit();
             }
             disr_vals.push(current_disr_val);
@@ -2384,6 +2404,12 @@ fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
                     arg_count,
                     if arg_count == 1 {" was"} else {"s were"}),
                 error_code);
+
+            err.span_label(sp, &format!("expected {}{} parameter{}",
+                                        if variadic {"at least "} else {""},
+                                        expected_count,
+                                        if expected_count == 1 {""} else {"s"}));
+
             let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
             if input_types.len() > 0 {
                 err.note(&format!("the following parameter type{} expected: {}",
@@ -3063,6 +3089,8 @@ fn check_expr_struct_fields(&self,
             remaining_fields.insert(field.name, field);
         }
 
+        let mut seen_fields = FnvHashMap();
+
         let mut error_happened = false;
 
         // Typecheck each field.
@@ -3071,13 +3099,25 @@ fn check_expr_struct_fields(&self,
 
             if let Some(v_field) = remaining_fields.remove(&field.name.node) {
                 expected_field_type = self.field_ty(field.span, v_field, substs);
+
+                seen_fields.insert(field.name.node, field.span);
             } else {
                 error_happened = true;
                 expected_field_type = tcx.types.err;
                 if let Some(_) = variant.find_field_named(field.name.node) {
-                    span_err!(self.tcx.sess, field.name.span, E0062,
-                        "field `{}` specified more than once",
-                        field.name.node);
+                    let mut err = struct_span_err!(self.tcx.sess,
+                                                field.name.span,
+                                                E0062,
+                                                "field `{}` specified more than once",
+                                                field.name.node);
+
+                    err.span_label(field.name.span, &format!("used more than once"));
+
+                    if let Some(prev_span) = seen_fields.get(&field.name.node) {
+                        err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
+                    }
+
+                    err.emit();
                 } else {
                     self.report_unknown_field(adt_ty, variant, field, ast_fields);
                 }
@@ -3147,9 +3187,12 @@ pub fn check_struct_path(&self,
         };
         if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple {
             // Reject tuple structs for now, braced and unit structs are allowed.
-            span_err!(self.tcx.sess, span, E0071,
-                      "`{}` does not name a struct or a struct variant",
-                      pprust::path_to_string(path));
+            struct_span_err!(self.tcx.sess, path.span, E0071,
+                             "`{}` does not name a struct or a struct variant",
+                             pprust::path_to_string(path))
+                .span_label(path.span, &format!("not a struct"))
+                .emit();
+
             return None;
         }
 
@@ -3383,8 +3426,10 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
                             // FIXME(#32730) propagate obligations
                             .map(|InferOk { obligations, .. }| assert!(obligations.is_empty()));
                         if eq_result.is_err() {
-                            span_err!(tcx.sess, expr.span, E0069,
-                                      "`return;` in a function whose return type is not `()`");
+                            struct_span_err!(tcx.sess, expr.span, E0069,
+                                     "`return;` in a function whose return type is not `()`")
+                                .span_label(expr.span, &format!("return type is not ()"))
+                                .emit();
                         }
                     }
                 }
@@ -3392,8 +3437,10 @@ fn check_expr_with_expectation_and_lvalue_pref(&self,
                     if let Some(ref e) = *expr_opt {
                         self.check_expr(&e);
                     }
-                    span_err!(tcx.sess, expr.span, E0166,
-                        "`return` in a function declared as diverging");
+                    struct_span_err!(tcx.sess, expr.span, E0166,
+                        "`return` in a function declared as diverging")
+                        .span_label(expr.span, &format!("diverging function cannot return"))
+                        .emit();
                 }
             }
             self.write_ty(id, self.next_diverging_ty_var());
index d02f87d0b9cd64236700279cd10bfc1744f0c7af..63487683ec3b990feff4aa0fc1687b465cc916f0 100644 (file)
@@ -176,11 +176,15 @@ fn check_overloaded_binop(&self,
                 // error types are considered "builtin"
                 if !lhs_ty.references_error() {
                     if let IsAssign::Yes = is_assign {
-                        span_err!(self.tcx.sess, lhs_expr.span, E0368,
-                                  "binary assignment operation `{}=` \
-                                   cannot be applied to type `{}`",
-                                  op.node.as_str(),
-                                  lhs_ty);
+                        struct_span_err!(self.tcx.sess, lhs_expr.span, E0368,
+                                         "binary assignment operation `{}=` \
+                                          cannot be applied to type `{}`",
+                                         op.node.as_str(),
+                                         lhs_ty)
+                            .span_label(lhs_expr.span,
+                                        &format!("cannot use `{}=` on type `{}`",
+                                        op.node.as_str(), lhs_ty))
+                            .emit();
                     } else {
                         let mut err = struct_span_err!(self.tcx.sess, lhs_expr.span, E0369,
                             "binary operation `{}` cannot be applied to type `{}`",
index 198e9afd5e12c77f1604d753ba612ba8414ad38c..2d14b0dacf24cdad759aaf5f63222a698082bd63 100644 (file)
@@ -249,8 +249,17 @@ fn populate_destructors(&self) {
                     if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) {
                         match tcx.map.find(impl_node_id) {
                             Some(hir_map::NodeItem(item)) => {
-                                span_err!(tcx.sess, item.span, E0120,
-                                          "the Drop trait may only be implemented on structures");
+                                let span = match item.node {
+                                    ItemImpl(_, _, _, _, ref ty, _) => {
+                                        ty.span
+                                    },
+                                    _ => item.span
+                                };
+                                struct_span_err!(tcx.sess, span, E0120,
+                                    "the Drop trait may only be implemented on structures")
+                                    .span_label(span,
+                                                &format!("implementing Drop requires a struct"))
+                                    .emit();
                             }
                             _ => {
                                 bug!("didn't find impl in ast map");
@@ -258,7 +267,7 @@ fn populate_destructors(&self) {
                         }
                     } else {
                         bug!("found external impl of Drop trait on \
-                              :omething other than a struct");
+                              something other than a struct");
                     }
                 }
             }
index dcaa5cfb20a46ff73a8c8f3509ec0bce51be717d..54bd141304d7816e21966f600a6c7c3878e1096f 100644 (file)
@@ -141,12 +141,18 @@ fn visit_item(&mut self, item: &'v hir::Item) {
                         self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119,
                         "conflicting implementations of trait `{}`{}:",
                         overlap.trait_desc,
-                        overlap.self_desc.map_or(String::new(),
-                                                 |ty| format!(" for type `{}`", ty)));
+                        overlap.self_desc.clone().map_or(String::new(),
+                                                         |ty| format!(" for type `{}`", ty)));
 
                     match self.tcx.span_of_impl(overlap.with_impl) {
                         Ok(span) => {
-                            err.span_note(span, "conflicting implementation is here:");
+                            err.span_label(span,
+                                           &format!("first implementation here"));
+                            err.span_label(self.tcx.span_of_impl(impl_def_id).unwrap(),
+                                           &format!("conflicting implementation{}",
+                                                    overlap.self_desc
+                                                        .map_or(String::new(),
+                                                                |ty| format!(" for `{}`", ty))));
                         }
                         Err(cname) => {
                             err.note(&format!("conflicting implementation in crate `{}`",
index 4486748a1f0564fbc9bf6c873d26be741c7edec9..92b91028b98b0b1401cc32faed14763e25b75ffd 100644 (file)
@@ -184,6 +184,7 @@ fn report_cycle(&self,
 
         let mut err = struct_span_err!(tcx.sess, span, E0391,
             "unsupported cyclic reference between types/traits detected");
+        err.span_label(span, &format!("cyclic reference"));
 
         match cycle[0] {
             AstConvRequest::GetItemTypeScheme(def_id) |
@@ -1010,11 +1011,12 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         let fid = ccx.tcx.map.local_def_id(f.id);
         let dup_span = seen_fields.get(&f.name).cloned();
         if let Some(prev_span) = dup_span {
-            let mut err = struct_span_err!(ccx.tcx.sess, f.span, E0124,
-                                           "field `{}` is already declared",
-                                           f.name);
-            span_note!(&mut err, prev_span, "previously declared here");
-            err.emit();
+            struct_span_err!(ccx.tcx.sess, f.span, E0124,
+                             "field `{}` is already declared",
+                             f.name)
+                .span_label(f.span, &"field already declared")
+                .span_label(prev_span, &format!("`{}` first declared here", f.name))
+                .emit();
         } else {
             seen_fields.insert(f.name, f.span);
         }
@@ -1057,6 +1059,7 @@ fn evaluate_disr_expr(ccx: &CrateCtxt, repr_ty: attr::IntType, e: &hir::Expr)
         let print_err = |cv: ConstVal| {
             struct_span_err!(ccx.tcx.sess, e.span, E0079, "mismatched types")
                 .note_expected_found(&"type", &ty_hint, &format!("{}", cv.description()))
+                .span_label(e.span, &format!("expected '{}' type", ty_hint))
                 .emit();
         };
 
@@ -2314,8 +2317,12 @@ fn report_unused_parameter(ccx: &CrateCtxt,
                            kind: &str,
                            name: &str)
 {
-    span_err!(ccx.tcx.sess, span, E0207,
-              "the {} parameter `{}` is not constrained by the \
-               impl trait, self type, or predicates",
-              kind, name);
+    struct_span_err!(
+        ccx.tcx.sess, span, E0207,
+        "the {} parameter `{}` is not constrained by the \
+        impl trait, self type, or predicates",
+        kind, name)
+        .span_label(span, &format!("unconstrained lifetime parameter"))
+        .emit();
+
 }
index b655d955429f06087ada1e969a5b866d3d2a084d..64b27857d2c610b50e6cc04850585b46ba4275ca 100644 (file)
@@ -3864,6 +3864,104 @@ fn fly(&self) {} // And now that's ok!
 ```
 "##,
 
+E0527: r##"
+The number of elements in an array or slice pattern differed from the number of
+elements in the array being matched.
+
+Example of erroneous code:
+
+```compile_fail,E0527
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4];
+match r {
+    &[a, b] => { // error: pattern requires 2 elements but array
+                 //        has 4
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+
+Ensure that the pattern is consistent with the size of the matched
+array. Additional elements can be matched with `..`:
+
+```
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4];
+match r {
+    &[a, b, ..] => { // ok!
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+"##,
+
+E0528: r##"
+An array or slice pattern required more elements than were present in the
+matched array.
+
+Example of erroneous code:
+
+```compile_fail,E0528
+#![feature(slice_patterns)]
+
+let r = &[1, 2];
+match r {
+    &[a, b, c, rest..] => { // error: pattern requires at least 3
+                            //        elements but array has 2
+        println!("a={}, b={}, c={} rest={:?}", a, b, c, rest);
+    }
+}
+```
+
+Ensure that the matched array has at least as many elements as the pattern
+requires. You can match an arbitrary number of remaining elements with `..`:
+
+```
+#![feature(slice_patterns)]
+
+let r = &[1, 2, 3, 4, 5];
+match r {
+    &[a, b, c, rest..] => { // ok!
+        // prints `a=1, b=2, c=3 rest=[4, 5]`
+        println!("a={}, b={}, c={} rest={:?}", a, b, c, rest);
+    }
+}
+```
+"##,
+
+E0529: r##"
+An array or slice pattern was matched against some other type.
+
+Example of erroneous code:
+
+```compile_fail,E0529
+#![feature(slice_patterns)]
+
+let r: f32 = 1.0;
+match r {
+    [a, b] => { // error: expected an array or slice, found `f32`
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+
+Ensure that the pattern and the expression being matched on are of consistent
+types:
+
+```
+#![feature(slice_patterns)]
+
+let r = [1.0, 2.0];
+match r {
+    [a, b] => { // ok!
+        println!("a={}, b={}", a, b);
+    }
+}
+```
+"##,
+
 E0559: r##"
 An unknown field was specified into an enum's structure variant.
 
@@ -3985,8 +4083,5 @@ struct Simba {
     E0436, // functional record update requires a struct
     E0513, // no type for local variable ..
     E0521, // redundant default implementations of trait
-    E0527, // expected {} elements, found {}
-    E0528, // expected at least {} elements, found {}
-    E0529, // slice pattern expects array or slice, not `{}`
     E0533, // `{}` does not name a unit variant, unit struct or a constant
 }
index 3b2d02dc861c4c62c0b8542f0b3f0da67eddbef8..6f0892cdcdf1619f62e74198f5af4940c129a215 100644 (file)
@@ -261,8 +261,11 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
                     match it.node {
                         hir::ItemFn(_,_,_,_,ref ps,_)
                         if ps.is_parameterized() => {
-                            span_err!(tcx.sess, start_span, E0132,
-                                      "start function is not allowed to have type parameters");
+                            struct_span_err!(tcx.sess, start_span, E0132,
+                                "start function is not allowed to have type parameters")
+                                .span_label(ps.span().unwrap(),
+                                            &format!("start function cannot have type parameters"))
+                                .emit();
                             return;
                         }
                         _ => ()
index 0d3e18f9b966a2848781cafd10f2944d14ec2156..f800a6e228e9ba0f96bcf56f20e4ef63964cb3e8 100644 (file)
@@ -356,6 +356,18 @@ fn borrow(&self) -> &CStr { self }
 impl NulError {
     /// Returns the position of the nul byte in the slice that was provided to
     /// `CString::new`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::CString;
+    ///
+    /// let nul_error = CString::new("foo\0bar").unwrap_err();
+    /// assert_eq!(nul_error.nul_position(), 3);
+    ///
+    /// let nul_error = CString::new("foo bar\0").unwrap_err();
+    /// assert_eq!(nul_error.nul_position(), 7);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn nul_position(&self) -> usize { self.0 }
 
index 38fd93501a528520f7b1ea951780f5209b966dba..b78db24e44b70784d202a6cff358804e88bda909 100644 (file)
@@ -156,7 +156,10 @@ pub struct File {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
 
-/// An structure representing a type of file with accessors for each file type.
+/// A structure representing a type of file with accessors for each file type.
+/// It is returned by [`Metadata::file_type`] method.
+///
+/// [`Metadata::file_type`]: struct.Metadata.html#method.file_type
 #[stable(feature = "file_type", since = "1.1.0")]
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType(fs_imp::FileType);
@@ -610,6 +613,19 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
 
 impl Metadata {
     /// Returns the file type for this metadata.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    ///
+    /// println!("{:?}", metadata.file_type());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn file_type(&self) -> FileType {
         FileType(self.0.file_type())
@@ -839,14 +855,56 @@ pub fn set_readonly(&mut self, readonly: bool) {
 
 impl FileType {
     /// Test whether this file type represents a directory.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_dir(), false);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_dir(&self) -> bool { self.0.is_dir() }
 
     /// Test whether this file type represents a regular file.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_file(), true);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_file(&self) -> bool { self.0.is_file() }
 
     /// Test whether this file type represents a symbolic link.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn foo() -> std::io::Result<()> {
+    /// use std::fs;
+    ///
+    /// let metadata = try!(fs::metadata("foo.txt"));
+    /// let file_type = metadata.file_type();
+    ///
+    /// assert_eq!(file_type.is_symlink(), false);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type", since = "1.1.0")]
     pub fn is_symlink(&self) -> bool { self.0.is_symlink() }
 }
index 05ae8ed5b0b66be71b491821fa99be19f2534f74..5333b0a531eaebd671245e8081c71a4cb72cc028 100644 (file)
@@ -55,7 +55,9 @@
 ///
 /// Errors mostly originate from the underlying OS, but custom instances of
 /// `Error` can be created with crafted error messages and a particular value of
-/// `ErrorKind`.
+/// [`ErrorKind`].
+///
+/// [`ErrorKind`]: enum.ErrorKind.html
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Error {
@@ -77,6 +79,10 @@ struct Custom {
 ///
 /// This list is intended to grow over time and it is not recommended to
 /// exhaustively match against it.
+///
+/// It is used with the [`io::Error`] type.
+///
+/// [`io::Error`]: struct.Error.html
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(deprecated)]
@@ -208,6 +214,14 @@ fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
     /// This function reads the value of `errno` for the target platform (e.g.
     /// `GetLastError` on Windows) and will return a corresponding instance of
     /// `Error` for the error code.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::Error;
+    ///
+    /// println!("last OS error: {:?}", Error::last_os_error());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn last_os_error() -> Error {
         Error::from_raw_os_error(sys::os::errno() as i32)
@@ -248,6 +262,27 @@ pub fn from_raw_os_error(code: i32) -> Error {
     /// If this `Error` was constructed via `last_os_error` or
     /// `from_raw_os_error`, then this function will return `Some`, otherwise
     /// it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_os_error(err: &Error) {
+    ///     if let Some(raw_os_err) = err.raw_os_error() {
+    ///         println!("raw OS error: {:?}", raw_os_err);
+    ///     } else {
+    ///         println!("Not an OS error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "raw OS error: ...".
+    ///     print_os_error(&Error::last_os_error());
+    ///     // Will print "Not an OS error".
+    ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn raw_os_error(&self) -> Option<i32> {
         match self.repr {
@@ -260,6 +295,27 @@ pub fn raw_os_error(&self) -> Option<i32> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: &Error) {
+    ///     if let Some(inner_err) = err.get_ref() {
+    ///         println!("Inner error: {:?}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(&Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
         match self.repr {
@@ -273,6 +329,63 @@ pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    /// use std::{error, fmt};
+    /// use std::fmt::Display;
+    ///
+    /// #[derive(Debug)]
+    /// struct MyError {
+    ///     v: String,
+    /// }
+    ///
+    /// impl MyError {
+    ///     fn new() -> MyError {
+    ///         MyError {
+    ///             v: "oh no!".to_owned()
+    ///         }
+    ///     }
+    ///
+    ///     fn change_message(&mut self, new_message: &str) {
+    ///         self.v = new_message.to_owned();
+    ///     }
+    /// }
+    ///
+    /// impl error::Error for MyError {
+    ///     fn description(&self) -> &str { &self.v }
+    /// }
+    ///
+    /// impl Display for MyError {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "MyError: {}", &self.v)
+    ///     }
+    /// }
+    ///
+    /// fn change_error(mut err: Error) -> Error {
+    ///     if let Some(inner_err) = err.get_mut() {
+    ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
+    ///     }
+    ///     err
+    /// }
+    ///
+    /// fn print_error(err: &Error) {
+    ///     if let Some(inner_err) = err.get_ref() {
+    ///         println!("Inner error: {}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(&change_error(Error::last_os_error()));
+    ///     // Will print "Inner error: ...".
+    ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
         match self.repr {
@@ -285,6 +398,27 @@ pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
     ///
     /// If this `Error` was constructed via `new` then this function will
     /// return `Some`, otherwise it will return `None`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: Error) {
+    ///     if let Some(inner_err) = err.into_inner() {
+    ///         println!("Inner error: {}", inner_err);
+    ///     } else {
+    ///         println!("No inner error");
+    ///     }
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
     pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
         match self.repr {
@@ -294,6 +428,23 @@ pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
     }
 
     /// Returns the corresponding `ErrorKind` for this error.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{Error, ErrorKind};
+    ///
+    /// fn print_error(err: Error) {
+    ///     println!("{:?}", err.kind());
+    /// }
+    ///
+    /// fn main() {
+    ///     // Will print "No inner error".
+    ///     print_error(Error::last_os_error());
+    ///     // Will print "Inner error: ...".
+    ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> ErrorKind {
         match self.repr {
index d5b255ee57376fb9dac3495ad74a9d453477f9ce..88fd4186e0a2a73be02e98964f822de8c46c692d 100644 (file)
@@ -1082,16 +1082,22 @@ pub trait Seek {
     ///
     /// If the seek operation completed successfully,
     /// this method returns the new position from the start of the stream.
-    /// That position can be used later with `SeekFrom::Start`.
+    /// That position can be used later with [`SeekFrom::Start`].
     ///
     /// # Errors
     ///
     /// Seeking to a negative offset is considered an error.
+    ///
+    /// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start
     #[stable(feature = "rust1", since = "1.0.0")]
     fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
 }
 
 /// Enumeration of possible methods to seek within an I/O object.
+///
+/// It is used by the [`Seek`] trait.
+///
+/// [`Seek`]: trait.Seek.html
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum SeekFrom {
@@ -1482,6 +1488,24 @@ impl<T> Take<T> {
     ///
     /// This instance may reach EOF after reading fewer bytes than indicated by
     /// this method if the underlying `Read` instance reaches EOF.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let f = try!(File::open("foo.txt"));
+    ///
+    /// // read at most five bytes
+    /// let handle = f.take(5);
+    ///
+    /// println!("limit: {}", handle.limit());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn limit(&self) -> u64 { self.limit }
 }
index c4b573db5f2dd41b44f4179cba30e5680ed88cfe..b8b66a58359e7013d135713767a4936c1a3d8c0d 100644 (file)
@@ -240,6 +240,21 @@ impl Stdin {
     ///
     /// [`Read`]: trait.Read.html
     /// [`BufRead`]: trait.BufRead.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Read};
+    ///
+    /// # fn foo() -> io::Result<String> {
+    /// let mut buffer = String::new();
+    /// let stdin = io::stdin();
+    /// let mut handle = stdin.lock();
+    ///
+    /// try!(handle.read_to_string(&mut buffer));
+    /// # Ok(buffer)
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdinLock {
         StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -399,6 +414,21 @@ impl Stdout {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Write};
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let stdout = io::stdout();
+    /// let mut handle = stdout.lock();
+    ///
+    /// try!(handle.write(b"hello world"));
+    ///
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StdoutLock {
         StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
@@ -505,6 +535,21 @@ impl Stderr {
     ///
     /// The lock is released when the returned lock goes out of scope. The
     /// returned guard also implements the `Write` trait for writing data.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::io::{self, Write};
+    ///
+    /// fn foo() -> io::Result<()> {
+    ///     let stderr = io::stderr();
+    ///     let mut handle = stderr.lock();
+    ///
+    ///     try!(handle.write(b"hello world"));
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> StderrLock {
         StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) }
index ac13b23ebee50256b70f780917b182f77ffce26b..11a16b271133be76cbc9ca1c386588a43b091ae6 100644 (file)
 mod parser;
 #[cfg(test)] mod test;
 
-/// Possible values which can be passed to the `shutdown` method of `TcpStream`.
+/// Possible values which can be passed to the [`shutdown`] method of
+/// [`TcpStream`].
+///
+/// [`shutdown`]: struct.TcpStream.html#method.shutdown
+/// [`TcpStream`]: struct.TcpStream.html
 #[derive(Copy, Clone, PartialEq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
index 5ab0d5a0877b7fee92d85e95b0c3806e3ab0a0bc..76617f159707dd2233da5ce8ab72b247bf05b84e 100644 (file)
 ///
 /// This iterator will infinitely yield `Some` of the accepted connections. It
 /// is equivalent to calling `accept` in a loop.
+///
+/// This `struct` is created by the [`incoming`] method on [`TcpListener`].
+///
+/// [`incoming`]: struct.TcpListener.html#method.incoming
+/// [`TcpListener`]: struct.TcpListener.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Incoming<'a> { listener: &'a TcpListener }
 
index b315e6762633b3fd982566c5a311360a3ad4065b..3b132744f7055ce176e0f0689aca601b53a454c6 100644 (file)
@@ -27,7 +27,7 @@
 #[cfg(any(target_os = "linux", target_os = "emscripten"))]
 use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
 #[cfg(target_os = "android")]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off64_t, lseek64,
+use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, lseek64,
            dirent as dirent64, open as open64};
 #[cfg(not(any(target_os = "linux",
               target_os = "emscripten",
@@ -485,9 +485,11 @@ pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, pos) = match pos {
-            SeekFrom::Start(off) => (libc::SEEK_SET, off as off64_t),
-            SeekFrom::End(off) => (libc::SEEK_END, off as off64_t),
-            SeekFrom::Current(off) => (libc::SEEK_CUR, off as off64_t),
+            // Casting to `i64` is fine, too large values will end up as
+            // negative which will cause an error in `lseek64`.
+            SeekFrom::Start(off) => (libc::SEEK_SET, off as i64),
+            SeekFrom::End(off) => (libc::SEEK_END, off),
+            SeekFrom::Current(off) => (libc::SEEK_CUR, off),
         };
         let n = cvt(unsafe { lseek64(self.0.raw(), pos, whence) })?;
         Ok(n as u64)
index 2683e57256dc79afc29a2872a31861f77a788d53..4e6cef9a28d8f32147d5db051c5e95c2f5469a69 100644 (file)
@@ -324,6 +324,8 @@ pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, pos) = match pos {
+            // Casting to `i64` is fine, `SetFilePointerEx` reinterprets this
+            // integer as `u64`.
             SeekFrom::Start(n) => (c::FILE_BEGIN, n as i64),
             SeekFrom::End(n) => (c::FILE_END, n),
             SeekFrom::Current(n) => (c::FILE_CURRENT, n),
index e9736fea7b37f43955f04d7137cefa517cfaaa9b..f06c105d30e6500eee11e92e8f8c73ecdd4c07ff 100644 (file)
@@ -447,6 +447,8 @@ pub fn park() {
     *guard = false;
 }
 
+/// Use [park_timeout].
+///
 /// Blocks unless or until the current thread's token is made available or
 /// the specified duration has been reached (may wake spuriously).
 ///
@@ -456,7 +458,10 @@ pub fn park() {
 /// preemption or platform differences that may not cause the maximum
 /// amount of time waited to be precisely `ms` long.
 ///
-/// See the module doc for more detail.
+/// See the [module documentation][thread] for more detail.
+///
+/// [thread]: index.html
+/// [park_timeout]: fn.park_timeout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
 pub fn park_timeout_ms(ms: u32) {
@@ -478,6 +483,25 @@ pub fn park_timeout_ms(ms: u32) {
 ///
 /// Platforms which do not support nanosecond precision for sleeping will have
 /// `dur` rounded up to the nearest granularity of time they can sleep for.
+///
+/// # Example
+///
+/// Waiting for the complete expiration of the timeout:
+///
+/// ```rust,no_run
+/// use std::thread::park_timeout;
+/// use std::time::{Instant, Duration};
+///
+/// let timeout = Duration::from_secs(2);
+/// let beginning_park = Instant::now();
+/// park_timeout(timeout);
+///
+/// while beginning_park.elapsed() < timeout {
+///     println!("restarting park_timeout after {:?}", beginning_park.elapsed());
+///     let timeout = timeout - beginning_park.elapsed();
+///     park_timeout(timeout);
+/// }
+/// ```
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
     let thread = current();
index f86d7ec114b938132fd532a8bc61a08b538b7872..2b2d278ad4cc63eb6f93cb47ecc215e3557d38ce 100644 (file)
@@ -18,5 +18,7 @@ fn foo(&self) {}
 fn main() {
     let foo = Foo;
     let ref_foo = &&Foo;
-    ref_foo.foo(); //~ ERROR E0055
+    ref_foo.foo();
+    //~^ ERROR E0055
+    //~| NOTE deref recursion limit reached
 }
index b4a289874979206a59f328f4e05607d41d445902..e1f2618c180f6d54db60ae488094f0a166e15e87 100644 (file)
@@ -13,5 +13,8 @@
 }
 
 fn main() {
-    unsafe { printf(); } //~ ERROR E0060
+    unsafe { printf(); }
+    //~^ ERROR E0060
+    //~| NOTE expected at least 1 parameter
+    //~| NOTE the following parameter type was expected
 }
index 4a8eac2a9e2268d98e85dda3b9d6cb13d4edb998..ca04b059dc7f699cc0a576378b0ac94252a10d90 100644 (file)
@@ -11,5 +11,8 @@
 fn f(a: u16, b: &str) {}
 
 fn main() {
-    f(0); //~ ERROR E0061
+    f(0);
+    //~^ ERROR E0061
+    //~| NOTE expected 2 parameters
+    //~| NOTE the following parameter types were expected
 }
index 86ec7db14b5c17d50621bddb8b45bf289ec56647..822d93e52d588c5688a7ecc759dd023b9ee5cf1d 100644 (file)
@@ -14,7 +14,9 @@ struct Foo {
 
 fn main() {
     let x = Foo {
+        x: 0, //~ NOTE first use of `x`
         x: 0,
-        x: 0, //~ ERROR E0062
+        //~^ ERROR E0062
+        //~| NOTE used more than once
     };
 }
index d164d86348784255b86e9bf57dd5efb746eb1de7..00facc91728027608eb85702b2517cd21e561ca1 100644 (file)
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 fn foo() -> u8 {
-    return; //~ ERROR E0069
+    return;
+    //~^ ERROR `return;` in a function whose return type is not `()`
+    //~| NOTE return type is not ()
 }
 
 fn main() {
index 658c8fb1551149fd909d0464a66fd109795eb006..6f0e55efffc921dc31a991972b007f515b5f46de 100644 (file)
 enum Foo { FirstValue(i32) }
 
 fn main() {
-    let u = Foo::FirstValue { value: 0 }; //~ ERROR E0071
-    let t = u32 { value: 4 }; //~ ERROR E0071
+    let u = Foo::FirstValue { value: 0 };
+    //~^ ERROR `Foo::FirstValue` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
+
+    let t = u32 { value: 4 };
+    //~^ ERROR `u32` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
 }
index 23957c72ff00eadd4ab402b8c0717bb947b11eb4..c9b7f549d5aaaea6cf029292716f1541c9b0d31d 100644 (file)
@@ -10,6 +10,7 @@
 
 enum Foo {
     Q = "32" //~ ERROR E0079
+    //~^ expected 'isize' type
 }
 
 fn main() {
index f1cd530863d341e4e291856688ed9cb7652d032d..dab03f0bccfd0b88befcaa5d581470af50a530a1 100644 (file)
@@ -9,13 +9,19 @@
 // except according to those terms.
 
 struct Foo {
-    x: &bool, //~ ERROR E0106
+    x: &bool,
+    //~^ ERROR E0106
+    //~| NOTE expected lifetime parameter
 }
 enum Bar {
     A(u8),
-    B(&bool), //~ ERROR E0106
+    B(&bool),
+   //~^ ERROR E0106
+   //~| NOTE expected lifetime parameter
 }
-type MyStr = &str; //~ ERROR E0106
+type MyStr = &str;
+        //~^ ERROR E0106
+        //~| NOTE expected lifetime parameter
 
 fn main() {
 }
index d27b70865bbfbccd7c925e6c03f1004f7de707bf..5f333e17c478efeabaeec150842e1bd4530df4ff 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 struct Foo<'a>(&'a str);
+struct Buzz<'a, 'b>(&'a str, &'b str);
 
 enum Bar {
     A,
@@ -16,9 +17,19 @@ enum Bar {
     C,
 }
 
-struct Baz<'a> {
-    foo: Foo, //~ ERROR E0107
-    bar: Bar<'a>, //~ ERROR E0107
+struct Baz<'a, 'b, 'c> {
+    foo: Foo,
+    //~^ ERROR E0107
+    //~| expected 1 lifetime parameter
+    buzz: Buzz<'a>,
+    //~^ ERROR E0107
+    //~| expected 2 lifetime parameters
+    bar: Bar<'a>,
+    //~^ ERROR E0107
+    //~| unexpected lifetime parameter
+    foo2: Foo<'a, 'b, 'c>,
+    //~^ ERROR E0107
+    //~| 2 unexpected lifetime parameters
 }
 
 fn main() {
index 9fc478422504bbe750c2f3b230f022bdb56c61cc..2e4cbf8692693c6844a318a924eba6bae0bb8c3e 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 type X = u32<i32>; //~ ERROR E0109
+                   //~| NOTE type parameter not allowed
 
 fn main() {
 }
index fd169f4acc5eb0250ad5fae39283d51883764ee0..5a9e7a43de96b6b68142936404135d419937ba01 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 type X = u32<'static>; //~ ERROR E0110
+                       //~| NOTE lifetime parameter not allowed on this type
 
 fn main() {
 }
index 9528631b3047b6bd749b3aad2db3a7f1ea5cd4a0..56820bcd1840ceafae7c0c45bab2322aa53ac2e4 100644 (file)
@@ -12,7 +12,7 @@ trait MyTrait {
     fn get(&self) -> usize;
 }
 
-impl<T> MyTrait for T {
+impl<T> MyTrait for T { //~ NOTE first implementation here
     fn get(&self) -> usize { 0 }
 }
 
@@ -21,6 +21,7 @@ struct Foo {
 }
 
 impl MyTrait for Foo { //~ ERROR E0119
+                       //~| NOTE conflicting implementation for `Foo`
     fn get(&self) -> usize { self.value }
 }
 
index de084274f6fb80883c8cce0380e1d4cf5cba7d1f..3fdeb7531754021d2f7ae780f039fb672df6265d 100644 (file)
@@ -10,7 +10,9 @@
 
 trait MyTrait {}
 
-impl Drop for MyTrait { //~ ERROR E0120
+impl Drop for MyTrait {
+              //~^ ERROR E0120
+              //~| NOTE implementing Drop requires a struct
     fn drop(&mut self) {}
 }
 
index 414b19ead624d052aea6d42f382d0b27b963fe5a..18c507461065642ab97ae52c82e48b5d116dc691 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 struct Foo {
+    field1: i32, //~ NOTE `field1` first declared here
     field1: i32,
-    field1: i32, //~ ERROR E0124
+    //~^ ERROR field `field1` is already declared [E0124]
+    //~| NOTE field already declared
 }
 
 fn main() {
index ff19a577f903dbe4016e18043eb6943768c6fb97..1a33fb24ca1a1a0eee3d3dac51f6620ffc602910 100644 (file)
@@ -12,6 +12,7 @@
 
 #[start]
 fn f<T>() {} //~ ERROR E0132
+             //~| NOTE start function cannot have type parameters
 
 fn main() {
 }
index 695ce7995a9a46ef3cb44fad2b4a5cc687c8388d..f45afc9f37bd51f0cb816552f5305e0c9a58af31 100644 (file)
@@ -11,7 +11,9 @@
 #![feature(main)]
 
 #[main]
-fn foo() {}
+fn foo() {} //~ NOTE first #[main] function
 
 #[main]
-fn f() {} //~ ERROR E0137
+fn f() {}
+//~^ ERROR E0137
+//~| NOTE additional #[main] function
index 9fa41249aa50b06a78d8286e4963c8ababc4f31f..f8585d71b402a080c052a5d09a79a45542b5079f 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() -> ! { return; } //~ ERROR E0166
+fn foo() -> ! { return; }
+    //~^ ERROR E0166
+    //~| NOTE diverging function cannot return
 
 fn main() {
 }
index 7011bf0e93734f9a4220b17c9a5a66ccfcfbca47..485a31d96663795a2cbb2eabe73d3ede755fde00 100644 (file)
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(bar: i32+std::fmt::Display) {} //~ ERROR E0172
+fn foo(bar: i32+std::fmt::Display) {}
+    //~^ ERROR E0172
+    //~| NOTE expected a trait
 
 fn main() {
 }
index f34f3834e05b196d47fd5715dfdc159745a5df1b..6527465e0b7f74631c17a159fe5ca41f289b9cbb 100644 (file)
 trait Foo {}
 
 struct Bar<'a> {
-    w: &'a Foo + Copy, //~ ERROR E0178
-    x: &'a Foo + 'a, //~ ERROR E0178
-    y: &'a mut Foo + 'a, //~ ERROR E0178
-    z: fn() -> Foo + 'a, //~ ERROR E0178
+    w: &'a Foo + Copy,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    x: &'a Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    y: &'a mut Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
+    z: fn() -> Foo + 'a,
+    //~^ ERROR E0178
+    //~| NOTE expected a path
 }
 
 fn main() {
index bd87dbaf786a518407bc28a07c8e5c8528e5ef8f..43ff085a4fa8e36c49c7d26447fbdc8629ad96fa 100644 (file)
@@ -11,6 +11,7 @@
 struct Foo;
 
 impl<T: Default> Foo { //~ ERROR E0207
+                       //~| NOTE unconstrained lifetime parameter
     fn get(&self) -> T {
         <T as Default>::default()
     }
index 45d5c59592f759cc120685f4d3e92c1782efd29d..6ff0baeeb4d4bd25c16e420febcebf7f2fb41af3 100644 (file)
@@ -20,7 +20,9 @@ impl Foo for isize {
     fn boo(&self) -> usize { 42 }
 }
 
-fn baz<I>(x: &<I as Foo<A=Bar>>::A) {} //~ ERROR E0229
+fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
+//~^ ERROR associated type bindings are not allowed here [E0229]
+//~| NOTE associate type not allowed here
 
 fn main() {
 }
diff --git a/src/test/compile-fail/E0253.rs b/src/test/compile-fail/E0253.rs
new file mode 100644 (file)
index 0000000..28fcf44
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+mod foo {
+    pub trait MyTrait {
+        fn do_something();
+    }
+}
+
+use foo::MyTrait::do_something; //~ ERROR E0253
+
+fn main() {}
diff --git a/src/test/compile-fail/E0254.rs b/src/test/compile-fail/E0254.rs
new file mode 100644 (file)
index 0000000..28f9aea
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+extern crate collections;
+
+mod foo {
+    pub trait collections {
+        fn do_something();
+    }
+}
+
+use foo::collections; //~ ERROR E0254
+
+fn main() {}
diff --git a/src/test/compile-fail/E0255.rs b/src/test/compile-fail/E0255.rs
new file mode 100644 (file)
index 0000000..e05c6be
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+use bar::foo;
+
+fn foo() {} //~ ERROR E0255
+
+mod bar {
+     pub fn foo() {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0259.rs b/src/test/compile-fail/E0259.rs
new file mode 100644 (file)
index 0000000..6b7e861
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2016 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.
+
+extern crate collections;
+extern crate libc as collections; //~ ERROR E0259
+
+fn main() {}
diff --git a/src/test/compile-fail/E0260.rs b/src/test/compile-fail/E0260.rs
new file mode 100644 (file)
index 0000000..d20829b
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2016 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.
+
+extern crate collections;
+
+mod collections { //~ ERROR E0260
+    pub trait MyTrait {
+        fn do_something();
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0261.rs b/src/test/compile-fail/E0261.rs
new file mode 100644 (file)
index 0000000..4196ad3
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2016 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 foo(x: &'a str) { } //~ ERROR E0261
+
+struct Foo {
+    x: &'a str, //~ ERROR E0261
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0262.rs b/src/test/compile-fail/E0262.rs
new file mode 100644 (file)
index 0000000..e09e476
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 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 foo<'static>(x: &'static str) { } //~ ERROR E0262
+
+fn main() {}
diff --git a/src/test/compile-fail/E0263.rs b/src/test/compile-fail/E0263.rs
new file mode 100644 (file)
index 0000000..09f654c
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 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 foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } //~ ERROR E0263
+
+fn main() {}
diff --git a/src/test/compile-fail/E0264.rs b/src/test/compile-fail/E0264.rs
new file mode 100644 (file)
index 0000000..9233297
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2016 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(lang_items)]
+
+extern "C" {
+    #[lang = "cake"]
+    fn cake(); //~ ERROR E0264
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0267.rs b/src/test/compile-fail/E0267.rs
new file mode 100644 (file)
index 0000000..6287256
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 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 w = || { break; }; //~ ERROR E0267
+}
diff --git a/src/test/compile-fail/E0268.rs b/src/test/compile-fail/E0268.rs
new file mode 100644 (file)
index 0000000..41e88e2
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2016 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() {
+    break; //~ ERROR E0268
+}
index 61cc8902036ec9966fdfc35d36134f23570900f6..9ffaef7472b7830d4c5b259589c4109cd66350ff 100644 (file)
@@ -8,9 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-const A: [u32; "hello"] = []; //~ ERROR E0306
-const B: [u32; true] = []; //~ ERROR E0306
-const C: [u32; 0.0] = []; //~ ERROR E0306
+const A: [u32; "hello"] = [];
+//~^ ERROR expected `usize` for array length, found string literal [E0306]
+//~| NOTE expected `usize`
+
+const B: [u32; true] = [];
+//~^ ERROR expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
+const C: [u32; 0.0] = [];
+//~^ ERROR expected `usize` for array length, found float [E0306]
+//~| NOTE expected `usize`
 
 fn main() {
 }
index de315a41361a7900667705cb9eb7882a7c871548..1a5496f0551507354ffcb5219f7fbca94911b742 100644 (file)
@@ -11,7 +11,9 @@
 // Tests that a function with a ! annotation always actually fails
 
 fn bad_bang(i: usize) -> ! {
-    return 7; //~ ERROR `return` in a function declared as diverging [E0166]
+    return 7;
+    //~^ ERROR `return` in a function declared as diverging [E0166]
+    //~| NOTE diverging function cannot return
 }
 
 fn main() { bad_bang(5); }
index 87e40df7663baacabd7c522321104fc0e7c82a61..ec330247f238b07c77a7f6a6b955dcaced8651b0 100644 (file)
@@ -22,4 +22,6 @@ fn main() {
     let mut books = vec![1,2,3];
     spawn(|| books.push(4));
     //~^ ERROR E0373
+    //~| NOTE `books` is borrowed here
+    //~| NOTE may outlive borrowed value `books`
 }
index 67700be890b1faa8a9c9090fdb0ea8382ddfd854..81685c32f2f29b6285b5fdadd05532746cc4c5b0 100644 (file)
@@ -20,6 +20,8 @@ fn foo<'a>(x: &'a i32) -> Box<FnMut()+'a> {
     let mut books = vec![1,2,3];
     Box::new(|| books.push(4))
     //~^ ERROR E0373
+    //~| NOTE `books` is borrowed here
+    //~| NOTE may outlive borrowed value `books`
 }
 
 fn main() { }
index d813cf32954e3349edcbfe5c1e21a7d3bb6af584..92568b27f7c1da143e24a4fd2a982f3df13026d7 100644 (file)
@@ -20,7 +20,9 @@ trait Foo {
 }
 
 impl Foo for u32 {
-    const fn f() -> u32 { 22 } //~ ERROR E0379
+    const fn f() -> u32 { 22 }
+    //~^ ERROR E0379
+    //~| NOTE trait fns cannot be const
 }
 
 fn main() { }
index 5dadd892f83520cca532436ce88986e7b4649476..398dc2f22150cc8c90fc1daf0ee9030990b00c86 100644 (file)
 const ARR3: [i32; X3] = [99; 6]; //~ NOTE: for array length here
 
 const Y: usize = 42.0 == 42.0;
-const ARRR: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y1: usize = 42.0 >= 42.0;
-const ARRR1: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR1: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y2: usize = 42.0 <= 42.0;
-const ARRR2: [i32; Y] = [99; 1]; //~ ERROR: expected usize for array length
+const ARRR2: [i32; Y] = [99; 1];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y3: usize = 42.0 > 42.0;
-const ARRR3: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR3: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y4: usize = 42.0 < 42.0;
-const ARRR4: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR4: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 const Y5: usize = 42.0 != 42.0;
-const ARRR5: [i32; Y] = [99; 0]; //~ ERROR: expected usize for array length
+const ARRR5: [i32; Y] = [99; 0];
+//~^ ERROR: expected `usize` for array length, found boolean [E0306]
+//~| NOTE expected `usize`
+
 
 fn main() {
     let _ = ARR;
index 75b6397f4ebd71ac5c7260acb3c93b57179aa481..11003067070f4e99b01f9cdfd1a55cd4253b4c75 100644 (file)
@@ -25,4 +25,5 @@ fn main() {
                //~^ NOTE cannot be named the same as a constant
     let d = 4; //~ ERROR let bindings cannot shadow constants
                //~^ NOTE cannot be named the same as a constant
+    fn f() {} // Check that the `NOTE`s still work with an item here (c.f. issue #35115).
 }
index 23401db21d89063643045ccf10d4fcac92783807..d48433ee928f1eb2b7c84d6133045766b3e14f3e 100644 (file)
@@ -19,6 +19,7 @@ trait Fun {
 struct Holder { x: String }
 
 impl<'a> Fun for Holder { //~ ERROR E0207
+                          //~| NOTE unconstrained lifetime parameter
     type Output = &'a str;
     fn call<'b>(&'b self) -> &'b str {
         &self.x[..]
index 9b3e28cbc01ee4eaa4cf98d746a6a9731c914a3c..6452e50d0893ea9b3bc44ea22f1857eeb435b0c0 100644 (file)
@@ -12,7 +12,9 @@
 
 trait Foo {
     fn bar(&self);
-    const MY_CONST: u32;
+    //~^ NOTE original trait requirement
+    //~| NOTE original trait requirement
+    const MY_CONST: u32; //~ NOTE original trait requirement
 }
 
 pub struct FooConstForMethod;
@@ -21,6 +23,7 @@ impl Foo for FooConstForMethod {
     //~^ ERROR E0046
     const bar: u64 = 1;
     //~^ ERROR E0323
+    //~| NOTE does not match trait
     const MY_CONST: u32 = 1;
 }
 
@@ -31,6 +34,7 @@ impl Foo for FooMethodForConst {
     fn bar(&self) {}
     fn MY_CONST() {}
     //~^ ERROR E0324
+    //~| NOTE does not match trait
 }
 
 pub struct FooTypeForMethod;
@@ -39,6 +43,7 @@ impl Foo for FooTypeForMethod {
     //~^ ERROR E0046
     type bar = u64;
     //~^ ERROR E0325
+    //~| NOTE does not match trait
     const MY_CONST: u32 = 1;
 }
 
index bdf344dcdfe8da8377ba866e99756a1fb1ad3b39..3d6f224c249040a1c1d168d0b5357ba9af7c06de 100644 (file)
 
 enum Foo {
     A = 1,
-    B = 1, //~ ERROR discriminant value `1isize` already exists
-    //~^^ NOTE conflicting
+    //~^ NOTE first use
+    //~| NOTE first use
+    //~| NOTE first use
+    B = 1, //~ ERROR discriminant value
+    //~^ NOTE enum already
     C = 0,
-    D, //~ ERROR discriminant value `1isize` already exists
-    //~^^^^^ NOTE conflicting
-    E = N, //~ ERROR discriminant value `1isize` already exists
-    //~^^^^^^^ NOTE conflicting
+    D, //~ ERROR discriminant value
+    //~^ NOTE enum already
+
+    E = N, //~ ERROR discriminant value
+    //~^ NOTE enum already
+
 }
 
 fn main() {}
index 3591b9824145bbdd2d114d457727baf2e6143425..cf650460c3de11408e6acc898303b5964f2e18de 100644 (file)
@@ -23,6 +23,8 @@ fn print_x(_: &Foo<Item=bool>, extra: &str) {
 }
 
 fn main() {
-    print_x(X);  //~error this function takes 2 parameters but 1 parameter was supplied
-    //~^ NOTE the following parameter types were expected: &Foo<Item=bool>, &str
+    print_x(X);
+    //~^ ERROR this function takes 2 parameters but 1 parameter was supplied
+    //~| NOTE the following parameter types were expected: &Foo<Item=bool>, &str
+    //~| NOTE expected 2 parameters
 }
index 4aa2571cad0cc9418709407687ff5ba9ac19056d..d258a4a8b3325b18149d8dd641a3c6d49534a46b 100644 (file)
@@ -21,6 +21,7 @@ fn crash_please() {
 struct Newtype(Option<Box<usize>>);
 
 impl<'a> Iterator for Newtype { //~ ERROR E0207
+                                //~| NOTE unconstrained lifetime parameter
     type Item = &'a Box<usize>;
 
     fn next(&mut self) -> Option<&Box<usize>> {
index 4ed44154c4748ce51514dc0201904507127a0a2d..f1c559b6b889f207cdc7e4542cd60de3895775a3 100644 (file)
@@ -16,6 +16,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Foo>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~| NOTE associate type not allowed here
 }
 
 fn main() {}
index 1d7c2187045ea28efdfe5925b5214437cc863a55..3959c22d1d489384a9baccac9b838ad467fcd2af 100644 (file)
@@ -14,6 +14,7 @@ pub trait D {
     fn f<T>(self)
         where T<Bogus = Self::AlsoBogus>: A;
         //~^ ERROR associated type bindings are not allowed here [E0229]
+        //~| NOTE associate type not allowed here
 }
 
 fn main() {}
index ee6ec52761266607887eef14302a41e2102c6278..e89bff025e006bf6fed83b4939302027ecadf66f 100644 (file)
@@ -16,5 +16,6 @@ fn main() {
     //~| expected type `usize`
     //~| found type `S`
     //~| expected usize, found struct `S`
-    //~| ERROR expected usize for repeat count, found struct
+    //~| ERROR expected `usize` for repeat count, found struct [E0306]
+    //~| expected `usize`
 }
index 7c051784f61a7dbbf253550c40cb03dffad0dcee..f03daafc63754b533828feddb9f3d8641c0d0c3b 100644 (file)
 struct MyStruct;
 
 impl Drop for MyStruct {
-//~^ NOTE conflicting implementation is here
+//~^ NOTE first implementation here
     fn drop(&mut self) { }
 }
 
 impl Drop for MyStruct {
 //~^ ERROR conflicting implementations of trait
+//~| NOTE conflicting implementation for `MyStruct`
     fn drop(&mut self) { }
 }
 
index 68046056fb3156eebb5691b80a0f82c6e06eabd7..d19e3b2c7b0a8c40d8193ac10b497e8151d353ad 100644 (file)
@@ -14,7 +14,7 @@ fn main() {
     needlesArr.iter().fold(|x, y| {
     });
     //~^^ ERROR this function takes 2 parameters but 1 parameter was supplied
-    //~^^^ NOTE the following parameter types were expected
-    //
+    //~| NOTE the following parameter types were expected
+    //~| NOTE expected 2 parameters
     // the first error is, um, non-ideal.
 }
index 2b3df9ad1d83b7fe8dc02bb3fff1c65fec2bdfbd..4997a6fee195b4c736816bd9c6d3bc150ac8c425 100644 (file)
@@ -22,6 +22,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         Var2 => (),
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     match &s {
         &Var1 => (),
@@ -29,6 +30,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         &Var2 => (),
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     let t = (Var1, Var1);
     match t {
@@ -37,6 +39,7 @@ fn main() {
         //~^ NOTE this pattern matches any value
         anything => ()
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
     // `_` need not emit a note, it is pretty obvious already.
     let t = (Var1, Var1);
@@ -45,5 +48,6 @@ fn main() {
         _ => (),
         anything => ()
         //~^ ERROR unreachable pattern
+        //~^^ NOTE this is an unreachable pattern
     };
 }
index 67f0e7aaf9717ee68161684dccc9d3ee6caf026c..5c4f161a5004ed9c20c190da2fe38468d8a98eac 100644 (file)
@@ -17,6 +17,7 @@ pub trait MethodType {
 pub struct MTFn;
 
 impl<'a> MethodType for MTFn { //~ ERROR E0207
+                               //~| NOTE unconstrained lifetime parameter
     type GetProp = fmt::Debug + 'a;
 }
 
index cbc09a028c2c6833cc24c22fa4d18caddbe16672..93556577ad345c66381d3452cb146cf4ea17e577 100644 (file)
@@ -18,6 +18,7 @@ struct S {
 }
 
 impl Foo for S { //~ ERROR: `Foo` is not a trait
+                 //~| NOTE: not a trait
                  //~| NOTE: type aliases cannot be used for traits
     fn bar() { }
 }
index 9a1b5d9b83d2c27a910164b0d687567dca23b43f..09371fbafcb560f98e91acab4a483709a4745a6b 100644 (file)
@@ -14,7 +14,10 @@ fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
     // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
     id(Box::new(|| *v))
         //~^ ERROR E0373
-        //~| ERROR cannot move out of borrowed content
+        //~| NOTE `v` is borrowed here
+        //~| NOTE may outlive borrowed value `v`
+        //~| ERROR E0507
+        //~| NOTE cannot move out of borrowed content
 }
 
 fn main() {
index 438d238b6fe6288c8c7202c6208dd42b2114ae30..58a84f3490b3c47f3b2f74a4da21fcb7900c00b6 100644 (file)
@@ -11,5 +11,7 @@
 // Regression test for issue #4935
 
 fn foo(a: usize) {}
-fn main() { foo(5, 6) } //~ ERROR this function takes 1 parameter but 2 parameters were supplied
-//~^ NOTE the following parameter type was expected
+fn main() { foo(5, 6) }
+//~^ ERROR this function takes 1 parameter but 2 parameters were supplied
+//~| NOTE the following parameter type was expected
+//~| NOTE expected 1 parameter
index 9648d64d1fb6ec0d086736c52d0baff31a9a8396..c2154e8a6c0b605ce78e135875aa19a2e414ecf9 100644 (file)
@@ -11,6 +11,7 @@
 trait I {}
 type K = I;
 impl K for isize {} //~ ERROR: `K` is not a trait
+                    //~| NOTE: not a trait
                     //~| NOTE: aliases cannot be used for traits
 
 use ImportError; //~ ERROR unresolved
index 1ebef06008ffa4f3c6b345dee1cd6110d7d62132..06e3c9a207b78c8d11007a54700ea75314457cd1 100644 (file)
@@ -13,4 +13,5 @@
 fn main() {
     let x = |ref x: isize| -> isize { x += 1; };
     //~^ ERROR E0368
+    //~| NOTE cannot use `+=` on type `&isize`
 }
index 40322f5a5b53b79f69c36a28fdde3e3c80ee7c6d..239f380e6c4abb6e0d673f26a153980e48eaea72 100644 (file)
@@ -79,6 +79,13 @@ fn f() {
     }
 }
 
+// c.f. issue #35135
+#[allow(unused_variables)]
+fn h() {
+    use test2::foo; //~ ERROR unused import
+    let foo = 0;
+}
+
 fn main() {
     cal(foo::Point{x:3, y:9});
     let mut a = 3;
index 212c09364cf4c027c711e40e4f51f277052772bc..bcf676dbede6ff5bbd60c1cd209bc941de948936 100644 (file)
@@ -20,10 +20,13 @@ fn two(self, _: isize, _: isize) -> Foo { self }
 fn main() {
     let x = Foo;
     x.zero(0)   //~ ERROR this function takes 0 parameters but 1 parameter was supplied
+     //~^ NOTE expected 0 parameters
      .one()     //~ ERROR this function takes 1 parameter but 0 parameters were supplied
      //~^ NOTE the following parameter type was expected
+     //~| NOTE expected 1 parameter
      .two(0);   //~ ERROR this function takes 2 parameters but 1 parameter was supplied
      //~^ NOTE the following parameter types were expected
+     //~| NOTE expected 2 parameters
 
     let y = Foo;
     y.zero()
index 0b12a9acbcb9e9d56de662b81d4234bda7fc35a7..eba61ede8cb20e673e945fbe6c19e8c6043f0422 100644 (file)
@@ -19,6 +19,7 @@ struct Foo {
 fn struct_with_a_nested_enum_and_vector() {
     match (Foo { first: true, second: None }) {
 //~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered
+//~| NOTE pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered
         Foo { first: true, second: None } => (),
         Foo { first: true, second: Some(_) } => (),
         Foo { first: false, second: None } => (),
@@ -35,6 +36,7 @@ enum Color {
 fn enum_with_single_missing_variant() {
     match Color::Red {
     //~^ ERROR non-exhaustive patterns: `Red` not covered
+    //~| NOTE pattern `Red` not covered
         Color::CustomRGBA { .. } => (),
         Color::Green => ()
     }
@@ -47,6 +49,7 @@ enum Direction {
 fn enum_with_multiple_missing_variants() {
     match Direction::North {
     //~^ ERROR non-exhaustive patterns: `East`, `South` and `West` not covered
+    //~| NOTE patterns `East`, `South` and `West` not covered
         Direction::North => ()
     }
 }
@@ -58,6 +61,7 @@ enum ExcessiveEnum {
 fn enum_with_excessive_missing_variants() {
     match ExcessiveEnum::First {
     //~^ ERROR `Second`, `Third`, `Fourth` and 8 more not covered
+    //~| NOTE patterns `Second`, `Third`, `Fourth` and 8 more not covered
 
         ExcessiveEnum::First => ()
     }
@@ -66,6 +70,7 @@ fn enum_with_excessive_missing_variants() {
 fn enum_struct_variant() {
     match Color::Red {
     //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered
+    //~| NOTE pattern `CustomRGBA { a: true, .. }` not covered
         Color::Red => (),
         Color::Green => (),
         Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (),
@@ -82,6 +87,7 @@ fn vectors_with_nested_enums() {
     let x: &'static [Enum] = &[Enum::First, Enum::Second(false)];
     match *x {
     //~^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered
+    //~| NOTE pattern `[Second(true), Second(false)]` not covered
         [] => (),
         [_] => (),
         [Enum::First, _] => (),
@@ -95,6 +101,7 @@ fn vectors_with_nested_enums() {
 fn missing_nil() {
     match ((), false) {
     //~^ ERROR non-exhaustive patterns: `((), false)` not covered
+    //~| NOTE pattern `((), false)` not covered
         ((), true) => ()
     }
 }
index 1f5a54477dd6d0fa83f4597179b819deec94c5db..f2f61fcaeec16d5fdd97b11c8243ecf8209cbdb3 100644 (file)
@@ -19,5 +19,6 @@ fn foo(a: isize, b: isize, c: isize, d:isize) {
 fn main() {
   foo(1, 2, 3);
   //~^ ERROR this function takes 4 parameters but 3
-  //~^^ NOTE the following parameter types were expected
+  //~| NOTE the following parameter types were expected
+  //~| NOTE expected 4 parameters
 }
index 8763fb0913a87287ef21d84b391dc7be7bc6bf68..5865d93e1282ffdbe28e397fa7bf4e93f8438996 100644 (file)
@@ -42,7 +42,9 @@ fn main() {
     let ans = s();
     //~^ ERROR this function takes 1 parameter but 0 parameters were supplied
     //~| NOTE the following parameter type was expected
+    //~| NOTE expected 1 parameter
     let ans = s("burma", "shave");
     //~^ ERROR this function takes 1 parameter but 2 parameters were supplied
     //~| NOTE the following parameter type was expected
+    //~| NOTE expected 1 parameter
 }
index 4fda8ec3f384ebaa2185e6c365d1bbefd54730be..6be2adbe2a0d1ac0eb200159b11af647bc1f875b 100644 (file)
 
 fn escaping_borrow_of_closure_params_1() {
     let g = |x: usize, y:usize| {
+        //~^ NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
+        //~| NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR `x` does not live long enough
         //~| ERROR `y` does not live long enough
@@ -31,6 +35,10 @@ fn escaping_borrow_of_closure_params_1() {
 
 fn escaping_borrow_of_closure_params_2() {
     let g = |x: usize, y:usize| {
+        //~^ NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
+        //~| NOTE reference must be valid for the scope of call-site for function
+        //~| NOTE ...but borrowed value is only valid for the scope of function body
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR `x` does not live long enough
         //~| ERROR `y` does not live long enough
@@ -64,7 +72,11 @@ fn escaping_borrow_of_fn_params_1() {
     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR E0373
+        //~| NOTE `x` is borrowed here
+        //~| NOTE may outlive borrowed value `x`
         //~| ERROR E0373
+        //~| NOTE `y` is borrowed here
+        //~| NOTE may outlive borrowed value `y`
         return Box::new(f);
     };
 
@@ -75,7 +87,11 @@ fn escaping_borrow_of_fn_params_2() {
     fn g<'a>(x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
         let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
         //~^ ERROR E0373
+        //~| NOTE `x` is borrowed here
+        //~| NOTE may outlive borrowed value `x`
         //~| ERROR E0373
+        //~| NOTE `y` is borrowed here
+        //~| NOTE may outlive borrowed value `y`
         Box::new(f)
     };
 
@@ -99,7 +115,11 @@ impl S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -113,7 +133,11 @@ impl S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
@@ -141,7 +165,11 @@ impl T for S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -156,7 +184,11 @@ impl T for S {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
@@ -184,7 +216,11 @@ trait T {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             return Box::new(f);
         }
     }
@@ -198,7 +234,11 @@ trait T {
         fn g<'a>(&self, x: usize, y:usize) -> Box<Fn(bool) -> usize + 'a> {
             let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
             //~^ ERROR E0373
+            //~| NOTE `x` is borrowed here
+            //~| NOTE may outlive borrowed value `x`
             //~| ERROR E0373
+            //~| NOTE `y` is borrowed here
+            //~| NOTE may outlive borrowed value `y`
             Box::new(f)
         }
     }
index 948dc8cd219689301a9b30ba2702422a39294451..40ba34b26ede673a1c0fb4f88e34f3d8b68e627e 100644 (file)
@@ -13,8 +13,11 @@ fn ignore<F>(_f: F) where F: for<'z> FnOnce(&'z isize) -> &'z isize {}
 fn nested() {
     let y = 3;
     ignore(
-        |z| { //~ ERROR E0373
+        |z| {
+            //~^ ERROR E0373
+            //~| NOTE may outlive borrowed value `y`
             if false { &y } else { z }
+            //~^ NOTE `y` is borrowed here
         });
 }
 
index 1758b28a32482555bb6911420f996ced91ed6330..555dd0f0c3945fd52c15de1690550b973f2cb1e7 100644 (file)
@@ -20,23 +20,27 @@ fn main() {
     //~| expected type `usize`
     //~| found type `()`
     //~| expected usize, found ()
-    //~| ERROR expected usize for repeat count, found tuple [E0306]
+    //~| ERROR expected `usize` for repeat count, found tuple [E0306]
+    //~| expected `usize`
     let c = [0; true];
     //~^ ERROR mismatched types
     //~| expected usize, found bool
-    //~| ERROR expected usize for repeat count, found boolean [E0306]
+    //~| ERROR expected `usize` for repeat count, found boolean [E0306]
+    //~| expected `usize`
     let d = [0; 0.5];
     //~^ ERROR mismatched types
     //~| expected type `usize`
     //~| found type `{float}`
     //~| expected usize, found floating-point variable
-    //~| ERROR expected usize for repeat count, found float [E0306]
+    //~| ERROR expected `usize` for repeat count, found float [E0306]
+    //~| expected `usize`
     let e = [0; "foo"];
     //~^ ERROR mismatched types
     //~| expected type `usize`
     //~| found type `&'static str`
     //~| expected usize, found &-ptr
-    //~| ERROR expected usize for repeat count, found string literal [E0306]
+    //~| ERROR expected `usize` for repeat count, found string literal [E0306]
+    //~| expected `usize`
     let f = [0; -4_isize];
     //~^ ERROR constant evaluation error
     //~| expected usize, found isize
@@ -55,5 +59,6 @@ struct G {
     //~| expected type `usize`
     //~| found type `main::G`
     //~| expected usize, found struct `main::G`
-    //~| ERROR expected usize for repeat count, found struct [E0306]
+    //~| ERROR expected `usize` for repeat count, found struct [E0306]
+    //~| expected `usize`
 }
index 049569e8a184fb3aa68ea428bdcac0a67ff0ff80..dd9d7d29468825eb56d6f32e64fd7c5cf5f0613b 100644 (file)
@@ -9,8 +9,10 @@
 // except according to those terms.
 
 struct BuildData {
+    foo: isize, //~ NOTE `foo` first declared here
     foo: isize,
-    foo: isize, //~ ERROR field `foo` is already declared
+    //~^ ERROR field `foo` is already declared [E0124]
+    //~| NOTE field already declared
 }
 
 fn main() {
index 13fdaa302f70a72ee0a800f21b42a93de4c9050d..c78eebddbfdb80051d8b5be9a4150f51df653000 100644 (file)
@@ -13,4 +13,5 @@ trait TraitNotAStruct {}
 fn main() {
     TraitNotAStruct{ value: 0 };
     //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071]
+    //~| NOTE not a struct
 }
index d8620ead836397d8a290c961cfb38c939913f047..cc9a7c84eded46c495a185350591a4b48382d53a 100644 (file)
@@ -18,8 +18,10 @@ fn main() {
     unsafe {
         foo(); //~ ERROR: this function takes at least 2 parameters but 0 parameters were supplied
         //~^ NOTE the following parameter types were expected
+        //~| NOTE expected at least 2 parameters
         foo(1); //~ ERROR: this function takes at least 2 parameters but 1 parameter was supplied
         //~^ NOTE the following parameter types were expected
+        //~| NOTE expected at least 2 parameters
 
         let x: unsafe extern "C" fn(f: isize, x: u8) = foo;
         //~^ ERROR: mismatched types
index 388d3238d4248960c37b2a317d249fca570f5a69..42c0da6286bdca27f95692cd6b85c074ac6cc569 100644 (file)
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
index 3ad307fd3b507b6b3cf199b4abb946227c881beb..42c0da6286bdca27f95692cd6b85c074ac6cc569 100644 (file)
 pub type F = Option<isize>;
 pub type G = usize;
 pub type H = &'static str;
+pub type I = Box<Fn()>;
 
-pub unsafe fn id_A() -> TypeId { TypeId::of::<A>() }
-pub unsafe fn id_B() -> TypeId { TypeId::of::<B>() }
-pub unsafe fn id_C() -> TypeId { TypeId::of::<C>() }
-pub unsafe fn id_D() -> TypeId { TypeId::of::<D>() }
-pub unsafe fn id_E() -> TypeId { TypeId::of::<E>() }
-pub unsafe fn id_F() -> TypeId { TypeId::of::<F>() }
-pub unsafe fn id_G() -> TypeId { TypeId::of::<G>() }
-pub unsafe fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_A() -> TypeId { TypeId::of::<A>() }
+pub fn id_B() -> TypeId { TypeId::of::<B>() }
+pub fn id_C() -> TypeId { TypeId::of::<C>() }
+pub fn id_D() -> TypeId { TypeId::of::<D>() }
+pub fn id_E() -> TypeId { TypeId::of::<E>() }
+pub fn id_F() -> TypeId { TypeId::of::<F>() }
+pub fn id_G() -> TypeId { TypeId::of::<G>() }
+pub fn id_H() -> TypeId { TypeId::of::<H>() }
+pub fn id_I() -> TypeId { TypeId::of::<I>() }
 
-pub unsafe fn foo<T:Any>() -> TypeId { TypeId::of::<T>() }
+pub fn foo<T: Any>() -> TypeId { TypeId::of::<T>() }
diff --git a/src/test/run-pass/type-id-higher-rank-2.rs b/src/test/run-pass/type-id-higher-rank-2.rs
new file mode 100644 (file)
index 0000000..aead8bc
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright 2016 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.
+
+// Test that we can't ignore lifetimes by going through Any.
+
+use std::any::Any;
+
+struct Foo<'a>(&'a str);
+
+fn good(s: &String) -> Foo { Foo(s) }
+
+fn bad1(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(good as fn(&String) -> Foo);
+    a.downcast_ref::<fn(&String) -> Foo<'static>>().map(|f| f(&s).0)
+}
+
+trait AsStr<'a, 'b> {
+    fn get(&'a self) -> &'b str;
+}
+
+impl<'a> AsStr<'a, 'a> for String {
+   fn get(&'a self) -> &'a str { self }
+}
+
+fn bad2(s: String) -> Option<&'static str> {
+    let a: Box<Any> = Box::new(Box::new(s) as Box<for<'a> AsStr<'a, 'a>>);
+    a.downcast_ref::<Box<for<'a> AsStr<'a, 'static>>>().map(|x| x.get())
+}
+
+fn main() {
+    assert_eq!(bad1(String::from("foo")), None);
+    assert_eq!(bad2(String::from("bar")), None);
+}
index c29fb5e86f51d54311b2db332b85c7a64910330d..827b05c0801e1eb39b5650defc365315f411b3d3 100644 (file)
@@ -16,6 +16,9 @@
 
 use std::any::{Any, TypeId};
 
+struct Struct<'a>(&'a ());
+trait Trait<'a> {}
+
 fn main() {
     // Bare fns
     {
@@ -34,6 +37,14 @@ fn main() {
         let e = TypeId::of::<for<'a> fn(fn(&'a isize) -> &'a isize)>();
         let f = TypeId::of::<fn(for<'a> fn(&'a isize) -> &'a isize)>();
         assert!(e != f);
+
+        // Make sure lifetime parameters of items are not ignored.
+        let g = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'a>>();
+        let h = TypeId::of::<for<'a> fn(&'a Trait<'a>) -> Struct<'static>>();
+        let i = TypeId::of::<for<'a, 'b> fn(&'a Trait<'b>) -> Struct<'b>>();
+        assert!(g != h);
+        assert!(g != i);
+        assert!(h != i);
     }
     // Boxed unboxed closures
     {
index 4bd82baafeb100c32897ccf9584969dc98902d2d..e99a5f69af40f23c984301370f54297b6034de1f 100644 (file)
 struct Test;
 
 pub fn main() {
-    unsafe {
-        assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
-        assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
-        assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
-        assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
-        assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
-        assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
-        assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
-        assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::A>(), other1::id_A());
+    assert_eq!(TypeId::of::<other1::B>(), other1::id_B());
+    assert_eq!(TypeId::of::<other1::C>(), other1::id_C());
+    assert_eq!(TypeId::of::<other1::D>(), other1::id_D());
+    assert_eq!(TypeId::of::<other1::E>(), other1::id_E());
+    assert_eq!(TypeId::of::<other1::F>(), other1::id_F());
+    assert_eq!(TypeId::of::<other1::G>(), other1::id_G());
+    assert_eq!(TypeId::of::<other1::H>(), other1::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other1::id_I());
 
-        assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
-        assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
-        assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
-        assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
-        assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
-        assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
-        assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
-        assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other2::A>(), other2::id_A());
+    assert_eq!(TypeId::of::<other2::B>(), other2::id_B());
+    assert_eq!(TypeId::of::<other2::C>(), other2::id_C());
+    assert_eq!(TypeId::of::<other2::D>(), other2::id_D());
+    assert_eq!(TypeId::of::<other2::E>(), other2::id_E());
+    assert_eq!(TypeId::of::<other2::F>(), other2::id_F());
+    assert_eq!(TypeId::of::<other2::G>(), other2::id_G());
+    assert_eq!(TypeId::of::<other2::H>(), other2::id_H());
+    assert_eq!(TypeId::of::<other1::I>(), other2::id_I());
 
-        assert_eq!(other1::id_F(), other2::id_F());
-        assert_eq!(other1::id_G(), other2::id_G());
-        assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_F(), other2::id_F());
+    assert_eq!(other1::id_G(), other2::id_G());
+    assert_eq!(other1::id_H(), other2::id_H());
+    assert_eq!(other1::id_I(), other2::id_I());
 
-        assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
-        assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
-        assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
-        assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
-        assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
-        assert_eq!(other2::foo::<A>(), other1::foo::<A>());
-    }
+    assert_eq!(TypeId::of::<isize>(), other2::foo::<isize>());
+    assert_eq!(TypeId::of::<isize>(), other1::foo::<isize>());
+    assert_eq!(other2::foo::<isize>(), other1::foo::<isize>());
+    assert_eq!(TypeId::of::<A>(), other2::foo::<A>());
+    assert_eq!(TypeId::of::<A>(), other1::foo::<A>());
+    assert_eq!(other2::foo::<A>(), other1::foo::<A>());
 
     // sanity test of TypeId
     let (a, b, c) = (TypeId::of::<usize>(), TypeId::of::<&'static str>(),
index cf3f187af93340474ac4755abbc93e6b55624e67..69560174346160fb1bb1146b655c470b25571459 100644 (file)
@@ -2,7 +2,7 @@ error[E0404]: `Bar` is not a trait
   --> $DIR/two_files.rs:16:6
    |
 16 | impl Bar for Baz { }
-   |      ^^^
+   |      ^^^ not a trait
    |
    = note: type aliases cannot be used for traits
 
index 8b7164819a7907390d3105335ae38039d47b9d65..72df09b7669f686ed4303f3fab6f0d93bc564fa9 100644 (file)
@@ -24,7 +24,7 @@ struct Test {
 const TEST_REPOS: &'static [Test] = &[Test {
                                           name: "cargo",
                                           repo: "https://github.com/rust-lang/cargo",
-                                          sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
+                                          sha: "fd90fd642d404d8c66505ca8db742c664ea352f2",
                                           lock: None,
                                       },
                                       Test {