Skip to content

Commit f0c9311

Browse files
committed
Use root obligation on E0277 for some cases
When encountering trait bound errors that satisfy some heuristics that tell us that the relevant trait for the user comes from the root obligation and not the current obligation, we use the root predicate for the main message. This allows to talk about "X doesn't implement Pattern<'_>" over the most specific case that just happened to fail, like "char doesn't implement Fn(&mut char)" in `tests/ui/traits/suggest-dereferences/root-obligation.rs` The heuristics are: - the type of the leaf predicate is (roughly) the same as the type from the root predicate, as a proxy for "we care about the root" - the leaf trait and the root trait are different, so as to avoid talking about `&mut T: Trait` and instead remain talking about `T: Trait` instead - the root trait is not `Unsize`, as to avoid talking about it in `tests/ui/coercion/coerce-issue-49593-box-never.rs`. ``` error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied --> $DIR/root-obligation.rs:6:38 | LL | .filter(|c| "aeiou".contains(c)) | -------- ^ the trait `Fn<(char,)>` is not implemented for `&char`, which is required by `&char: Pattern<'_>` | | | required by a bound introduced by this call | = note: required for `&char` to implement `FnOnce<(char,)>` = note: required for `&char` to implement `Pattern<'_>` note: required by a bound in `core::str::<impl str>::contains` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider dereferencing here | LL | .filter(|c| "aeiou".contains(*c)) | + ``` Fix rust-lang#79359, fix rust-lang#119983, fix rust-lang#118779, cc rust-lang#118415 (the suggestion needs to change).
1 parent 2690737 commit f0c9311

File tree

49 files changed

+166
-120
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+166
-120
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+46-5
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,51 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
416416
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
417417
let trait_predicate = bound_predicate.rebind(trait_predicate);
418418
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
419-
let trait_ref = trait_predicate.to_poly_trait_ref();
420419

421-
if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
420+
// Let's use the root obligation as the main message, when we care about the
421+
// most general case ("X doesn't implement Pattern<'_>") over the case that
422+
// happened to fail ("char doesn't implement Fn(&mut char)").
423+
//
424+
// We rely on a few heuristics to identify cases where this root
425+
// obligation is more important than the leaf obligation:
426+
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
427+
ty::ClauseKind::Trait(root_pred)
428+
) = root_obligation.predicate.kind().skip_binder()
429+
// The type of the leaf predicate is (roughly) the same as the type
430+
// from the root predicate, as a proxy for "we care about the root"
431+
// FIXME: this doesn't account for trivial derefs, but works as a first
432+
// approximation.
433+
&& (
434+
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
435+
trait_predicate.self_ty().skip_binder()
436+
== root_pred.self_ty().peel_refs()
437+
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
438+
|| trait_predicate.self_ty().skip_binder()
439+
== root_pred.self_ty()
440+
)
441+
// The leaf trait and the root trait are different, so as to avoid
442+
// talking about `&mut T: Trait` and instead remain talking about
443+
// `T: Trait` instead
444+
&& trait_predicate.def_id() != root_pred.def_id()
445+
// The root trait is not `Unsize`, as to avoid talking about it in
446+
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
447+
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
448+
{
449+
(
450+
self.resolve_vars_if_possible(
451+
root_obligation.predicate.kind().rebind(root_pred),
452+
),
453+
root_obligation,
454+
)
455+
} else {
456+
(trait_predicate, &obligation)
457+
};
458+
let trait_ref = main_trait_predicate.to_poly_trait_ref();
459+
460+
if let Some(guar) = self.emit_specialized_closure_kind_error(
461+
&obligation,
462+
trait_ref,
463+
) {
422464
return guar;
423465
}
424466

@@ -459,8 +501,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
459501
notes,
460502
parent_label,
461503
append_const_msg,
462-
} = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
463-
504+
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
464505
let have_alt_message = message.is_some() || label.is_some();
465506
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
466507
let is_unsize =
@@ -483,7 +524,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
483524
};
484525

