Skip to content

Commit 9c8f2b9

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 #79359, fix #119983, fix #118779, cc #118415 (the suggestion needs to change).
1 parent c475e23 commit 9c8f2b9

38 files changed

+155
-78
lines changed

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

+38-4
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,43 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
409409
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
410410
let trait_predicate = bound_predicate.rebind(trait_predicate);
411411
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
412-
let trait_ref = trait_predicate.to_poly_trait_ref();
413412

414-
if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
413+
// Let's use the root obligation as the main message, when we care about the
414+
// most general case ("X doesn't implement Pattern<'_>") over the case that
415+
// happened to fail ("char doesn't implement Fn(&mut char)").
416+
//
417+
// We rely on a few heuristics to identify cases where this root
418+
// obligation is more important than the leaf obligation:
419+
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
420+
ty::ClauseKind::Trait(root_pred)
421+
) = root_obligation.predicate.kind().skip_binder()
422+
// The type of the leaf predicate is (roughly) the same as the type
423+
// from the root predicate, as a proxy for "we care about the root"
424+
&& trait_predicate.self_ty().skip_binder()
425+
== root_pred.self_ty().peel_refs()
426+
// The leaf trait and the root trait are different, so as to avoid
427+
// talking about `&mut T: Trait` and instead remain talking about
428+
// `T: Trait` instead
429+
&& trait_predicate.def_id() != root_pred.def_id()
430+
// The root trait is not `Unsize`, as to avoid talking about it in
431+
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
432+
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
433+
{
434+
(
435+
self.resolve_vars_if_possible(
436+
root_obligation.predicate.kind().rebind(root_pred),
437+
),
438+
root_obligation,
439+
)
440+
} else {
441+
(trait_predicate, &obligation)
442+
};
443+
let trait_ref = main_trait_predicate.to_poly_trait_ref();
444+
445+
if let Some(guar) = self.emit_specialized_closure_kind_error(
446+
&obligation,
447+
trait_ref,
448+
) {
415449
return guar;
416450
}
417451

@@ -450,7 +484,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
450484
notes,
451485
parent_label,
452486
append_const_msg,
453-
} = self.on_unimplemented_note(trait_ref, &obligation);
487+
} = self.on_unimplemented_note(trait_ref, o);
454488
let have_alt_message = message.is_some() || label.is_some();
455489
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
456490
let is_unsize =
@@ -473,7 +507,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
473507
};
474508

475509
let err_msg = self.get_standard_error_message(
476-
&trait_predicate,
510+
&main_trait_predicate,
477511
message,
478512
predicate_is_const,
479513
append_const_msg,

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.

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/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/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/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)>();

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

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

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trait Dummy { }
55

66
fn test50() {
77
assert_send::<&'static dyn Dummy>();
8-
//~^ ERROR `(dyn Dummy + 'static)` cannot be shared between threads safely [E0277]
8+
//~^ ERROR `&'static (dyn Dummy + 'static)` cannot be sent between threads safely [E0277]
99
}
1010

1111
fn test53() {

tests/ui/kindck/kindck-send-object2.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-object2.rs:7:19
33
|
44
LL | assert_send::<&'static dyn Dummy>();
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-object2.rs:3:18

tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ fn stuff<T: Bar>(_: T) {}
1717

1818
fn main() {
1919
stuff(1u8);
20-
//~^ the trait bound `u8: Foo` is not satisfied
20+
//~^ the trait bound `u8: Bar` is not satisfied
2121
}

tests/ui/rfcs/rfc-2397-do-not-recommend/feature-gate-do_not_recommend.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0277]: the trait bound `u8: Foo` is not satisfied
1+
error[E0277]: the trait bound `u8: Bar` is not satisfied
22
--> $DIR/feature-gate-do_not_recommend.rs:19:11
33
|
44
LL | stuff(1u8);

tests/ui/suggestions/issue-104961.fixed

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
fn foo(x: &str) -> bool {
44
x.starts_with(&("hi".to_string() + " you"))
5-
//~^ ERROR expected a `FnMut(char)` closure, found `String`
5+
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
66
}
77

88
fn foo2(x: &str) -> bool {
99
x.starts_with(&"hi".to_string())
10-
//~^ ERROR expected a `FnMut(char)` closure, found `String`
10+
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
1111
}
1212

1313
fn main() {

tests/ui/suggestions/issue-104961.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
fn foo(x: &str) -> bool {
44
x.starts_with("hi".to_string() + " you")
5-
//~^ ERROR expected a `FnMut(char)` closure, found `String`
5+
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
66
}
77

88
fn foo2(x: &str) -> bool {
99
x.starts_with("hi".to_string())
10-
//~^ ERROR expected a `FnMut(char)` closure, found `String`
10+
//~^ ERROR the trait bound `String: Pattern<'_>` is not satisfied [E0277]
1111
}
1212

1313
fn main() {

tests/ui/suggestions/issue-104961.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
error[E0277]: expected a `FnMut(char)` closure, found `String`
1+
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
22
--> $DIR/issue-104961.rs:4:19
33
|
44
LL | x.starts_with("hi".to_string() + " you")
55
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: the trait bound `String: Pattern<'_>` is not satisfied
109
= note: required for `String` to implement `Pattern<'_>`
1110
note: required by a bound in `core::str::<impl str>::starts_with`
1211
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
@@ -15,15 +14,14 @@ help: consider borrowing here
1514
LL | x.starts_with(&("hi".to_string() + " you"))
1615
| ++ +
1716

18-
error[E0277]: expected a `FnMut(char)` closure, found `String`
17+
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
1918
--> $DIR/issue-104961.rs:9:19
2019
|
2120
LL | x.starts_with("hi".to_string())
2221
| ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
2322
| |
2423
| required by a bound introduced by this call
2524
|
26-
= note: the trait bound `String: Pattern<'_>` is not satisfied
2725
= note: required for `String` to implement `Pattern<'_>`
2826
note: required by a bound in `core::str::<impl str>::starts_with`
2927
--> $SRC_DIR/core/src/str/mod.rs:LL:COL

tests/ui/suggestions/issue-62843.stderr

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
error[E0277]: expected a `FnMut(char)` closure, found `String`
1+
error[E0277]: the trait bound `String: Pattern<'_>` is not satisfied
22
--> $DIR/issue-62843.rs:4:32
33
|
44
LL | println!("{:?}", line.find(pattern));
55
| ---- ^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
66
| |
77
| required by a bound introduced by this call
88
|
9-
= note: the trait bound `String: Pattern<'_>` is not satisfied
109
= note: required for `String` to implement `Pattern<'_>`
1110
note: required by a bound in `core::str::<impl str>::find`
1211
--> $SRC_DIR/core/src/str/mod.rs:LL:COL

0 commit comments

Comments
 (0)