Skip to content

Commit 493233c

Browse files
Rollup merge of #128527 - estebank:ambiguity-suggestion, r=Nadrieril
More information for fully-qualified suggestion when there are multiple impls ``` error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/E0283.rs:30:21 | LL | fn create() -> u32; | ------------------- `Coroutine::create` defined here ... LL | let cont: u32 = Coroutine::create(); | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait | help: use a fully-qualified path to a specific available implementation | LL | let cont: u32 = <Impl as Coroutine>::create(); | ++++++++ + LL | let cont: u32 = <AnotherImpl as Coroutine>::create(); | +++++++++++++++ + ```
2 parents a6cacee + 2c83c99 commit 493233c

File tree

3 files changed

+59
-27
lines changed

3 files changed

+59
-27
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs

+49-21
Original file line numberDiff line numberDiff line change
@@ -388,39 +388,67 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
388388
trait_impls.non_blanket_impls().values().flatten().count();
389389
// If there is only one implementation of the trait, suggest using it.
390390
// Otherwise, use a placeholder comment for the implementation.
391-
let (message, self_type) = if non_blanket_impl_count == 1 {
391+
let (message, self_types) = if non_blanket_impl_count == 1 {
392392
(
393393
"use the fully-qualified path to the only available \
394394
implementation",
395-
format!(
395+
vec![format!(
396396
"{}",
397397
self.tcx.type_of(impl_def_id).instantiate_identity()
398-
),
398+
)],
399+
)
400+
} else if non_blanket_impl_count < 20 {
401+
(
402+
"use a fully-qualified path to one of the available \
403+
implementations",
404+
trait_impls
405+
.non_blanket_impls()
406+
.values()
407+
.flatten()
408+
.map(|id| {
409+
format!(
410+
"{}",
411+
self.tcx.type_of(id).instantiate_identity()
412+
)
413+
})
414+
.collect::<Vec<String>>(),
399415
)
400416
} else {
401417
(
402418
"use a fully-qualified path to a specific available \
403419
implementation",
404-
"/* self type */".to_string(),
420+
vec!["/* self type */".to_string()],
405421
)
406422
};
407-
let mut suggestions =
408-
vec![(path.span.shrink_to_lo(), format!("<{self_type} as "))];
409-
if let Some(generic_arg) = trait_path_segment.args {
410-
let between_span =
411-
trait_path_segment.ident.span.between(generic_arg.span_ext);
412-
// get rid of :: between Trait and <type>
413-
// must be '::' between them, otherwise the parser won't accept the code
414-
suggestions.push((between_span, "".to_string()));
415-
suggestions
416-
.push((generic_arg.span_ext.shrink_to_hi(), ">".to_string()));
417-
} else {
418-
suggestions.push((
419-
trait_path_segment.ident.span.shrink_to_hi(),
420-
">".to_string(),
421-
));
422-
}
423-
err.multipart_suggestion(
423+
let suggestions: Vec<_> = self_types
424+
.into_iter()
425+
.map(|self_type| {
426+
let mut suggestions = vec![(
427+
path.span.shrink_to_lo(),
428+
format!("<{self_type} as "),
429+
)];
430+
if let Some(generic_arg) = trait_path_segment.args {
431+
let between_span = trait_path_segment
432+
.ident
433+
.span
434+
.between(generic_arg.span_ext);
435+
// get rid of :: between Trait and <type>
436+
// must be '::' between them, otherwise the parser won't accept the code
437+
suggestions.push((between_span, "".to_string()));
438+
suggestions.push((
439+
generic_arg.span_ext.shrink_to_hi(),
440+
">".to_string(),
441+
));
442+
} else {
443+
suggestions.push((
444+
trait_path_segment.ident.span.shrink_to_hi(),
445+
">".to_string(),
446+
));
447+
}
448+
suggestions
449+
})
450+
.collect();
451+
err.multipart_suggestions(
424452
message,
425453
suggestions,
426454
Applicability::MaybeIncorrect,

tests/ui/error-codes/E0283.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ LL | fn create() -> u32;
77
LL | let cont: u32 = Coroutine::create();
88
| ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
99
|
10-
help: use a fully-qualified path to a specific available implementation
10+
help: use a fully-qualified path to one of the available implementations
1111
|
12-
LL | let cont: u32 = </* self type */ as Coroutine>::create();
13-
| +++++++++++++++++++ +
12+
LL | let cont: u32 = <Impl as Coroutine>::create();
13+
| ++++++++ +
14+
LL | let cont: u32 = <AnotherImpl as Coroutine>::create();
15+
| +++++++++++++++ +
1416

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

tests/ui/error-codes/E0790.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,12 @@ LL | fn my_fn();
6363
LL | MyTrait2::my_fn();
6464
| ^^^^^^^^^^^^^^^^^ cannot call associated function of trait
6565
|
66-
help: use a fully-qualified path to a specific available implementation
66+
help: use a fully-qualified path to one of the available implementations
6767
|
68-
LL | </* self type */ as MyTrait2>::my_fn();
69-
| +++++++++++++++++++ +
68+
LL | <Impl1 as MyTrait2>::my_fn();
69+
| +++++++++ +
70+
LL | <Impl2 as MyTrait2>::my_fn();
71+
| +++++++++ +
7072

7173
error: aborting due to 5 previous errors
7274

0 commit comments

Comments
 (0)