mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
Add "dereference boxed value" suggestion.
This commit adds a `help: consider dereferencing the boxed value` suggestion to discriminants of match statements when the match arms have type `T` and the discriminant has type `Box<T>`.
This commit is contained in:
parent
f613dc138b
commit
f13fe5f3f7
@ -485,12 +485,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn note_error_origin(&self, err: &mut DiagnosticBuilder<'tcx>, cause: &ObligationCause<'tcx>) {
|
||||
fn note_error_origin(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
|
||||
) {
|
||||
match cause.code {
|
||||
ObligationCauseCode::MatchExpressionArmPattern { span, ty } => {
|
||||
if ty.is_suggestable() { // don't show type `_`
|
||||
err.span_label(span, format!("this match expression has type `{}`", ty));
|
||||
}
|
||||
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found {
|
||||
if ty.is_box() && ty.boxed_ty() == found {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
err.span_suggestion_with_applicability(
|
||||
span,
|
||||
"consider dereferencing the boxed value",
|
||||
format!("*{}", snippet),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::MatchExpressionArm { arm_span, source } => match source {
|
||||
hir::MatchSource::IfLetDesugar { .. } => {
|
||||
@ -1013,7 +1030,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// It reads better to have the error origin as the final
|
||||
// thing.
|
||||
self.note_error_origin(diag, &cause);
|
||||
self.note_error_origin(diag, &cause, exp_found);
|
||||
}
|
||||
|
||||
/// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate,
|
||||
|
18
src/test/ui/issues/issue-57741-1.rs
Normal file
18
src/test/ui/issues/issue-57741-1.rs
Normal file
@ -0,0 +1,18 @@
|
||||
#![allow(warnings)]
|
||||
|
||||
// This tests that the `help: consider dereferencing the boxed value` suggestion isn't made
|
||||
// because the box doesn't deref to the type of the arm.
|
||||
|
||||
enum S {
|
||||
A { a: usize },
|
||||
B { b: usize },
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(3u32);
|
||||
let y = match x {
|
||||
S::A { a } | S::B { b: a } => a,
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^^ ERROR mismatched types [E0308]
|
||||
};
|
||||
}
|
25
src/test/ui/issues/issue-57741-1.stderr
Normal file
25
src/test/ui/issues/issue-57741-1.stderr
Normal file
@ -0,0 +1,25 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741-1.rs:14:9
|
||||
|
|
||||
LL | let y = match x {
|
||||
| - this match expression has type `std::boxed::Box<u32>`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<u32>`
|
||||
found type `S`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741-1.rs:14:22
|
||||
|
|
||||
LL | let y = match x {
|
||||
| - this match expression has type `std::boxed::Box<u32>`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<u32>`
|
||||
found type `S`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
31
src/test/ui/issues/issue-57741.fixed
Normal file
31
src/test/ui/issues/issue-57741.fixed
Normal file
@ -0,0 +1,31 @@
|
||||
// run-rustfix
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works.
|
||||
|
||||
enum S {
|
||||
A { a: usize },
|
||||
B { b: usize },
|
||||
}
|
||||
|
||||
enum T {
|
||||
A(usize),
|
||||
B(usize),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(T::A(3));
|
||||
let y = match *x {
|
||||
T::A(a) | T::B(a) => a,
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^^ ERROR mismatched types [E0308]
|
||||
};
|
||||
|
||||
let x = Box::new(S::A { a: 3 });
|
||||
let y = match *x {
|
||||
S::A { a } | S::B { b: a } => a,
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^^ ERROR mismatched types [E0308]
|
||||
};
|
||||
}
|
31
src/test/ui/issues/issue-57741.rs
Normal file
31
src/test/ui/issues/issue-57741.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// run-rustfix
|
||||
|
||||
#![allow(warnings)]
|
||||
|
||||
// This tests that the `help: consider dereferencing the boxed value` suggestion is made and works.
|
||||
|
||||
enum S {
|
||||
A { a: usize },
|
||||
B { b: usize },
|
||||
}
|
||||
|
||||
enum T {
|
||||
A(usize),
|
||||
B(usize),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(T::A(3));
|
||||
let y = match x {
|
||||
T::A(a) | T::B(a) => a,
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^^ ERROR mismatched types [E0308]
|
||||
};
|
||||
|
||||
let x = Box::new(S::A { a: 3 });
|
||||
let y = match x {
|
||||
S::A { a } | S::B { b: a } => a,
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^^ ERROR mismatched types [E0308]
|
||||
};
|
||||
}
|
59
src/test/ui/issues/issue-57741.stderr
Normal file
59
src/test/ui/issues/issue-57741.stderr
Normal file
@ -0,0 +1,59 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741.rs:20:9
|
||||
|
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<T>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | T::A(a) | T::B(a) => a,
|
||||
| ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<T>`
|
||||
found type `T`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741.rs:20:19
|
||||
|
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<T>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | T::A(a) | T::B(a) => a,
|
||||
| ^^^^^^^ expected struct `std::boxed::Box`, found enum `T`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<T>`
|
||||
found type `T`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741.rs:27:9
|
||||
|
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<S>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<S>`
|
||||
found type `S`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-57741.rs:27:22
|
||||
|
|
||||
LL | let y = match x {
|
||||
| -
|
||||
| |
|
||||
| this match expression has type `std::boxed::Box<S>`
|
||||
| help: consider dereferencing the boxed value: `*x`
|
||||
LL | S::A { a } | S::B { b: a } => a,
|
||||
| ^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found enum `S`
|
||||
|
|
||||
= note: expected type `std::boxed::Box<S>`
|
||||
found type `S`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user