about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-03-15 13:16:09 +0000
committerbors <bors@rust-lang.org>2018-03-15 13:16:09 +0000
commitff2d506c2c748bd218f74c6014abc4cecc8c74c4 (patch)
treeaed38048b055954674cf19b081f6e60bd05eb1e3
parenta4af6f089b2836530f31b6b839bde7cea8ae0b8a (diff)
parent1bbd4fd395b7b8f5f51f90401665168b19f0b9fd (diff)
downloadrust-ff2d506c2c748bd218f74c6014abc4cecc8c74c4.tar.gz
rust-ff2d506c2c748bd218f74c6014abc4cecc8c74c4.zip
Auto merge of #48138 - estebank:issue-45092, r=nikomatsakis
Reword E0044 and message for `!Send` types

 - Reword E0044 help.
 - Change error message for types that don't implement `Send`

CC #45092, #46678, #24909, #33307.
-rw-r--r--src/libcore/marker.rs15
-rw-r--r--src/librustc/traits/error_reporting.rs31
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/test/compile-fail/builtin-superkinds-double-superkind.rs6
-rw-r--r--src/test/compile-fail/closure-bounds-subtype.rs2
-rw-r--r--src/test/compile-fail/extern-types-not-sync-send.rs2
-rw-r--r--src/test/compile-fail/issue-16538.rs2
-rw-r--r--src/test/compile-fail/issue-17718-static-sync.rs2
-rw-r--r--src/test/compile-fail/issue-43733-2.rs4
-rw-r--r--src/test/compile-fail/issue-7364.rs2
-rw-r--r--src/test/compile-fail/kindck-send-object.rs2
-rw-r--r--src/test/compile-fail/kindck-send-object1.rs2
-rw-r--r--src/test/compile-fail/kindck-send-object2.rs3
-rw-r--r--src/test/compile-fail/mutable-enum-indirect.rs3
-rw-r--r--src/test/compile-fail/mutexguard-sync.rs3
-rw-r--r--src/test/compile-fail/no_share-enum.rs2
-rw-r--r--src/test/compile-fail/no_share-struct.rs2
-rw-r--r--src/test/compile-fail/not-sync.rs12
-rw-r--r--src/test/compile-fail/phantom-oibit.rs6
-rw-r--r--src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs6
-rw-r--r--src/test/compile-fail/typeck-unsafe-always-share.rs8
-rw-r--r--src/test/ui/closure-move-sync.rs32
-rw-r--r--src/test/ui/closure-move-sync.stderr25
-rw-r--r--src/test/ui/error-codes/E0044.rs9
-rw-r--r--src/test/ui/error-codes/E0044.stderr12
-rw-r--r--src/test/ui/fmt/send-sync.rs4
-rw-r--r--src/test/ui/fmt/send-sync.stderr8
-rw-r--r--src/test/ui/generator/not-send-sync.rs4
-rw-r--r--src/test/ui/generator/not-send-sync.stderr4
29 files changed, 152 insertions, 69 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 98e0f71eb93..53b1d1cd12d 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -343,8 +343,21 @@ pub trait Copy : Clone {
 /// [transmute]: ../../std/mem/fn.transmute.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "sync"]
-#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
+#[rustc_on_unimplemented(
+    message="`{Self}` cannot be shared between threads safely",
+    label="`{Self}` cannot be shared between threads safely"
+)]
 pub unsafe auto trait Sync {
+    // FIXME(estebank): once support to add notes in `rustc_on_unimplemented`
+    // lands in beta, and it has been extended to check whether a closure is
+    // anywhere in the requirement chain, extend it as such (#48534):
+    // ```
+    // on(
+    //     closure,
+    //     note="`{Self}` cannot be shared safely, consider marking the closure `move`"
+    // ),
+    // ```
+
     // Empty
 }
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 206a4bf6689..7e5dc02798d 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -339,18 +339,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             .unwrap_or(trait_ref.def_id());
         let trait_ref = *trait_ref.skip_binder();
 
-        let desugaring;
-        let method;
         let mut flags = vec![];
