Try to suggest dereferences when trait selection failed.

This commit is contained in:
Donough Liu 2020-06-20 18:30:12 +08:00
parent 51555186b6
commit ef68bf3929
11 changed files with 254 additions and 1 deletions

View file

@ -0,0 +1,18 @@
// run-rustfix
use std::net::TcpListener;
struct NoToSocketAddrs(String);
impl std::ops::Deref for NoToSocketAddrs {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let _works = TcpListener::bind("some string");
let bad = NoToSocketAddrs("bad".to_owned());
let _errors = TcpListener::bind(&*bad);
//~^ ERROR the trait bound `NoToSocketAddrs: std::net::ToSocketAddrs` is not satisfied
}

View file

@ -0,0 +1,18 @@
// run-rustfix
use std::net::TcpListener;
struct NoToSocketAddrs(String);
impl std::ops::Deref for NoToSocketAddrs {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let _works = TcpListener::bind("some string");
let bad = NoToSocketAddrs("bad".to_owned());
let _errors = TcpListener::bind(&bad);
//~^ ERROR the trait bound `NoToSocketAddrs: std::net::ToSocketAddrs` is not satisfied
}

View file

@ -0,0 +1,19 @@
error[E0277]: the trait bound `NoToSocketAddrs: std::net::ToSocketAddrs` is not satisfied
--> $DIR/trait-suggest-deferences-issue-39029.rs:16:37
|
LL | let _errors = TcpListener::bind(&bad);
| ^^^^
| |
| the trait `std::net::ToSocketAddrs` is not implemented for `NoToSocketAddrs`
| help: consider adding dereference here: `&*bad`
|
::: $SRC_DIR/libstd/net/tcp.rs:LL:COL
|
LL | pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
| ------------- required by this bound in `std::net::TcpListener::bind`
|
= note: required because of the requirements on the impl of `std::net::ToSocketAddrs` for `&NoToSocketAddrs`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,15 @@
// run-rustfix
fn takes_str(_x: &str) {}
fn takes_type_parameter<T>(_x: T) where T: SomeTrait {}
trait SomeTrait {}
impl SomeTrait for &'_ str {}
impl SomeTrait for char {}
fn main() {
let string = String::new();
takes_str(&string); // Ok
takes_type_parameter(&*string); // Error
//~^ ERROR the trait bound `&std::string::String: SomeTrait` is not satisfied
}

View file

@ -0,0 +1,15 @@
// run-rustfix
fn takes_str(_x: &str) {}
fn takes_type_parameter<T>(_x: T) where T: SomeTrait {}
trait SomeTrait {}
impl SomeTrait for &'_ str {}
impl SomeTrait for char {}
fn main() {
let string = String::new();
takes_str(&string); // Ok
takes_type_parameter(&string); // Error
//~^ ERROR the trait bound `&std::string::String: SomeTrait` is not satisfied
}

View file

@ -0,0 +1,15 @@
error[E0277]: the trait bound `&std::string::String: SomeTrait` is not satisfied
--> $DIR/trait-suggest-deferences-issue-62530.rs:13:26
|
LL | fn takes_type_parameter<T>(_x: T) where T: SomeTrait {}
| --------- required by this bound in `takes_type_parameter`
...
LL | takes_type_parameter(&string); // Error
| ^^^^^^^
| |
| the trait `SomeTrait` is not implemented for `&std::string::String`
| help: consider adding dereference here: `&*string`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,36 @@
// run-rustfix
use std::ops::Deref;
trait Happy {}
struct LDM;
impl Happy for &LDM {}
struct Foo(LDM);
struct Bar(Foo);
struct Baz(Bar);
impl Deref for Foo {
type Target = LDM;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for Bar {
type Target = Foo;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for Baz {
type Target = Bar;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn foo<T>(_: T) where T: Happy {}
fn main() {
let baz = Baz(Bar(Foo(LDM)));
foo(&***baz);
//~^ ERROR the trait bound `&Baz: Happy` is not satisfied
}

View file

@ -0,0 +1,36 @@
// run-rustfix
use std::ops::Deref;
trait Happy {}
struct LDM;
impl Happy for &LDM {}
struct Foo(LDM);
struct Bar(Foo);
struct Baz(Bar);
impl Deref for Foo {
type Target = LDM;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for Bar {
type Target = Foo;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for Baz {
type Target = Bar;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn foo<T>(_: T) where T: Happy {}
fn main() {
let baz = Baz(Bar(Foo(LDM)));
foo(&baz);
//~^ ERROR the trait bound `&Baz: Happy` is not satisfied
}

View file

@ -0,0 +1,15 @@
error[E0277]: the trait bound `&Baz: Happy` is not satisfied
--> $DIR/trait-suggest-deferences-multiple.rs:34:9
|
LL | fn foo<T>(_: T) where T: Happy {}
| ----- required by this bound in `foo`
...
LL | foo(&baz);
| ^^^^
| |
| the trait `Happy` is not implemented for `&Baz`
| help: consider adding dereference here: `&***baz`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.