mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Tweak if let
suggestion to be more liberal with suggestion and to not ICE
Fix #77218. Fix #77238.
This commit is contained in:
parent
07a63e6d1f
commit
cabf6d0523
@ -769,34 +769,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
|
||||
let lhs_ty = self.check_expr(&lhs);
|
||||
let rhs_ty = self.check_expr(&rhs);
|
||||
if self.can_coerce(lhs_ty, rhs_ty) {
|
||||
if !lhs.is_syntactic_place_expr() {
|
||||
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
|
||||
if let hir::Node::Expr(hir::Expr {
|
||||
kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }),
|
||||
..
|
||||
}) = self.tcx.hir().get(
|
||||
self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
|
||||
) {
|
||||
// Likely `if let` intended.
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_lo(),
|
||||
"you might have meant to use pattern matching",
|
||||
"let ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
|
||||
(Applicability::MachineApplicable, true)
|
||||
} else {
|
||||
(Applicability::MaybeIncorrect, false)
|
||||
};
|
||||
if !lhs.is_syntactic_place_expr() {
|
||||
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
|
||||
if let hir::Node::Expr(hir::Expr {
|
||||
kind:
|
||||
ExprKind::Match(
|
||||
_,
|
||||
_,
|
||||
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar,
|
||||
),
|
||||
..
|
||||
}) = self.tcx.hir().get(
|
||||
self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
|
||||
) {
|
||||
// Likely `if let` intended.
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_lo(),
|
||||
"you might have meant to use pattern matching",
|
||||
"let ".to_string(),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
if eq {
|
||||
err.span_suggestion_verbose(
|
||||
*span,
|
||||
"you might have meant to compare for equality",
|
||||
"==".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
applicability,
|
||||
);
|
||||
} else {
|
||||
// Do this to cause extra errors about the assignment.
|
||||
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
|
||||
let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
|
||||
}
|
||||
|
||||
if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {
|
||||
|
7
src/test/ui/issues/issue-77218.rs
Normal file
7
src/test/ui/issues/issue-77218.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn main() {
|
||||
let value = [7u8];
|
||||
while Some(0) = value.get(0) { //~ ERROR mismatched types
|
||||
//~^ NOTE expected `bool`, found `()`
|
||||
//~| HELP you might have meant to use pattern matching
|
||||
}
|
||||
}
|
14
src/test/ui/issues/issue-77218.stderr
Normal file
14
src/test/ui/issues/issue-77218.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-77218.rs:3:11
|
||||
|
|
||||
LL | while Some(0) = value.get(0) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
|
||||
help: you might have meant to use pattern matching
|
||||
|
|
||||
LL | while let Some(0) = value.get(0) {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -4,6 +4,5 @@ fn main() {
|
||||
if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
|
||||
if Some(foo) = bar {} //~ ERROR mismatched types
|
||||
if 3 = foo {} //~ ERROR mismatched types
|
||||
//~^ ERROR mismatched types
|
||||
if Some(3) = foo {} //~ ERROR mismatched types
|
||||
}
|
||||
|
@ -24,23 +24,19 @@ help: you might have meant to compare for equality
|
||||
LL | if Some(foo) == bar {}
|
||||
| ^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/if-let-typo.rs:6:12
|
||||
|
|
||||
LL | if 3 = foo {}
|
||||
| ^^^ expected integer, found enum `Option`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found enum `Option<{integer}>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/if-let-typo.rs:6:8
|
||||
|
|
||||
LL | if 3 = foo {}
|
||||
| ^^^^^^^ expected `bool`, found `()`
|
||||
|
|
||||
help: you might have meant to use pattern matching
|
||||
|
|
||||
LL | if let 3 = foo {}
|
||||
| ^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/if-let-typo.rs:8:8
|
||||
--> $DIR/if-let-typo.rs:7:8
|
||||
|
|
||||
LL | if Some(3) = foo {}
|
||||
| ^^^^^^^^^^^^^ expected `bool`, found `()`
|
||||
@ -54,7 +50,7 @@ help: you might have meant to compare for equality
|
||||
LL | if Some(3) == foo {}
|
||||
| ^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0425.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user