485526
let err_msg = self.get_standard_error_message(
486-
&trait_predicate,
527+
&main_trait_predicate,
487528
message,
488529
predicate_is_const,
489530
append_const_msg,

library/core/src/future/future.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ use crate::task::{Context, Poll};
3030
#[lang = "future_trait"]
3131
#[diagnostic::on_unimplemented(
3232
label = "`{Self}` is not a future",
33-
message = "`{Self}` is not a future",
34-
note = "{Self} must be a future or must implement `IntoFuture` to be awaited"
33+
message = "`{Self}` is not a future"
3534
)]
3635
pub trait Future {
3736
/// The type of value produced on completion.

library/core/src/future/into_future.rs

+5
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ use crate::future::Future;
100100
/// ```
101101
#[stable(feature = "into_future", since = "1.64.0")]
102102
#[rustc_diagnostic_item = "IntoFuture"]
103+
#[diagnostic::on_unimplemented(
104+
label = "`{Self}` is not a future",
105+
message = "`{Self}` is not a future",
106+
note = "{Self} must be a future or must implement `IntoFuture` to be awaited"
107+
)]
103108
pub trait IntoFuture {
104109
/// The output that the future will produce on completion.
105110
#[stable(feature = "into_future", since = "1.64.0")]

library/core/src/iter/traits/collect.rs

+43
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,49 @@ pub trait FromIterator<A>: Sized {
236236
/// ```
237237
#[rustc_diagnostic_item = "IntoIterator"]
238238
#[rustc_skip_array_during_method_dispatch]
239+
#[rustc_on_unimplemented(
240+
on(
241+
_Self = "core::ops::range::RangeTo<Idx>",
242+
label = "if you meant to iterate until a value, add a starting value",
243+
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
244+
bounded `Range`: `0..end`"
245+
),
246+
on(
247+
_Self = "core::ops::range::RangeToInclusive<Idx>",
248+
label = "if you meant to iterate until a value (including it), add a starting value",
249+
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
250+
to have a bounded `RangeInclusive`: `0..=end`"
251+
),
252+
on(
253+
_Self = "[]",
254+
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
255+
),
256+
on(_Self = "&[]", label = "`{Self}` is not an iterator; try calling `.iter()`"),
257+
on(
258+
_Self = "alloc::vec::Vec<T, A>",
259+
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
260+
),
261+
on(
262+
_Self = "&str",
263+
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
264+
),
265+
on(
266+
_Self = "alloc::string::String",
267+
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
268+
),
269+
on(
270+
_Self = "{integral}",
271+
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
272+
syntax `start..end` or the inclusive range syntax `start..=end`"
273+
),
274+
on(
275+
_Self = "{float}",
276+
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
277+
syntax `start..end` or the inclusive range syntax `start..=end`"
278+
),
279+
label = "`{Self}` is not an iterator",
280+
message = "`{Self}` is not an iterator"
281+
)]
239282
#[stable(feature = "rust1", since = "1.0.0")]
240283
pub trait IntoIterator {
241284
/// The type of the elements being iterated over.

library/core/src/iter/traits/iterator.rs

+2-24
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,11 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
2828
#[rustc_on_unimplemented(
2929
on(
3030
_Self = "core::ops::range::RangeTo<Idx>",
31-
label = "if you meant to iterate until a value, add a starting value",
32-
note = "`..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a \
33-
bounded `Range`: `0..end`"
31+
note = "you might have meant to use a bounded `Range`"
3432
),
3533
on(
3634
_Self = "core::ops::range::RangeToInclusive<Idx>",
37-
label = "if you meant to iterate until a value (including it), add a starting value",
38-
note = "`..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant \
39-
to have a bounded `RangeInclusive`: `0..=end`"
35+
note = "you might have meant to use a bounded `RangeInclusive`"
4036
),
4137
on(
4238
_Self = "[]",
@@ -47,24 +43,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
4743
_Self = "alloc::vec::Vec<T, A>",
4844
label = "`{Self}` is not an iterator; try calling `.into_iter()` or `.iter()`"
4945
),
50-
on(
51-
_Self = "&str",
52-
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
53-
),
54-
on(
55-
_Self = "alloc::string::String",
56-
label = "`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`"
57-
),
58-
on(
59-
_Self = "{integral}",
60-
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
61-
syntax `start..end` or the inclusive range syntax `start..=end`"
62-
),
63-
on(
64-
_Self = "{float}",
65-
note = "if you want to iterate between `start` until a value `end`, use the exclusive range \
66-
syntax `start..end` or the inclusive range syntax `start..=end`"
67-
),
6846
label = "`{Self}` is not an iterator",
6947
message = "`{Self}` is not an iterator"
7048
)]

tests/ui/associated-types/substs-ppaux.normal.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ help: use parentheses to call this function
7070
LL | let x: () = foo::<'static>();
7171
| ++
7272

