Skip to content

Commit

Permalink
Tweak if let suggestion to be more liberal with suggestion and to n…
Browse files Browse the repository at this point in the history
…ot ICE

Fix rust-lang#77218. Fix rust-lang#77238.
  • Loading branch information
estebank committed Oct 25, 2020
1 parent 07a63e6 commit cabf6d0
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 34 deletions.
50 changes: 28 additions & 22 deletions compiler/rustc_typeck/src/check/expr.rs
Expand Up @@ -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() {
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/issues/issue-77218.rs
@@ -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 changes: 14 additions & 0 deletions src/test/ui/issues/issue-77218.stderr
@@ -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`.
1 change: 0 additions & 1 deletion src/test/ui/suggestions/if-let-typo.rs
Expand Up @@ -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
}
18 changes: 7 additions & 11 deletions src/test/ui/suggestions/if-let-typo.stderr
Expand Up @@ -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 `()`
Expand All @@ -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`.

0 comments on commit cabf6d0

Please sign in to comment.