-        let direct = match obligation.cause.code {
+        match obligation.cause.code {
             ObligationCauseCode::BuiltinDerivedObligation(..) |
-            ObligationCauseCode::ImplDerivedObligation(..) => false,
-            _ => true
-        };
-        if direct {
-            // this is a "direct", user-specified, rather than derived,
-            // obligation.
-            flags.push(("direct".to_string(), None));
+            ObligationCauseCode::ImplDerivedObligation(..) => {}
+            _ => {
+                // this is a "direct", user-specified, rather than derived,
+                // obligation.
+                flags.push(("direct".to_string(), None));
+            }
         }
 
         if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
@@ -360,21 +357,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             //
             // Currently I'm leaving it for what I need for `try`.
             if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
-                method = self.tcx.item_name(item);
+                let method = self.tcx.item_name(item);
                 flags.push(("from_method".to_string(), None));
                 flags.push(("from_method".to_string(), Some(method.to_string())));
             }
         }
 
         if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
-            desugaring = k.as_symbol().as_str();
+            let desugaring = k.as_symbol().as_str();
             flags.push(("from_desugaring".to_string(), None));
             flags.push(("from_desugaring".to_string(), Some(desugaring.to_string())));
         }
         let generics = self.tcx.generics_of(def_id);
         let self_ty = trait_ref.self_ty();
