Note that type param is chosen by caller when suggesting return impl Trait
This commit is contained in:
parent
22e241e32e
commit
cacdf92d37
@ -103,6 +103,8 @@ hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {
|
||||
*[other] {" "}in the current scope
|
||||
}
|
||||
|
||||
hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
|
||||
|
||||
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
|
||||
hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}`
|
||||
|
@ -11,7 +11,7 @@
|
||||
use rustc_span::{
|
||||
edition::{Edition, LATEST_STABLE_EDITION},
|
||||
symbol::Ident,
|
||||
Span,
|
||||
Span, Symbol,
|
||||
};
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -614,3 +614,10 @@ pub struct SuggestConvertViaMethod<'tcx> {
|
||||
pub expected: Ty<'tcx>,
|
||||
pub found: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(hir_typeck_note_caller_chooses_ty_for_ty_param)]
|
||||
pub struct NoteCallerChoosesTyForTyParam<'tcx> {
|
||||
pub ty_param_name: Symbol,
|
||||
pub found_ty: Ty<'tcx>,
|
||||
}
|
||||
|
@ -889,7 +889,8 @@ pub(in super::super) fn suggest_missing_return_type(
|
||||
self.dcx(),
|
||||
errors::ExpectedReturnTypeLabel::Other { span: hir_ty.span, expected },
|
||||
);
|
||||
self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
|
||||
self.try_suggest_return_impl_trait(err, expected, found, fn_id);
|
||||
self.note_caller_chooses_ty_for_ty_param(err, expected, found);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -899,6 +900,23 @@ pub(in super::super) fn suggest_missing_return_type(
|
||||
false
|
||||
}
|
||||
|
||||
fn note_caller_chooses_ty_for_ty_param(
|
||||
&self,
|
||||
diag: &mut Diag<'_>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) {
|
||||
if let ty::Param(expected_ty_as_param) = expected.kind() {
|
||||
diag.subdiagnostic(
|
||||
self.dcx(),
|
||||
errors::NoteCallerChoosesTyForTyParam {
|
||||
ty_param_name: expected_ty_as_param.name,
|
||||
found_ty: found,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// check whether the return type is a generic type with a trait bound
|
||||
/// only suggest this if the generic param is not present in the arguments
|
||||
/// if this is true, hint them towards changing the return type to `impl Trait`
|
||||
|
@ -19,6 +19,7 @@ LL | 42
|
||||
|
|
||||
= note: expected type parameter `u32`
|
||||
found type `{integer}`
|
||||
= note: the caller chooses a type for `u32` which can be different from `i32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -10,6 +10,7 @@ LL | "this should not suggest impl Trait"
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found reference `&'static str`
|
||||
= note: the caller chooses a type for `T` which can be different from `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-impl-trait-bad.rs:9:5
|
||||
@ -23,6 +24,7 @@ LL | "this will not suggest it, because that would probably be wrong"
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found reference `&'static str`
|
||||
= note: the caller chooses a type for `T` which can be different from `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-impl-trait-bad.rs:17:5
|
||||
@ -37,6 +39,7 @@ LL | "don't suggest this, because Option<T> places additional constraints"
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found reference `&'static str`
|
||||
= note: the caller chooses a type for `T` which can be different from `&'static str`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-impl-trait-bad.rs:28:5
|
||||
@ -53,6 +56,7 @@ LL | "don't suggest this, because the generic param is used in the bound."
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found reference `&'static str`
|
||||
= note: the caller chooses a type for `T` which can be different from `&'static str`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -12,6 +12,7 @@ LL | ()
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found unit type `()`
|
||||
= note: the caller chooses a type for `T` which can be different from `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-impl-trait.rs:23:5
|
||||
@ -28,6 +29,7 @@ LL | ()
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found unit type `()`
|
||||
= note: the caller chooses a type for `T` which can be different from `()`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
21
tests/ui/return/return-ty-mismatch-note.rs
Normal file
21
tests/ui/return/return-ty-mismatch-note.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// Checks existence of a note for "a caller chooses ty for ty param" upon return ty mismatch.
|
||||
|
||||
fn f<T>() -> (T,) {
|
||||
(0,) //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn g<U, V>() -> (U, V) {
|
||||
(0, "foo")
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
|
||||
fn h() -> u8 {
|
||||
0u8
|
||||
}
|
||||
|
||||
fn main() {
|
||||
f::<()>();
|
||||
g::<(), ()>;
|
||||
let _ = h();
|
||||
}
|
36
tests/ui/return/return-ty-mismatch-note.stderr
Normal file
36
tests/ui/return/return-ty-mismatch-note.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-ty-mismatch-note.rs:4:6
|
||||
|
|
||||
LL | fn f<T>() -> (T,) {
|
||||
| - expected this type parameter
|
||||
LL | (0,)
|
||||
| ^ expected type parameter `T`, found integer
|
||||
|
|
||||
= note: expected type parameter `T`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-ty-mismatch-note.rs:8:6
|
||||
|
|
||||
LL | fn g<U, V>() -> (U, V) {
|
||||
| - expected this type parameter
|
||||
LL | (0, "foo")
|
||||
| ^ expected type parameter `U`, found integer
|
||||
|
|
||||
= note: expected type parameter `U`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-ty-mismatch-note.rs:8:9
|
||||
|
|
||||
LL | fn g<U, V>() -> (U, V) {
|
||||
| - expected this type parameter
|
||||
LL | (0, "foo")
|
||||
| ^^^^^ expected type parameter `V`, found `&str`
|
||||
|
|
||||
= note: expected type parameter `V`
|
||||
found reference `&'static str`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -10,6 +10,7 @@ LL | t.clone()
|
||||
|
|
||||
= note: expected type parameter `_`
|
||||
found reference `&_`
|
||||
= note: the caller chooses a type for `T` which can be different from `&T`
|
||||
note: `T` does not implement `Clone`, so `&T` was cloned instead
|
||||
--> $DIR/clone-on-unconstrained-borrowed-type-param.rs:3:5
|
||||
|
|
||||
|
@ -10,6 +10,7 @@ LL | return a.bar();
|
||||
|
|
||||
= note: expected type parameter `B`
|
||||
found associated type `<A as MyTrait>::T`
|
||||
= note: the caller chooses a type for `B` which can be different from `<A as MyTrait>::T`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | pub fn foo<A: MyTrait<T = B>, B>(a: A) -> B {
|
||||
|
@ -13,6 +13,7 @@ LL | x
|
||||
found type parameter `Foo`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
= note: the caller chooses a type for `Bar` which can be different from `Foo`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -14,6 +14,7 @@ LL | u
|
||||
found type parameter `X`
|
||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||
= note: the caller chooses a type for `Self` which can be different from `X`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -9,6 +9,7 @@ LL | self.iter()
|
||||
|
|
||||
= note: expected type parameter `I`
|
||||
found struct `std::slice::Iter<'_, N>`
|
||||
= note: the caller chooses a type for `I` which can be different from `std::slice::Iter<'_, N>`
|
||||
|
||||
error[E0599]: no method named `iter` found for reference `&G` in the current scope
|
||||
--> $DIR/issue-13853.rs:27:23
|
||||
|
Loading…
Reference in New Issue
Block a user