Skip to content

Commit

Permalink
Rollup merge of #122195 - jieyouxu:impl-return-note, r=fmease
Browse files Browse the repository at this point in the history
Note that the caller chooses a type for type param

```
error[E0308]: mismatched types
  --> $DIR/return-impl-trait.rs:23:5
   |
LL | fn other_bounds<T>() -> T
   |                 -       -
   |                 |       |
   |                 |       expected `T` because of return type
   |                 |       help: consider using an impl return type: `impl Trait`
   |                 expected this type parameter
...
LL |     ()
   |     ^^ expected type parameter `T`, found `()`
   |
   = note: expected type parameter `T`
                   found unit type `()`
   = note: the caller chooses the type of T which can be different from ()
```

Tried to see if "expected this type parameter" can be replaced, but that goes all the way to `rustc_infer` so seems not worth the effort and can affect other diagnostics.

Revives #112088 and #104755.
  • Loading branch information
matthiaskrgr authored Mar 22, 2024
2 parents 104c4bc + cacdf92 commit aa184c5
Show file tree
Hide file tree
Showing 13 changed files with 98 additions and 2 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
Expand Down
9 changes: 8 additions & 1 deletion compiler/rustc_hir_typeck/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_middle::ty::Ty;
use rustc_span::{
edition::{Edition, LATEST_STABLE_EDITION},
symbol::Ident,
Span,
Span, Symbol,
};

#[derive(Diagnostic)]
Expand Down Expand Up @@ -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>,
}
20 changes: 19 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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;
}
}
Expand All @@ -899,6 +900,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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`
Expand Down
1 change: 1 addition & 0 deletions src/tools/clippy/tests/ui/builtin_type_shadow.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions tests/ui/return/return-impl-trait-bad.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/return/return-impl-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down
21 changes: 21 additions & 0 deletions tests/ui/return/return-ty-mismatch-note.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 36 additions & 0 deletions tests/ui/return/return-ty-mismatch-note.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions tests/ui/type/type-parameter-names.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions tests/ui/type/type-params-in-different-spaces-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions tests/ui/typeck/issue-13853.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit aa184c5

Please sign in to comment.