about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-03-14 19:10:28 -0700
committerEsteban Küber <esteban@kuber.com.ar>2018-03-15 11:59:54 -0700
commit4d5cd21a0db601636d88f4c95f50435b04bf71df (patch)
tree0bb52e32d0f72ad2851c68a977783eed058958c7
parent883e74645d350b6752cb94d48f46363f6f8789e9 (diff)
downloadrust-4d5cd21a0db601636d88f4c95f50435b04bf71df.tar.gz
rust-4d5cd21a0db601636d88f4c95f50435b04bf71df.zip
Coherence diagnostic tweaks
-rw-r--r--src/librustc_typeck/coherence/mod.rs47
-rw-r--r--src/librustc_typeck/coherence/orphan.rs56
-rw-r--r--src/test/ui/codemap_tests/empty_span.stderr2
-rw-r--r--src/test/ui/coherence-impls-copy.stderr6
-rw-r--r--src/test/ui/e0119/complex-impl.stderr6
-rw-r--r--src/test/ui/e0119/issue-28981.stderr6
-rw-r--r--src/test/ui/error-codes/E0117.stderr2
-rw-r--r--src/test/ui/error-codes/E0206.stderr2
-rw-r--r--src/test/ui/error-codes/E0328.rs20
-rw-r--r--src/test/ui/error-codes/E0328.stderr9
10 files changed, 104 insertions, 52 deletions
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index d3de31d630a..07b7c600b9f 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -52,10 +52,10 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) {
 fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) {
     let did = Some(trait_def_id);
     let li = tcx.lang_items();
+    let span = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
 
     // Disallow *all* explicit impls of `Sized` and `Unsize` for now.
     if did == li.sized_trait() {
-        let span = tcx.span_of_impl(impl_def_id).unwrap();
         struct_span_err!(tcx.sess,
                          span,
                          E0322,
@@ -66,11 +66,12 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
     }
 
     if did == li.unsize_trait() {
-        let span = tcx.span_of_impl(impl_def_id).unwrap();
-        span_err!(tcx.sess,
-                  span,
-                  E0328,
-                  "explicit impls for the `Unsize` trait are not permitted");
+        struct_span_err!(tcx.sess,
+                         span,
+                         E0328,
+                         "explicit impls for the `Unsize` trait are not permitted")
+            .span_label(span, "impl of `Unsize` not allowed")
+            .emit();
         return;
     }
 
@@ -88,14 +89,14 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d
     } else {
         return; // everything OK
     };
-    let mut err = struct_span_err!(tcx.sess,
-                                   tcx.span_of_impl(impl_def_id).unwrap(),
-                                   E0183,
-                                   "manual implementations of `{}` are experimental",
-                                   trait_name);
-    help!(&mut err,
-          "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
-    err.emit();
+    struct_span_err!(tcx.sess,
+                     span,
+                     E0183,
+                     "manual implementations of `{}` are experimental",
+                     trait_name)
+        .span_label(span, format!("manual implementations of `{}` are experimental", trait_name))
+        .help("add `#![feature(unboxed_closures)]` to the crate attributes to enable")
+        .emit();
 }
 
 pub fn provide(providers: &mut Providers) {
@@ -168,13 +169,17 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
                 traits::supertrait_def_ids(tcx,
                                            data.principal().unwrap().def_id());
             if supertrait_def_ids.any(|d| d == trait_def_id) {
-                span_err!(tcx.sess,
-                          tcx.span_of_impl(impl_def_id).unwrap(),
-                          E0371,
-                          "the object type `{}` automatically \
-                           implements the trait `{}`",
-                          trait_ref.self_ty(),
-                          tcx.item_path_str(trait_def_id));
+                let sp = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap());
+                struct_span_err!(tcx.sess,
+                                 sp,
+                                 E0371,
+                                 "the object type `{}` automatically implements the trait `{}`",
+                                 trait_ref.self_ty(),
+                                 tcx.item_path_str(trait_def_id))
+                    .span_label(sp, format!("`{}` automatically implements trait `{}`",
+                                            trait_ref.self_ty(),
+                                            tcx.item_path_str(trait_def_id)))
+                    .emit();
             }
         }
     }
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index c2dfd798a3c..6d6594e5543 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -40,29 +40,36 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                        self.tcx.hir.node_to_string(item.id));
                 let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
                 let trait_def_id = trait_ref.def_id;
