mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Suggest dereference of Box
when inner type is expected
For example: enum Ty { Unit, List(Box<Ty>), } fn foo(x: Ty) -> Ty { match x { Ty::Unit => Ty::Unit, Ty::List(elem) => foo(elem), } } Before, the only suggestion was to rewrap `elem` with `Ty::List`, which is unhelpful and confusing: error[E0308]: mismatched types --> src/test/ui/suggestions/boxed-variant-field.rs:9:31 | 9 | Ty::List(elem) => foo(elem), | ^^^^ | | | expected enum `Ty`, found struct `Box` | help: try using a variant of the expected enum: `Ty::List(elem)` | = note: expected enum `Ty` found struct `Box<Ty>` Now, rustc will first suggest dereferencing the `Box`, which is most likely what the user intended: error[E0308]: mismatched types --> src/test/ui/suggestions/boxed-variant-field.rs:9:31 | 9 | Ty::List(elem) => foo(elem), | ^^^^ expected enum `Ty`, found struct `Box` | = note: expected enum `Ty` found struct `Box<Ty>` help: try dereferencing the `Box` | 9 | Ty::List(elem) => foo(*elem), | + help: try using a variant of the expected enum | 9 | Ty::List(elem) => foo(Ty::List(elem)), | ~~~~~~~~~~~~~~
This commit is contained in:
parent
2cff30b17a
commit
d93f7f93c4
@ -29,6 +29,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||||
) {
|
) {
|
||||||
self.annotate_expected_due_to_let_ty(err, expr);
|
self.annotate_expected_due_to_let_ty(err, expr);
|
||||||
|
self.suggest_box_deref(err, expr, expected, expr_ty);
|
||||||
self.suggest_compatible_variants(err, expr, expected, expr_ty);
|
self.suggest_compatible_variants(err, expr, expected, expr_ty);
|
||||||
self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
|
self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr);
|
||||||
if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
|
if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) {
|
||||||
@ -167,6 +168,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_box_deref(
|
||||||
|
&self,
|
||||||
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
|
expr: &hir::Expr<'_>,
|
||||||
|
expected: Ty<'tcx>,
|
||||||
|
expr_ty: Ty<'tcx>,
|
||||||
|
) {
|
||||||
|
if expr_ty.is_box() && expr_ty.boxed_ty() == expected {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
expr.span.shrink_to_lo(),
|
||||||
|
"try dereferencing the `Box`",
|
||||||
|
"*".to_string(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// If the expected type is an enum (Issue #55250) with any variants whose
|
/// If the expected type is an enum (Issue #55250) with any variants whose
|
||||||
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
/// sole field is of the found type, suggest such variants. (Issue #42764)
|
||||||
fn suggest_compatible_variants(
|
fn suggest_compatible_variants(
|
||||||
|
16
src/test/ui/suggestions/boxed-variant-field.rs
Normal file
16
src/test/ui/suggestions/boxed-variant-field.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
enum Ty {
|
||||||
|
Unit,
|
||||||
|
List(Box<Ty>),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(x: Ty) -> Ty {
|
||||||
|
match x {
|
||||||
|
Ty::Unit => Ty::Unit,
|
||||||
|
Ty::List(elem) => foo(elem),
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| HELP try dereferencing the `Box`
|
||||||
|
//~| HELP try using a variant of the expected enum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
20
src/test/ui/suggestions/boxed-variant-field.stderr
Normal file
20
src/test/ui/suggestions/boxed-variant-field.stderr
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/boxed-variant-field.rs:9:31
|
||||||
|
|
|
||||||
|
LL | Ty::List(elem) => foo(elem),
|
||||||
|
| ^^^^ expected enum `Ty`, found struct `Box`
|
||||||
|
|
|
||||||
|
= note: expected enum `Ty`
|
||||||
|
found struct `Box<Ty>`
|
||||||
|
help: try dereferencing the `Box`
|
||||||
|
|
|
||||||
|
LL | Ty::List(elem) => foo(*elem),
|
||||||
|
| +
|
||||||
|
help: try using a variant of the expected enum
|
||||||
|
|
|
||||||
|
LL | Ty::List(elem) => foo(Ty::List(elem)),
|
||||||
|
| ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
@ -6,6 +6,10 @@ LL | want_foo(b);
|
|||||||
|
|
|
|
||||||
= note: expected struct `Foo`
|
= note: expected struct `Foo`
|
||||||
found struct `Box<Foo>`
|
found struct `Box<Foo>`
|
||||||
|
help: try dereferencing the `Box`
|
||||||
|
|
|
||||||
|
LL | want_foo(*b);
|
||||||
|
| +
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user