73-
error[E0277]: the size for values of type `str` cannot be known at compilation time
73+
error[E0277]: the trait bound `str: Foo<'_, '_, u8>` is not satisfied
7474
--> $DIR/substs-ppaux.rs:49:6
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^ doesn't have a size known at compile-time
77+
| ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>`
7878
|
79-
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'_, '_, u8>`
8079
note: required for `str` to implement `Foo<'_, '_, u8>`
8180
--> $DIR/substs-ppaux.rs:11:17
8281
|

tests/ui/associated-types/substs-ppaux.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ fn foo<'z>() where &'z (): Sized {
4747
//[normal]~| found fn item `fn() {foo::<'static>}`
4848

4949
<str as Foo<u8>>::bar;
50-
//[verbose]~^ ERROR the size for values of type
51-
//[normal]~^^ ERROR the size for values of type
50+
//[verbose]~^ ERROR the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied
51+
//[normal]~^^ ERROR the trait bound `str: Foo<'_, '_, u8>` is not satisfied
5252
}

tests/ui/associated-types/substs-ppaux.verbose.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ help: use parentheses to call this function
7070
LL | let x: () = foo::<'static>();
7171
| ++
7272

73-
error[E0277]: the size for values of type `str` cannot be known at compilation time
73+
error[E0277]: the trait bound `str: Foo<'?0, '?1, u8>` is not satisfied
7474
--> $DIR/substs-ppaux.rs:49:6
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^ doesn't have a size known at compile-time
77+
| ^^^ the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>`
7878
|
79-
= help: the trait `Sized` is not implemented for `str`, which is required by `str: Foo<'?0, '?1, u8>`
8079
note: required for `str` to implement `Foo<'?0, '?1, u8>`
8180
--> $DIR/substs-ppaux.rs:11:17
8281
|

tests/ui/async-await/async-error-span.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | fn get_future() -> impl Future<Output = ()> {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
66
|
77
= help: the trait `Future` is not implemented for `()`
8-
= note: () must be a future or must implement `IntoFuture` to be awaited
98

109
error[E0282]: type annotations needed
1110
--> $DIR/async-error-span.rs:13:9

tests/ui/async-await/coroutine-not-future.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ LL | takes_future(returns_coroutine());
4949
| required by a bound introduced by this call
5050
|
5151
= help: the trait `Future` is not implemented for `impl Coroutine<Yield = (), Return = ()>`
52-
= note: impl Coroutine<Yield = (), Return = ()> must be a future or must implement `IntoFuture` to be awaited
5352
note: required by a bound in `takes_future`
5453
--> $DIR/coroutine-not-future.rs:17:26
5554
|
@@ -69,7 +68,6 @@ LL | | });
6968
| |_____^ `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}` is not a future
7069
|
7170
= help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23}`
72-
= note: {coroutine@$DIR/coroutine-not-future.rs:41:18: 41:23} must be a future or must implement `IntoFuture` to be awaited
7371
note: required by a bound in `takes_future`
7472
--> $DIR/coroutine-not-future.rs:17:26
7573
|

tests/ui/auto-traits/typeck-default-trait-impl-precedence.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ impl Signed for i32 { }
1717
fn main() {
1818
is_defaulted::<&'static i32>();
1919
is_defaulted::<&'static u32>();
20-
//~^ ERROR `u32: Signed` is not satisfied
20+
//~^ ERROR the trait bound `&'static u32: Defaulted` is not satisfied
2121
}

tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0277]: the trait bound `u32: Signed` is not satisfied
1+
error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied
22
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
33
|
44
LL | is_defaulted::<&'static u32>();
5-
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`, which is required by `&'static u32: Defaulted`
5+
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
66
|
77
note: required for `&'static u32` to implement `Defaulted`
88
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19

tests/ui/coroutine/gen_block_is_no_future.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | fn foo() -> impl std::future::Future {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}` is not a future
66
|
77
= help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21}`
8-
= note: {gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:21} must be a future or must implement `IntoFuture` to be awaited
98

109
error: aborting due to 1 previous error
1110