+                let cm = self.tcx.sess.codemap();
+                let sp = cm.def_span(item.span);
                 match traits::orphan_check(self.tcx, def_id) {
                     Ok(()) => {}
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
                         struct_span_err!(self.tcx.sess,
-                                         item.span,
+                                         sp,
                                          E0117,
                                          "only traits defined in the current crate can be \
                                           implemented for arbitrary types")
-                            .span_label(item.span, "impl doesn't use types inside crate")
-                            .note(&format!("the impl does not reference any types defined in \
-                                            this crate"))
+                            .span_label(sp, "impl doesn't use types inside crate")
+                            .note("the impl does not reference any types defined in this crate")
                             .note("define and implement a trait or new type instead")
                             .emit();
                         return;
                     }
                     Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
-                        span_err!(self.tcx.sess,
-                                  item.span,
-                                  E0210,
-                                  "type parameter `{}` must be used as the type parameter for \
-                                   some local type (e.g. `MyStruct<T>`); only traits defined in \
-                                   the current crate can be implemented for a type parameter",
-                                  param_ty);
+                        struct_span_err!(self.tcx.sess,
+                                         sp,
+                                         E0210,
+                                         "type parameter `{}` must be used as the type parameter \
+                                          for some local type (e.g. `MyStruct<{}>`)",
+                                         param_ty,
+                                         param_ty)
+                            .span_label(sp,
+                                        format!("type parameter `{}` must be used as the type \
+                                                 parameter for some local type", param_ty))
+                            .note("only traits defined in the current crate can be implemented \
+                                   for a type parameter")
+                            .emit();
                         return;
                     }
                 }
@@ -121,22 +128,29 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> {
                             if self_def_id.is_local() {
                                 None
                             } else {
-                                Some(format!("cross-crate traits with a default impl, like `{}`, \
-                                              can only be implemented for a struct/enum type \
-                                              defined in the current crate",
-                                             self.tcx.item_path_str(trait_def_id)))
+                                Some((
+                                    format!("cross-crate traits with a default impl, like `{}`, \
+                                             can only be implemented for a struct/enum type \
+                                             defined in the current crate",
+                                            self.tcx.item_path_str(trait_def_id)),
+                                    "can't implement cross-crate trait for type in another crate"
+                                ))
                             }
                         }
                         _ => {
-                            Some(format!("cross-crate traits with a default impl, like `{}`, can \
-                                          only be implemented for a struct/enum type, not `{}`",
-                                         self.tcx.item_path_str(trait_def_id),
-                                         self_ty))
+                            Some((format!("cross-crate traits with a default impl, like `{}`, can \
+                                           only be implemented for a struct/enum type, not `{}`",
+                                          self.tcx.item_path_str(trait_def_id),
+                                          self_ty),
+                                  "can't implement cross-crate trait with a default impl for \
+                                   non-struct/enum type"))
                         }
                     };
 
-                    if let Some(msg) = msg {
-                        span_err!(self.tcx.sess, item.span, E0321, "{}", msg);
+                    if let Some((msg, label)) = msg {
+                        struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
+                            .span_label(sp, label)
+                            .emit();
                         return;
                     }
                 }
diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr
index 63b19c9e0c6..2df1d69acdb 100644
--- a/src/test/ui/codemap_tests/empty_span.stderr
+++ b/src/test/ui/codemap_tests/empty_span.stderr
@@ -2,7 +2,7 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`,
   --> $DIR/empty_span.rs:17:5
    |
 LL |     unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence-impls-copy.stderr b/src/test/ui/coherence-impls-copy.stderr
index 029b0478952..c276d8b9510 100644
--- a/src/test/ui/coherence-impls-copy.stderr
+++ b/src/test/ui/coherence-impls-copy.stderr
@@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/coherence-impls-copy.rs:33:1
    |
 LL | impl Copy for (MyType, MyType) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
@@ -41,7 +41,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/coherence-impls-copy.rs:40:1
    |
 LL | impl Copy for [MyType] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
@@ -50,7 +50,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/coherence-impls-copy.rs:44:1
    |
 LL | impl Copy for &'static [NotSync] {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr
index b268c755404..7e0e8ff0372 100644
--- a/src/test/ui/e0119/complex-impl.stderr
+++ b/src/test/ui/e0119/complex-impl.stderr
@@ -8,11 +8,13 @@ LL | impl<R> External for (Q, R) {} //~ ERROR must be used
            - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box<U>, V, W>)
              where <U as std::ops::FnOnce<(T,)>>::Output == V, <V as std::iter::Iterator>::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, <W as std::ops::Add>::Output: std::marker::Copy;
 
-error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
+error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct<R>`)
   --> $DIR/complex-impl.rs:19:1
    |
 LL | impl<R> External for (Q, R) {} //~ ERROR must be used
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type
+   |
+   = note: only traits defined in the current crate can be implemented for a type parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr
index b1ec1111ede..ade072336bc 100644
--- a/src/test/ui/e0119/issue-28981.stderr
+++ b/src/test/ui/e0119/issue-28981.stderr
@@ -8,11 +8,13 @@ LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
            - impl<'a, T> std::ops::Deref for &'a T
              where T: ?Sized;
 
-error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
+error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct<Foo>`)
   --> $DIR/issue-28981.rs:15:1
    |
 LL | impl<Foo> Deref for Foo { } //~ ERROR must be used
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type
+   |
+   = note: only traits defined in the current crate can be implemented for a type parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr
index 240aa4240cc..39702886348 100644
--- a/src/test/ui/error-codes/E0117.stderr
+++ b/src/test/ui/error-codes/E0117.stderr
@@ -8,7 +8,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/E0117.rs:11:1
    |
 LL | impl Drop for u32 {} //~ ERROR E0117
-   | ^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr
index 0cd22a454e1..6c671967e84 100644
--- a/src/test/ui/error-codes/E0206.stderr
+++ b/src/test/ui/error-codes/E0206.stderr
@@ -14,7 +14,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/E0206.rs:13:1
    |
 LL | impl Copy for Foo { }
-   | ^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
+   | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
    |
    = note: the impl does not reference any types defined in this crate
    = note: define and implement a trait or new type instead
diff --git a/src/test/ui/error-codes/E0328.rs b/src/test/ui/error-codes/E0328.rs
new file mode 100644
index 00000000000..e08532b0249
--- /dev/null
+++ b/src/test/ui/error-codes/E0328.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 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(unsize)]
+
+use std::marker::Unsize;
+
+pub struct MyType;
+
+impl<T> Unsize<T> for MyType {}
+//~^ ERROR explicit impls for the `Unsize` trait are not permitted [E0328]
+
+fn main() {}
diff --git a/src/test/ui/error-codes/E0328.stderr b/src/test/ui/error-codes/E0328.stderr
new file mode 100644
index 00000000000..ad3a224279c
--- /dev/null
+++ b/src/test/ui/error-codes/E0328.stderr
@@ -0,0 +1,9 @@
+error[E0328]: explicit impls for the `Unsize` trait are not permitted
+  --> $DIR/E0328.rs:17:1
+   |
+LL | impl<T> Unsize<T> for MyType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Unsize` not allowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0328`.