-        let self_ty_str = self_ty.to_string();
-        flags.push(("_Self".to_string(), Some(self_ty_str.clone())));
+        // This is also included through the generics list as `Self`,
+        // but the parser won't allow you to use it
+        flags.push(("_Self".to_string(), Some(self_ty.to_string())));
+        if let Some(def) = self_ty.ty_adt_def() {
+            // We also want to be able to select self's original
+            // signature with no type arguments resolved
+            flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
+        }
 
         for param in generics.types.iter() {
             let name = param.name.as_str().to_string();
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 18de8d1bee7..dc9455487ed 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1223,9 +1223,11 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
                 if !generics.types.is_empty() {
                     let mut err = struct_span_err!(tcx.sess, item.span, E0044,
                         "foreign items may not have type parameters");
-                    span_help!(&mut err, item.span,
-                        "consider using specialization instead of \
-                        type parameters");
+                    err.span_label(item.span, "can't have type parameters");
+                    // FIXME: once we start storing spans for type arguments, turn this into a
+                    // suggestion.
+                    err.help("use specialization instead of type parameters by replacing them \
+                              with concrete types like `u32`");
                     err.emit();
                 }
 
diff --git a/src/test/compile-fail/builtin-superkinds-double-superkind.rs b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
index 8d5d8e8dc9b..261881d880b 100644
--- a/src/test/compile-fail/builtin-superkinds-double-superkind.rs
+++ b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
@@ -13,9 +13,11 @@
 
 trait Foo : Send+Sync { }
 
-impl <T: Sync+'static> Foo for (T,) { } //~ ERROR `T: std::marker::Send` is not satisfied
+impl <T: Sync+'static> Foo for (T,) { }
+//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277]
 
-impl <T: Send> Foo for (T,T) { } //~ ERROR `T: std::marker::Sync` is not satisfied
+impl <T: Send> Foo for (T,T) { }
+//~^ ERROR `T` cannot be shared between threads safely [E0277]
 
 impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
 
diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs
index d3339c4845a..db26535b004 100644
--- a/src/test/compile-fail/closure-bounds-subtype.rs
+++ b/src/test/compile-fail/closure-bounds-subtype.rs
@@ -21,7 +21,7 @@ fn give_any<F>(f: F) where F: FnOnce() {
 
 fn give_owned<F>(f: F) where F: FnOnce() + Send {
     take_any(f);
-    take_const_owned(f); //~ ERROR `F: std::marker::Sync` is not satisfied
+    take_const_owned(f); //~ ERROR `F` cannot be shared between threads safely [E0277]
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/extern-types-not-sync-send.rs b/src/test/compile-fail/extern-types-not-sync-send.rs
index 2f00cf812e4..6a7a515ba5f 100644
--- a/src/test/compile-fail/extern-types-not-sync-send.rs
+++ b/src/test/compile-fail/extern-types-not-sync-send.rs
@@ -21,7 +21,7 @@ fn assert_send<T: ?Sized + Send>() { }
 
 fn main() {
     assert_sync::<A>();
-    //~^ ERROR the trait bound `A: std::marker::Sync` is not satisfied
+    //~^ ERROR `A` cannot be shared between threads safely [E0277]
 
     assert_send::<A>();
     //~^ ERROR the trait bound `A: std::marker::Send` is not satisfied
diff --git a/src/test/compile-fail/issue-16538.rs b/src/test/compile-fail/issue-16538.rs
index 08c3f7a7c15..7df445c676c 100644
--- a/src/test/compile-fail/issue-16538.rs
+++ b/src/test/compile-fail/issue-16538.rs
@@ -21,7 +21,7 @@ mod Y {
 }
 
 static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
-//~^ ERROR `*const usize: std::marker::Sync` is not satisfied
+//~^ ERROR `*const usize` cannot be shared between threads safely [E0277]
 //~| ERROR cannot refer to other statics by value, use the address-of operator or a constant instead
 //~| ERROR E0015
 
diff --git a/src/test/compile-fail/issue-17718-static-sync.rs b/src/test/compile-fail/issue-17718-static-sync.rs
index 790329cd2e4..c5349d4e82b 100644
--- a/src/test/compile-fail/issue-17718-static-sync.rs
+++ b/src/test/compile-fail/issue-17718-static-sync.rs
@@ -17,6 +17,6 @@ impl !Sync for Foo {}
 
 static FOO: usize = 3;
 static BAR: Foo = Foo;
-//~^ ERROR: `Foo: std::marker::Sync` is not satisfied
+//~^ ERROR: `Foo` cannot be shared between threads safely [E0277]
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-43733-2.rs b/src/test/compile-fail/issue-43733-2.rs
index 0fd31454596..a5ba9ef9bd3 100644
--- a/src/test/compile-fail/issue-43733-2.rs
+++ b/src/test/compile-fail/issue-43733-2.rs
@@ -33,7 +33,7 @@ impl<T> Key<T> {
 use std::thread::__FastLocalKeyInner as Key;
 
 static __KEY: Key<()> = Key::new();
-//~^ ERROR `std::cell::UnsafeCell<std::option::Option<()>>: std::marker::Sync` is not satisfied
-//~| ERROR `std::cell::Cell<bool>: std::marker::Sync` is not satisfied
+//~^ ERROR `std::cell::UnsafeCell<std::option::Option<()>>` cannot be shared between threads
+//~| ERROR `std::cell::Cell<bool>` cannot be shared between threads safely [E0277]
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs
index 16138c992ff..801a1301ad7 100644
--- a/src/test/compile-fail/issue-7364.rs
+++ b/src/test/compile-fail/issue-7364.rs
@@ -15,6 +15,6 @@ use std::cell::RefCell;
 // Regression test for issue 7364
 static boxed: Box<RefCell<isize>> = box RefCell::new(0);
 //~^ ERROR allocations are not allowed in statics
-//~| ERROR `std::cell::RefCell<isize>: std::marker::Sync` is not satisfied
+//~| ERROR `std::cell::RefCell<isize>` cannot be shared between threads safely [E0277]
 
 fn main() { }
diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs
index bd0e5642b9c..a84eae0bfda 100644
--- a/src/test/compile-fail/kindck-send-object.rs
+++ b/src/test/compile-fail/kindck-send-object.rs
@@ -20,7 +20,7 @@ trait Message : Send { }
 
 fn object_ref_with_static_bound_not_ok() {
     assert_send::<&'static (Dummy+'static)>();
-    //~^ ERROR : std::marker::Sync` is not satisfied
+    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
 }
 
 fn box_object_with_no_bound_not_ok<'a>() {
diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs
index da56fccde2d..66865bbcc7e 100644
--- a/src/test/compile-fail/kindck-send-object1.rs
+++ b/src/test/compile-fail/kindck-send-object1.rs
@@ -18,7 +18,7 @@ trait Dummy { }
 // careful with object types, who knows what they close over...
 fn test51<'a>() {
     assert_send::<&'a Dummy>();
-    //~^ ERROR : std::marker::Sync` is not satisfied
+    //~^ ERROR `Dummy + 'a` cannot be shared between threads safely [E0277]
 }
 fn test52<'a>() {
     assert_send::<&'a (Dummy+Sync)>();
diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs
index e52a6e12efc..51bc587d74f 100644
--- a/src/test/compile-fail/kindck-send-object2.rs
+++ b/src/test/compile-fail/kindck-send-object2.rs
@@ -14,7 +14,8 @@ fn assert_send<T:Send>() { }
 trait Dummy { }
 
 fn test50() {
-    assert_send::<&'static Dummy>(); //~ ERROR : std::marker::Sync` is not satisfied
+    assert_send::<&'static Dummy>();
+    //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277]
 }
 
 fn test53() {
diff --git a/src/test/compile-fail/mutable-enum-indirect.rs b/src/test/compile-fail/mutable-enum-indirect.rs
index cafcabe6279..9107745b0e9 100644
--- a/src/test/compile-fail/mutable-enum-indirect.rs
+++ b/src/test/compile-fail/mutable-enum-indirect.rs
@@ -24,5 +24,6 @@ fn bar<T: Sync>(_: T) {}
 
 fn main() {
     let x = Foo::A(NoSync);
-    bar(&x); //~ ERROR `NoSync: std::marker::Sync` is not satisfied
+    bar(&x);
+    //~^ ERROR `NoSync` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/mutexguard-sync.rs b/src/test/compile-fail/mutexguard-sync.rs
index 861714720c5..2d4b50eb7b2 100644
--- a/src/test/compile-fail/mutexguard-sync.rs
+++ b/src/test/compile-fail/mutexguard-sync.rs
@@ -18,5 +18,6 @@ fn main()
 {
     let m = Mutex::new(Cell::new(0i32));
     let guard = m.lock().unwrap();
-    test_sync(guard); //~ ERROR the trait bound
+    test_sync(guard);
+    //~^ ERROR `std::cell::Cell<i32>` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/no_share-enum.rs b/src/test/compile-fail/no_share-enum.rs
index ae9a25a95b4..77a7012b3b0 100644
--- a/src/test/compile-fail/no_share-enum.rs
+++ b/src/test/compile-fail/no_share-enum.rs
@@ -22,5 +22,5 @@ fn bar<T: Sync>(_: T) {}
 fn main() {
     let x = Foo::A(NoSync);
     bar(x);
-    //~^ ERROR `NoSync: std::marker::Sync` is not satisfied
+    //~^ ERROR `NoSync` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/no_share-struct.rs b/src/test/compile-fail/no_share-struct.rs
index d64d37a2f6c..34e43e9f2aa 100644
--- a/src/test/compile-fail/no_share-struct.rs
+++ b/src/test/compile-fail/no_share-struct.rs
@@ -20,5 +20,5 @@ fn bar<T: Sync>(_: T) {}
 fn main() {
     let x = Foo { a: 5 };
     bar(x);
-    //~^ ERROR `Foo: std::marker::Sync` is not satisfied
+    //~^ ERROR `Foo` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/not-sync.rs b/src/test/compile-fail/not-sync.rs
index 12c29279178..a383244f415 100644
--- a/src/test/compile-fail/not-sync.rs
+++ b/src/test/compile-fail/not-sync.rs
@@ -16,17 +16,17 @@ fn test<T: Sync>() {}
 
 fn main() {
     test::<Cell<i32>>();
-    //~^ ERROR `std::cell::Cell<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::Cell<i32>` cannot be shared between threads safely [E0277]
     test::<RefCell<i32>>();
-    //~^ ERROR `std::cell::RefCell<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely [E0277]
 
     test::<Rc<i32>>();
-    //~^ ERROR `std::rc::Rc<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::rc::Rc<i32>` cannot be shared between threads safely [E0277]
     test::<Weak<i32>>();
-    //~^ ERROR `std::rc::Weak<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::rc::Weak<i32>` cannot be shared between threads safely [E0277]
 
     test::<Receiver<i32>>();
-    //~^ ERROR `std::sync::mpsc::Receiver<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely [E0277]
     test::<Sender<i32>>();
-    //~^ ERROR `std::sync::mpsc::Sender<i32>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs
index e36c4835ca1..51e7d5da98f 100644
--- a/src/test/compile-fail/phantom-oibit.rs
+++ b/src/test/compile-fail/phantom-oibit.rs
@@ -28,11 +28,13 @@ struct Nested<T>(T);
 fn is_zen<T: Zen>(_: T) {}
 
 fn not_sync<T>(x: Guard<T>) {
-    is_zen(x)  //~ error: `T: std::marker::Sync` is not satisfied
+    is_zen(x)
+    //~^ ERROR `T` cannot be shared between threads safely [E0277]
 }
 
 fn nested_not_sync<T>(x: Nested<Guard<T>>) {
-    is_zen(x)  //~ error: `T: std::marker::Sync` is not satisfied
+    is_zen(x)
+    //~^ ERROR `T` cannot be shared between threads safely [E0277]
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs b/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs
index cdf787a60ad..c829ba3dcc3 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs
@@ -43,11 +43,11 @@ fn is_sync<T: Sync>() {}
 fn main() {
     is_sync::<MySync>();
     is_sync::<MyNotSync>();
-    //~^ ERROR `MyNotSync: std::marker::Sync` is not satisfied
+    //~^ ERROR `MyNotSync` cannot be shared between threads safely [E0277]
 
     is_sync::<MyTypeWUnsafe>();
-    //~^ ERROR `std::cell::UnsafeCell<u8>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::UnsafeCell<u8>` cannot be shared between threads safely [E0277]
 
     is_sync::<MyTypeManaged>();
-    //~^ ERROR `Managed: std::marker::Sync` is not satisfied
+    //~^ ERROR `Managed` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs
index f0172777cda..fcfc8574b21 100644
--- a/src/test/compile-fail/typeck-unsafe-always-share.rs
+++ b/src/test/compile-fail/typeck-unsafe-always-share.rs
@@ -27,16 +27,16 @@ fn test<T: Sync>(s: T) {}
 fn main() {
     let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)});
     test(us);
-    //~^ ERROR `std::cell::UnsafeCell<MySync<{integer}>>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
 
     let uns = UnsafeCell::new(NoSync);
     test(uns);
-    //~^ ERROR `std::cell::UnsafeCell<NoSync>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely [E0277]
 
     let ms = MySync{u: uns};
     test(ms);
-    //~^ ERROR `std::cell::UnsafeCell<NoSync>: std::marker::Sync` is not satisfied
+    //~^ ERROR `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely [E0277]
 
     test(NoSync);
-    //~^ ERROR `NoSync: std::marker::Sync` is not satisfied
+    //~^ ERROR `NoSync` cannot be shared between threads safely [E0277]
 }
diff --git a/src/test/ui/closure-move-sync.rs b/src/test/ui/closure-move-sync.rs
new file mode 100644
index 00000000000..e096e7ca3a0
--- /dev/null
+++ b/src/test/ui/closure-move-sync.rs
@@ -0,0 +1,32 @@
+// 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.
+
+use std::thread;
+use std::sync::mpsc::channel;
+
+fn bar() {
+    let (send, recv) = channel();
+    let t = thread::spawn(|| {
+        recv.recv().unwrap();
+        //~^^ ERROR `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
+    });
+
+    send.send(());
+
+    t.join().unwrap();
+}
+
+fn foo() {
+    let (tx, _rx) = channel();
+    thread::spawn(|| tx.send(()).unwrap());
+    //~^ ERROR `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
+}
+
+fn main() {}
diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr
new file mode 100644
index 00000000000..076bae8dbd7
--- /dev/null
+++ b/src/test/ui/closure-move-sync.stderr
@@ -0,0 +1,25 @@
+error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
+  --> $DIR/closure-move-sync.rs:16:13
+   |
+LL |     let t = thread::spawn(|| {
+   |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:16:27: 19:6 recv:&std::sync::mpsc::Receiver<()>]`
+   = note: required by `std::thread::spawn`
+
+error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
+  --> $DIR/closure-move-sync.rs:28:5
+   |
+LL |     thread::spawn(|| tx.send(()).unwrap());
+   |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
+   |
+   = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
+   = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:28:19: 28:42 tx:&std::sync::mpsc::Sender<()>]`
+   = note: required by `std::thread::spawn`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs
index 48fe2300031..35e3c768558 100644
--- a/src/test/ui/error-codes/E0044.rs
+++ b/src/test/ui/error-codes/E0044.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// 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.
 //
@@ -8,7 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-extern { fn some_func<T>(x: T); } //~ ERROR E0044
+extern {
+    fn sqrt<T>(f: T) -> T;
+    //~^ ERROR foreign items may not have type parameters [E0044]
+    //~| HELP use specialization instead of type parameters by replacing them with concrete types
+    //~| NOTE can't have type parameters
+}
 
 fn main() {
 }
diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr
index b981f525517..ce966251bf4 100644
--- a/src/test/ui/error-codes/E0044.stderr
+++ b/src/test/ui/error-codes/E0044.stderr
@@ -1,14 +1,10 @@
 error[E0044]: foreign items may not have type parameters
-  --> $DIR/E0044.rs:11:10
+  --> $DIR/E0044.rs:12:5
    |
-LL | extern { fn some_func<T>(x: T); } //~ ERROR E0044
-   |          ^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn sqrt<T>(f: T) -> T;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters
    |
-help: consider using specialization instead of type parameters
-  --> $DIR/E0044.rs:11:10
-   |
-LL | extern { fn some_func<T>(x: T); } //~ ERROR E0044
-   |          ^^^^^^^^^^^^^^^^^^^^^^
+   = help: use specialization instead of type parameters by replacing them with concrete types like `u32`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs
index 3f13fd2e491..424919a0eba 100644
--- a/src/test/ui/fmt/send-sync.rs
+++ b/src/test/ui/fmt/send-sync.rs
@@ -15,6 +15,6 @@ fn main() {
     // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`,
     // `std::fmt::Arguments` used to forget this...
     let c = std::cell::Cell::new(42);
-    send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied
-    sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied
+    send(format_args!("{:?}", c)); //~ ERROR E0277
+    sync(format_args!("{:?}", c)); //~ ERROR E0277
 }
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index abbe6d5b11c..807b499155b 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -1,7 +1,7 @@
-error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `[std::fmt::ArgumentV1<'_>]`
+error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
   --> $DIR/send-sync.rs:18:5
    |
-LL |     send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied
+LL |     send(format_args!("{:?}", c)); //~ ERROR E0277
    |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
    |
    = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
@@ -18,10 +18,10 @@ note: required by `send`
 LL | fn send<T: Send>(_: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>`
+error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
   --> $DIR/send-sync.rs:19:5
    |
-LL |     sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied
+LL |     sync(format_args!("{:?}", c)); //~ ERROR E0277
    |     ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely
    |
    = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static`
diff --git a/src/test/ui/generator/not-send-sync.rs b/src/test/ui/generator/not-send-sync.rs
index 0419758d8ea..f0df05ebfdf 100644
--- a/src/test/ui/generator/not-send-sync.rs
+++ b/src/test/ui/generator/not-send-sync.rs
@@ -17,14 +17,14 @@ fn main() {
     fn assert_send<T: Send>(_: T) {}
 
     assert_sync(|| {
-        //~^ ERROR: Sync` is not satisfied
+        //~^ ERROR: E0277
         let a = Cell::new(2);
         yield;
     });
 
     let a = Cell::new(2);
     assert_send(|| {
-        //~^ ERROR: Sync` is not satisfied
+        //~^ ERROR: E0277
         drop(&a);
         yield;
     });
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 7ef6edfacf4..edf7151f7c4 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -1,4 +1,4 @@
-error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied
+error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:26:5
    |
 LL |     assert_send(|| {
@@ -13,7 +13,7 @@ note: required by `main::assert_send`
 LL |     fn assert_send<T: Send>(_: T) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell<i32>, ()}]`
+error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:19:5
    |
 LL |     assert_sync(|| {