tests/ui/feature-gates/feature-gate-trivial_bounds.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ LL | fn use_for() where i32: Iterator {
7474
| ^^^^^^^^^^^^^ `i32` is not an iterator
7575
|
7676
= help: the trait `Iterator` is not implemented for `i32`
77-
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
7877
= help: see issue #48214
7978
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
8079

tests/ui/for/issue-20605.current.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the size for values of type `dyn Iterator<Item = &'a mut u8>` cannot be known at compilation time
1+
error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
22
--> $DIR/issue-20605.rs:5:17
33
|
44
LL | for item in *things { *item = 0 }

tests/ui/for/issue-20605.next.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
error[E0277]: the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
1+
error[E0277]: `dyn Iterator<Item = &'a mut u8>` is not an iterator
22
--> $DIR/issue-20605.rs:5:17
33
|
44
LL | for item in *things { *item = 0 }
5-
| ^^^^^^^ the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
5+
| ^^^^^^^ `dyn Iterator<Item = &'a mut u8>` is not an iterator
6+
|
7+
= help: the trait `IntoIterator` is not implemented for `dyn Iterator<Item = &'a mut u8>`
68

79
error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
810
--> $DIR/issue-20605.rs:5:17

tests/ui/for/issue-20605.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
55
for item in *things { *item = 0 }
6-
//[current]~^ ERROR the size for values of type
7-
//[next]~^^ ERROR the trait bound `dyn Iterator<Item = &'a mut u8>: IntoIterator` is not satisfied
6+
//[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
7+
//[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
88
//[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
99
//[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
1010
//[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed

tests/ui/impl-trait/issues/issue-83919.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | fn get_fut(&self) -> Self::Fut {
55
| ^^^^^^^^^ `{integer}` is not a future
66
|
77
= help: the trait `Future` is not implemented for `{integer}`
8-
= note: {integer} must be a future or must implement `IntoFuture` to be awaited
98

109
error: aborting due to 1 previous error
1110

tests/ui/issues-71798.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ LL | *x
1414
| -- return type was inferred to be `u32` here
1515
|
1616
= help: the trait `Future` is not implemented for `u32`
17-
= note: u32 must be a future or must implement `IntoFuture` to be awaited
1817

1918
error: aborting due to 2 previous errors
2019

tests/ui/iterators/bound.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ LL | struct T(S<u8>);
55
| ^^^^^ `u8` is not an iterator
66
|
77
= help: the trait `Iterator` is not implemented for `u8`
8-
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
98
note: required by a bound in `S`
109
--> $DIR/bound.rs:1:13
1110
|

tests/ui/kindck/kindck-impl-type-params-2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ fn take_param<T:Foo>(foo: &T) { }
1111
fn main() {
1212
let x: Box<_> = Box::new(3);
1313
take_param(&x);
14-
//~^ ERROR the trait bound `Box<{integer}>: Copy` is not satisfied
14+
//~^ ERROR the trait bound `Box<{integer}>: Foo` is not satisfied
1515
}

tests/ui/kindck/kindck-impl-type-params-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
1+
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
22
--> $DIR/kindck-impl-type-params-2.rs:13:16
33
|
44
LL | take_param(&x);

tests/ui/kindck/kindck-inherited-copy-bound.curr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
1+
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
22
--> $DIR/kindck-inherited-copy-bound.rs:21:16
33
|
44
LL | take_param(&x);

tests/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `Box<{integer}>: Copy` is not satisfied
1+
error[E0277]: the trait bound `Box<{integer}>: Foo` is not satisfied
22
--> $DIR/kindck-inherited-copy-bound.rs:21:16
33
|
44
LL | take_param(&x);

tests/ui/kindck/kindck-send-object.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Message : Send { }
1010

1111
fn object_ref_with_static_bound_not_ok() {
1212
assert_send::<&'static (dyn Dummy + 'static)>();
13-
//~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
13+
//~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277]
1414
}
1515

1616
fn box_object_with_no_bound_not_ok<'a>() {

tests/ui/kindck/kindck-send-object.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
1+
error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
22
--> $DIR/kindck-send-object.rs:12:19
33
|
44
LL | assert_send::<&'static (dyn Dummy + 'static)>();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
66
|
7-
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
7+
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
88
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
99
note: required by a bound in `assert_send`
1010
--> $DIR/kindck-send-object.rs:5:18

tests/ui/kindck/kindck-send-object1.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ trait Dummy { }
88
// careful with object types, who knows what they close over...
99
fn test51<'a>() {
1010
assert_send::<&'a dyn Dummy>();
11-
//~^ ERROR `(dyn Dummy + 'a)` cannot be shared between threads safely [E0277]
11+
//~^ ERROR `&'a (dyn Dummy + 'a)` cannot be sent between threads safely [E0277]
1212
}
1313
fn test52<'a>() {
1414
assert_send::<&'a (dyn Dummy + Sync)>();

0 commit comments

Comments
 (0)