Auto merge of #104334 - compiler-errors:ufcs-sugg-wrong-def-id, r=estebank
Use impl's def id when calculating type to specify in UFCS Fixes #104327 Fixes #104328 Also addresses https://github.com/rust-lang/rust/pull/102670#discussion_r987381197
This commit is contained in:
commit
39b2a41b39
8 changed files with 75 additions and 11 deletions
|
@ -2312,18 +2312,19 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id);
|
let trait_impls = self.tcx.trait_impls_of(data.trait_ref.def_id);
|
||||||
|
|
||||||
if trait_impls.blanket_impls().is_empty()
|
if trait_impls.blanket_impls().is_empty()
|
||||||
&& let Some((impl_ty, _)) = trait_impls.non_blanket_impls().iter().next()
|
&& let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next()
|
||||||
&& let Some(impl_def_id) = impl_ty.def() {
|
{
|
||||||
let message = if trait_impls.non_blanket_impls().len() == 1 {
|
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()
|
"use the fully-qualified path to the only available implementation".to_string()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"use a fully-qualified path to a specific available implementation ({} found)",
|
"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![(
|
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))
|
format!("<{} as ", self.tcx.type_of(impl_def_id))
|
||||||
)];
|
)];
|
||||||
if let Some(generic_arg) = trait_path_segment.args {
|
if let Some(generic_arg) = trait_path_segment.args {
|
||||||
|
|
|
@ -6,6 +6,11 @@ LL | fn bar() -> isize;
|
||||||
...
|
...
|
||||||
LL | let x: isize = Foo::bar();
|
LL | let x: isize = Foo::bar();
|
||||||
| ^^^^^^^^ cannot call associated function of trait
|
| ^^^^^^^^ 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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ LL | inner::MyTrait::my_fn();
|
||||||
|
|
|
|
||||||
help: use the fully-qualified path to the only available implementation
|
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
|
error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type
|
||||||
|
@ -51,7 +51,7 @@ LL | let _ = inner::MyTrait::MY_ASSOC_CONST;
|
||||||
|
|
|
|
||||||
help: use the fully-qualified path to the only available implementation
|
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
|
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
|
||||||
|
|
12
src/test/ui/suggestions/issue-104327.rs
Normal file
12
src/test/ui/suggestions/issue-104327.rs
Normal file
|
@ -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
src/test/ui/suggestions/issue-104327.stderr
Normal file
17
src/test/ui/suggestions/issue-104327.stderr
Normal file
|
@ -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
src/test/ui/suggestions/issue-104328.rs
Normal file
12
src/test/ui/suggestions/issue-104328.rs
Normal file
|
@ -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
src/test/ui/suggestions/issue-104328.stderr
Normal file
17
src/test/ui/suggestions/issue-104328.stderr
Normal file
|
@ -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`.
|
|
@ -9,7 +9,7 @@ LL | let _f: base::Foo = base::HasNew::new();
|
||||||
|
|
|
|
||||||
help: use the fully-qualified path to the only available implementation
|
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();
|
||||||
| +++++++ +
|
| +++++++ +
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue