From 6d8a1739805fa81b6baa8c86efc3e79920ecb306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 10 Feb 2018 21:01:49 -0800 Subject: [PATCH 1/5] Reword E0044 and message for `!Send` types - Reword E0044 help. - Change error message for types that don't implement `Send` --- src/libcore/marker.rs | 5 ++++- src/librustc_typeck/check/mod.rs | 7 ++++--- .../builtin-superkinds-double-superkind.rs | 6 ++++-- src/test/compile-fail/closure-bounds-subtype.rs | 2 +- src/test/compile-fail/extern-types-not-sync-send.rs | 2 +- src/test/compile-fail/issue-16538.rs | 2 +- src/test/compile-fail/issue-17718-static-sync.rs | 2 +- src/test/compile-fail/issue-43733-2.rs | 4 ++-- src/test/compile-fail/issue-7364.rs | 2 +- src/test/compile-fail/kindck-send-object.rs | 2 +- src/test/compile-fail/kindck-send-object1.rs | 2 +- src/test/compile-fail/kindck-send-object2.rs | 3 ++- src/test/compile-fail/mutable-enum-indirect.rs | 3 ++- src/test/compile-fail/mutexguard-sync.rs | 3 ++- src/test/compile-fail/no_share-enum.rs | 2 +- src/test/compile-fail/no_share-struct.rs | 2 +- src/test/compile-fail/not-sync.rs | 12 ++++++------ src/test/compile-fail/phantom-oibit.rs | 6 ++++-- .../typeck-default-trait-impl-negation-sync.rs | 6 +++--- src/test/compile-fail/typeck-unsafe-always-share.rs | 8 ++++---- src/test/ui/error-codes/E0044.rs | 8 ++++++-- src/test/ui/error-codes/E0044.stderr | 12 ++++-------- src/test/ui/fmt/send-sync.rs | 4 ++-- src/test/ui/fmt/send-sync.stderr | 8 ++++---- src/test/ui/generator/not-send-sync.rs | 4 ++-- src/test/ui/generator/not-send-sync.stderr | 4 ++-- 26 files changed, 66 insertions(+), 55 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 98e0f71eb9356..fd57491fcc765 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -343,7 +343,10 @@ 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 { // Empty } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 19085ff039ec5..92c6e3ffed2db 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1222,9 +1222,10 @@ 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"); + // 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 8d5d8e8dc9b7d..261881d880bf9 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 Foo for (T,) { } //~ ERROR `T: std::marker::Send` is not satisfied +impl Foo for (T,) { } +//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277] -impl Foo for (T,T) { } //~ ERROR `T: std::marker::Sync` is not satisfied +impl Foo for (T,T) { } +//~^ ERROR `T` cannot be shared between threads safely [E0277] impl 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 d3339c4845ab2..db26535b004ac 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) where F: FnOnce() { fn give_owned(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 2f00cf812e473..6a7a515ba5fbb 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() { } fn main() { assert_sync::(); - //~^ ERROR the trait bound `A: std::marker::Sync` is not satisfied + //~^ ERROR `A` cannot be shared between threads safely [E0277] assert_send::(); //~^ 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 08c3f7a7c1545..7df445c676c9c 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 790329cd2e429..c5349d4e82b4b 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 0fd31454596e6..a5ba9ef9bd35d 100644 --- a/src/test/compile-fail/issue-43733-2.rs +++ b/src/test/compile-fail/issue-43733-2.rs @@ -33,7 +33,7 @@ impl Key { use std::thread::__FastLocalKeyInner as Key; static __KEY: Key<()> = Key::new(); -//~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied -//~| ERROR `std::cell::Cell: std::marker::Sync` is not satisfied +//~^ ERROR `std::cell::UnsafeCell>` cannot be shared between threads +//~| ERROR `std::cell::Cell` 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 16138c992ff78..801a1301ad774 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> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics -//~| ERROR `std::cell::RefCell: std::marker::Sync` is not satisfied +//~| ERROR `std::cell::RefCell` 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 bd0e5642b9ccd..a84eae0bfdae8 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 da56fccde2d4a..66865bbcc7ee1 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 e52a6e12efc96..51bc587d74ff8 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() { } 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 cafcabe6279b0..9107745b0e9c4 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) {} 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 861714720c57a..2d4b50eb7b23c 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` 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 ae9a25a95b4ea..77a7012b3b033 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) {} 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 d64d37a2f6c33..34e43e9f2aaec 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) {} 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 12c2927917890..a383244f415c8 100644 --- a/src/test/compile-fail/not-sync.rs +++ b/src/test/compile-fail/not-sync.rs @@ -16,17 +16,17 @@ fn test() {} fn main() { test::>(); - //~^ ERROR `std::cell::Cell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::Cell` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::cell::RefCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::rc::Rc: std::marker::Sync` is not satisfied + //~^ ERROR `std::rc::Rc` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::rc::Weak: std::marker::Sync` is not satisfied + //~^ ERROR `std::rc::Weak` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::sync::mpsc::Receiver: std::marker::Sync` is not satisfied + //~^ ERROR `std::sync::mpsc::Receiver` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::sync::mpsc::Sender: std::marker::Sync` is not satisfied + //~^ ERROR `std::sync::mpsc::Sender` 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 e36c4835ca1c9..51e7d5da98f4b 100644 --- a/src/test/compile-fail/phantom-oibit.rs +++ b/src/test/compile-fail/phantom-oibit.rs @@ -28,11 +28,13 @@ struct Nested(T); fn is_zen(_: T) {} fn not_sync(x: Guard) { - 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(x: Nested>) { - 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 cdf787a60ad43..c829ba3dcc357 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() {} fn main() { is_sync::(); is_sync::(); - //~^ ERROR `MyNotSync: std::marker::Sync` is not satisfied + //~^ ERROR `MyNotSync` cannot be shared between threads safely [E0277] is_sync::(); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` cannot be shared between threads safely [E0277] is_sync::(); - //~^ 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 f0172777cdabb..fcfc8574b2135 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(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>` cannot be shared between threads safely let uns = UnsafeCell::new(NoSync); test(uns); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` cannot be shared between threads safely [E0277] let ms = MySync{u: uns}; test(ms); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` 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/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs index 48fe230003129..4d20edea5fe18 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,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern { fn some_func(x: T); } //~ ERROR E0044 +extern { + fn sqrt(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 +} fn main() { } diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr index b823f3717b356..12324e771d3ab 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(x: T); } //~ ERROR E0044 - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn sqrt(f: T) -> T; + | ^^^^^^^^^^^^^^^^^^^^^^ | -help: consider using specialization instead of type parameters - --> $DIR/E0044.rs:11:10 - | -LL | extern { fn some_func(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 3f13fd2e4913a..424919a0eba67 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 0943b64c5c090..113a2a480aaf7 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) {} | ^^^^^^^^^^^^^^^^^^^^^^ -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 0419758d8ea17..f0df05ebfdf80 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) {} 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 6ca583bf16d6c..669e0d26cf07c 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: std::marker::Sync` is not satisfied +error[E0277]: `std::cell::Cell` 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) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell, ()}]` +error[E0277]: `std::cell::Cell` cannot be shared between threads safely --> $DIR/not-send-sync.rs:19:5 | LL | assert_sync(|| { From fe1975448cf180a39393104a7b424291975998d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 11 Feb 2018 13:39:32 -0800 Subject: [PATCH 2/5] Suggest using `move` when trying to share `...::channel::{Receiver, Sender}` Extend `rustc_on_unimplemented` to match on ADT without evaluating type arguments. --- src/libcore/marker.rs | 8 +++++++ src/librustc/traits/error_reporting.rs | 31 ++++++++++++++----------- src/test/ui/closure-move-sync.rs | 32 ++++++++++++++++++++++++++ src/test/ui/closure-move-sync.stderr | 24 +++++++++++++++++++ 4 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/closure-move-sync.rs create mode 100644 src/test/ui/closure-move-sync.stderr diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index fd57491fcc765..51d2e29e6b15a 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -344,6 +344,14 @@ pub trait Copy : Clone { #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sync"] #[rustc_on_unimplemented( + on( + _Self="std::sync::mpsc::Receiver", + label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + ), + on( + _Self="std::sync::mpsc::Sender", + label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + ), message="`{Self}` cannot be shared between threads safely", label="`{Self}` cannot be shared between threads safely" )] diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index cd2d0d7e2a043..9cdab856b05ec 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -338,18 +338,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 { @@ -359,21 +356,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/test/ui/closure-move-sync.rs b/src/test/ui/closure-move-sync.rs new file mode 100644 index 0000000000000..e096e7ca3a06b --- /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 or the MIT license +// , 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 0000000000000..fc53deeeef7ad --- /dev/null +++ b/src/test/ui/closure-move-sync.stderr @@ -0,0 +1,24 @@ +error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely + --> $DIR/closure-move-sync.rs:16:13 + | +16 | let t = thread::spawn(|| { + | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, if using a closure consider marking it `move` + | + = 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 + | +28 | thread::spawn(|| tx.send(()).unwrap()); + | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, if using a closure consider marking it `move` + | + = 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 + From cb5667eaa53c45f1cdf69f367f8cd749b0499ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Feb 2018 00:15:12 -0800 Subject: [PATCH 3/5] Make hint clearer, with the potential of being wrong --- src/libcore/marker.rs | 4 ++-- src/test/ui/closure-move-sync.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 51d2e29e6b15a..d78453cc900bd 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -346,11 +346,11 @@ pub trait Copy : Clone { #[rustc_on_unimplemented( on( _Self="std::sync::mpsc::Receiver", - label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + label="`{Self}` cannot be shared safely, consider marking the closure `move`" ), on( _Self="std::sync::mpsc::Sender", - label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + label="`{Self}` cannot be shared safely, consider marking the closure `move`" ), message="`{Self}` cannot be shared between threads safely", label="`{Self}` cannot be shared between threads safely" diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index fc53deeeef7ad..4b59ef8a4373d 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -2,7 +2,7 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads s --> $DIR/closure-move-sync.rs:16:13 | 16 | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, if using a closure consider marking it `move` + | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, consider marking the closure `move` | = 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<()>` @@ -13,7 +13,7 @@ error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads saf --> $DIR/closure-move-sync.rs:28:5 | 28 | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, if using a closure consider marking it `move` + | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, consider marking the closure `move` | = 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<()>` From bfc66daef9d1bdc52000cf8c079ea8572699f6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Feb 2018 13:18:29 -0800 Subject: [PATCH 4/5] Review comment: remove mention of `move` closure --- src/libcore/marker.rs | 18 ++++++++++-------- src/test/ui/closure-move-sync.stderr | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index d78453cc900bd..53b1d1cd12de3 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -344,18 +344,20 @@ pub trait Copy : Clone { #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sync"] #[rustc_on_unimplemented( - on( - _Self="std::sync::mpsc::Receiver", - label="`{Self}` cannot be shared safely, consider marking the closure `move`" - ), - on( - _Self="std::sync::mpsc::Sender", - label="`{Self}` cannot be shared safely, consider marking the closure `move`" - ), 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/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index 4b59ef8a4373d..abf07d2cef526 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -1,8 +1,8 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:16:13 | -16 | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, consider marking the closure `move` +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<()>` @@ -12,8 +12,8 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads s error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:28:5 | -28 | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, consider marking the closure `move` +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<()>` @@ -22,3 +22,4 @@ error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads saf error: aborting due to 2 previous errors +If you want more information on this error, try using "rustc --explain E0277" From 1bbd4fd395b7b8f5f51f90401665168b19f0b9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Mar 2018 18:10:25 -0700 Subject: [PATCH 5/5] Add span label to E0044 --- src/librustc_typeck/check/mod.rs | 1 + src/test/ui/closure-move-sync.stderr | 2 +- src/test/ui/error-codes/E0044.rs | 1 + src/test/ui/error-codes/E0044.stderr | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 92c6e3ffed2db..8fe9c62927ed6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1222,6 +1222,7 @@ 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"); + 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 \ diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index abf07d2cef526..076bae8dbd7af 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -22,4 +22,4 @@ LL | thread::spawn(|| tx.send(()).unwrap()); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +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 4d20edea5fe18..35e3c76855890 100644 --- a/src/test/ui/error-codes/E0044.rs +++ b/src/test/ui/error-codes/E0044.rs @@ -12,6 +12,7 @@ extern { fn sqrt(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 12324e771d3ab..0e22818f789f4 100644 --- a/src/test/ui/error-codes/E0044.stderr +++ b/src/test/ui/error-codes/E0044.stderr @@ -2,7 +2,7 @@ error[E0044]: foreign items may not have type parameters --> $DIR/E0044.rs:12:5 | LL | fn sqrt(f: T) -> T; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters | = help: use specialization instead of type parameters by replacing them with concrete types like `u32`