Skip to content

Commit ff2d506

Browse files
committed
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.
2 parents a4af6f0 + 1bbd4fd commit ff2d506

29 files changed

+152
-69
lines changed

src/libcore/marker.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,21 @@ pub trait Copy : Clone {
343343
/// [transmute]: ../../std/mem/fn.transmute.html
344344
#[stable(feature = "rust1", since = "1.0.0")]
345345
#[lang = "sync"]
346-
#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"]
346+
#[rustc_on_unimplemented(
347+
message="`{Self}` cannot be shared between threads safely",
348+
label="`{Self}` cannot be shared between threads safely"
349+
)]
347350
pub unsafe auto trait Sync {
351+
// FIXME(estebank): once support to add notes in `rustc_on_unimplemented`
352+
// lands in beta, and it has been extended to check whether a closure is
353+
// anywhere in the requirement chain, extend it as such (#48534):
354+
// ```
355+
// on(
356+
// closure,
357+
// note="`{Self}` cannot be shared safely, consider marking the closure `move`"
358+
// ),
359+
// ```
360+
348361
// Empty
349362
}
350363

src/librustc/traits/error_reporting.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -339,18 +339,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
339339
.unwrap_or(trait_ref.def_id());
340340
let trait_ref = *trait_ref.skip_binder();
341341

342-
let desugaring;
343-
let method;
344342
let mut flags = vec![];
345-
let direct = match obligation.cause.code {
343+
match obligation.cause.code {
346344
ObligationCauseCode::BuiltinDerivedObligation(..) |
347-
ObligationCauseCode::ImplDerivedObligation(..) => false,
348-
_ => true
349-
};
350-
if direct {
351-
// this is a "direct", user-specified, rather than derived,
352-
// obligation.
353-
flags.push(("direct".to_string(), None));
345+
ObligationCauseCode::ImplDerivedObligation(..) => {}
346+
_ => {
347+
// this is a "direct", user-specified, rather than derived,
348+
// obligation.
349+
flags.push(("direct".to_string(), None));
350+
}
354351
}
355352

356353
if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code {
@@ -360,21 +357,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
360357
//
361358
// Currently I'm leaving it for what I need for `try`.
362359
if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) {
363-
method = self.tcx.item_name(item);
360+
let method = self.tcx.item_name(item);
364361
flags.push(("from_method".to_string(), None));
365362
flags.push(("from_method".to_string(), Some(method.to_string())));
366363
}
367364
}
368365

369366
if let Some(k) = obligation.cause.span.compiler_desugaring_kind() {
370-
desugaring = k.as_symbol().as_str();
367+
let desugaring = k.as_symbol().as_str();
371368
flags.push(("from_desugaring".to_string(), None));
372369
flags.push(("from_desugaring".to_string(), Some(desugaring.to_string())));
373370
}
374371
let generics = self.tcx.generics_of(def_id);
375372
let self_ty = trait_ref.self_ty();
376-
let self_ty_str = self_ty.to_string();
377-
flags.push(("_Self".to_string(), Some(self_ty_str.clone())));
373+
// This is also included through the generics list as `Self`,
374+
// but the parser won't allow you to use it
375+
flags.push(("_Self".to_string(), Some(self_ty.to_string())));
376+
if let Some(def) = self_ty.ty_adt_def() {
377+
// We also want to be able to select self's original
378+
// signature with no type arguments resolved
379+
flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string())));
380+
}
378381

