Skip to content

Commit c5fd537

Browse files
authored
Rollup merge of #112948 - bkrl:trait-impl-suggestion, r=compiler-errors
Avoid guessing unknown trait implementation in suggestions When a trait is used without specifying the implementation (e.g. calling a non-member associated function without fully-qualified syntax) and there are multiple implementations available, use a placeholder comment for the implementation type in the suggestion instead of picking a random implementation. Example: ``` fn main() { let _ = Default::default(); } ``` Previous output: ``` error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> test.rs:2:13 | 2 | let _ = Default::default(); | ^^^^^^^^^^^^^^^^ cannot call associated function of trait | help: use a fully-qualified path to a specific available implementation (273 found) | 2 | let _ = <FileTimes as Default>::default(); | +++++++++++++ + ``` New output: ``` error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> test.rs:2:13 | 2 | let _ = Default::default(); | ^^^^^^^^^^^^^^^^ cannot call associated function of trait | help: use a fully-qualified path to a specific available implementation (273 found) | 2 | let _ = </* self type */ as Default>::default(); | +++++++++++++++++++ + ``` Fixes #112897
2 parents 8d6b02f + 48167bd commit c5fd537

File tree

3 files changed

+14
-10
lines changed

3 files changed

+14
-10
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -2382,17 +2382,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
23822382
&& let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next()
23832383
{
23842384
let non_blanket_impl_count = trait_impls.non_blanket_impls().values().flatten().count();
2385-
let message = if non_blanket_impl_count == 1 {
2386-
"use the fully-qualified path to the only available implementation".to_string()
2387-
} else {
2385+
// If there is only one implementation of the trait, suggest using it.
2386+
// Otherwise, use a placeholder comment for the implementation.
2387+
let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
2388+
"use the fully-qualified path to the only available implementation".to_string(),
2389+
format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
2390+
)} else {(
23882391
format!(
23892392
"use a fully-qualified path to a specific available implementation ({} found)",
23902393
non_blanket_impl_count
2391-
)
2392-
};
2394+
),
2395+
"</* self type */ as ".to_string()
2396+
)};
23932397
let mut suggestions = vec![(
23942398
path.span.shrink_to_lo(),
2395-
format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
2399+
impl_suggestion
23962400
)];
23972401
if let Some(generic_arg) = trait_path_segment.args {
23982402
let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext);

Diff for: tests/ui/error-codes/E0283.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ LL | let cont: u32 = Generator::create();
99
|
1010
help: use a fully-qualified path to a specific available implementation (2 found)
1111
|
12-
LL | let cont: u32 = <Impl as Generator>::create();
13-
| ++++++++ +
12+
LL | let cont: u32 = </* self type */ as Generator>::create();
13+
| +++++++++++++++++++ +
1414

1515
error[E0283]: type annotations needed
1616
--> $DIR/E0283.rs:35:24

Diff for: tests/ui/error-codes/E0790.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ LL | MyTrait2::my_fn();
6565
|
6666
help: use a fully-qualified path to a specific available implementation (2 found)
6767
|
68-
LL | <Impl1 as MyTrait2>::my_fn();
69-
| +++++++++ +
68+
LL | </* self type */ as MyTrait2>::my_fn();
69+
| +++++++++++++++++++ +
7070

7171
error: aborting due to 5 previous errors
7272

0 commit comments

Comments
 (0)