Closed RalfJung closed 11 months ago
Re-posting from #63966 since it was closed in favor of this thread.
playground 1.39.0-nightly 2019-08-23 9eae1fc0ea9b00341b8f
mod First {
trait Foo { fn m(self: Box<Self>); }
fn foo<T: Foo>(a: T) {
a.m();
}
}
mod Second {
trait Bar { fn m(self: std::sync::Arc<Self>); }
fn bar(b: impl Bar) {
b.m();
}
}
help: the following traits define an item `m`, perhaps you need to restrict type parameter `T` with one of them:
|
3 | fn foo<T: First::Foo + Foo>(a: T) {
| ^^^^^^^^^^^^^^^
3 | fn foo<T: Second::Bar + Foo>(a: T) {
| ^^^^^^^^^^^^^^^^
The above suggests a trait from another module with a different name
help: the following traits define an item `m`, perhaps you need to restrict type parameter `impl Bar` with one of them:
|
9 | fn bar(b: impl Bar: First::Foo + {
| ^^^^^^^^^^^^^^^^^^^^^^
9 | fn bar(b: impl Bar: Second::Bar + {
| ^^^^^^^^^^^^^^^^^^^^^^^
and the next suggestion isn't syntactically correct.
Current output:
error[E0599]: no method named `m` found for type `T` in the current scope
--> src/lib.rs:4:11
|
4 | a.m();
| ^ method not found in `T`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following traits define an item `m`, perhaps you need to restrict type parameter `T` with one of them:
|
3 | fn foo<T: First::Foo + Foo>(a: T) {
| ^^^^^^^^^^^^^^^
3 | fn foo<T: Second::Bar + Foo>(a: T) {
| ^^^^^^^^^^^^^^^^
error[E0599]: no method named `m` found for type `impl Bar` in the current scope
--> src/lib.rs:10:11
|
10 | b.m();
| ^ method not found in `impl Bar`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following traits define an item `m`, perhaps you need to restrict type parameter `impl Bar` with one of them:
|
9 | fn bar(b: impl Bar + First::Foo) {
| ^^^^^^^^^^^^^^^^^^^^^
9 | fn bar(b: impl Bar + Second::Bar) {
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0599]: no method named `test` found for type `impl Test` in the current scope
--> src/lib.rs:8:7
|
8 | t.test()
| ^^^^ method not found in `impl Test`
|
= help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl Test` with it:
|
7 | fn foo(t: impl Test + Test) {
| ^^^^^^^^^^^^^^^^
@rustbot modify labels to +AsyncAwait-OnDeck
This error message comes up a lot when users attempt to manually implement Future
or the associated traits like futures::io::{AsyncRead, AsyncWrite}
by delegating to a field without pinning it.
Triage: we no longer emit the incorrect suggestions.
Is the following output acceptable?
error[E0599]: no method named `test` found for type parameter `impl Test` in the current scope
--> file5.rs:8:7
|
4 | fn test(self: Pin<&mut Self>);
| -------------- the method might not be found because of this arbitrary self type
...
8 | t.test()
| ^^^^ method not found in `impl Test`
That wording does indicates the actual problem (hooray!), but it also doesn't feel very newcomer-friendly to me because of the phrase "arbitrary self type". IMO something like "test()
is called on an X
but must be called on a Pin<&mut X>
" would be more obvious, but I can see that getting difficult to implement in the error messages.
@estebank was a note like you suggested in https://github.com/rust-lang/rust/issues/57994#issuecomment-588534790 implemented? (yes, but only for trait methods?)
Currently this code
use core::pin::Pin;
struct S;
impl S {
fn x(self: Pin<&mut Self>) {
}
}
fn main() {
S.x();
}
Outputs
error[E0599]: no method named `x` found for struct `S` in the current scope
--> src/main.rs:10:7
|
2 | struct S;
| --------- method `x` not found for this
...
10 | S.x();
| ^ method not found in `S`
error: aborting due to previous error
Without any hint about there being a method by that name with an unusual receiver type.
Not sure whether I should file a new issue or ask for this one to be reopened.
Also fails to provide a hint on opaque Future
s from async fn
s:
use std::future::Future; //would be necessary to call `poll` if the receiver type was correct
async fn f() {
}
fn foo(cx: &mut std::task::Context) {
f().poll(cx);
}
Outputs
error[E0599]: no method named `poll` found for opaque type `impl std::future::Future` in the current scope
--> src/lib.rs:8:9
|
8 | f().poll(cx);
| ^^^^ method not found in `impl std::future::Future`
warning: unused import: `std::future::Future`
--> src/lib.rs:1:5
|
1 | use std::future::Future; //would be necessary to call `poll` if the receiver type was correct
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error: aborting due to previous error; 1 warning emitted
Triage: no change.
Yet another error that needs to be accounted for:
error[E0277]: the trait bound `S: Deref` is not satisfied
--> src/main.rs:10:14
|
10 | Pin::new(S).x();
| ^ the trait `Deref` is not implemented for `S`
|
= note: required by `Pin::<P>::new`
error[E0599]: no method named `x` found for struct `Pin<S>` in the current scope
--> src/main.rs:10:17
|
10 | Pin::new(S).x();
| ^ method not found in `Pin<S>`
Current output for the first comment:
error[E0599]: no method named `m` found for type parameter `T` in the current scope
--> src/lib.rs:4:11
|
2 | trait Foo { fn m(self: Box<Self>); }
| - --------- the method might not be found because of this arbitrary self type
| |
| the method is available for `Box<T>` here
3 | fn foo<T: Foo>(a: T) {
4 | a.m();
| ^ method not found in `T`
...
8 | trait Bar { fn m(self: std::sync::Arc<Self>); }
| -------------------- the method might not be found because of this arbitrary self type
|
help: consider wrapping the receiver expression with the appropriate type
|
4 | Box::new(a).m();
| +++++++++ +
error[E0599]: no method named `m` found for type parameter `impl Bar` in the current scope
--> src/lib.rs:10:11
|
2 | trait Foo { fn m(self: Box<Self>); }
| --------- the method might not be found because of this arbitrary self type
...
8 | trait Bar { fn m(self: std::sync::Arc<Self>); }
| - -------------------- the method might not be found because of this arbitrary self type
| |
| the method is available for `Arc<impl Bar>` here
9 | fn bar(b: impl Bar) {
10 | b.m();
| ^ method not found in `impl Bar`
|
help: consider wrapping the receiver expression with the appropriate type
|
10 | Arc::new(b).m();
| +++++++++ +
Current output for my comment above (it should suggest &mut S
instead of &S
, but it's might be good enough):
error[E0277]: the trait bound `S: Deref` is not satisfied
--> src/main.rs:10:14
|
10 | Pin::new(S).x();
| ^
| |
| expected an implementor of trait `Deref`
| help: consider borrowing here: `&S`
|
note: required by `Pin::<P>::new`
error[E0599]: no method named `x` found for struct `Pin` in the current scope
--> src/main.rs:10:17
|
10 | Pin::new(S).x();
| ^ method not found in `Pin<S>`
Current output for the previous comment (it doesn't fix the issue because f: !Unpin
, then suggests Box::pin
which gives you another E0599):
error[E0599]: no method named `poll` found for opaque type `impl Future` in the current scope
--> src/lib.rs:8:9
|
8 | f().poll(cx);
| ^^^^ method not found in `impl Future`
|
help: consider wrapping the receiver expression with the appropriate type
|
8 | Pin::new(&mut f()).poll(cx);
| +++++++++++++ +
Current output for the comment prior to that, which I considered solved:
error[E0599]: no method named `x` found for struct `S` in the current scope
--> src/main.rs:10:7
|
2 | struct S;
| --------- method `x` not found for this
...
5 | fn x(self: Pin<&mut Self>) {
| - the method is available for `Pin<&mut S>` here
...
10 | S.x();
| ^ method not found in `S`
|
help: consider wrapping the receiver expression with the appropriate type
|
10 | Pin::new(&mut S).x();
| +++++++++++++ +
Fixed:
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `m` found for type parameter `T` in the current scope
--> src/lib.rs:4:11
|
2 | trait Foo { fn m(self: Box<Self>); }
| - --------- the method might not be found because of this arbitrary self type
| |
| the method is available for `Box<T>` here
3 | fn foo<T: Foo>(a: T) {
| - method `m` not found for this type parameter
4 | a.m();
| ^ method not found in `T`
...
8 | trait Bar { fn m(self: std::sync::Arc<Self>); }
| -------------------- the method might not be found because of this arbitrary self type
|
help: consider wrapping the receiver expression with the appropriate type
|
4 | Box::new(a).m();
| +++++++++ +
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `m` found for type parameter `impl Bar` in the current scope
--> src/lib.rs:10:11
|
2 | trait Foo { fn m(self: Box<Self>); }
| --------- the method might not be found because of this arbitrary self type
...
8 | trait Bar { fn m(self: std::sync::Arc<Self>); }
| - -------------------- the method might not be found because of this arbitrary self type
| |
| the method is available for `Arc<impl Bar>` here
9 | fn bar(b: impl Bar) {
| -------- method `m` not found for this type parameter
10 | b.m();
| ^ method not found in `impl Bar`
|
help: consider wrapping the receiver expression with the appropriate type
|
10 | Arc::new(b).m();
| +++++++++ +
Needs to further refine mutability suggested, when using Pin::new(&S)
the error doesn't mention that the method is available for Pin::new(&mut S)
, and the E0599 is redundant.
error[[E0277]](https://doc.rust-lang.org/nightly/error-index.html#E0277): the trait bound `S: Deref` is not satisfied
--> src/main.rs:10:14
|
10 | Pin::new(S).x();
| -------- ^ the trait `Deref` is not implemented for `S`
| |
| required by a bound introduced by this call
|
note: required by a bound in `Pin::<P>::new`
--> /rustc/659e169d37990b9c730a59a96081f2ef7afbe8f1/library/core/src/pin.rs:501:5
help: consider borrowing here
|
10 | Pin::new(&S).x();
| +
10 | Pin::new(&mut S).x();
| ++++
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `x` found for struct `Pin` in the current scope
--> src/main.rs:10:17
|
10 | Pin::new(S).x();
| ^ method not found in `Pin<S>`
Gives a suggestion but it doesn't lead to working code:
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `poll` found for opaque type `impl Future<Output = ()>` in the current scope
--> src/lib.rs:8:9
|
8 | f().poll(cx);
| ^^^^ method not found in `impl Future<Output = ()>`
--> /rustc/659e169d37990b9c730a59a96081f2ef7afbe8f1/library/core/src/future/future.rs:105:8
|
= note: the method is available for `Pin<&mut impl Future<Output = ()>>` here
|
help: consider wrapping the receiver expression with the appropriate type
|
8 | Pin::new(&mut f()).poll(cx);
| +++++++++++++ +
Fixed
error[[E0599]](https://doc.rust-lang.org/nightly/error-index.html#E0599): no method named `x` found for struct `S` in the current scope
--> src/main.rs:10:7
|
2 | struct S;
| -------- method `x` not found for this struct
...
5 | fn x(self: Pin<&mut Self>) {
| - the method is available for `Pin<&mut S>` here
...
10 | S.x();
| ^ method not found in `S`
|
help: consider wrapping the receiver expression with the appropriate type
|
10 | Pin::new(&mut S).x();
| +++++++++++++ +
Only outstanding issue is for the poll
case, and I'm not quite sure how we can help the user there (hell, I don't know how to make that code compile myself). @SNCPlay42, what would have been the right code the user should have written for https://github.com/rust-lang/rust/issues/57994#issuecomment-674435883?
The code it currently suggests does not even build, so that should definitely be fixed.
Here's how poll
can be called:
fn foo(cx: &mut std::task::Context) {
let mut f = std::pin::pin!(f());
f.as_mut().poll(cx);
}
@RalfJung I noticed that we already provide an appropriate note on the E0277 to use the pin!
macro, but it isn't as prominent as I'd like:
error[E0277]: `[async fn body@src/lib.rs:3:14: 5:2]` cannot be unpinned
--> src/lib.rs:8:24
|
3 | async fn f() {
| - within this `impl Future<Output = ()>`
...
8 | std::pin::Pin::new(&mut f()).poll(cx);
| ------------------ ^^^^^^^^ within `impl Future<Output = ()>`, the trait `Unpin` is not implemented for `[async fn body@src/lib.rs:3:14: 5:2]`
| |
| required by a bound introduced by this call
|
= note: consider using the `pin!` macro
consider using `Box::pin` if you need to access the pinned value outside of the current scope
note: required because it appears within the type `impl Future<Output = ()>`
--> src/lib.rs:3:14
|
3 | async fn f() {
| ^
note: required by a bound in `Pin::<P>::new`
--> /rustc/f88a8b71cebb730cbd5058c45ebcae1d4d9be377/library/core/src/pin.rs:503:5
Having said that, between https://github.com/rust-lang/rust/pull/114654:
error[E0599]: no method named `poll` found for opaque type `impl Future<Output = ()>` in the current scope
--> f63.rs:4:9
|
4 | f().poll(cx);
| ^^^^ method not found in `impl Future<Output = ()>`
|
= help: method `poll` found on `Pin<&mut impl Future<Output = ()>>`, see documentation for `std::pin::Pin`
= help: self type must be pinned to call `Future::poll`, see https://rust-lang.github.io/async-book/04_pinning/01_chapter.html#pinning-in-practice
help: consider pinning the expression
|
4 ~ let mut pinned = std::pin::pin!(f());
5 ~ pinned.as_mut().poll(cx);
|
and https://github.com/rust-lang/rust/pull/114469:
error[E0599]: no method named `x` found for struct `Pin<&S>` in the current scope
--> $DIR/arbitrary_self_type_mut_difference.rs:11:18
|
LL | Pin::new(&S).x();
| ^ help: there is a method with a similar name: `y`
|
note: method is available for `Pin<&mut S>`
--> $DIR/arbitrary_self_type_mut_difference.rs:6:5
|
LL | fn x(self: Pin<&mut Self>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
I think we can consider this ticket addressed.
Consider the following piece of code:
The error here is that
test
can only be called onPin<&mut Self>
, sot.test
does not work. But the error message is less than helpful:It suggests I import a trait that is already in scope. This leads down the totally wrong path -- not showing the "help" and "note" at all would be better than this. Ideally it could point out the receiver type mismatch.