379382
for param in generics.types.iter() {
380383
let name = param.name.as_str().to_string();

src/librustc_typeck/check/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,9 +1223,11 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
12231223
if !generics.types.is_empty() {
12241224
let mut err = struct_span_err!(tcx.sess, item.span, E0044,
12251225
"foreign items may not have type parameters");
1226-
span_help!(&mut err, item.span,
1227-
"consider using specialization instead of \
1228-
type parameters");
1226+
err.span_label(item.span, "can't have type parameters");
1227+
// FIXME: once we start storing spans for type arguments, turn this into a
1228+
// suggestion.
1229+
err.help("use specialization instead of type parameters by replacing them \
1230+
with concrete types like `u32`");
12291231
err.emit();
12301232
}
12311233

src/test/compile-fail/builtin-superkinds-double-superkind.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
trait Foo : Send+Sync { }
1515

16-
impl <T: Sync+'static> Foo for (T,) { } //~ ERROR `T: std::marker::Send` is not satisfied
16+
impl <T: Sync+'static> Foo for (T,) { }
17+
//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277]
1718

18-
impl <T: Send> Foo for (T,T) { } //~ ERROR `T: std::marker::Sync` is not satisfied
19+
impl <T: Send> Foo for (T,T) { }
20+
//~^ ERROR `T` cannot be shared between threads safely [E0277]
1921

2022
impl <T: Send+Sync> Foo for (T,T,T) { } // (ok)
2123

src/test/compile-fail/closure-bounds-subtype.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn give_any<F>(f: F) where F: FnOnce() {
2121

2222
fn give_owned<F>(f: F) where F: FnOnce() + Send {
2323
take_any(f);
24-
take_const_owned(f); //~ ERROR `F: std::marker::Sync` is not satisfied
24+
take_const_owned(f); //~ ERROR `F` cannot be shared between threads safely [E0277]
2525
}
2626

2727
fn main() {}

src/test/compile-fail/extern-types-not-sync-send.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn assert_send<T: ?Sized + Send>() { }
2121

2222
fn main() {
2323
assert_sync::<A>();
24-
//~^ ERROR the trait bound `A: std::marker::Sync` is not satisfied
24+
//~^ ERROR `A` cannot be shared between threads safely [E0277]
2525

2626
assert_send::<A>();
2727
//~^ ERROR the trait bound `A: std::marker::Send` is not satisfied

src/test/compile-fail/issue-16538.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod Y {
2121
}
2222

2323
static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
24-
//~^ ERROR `*const usize: std::marker::Sync` is not satisfied
24+
//~^ ERROR `*const usize` cannot be shared between threads safely [E0277]
2525
//~| ERROR cannot refer to other statics by value, use the address-of operator or a constant instead
2626
//~| ERROR E0015
2727

src/test/compile-fail/issue-17718-static-sync.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ impl !Sync for Foo {}
1717

1818
static FOO: usize = 3;
1919
static BAR: Foo = Foo;
20-
//~^ ERROR: `Foo: std::marker::Sync` is not satisfied
20+
//~^ ERROR: `Foo` cannot be shared between threads safely [E0277]
2121

2222
fn main() {}

src/test/compile-fail/issue-43733-2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl<T> Key<T> {
3333
use std::thread::__FastLocalKeyInner as Key;
3434

3535
static __KEY: Key<()> = Key::new();
36-
//~^ ERROR `std::cell::UnsafeCell<std::option::Option<()>>: std::marker::Sync` is not satisfied
37-
//~| ERROR `std::cell::Cell<bool>: std::marker::Sync` is not satisfied
36+
//~^ ERROR `std::cell::UnsafeCell<std::option::Option<()>>` cannot be shared between threads
37+
//~| ERROR `std::cell::Cell<bool>` cannot be shared between threads safely [E0277]
3838

3939
fn main() {}

src/test/compile-fail/issue-7364.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ use std::cell::RefCell;
1515
// Regression test for issue 7364
1616
static boxed: Box<RefCell<isize>> = box RefCell::new(0);
1717
//~^ ERROR allocations are not allowed in statics
18-
//~| ERROR `std::cell::RefCell<isize>: std::marker::Sync` is not satisfied
18+
//~| ERROR `std::cell::RefCell<isize>` cannot be shared between threads safely [E0277]
1919

2020
fn main() { }

0 commit comments

Comments
 (0)