mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Avoid guessing unknown trait impl 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(); | +++++++++++++++++++ + ```
This commit is contained in:
parent
04075b3202
commit
48167bd4bd
@ -2382,17 +2382,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
&& 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 {
|
||||
// If there is only one implementation of the trait, suggest using it.
|
||||
// Otherwise, use a placeholder comment for the implementation.
|
||||
let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
|
||||
"use the fully-qualified path to the only available implementation".to_string(),
|
||||
format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
|
||||
)} else {(
|
||||
format!(
|
||||
"use a fully-qualified path to a specific available implementation ({} found)",
|
||||
non_blanket_impl_count
|
||||
)
|
||||
};
|
||||
),
|
||||
"</* self type */ as ".to_string()
|
||||
)};
|
||||
let mut suggestions = vec![(
|
||||
path.span.shrink_to_lo(),
|
||||
format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
|
||||
impl_suggestion
|
||||
)];
|
||||
if let Some(generic_arg) = trait_path_segment.args {
|
||||
let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext);
|
||||
|
@ -9,8 +9,8 @@ LL | let cont: u32 = Generator::create();
|
||||
|
|
||||
help: use a fully-qualified path to a specific available implementation (2 found)
|
||||
|
|
||||
LL | let cont: u32 = <Impl as Generator>::create();
|
||||
| ++++++++ +
|
||||
LL | let cont: u32 = </* self type */ as Generator>::create();
|
||||
| +++++++++++++++++++ +
|
||||
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/E0283.rs:35:24
|
||||
|
@ -65,8 +65,8 @@ LL | MyTrait2::my_fn();
|
||||
|
|
||||
help: use a fully-qualified path to a specific available implementation (2 found)
|
||||
|
|
||||
LL | <Impl1 as MyTrait2>::my_fn();
|
||||
| +++++++++ +
|
||||
LL | </* self type */ as MyTrait2>::my_fn();
|
||||
| +++++++++++++++++++ +
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user