Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use impl's def id when calculating type to specify in UFCS #104334

Merged
merged 2 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2290,18 +2290,19 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id);

if trait_impls.blanket_impls().is_empty()
&& let Some((impl_ty, _)) = trait_impls.non_blanket_impls().iter().next()
&& let Some(impl_def_id) = impl_ty.def() {
let message = if trait_impls.non_blanket_impls().len() == 1 {
&& let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next()
{
let non_blanket_impl_count = trait_impls.non_blanket_impls().values().flatten().count();
let message = if non_blanket_impl_count == 1 {
"use the fully-qualified path to the only available implementation".to_string()
} else {
format!(
"use a fully-qualified path to a specific available implementation ({} found)",
trait_impls.non_blanket_impls().len()
non_blanket_impl_count
)
};
let mut suggestions = vec![(
trait_path_segment.ident.span.shrink_to_lo(),
path.span.shrink_to_lo(),
format!("<{} as ", self.tcx.type_of(impl_def_id))
)];
if let Some(generic_arg) = trait_path_segment.args {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ LL | fn bar() -> isize;
...
LL | let x: isize = Foo::bar();
| ^^^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
LL | let x: isize = <isize as Foo>::bar();
| +++++++++ +

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0790.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ LL | inner::MyTrait::my_fn();
|
help: use the fully-qualified path to the only available implementation
|
LL | inner::<MyStruct as MyTrait>::my_fn();
| ++++++++++++ +
LL | <MyStruct as inner::MyTrait>::my_fn();
| ++++++++++++ +

error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
--> $DIR/E0790.rs:30:13
Expand All @@ -51,8 +51,8 @@ LL | let _ = inner::MyTrait::MY_ASSOC_CONST;
|
help: use the fully-qualified path to the only available implementation
|
LL | let _ = inner::<MyStruct as MyTrait>::MY_ASSOC_CONST;
| ++++++++++++ +
LL | let _ = <MyStruct as inner::MyTrait>::MY_ASSOC_CONST;
| ++++++++++++ +

error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/E0790.rs:50:5
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/issue-104327.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
trait Bar {}

trait Foo {
fn f() {}
}

impl Foo for dyn Bar {}

fn main() {
Foo::f();
//~^ ERROR cannot call associated function on trait without specifying the corresponding `impl` type
}
17 changes: 17 additions & 0 deletions src/test/ui/suggestions/issue-104327.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/issue-104327.rs:10:5
|
LL | fn f() {}
| --------- `Foo::f` defined here
...
LL | Foo::f();
| ^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
LL | <(dyn Bar + 'static) as Foo>::f();
| +++++++++++++++++++++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0790`.
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/issue-104328.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(object_safe_for_dispatch)]

trait Foo {
fn f() {}
}

impl Foo for dyn Sized {}

fn main() {
Foo::f();
//~^ ERROR cannot call associated function on trait without specifying the corresponding `impl` type
}
17 changes: 17 additions & 0 deletions src/test/ui/suggestions/issue-104328.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> $DIR/issue-104328.rs:10:5
|
LL | fn f() {}
| --------- `Foo::f` defined here
...
LL | Foo::f();
| ^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
LL | <(dyn Sized + 'static) as Foo>::f();
| +++++++++++++++++++++++++ +

error: aborting due to previous error

For more information about this error, try `rustc --explain E0790`.
4 changes: 2 additions & 2 deletions src/test/ui/traits/static-method-generic-inference.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ LL | let _f: base::Foo = base::HasNew::new();
|
help: use the fully-qualified path to the only available implementation
|
LL | let _f: base::Foo = base::<Foo as HasNew>::new();
| +++++++ +
LL | let _f: base::Foo = <Foo as base::HasNew>::new();
Copy link
Contributor

@jruderman jruderman Nov 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an improvement, but for it to actually compile it needs a path to Foo and type params for HasNew:

let _f: base::Foo = <base::Foo as base::HasNew<_>>::new();

I can spin this off into a new issue (or two new issues) if you prefer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make a new issue for this. Thanks for pointing it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reported the missing path as #117623. The missing type params is probably okay, since the problem is in the original code rather than being introduced by the hint.

| +++++++ +

error: aborting due to previous error

Expand Down