Change:
: <details<summary<strongBacktrace</strong</summary<p</p</details
Regressed in
Cc
Related: this code should probably have a suggestion for (): Currently it produces:
Minimized (): I think this might be caused by the lifetimes.
Never mind! This causes it too, with no lifetimes (): EDIT: removed the type aliases EDIT 2: changed to to make it clearer that they don't need to be the same type EDIT 3: shortened names, removed comment
Assigning and removing as .20.3D.20.2E.2E.2E.60.20expression.E2.80.A6) in the prioritization working group.
Further minimized to this (): Having be a or produces the ICE, but making it an owned does not produce the ICE.
causes the operands to be typechecked twice: I think this has side effects that are causing problems by being applied twice. Commenting out the second makes the ICE go away, but I'm not sure what the best approach for a proper fix is. The effect on the UI suite is rather low: (It still emits this error:)
I tried a couple of things but it seems to me that you hit the nail in the head and we just need to remove the branch. this is caused because one side is seen to be while the other is seen to be or (depending on the case). This is a problem because the left hand side expression should in reality be a pattern instead, but there's no utility to build a pattern from an expression: patterns are built during parsing (due to differences like, being a valid thing there). Because of that it'll be very hard to make the suggestion happen for those cases, much harder than for the ones we already handle.
I think I just found a smaller example (granted, it's not valid code any more, but how is one supposed to know that in case of ICE? ;-) ): (If that's not the same error I'm happy to open a new ICE issue, but to me it looks the same, with all the , the panic at and the conditional destructuring in a loop).

Discussion:
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); <del> 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, ); } </del> <ins> 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, ); </ins> } <ins> } if eq { </ins> err.span_suggestion_verbose( *span, "you might have meant to compare for equality", "==".to_string(), <del> Applicability::MaybeIncorrect, </del> <ins> applicability, </ins> ); <del> } 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)); </del> } if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {

<ins> 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 } } </ins>

<ins> 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`. </ins>

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 <del> //~^ ERROR mismatched types </del> if Some(3) = foo {} //~ ERROR mismatched types }

|                  ^^ error[E0308]: mismatched types <del> --> $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 </del> --> $DIR/if-let-typo.rs:6:8 | LL |     if 3 = foo {} |        ^^^^^^^ expected `bool`, found `()` <ins> | help: you might have meant to use pattern matching | LL |     if let 3 = foo {} |        ^^^ </ins> error[E0308]: mismatched types <del> --> $DIR/if-let-typo.rs:8:8 </del> <ins> --> $DIR/if-let-typo.rs:7:8 </ins> | LL |     if Some(3) = foo {} |        ^^^^^^^^^^^^^ expected `bool`, found `()`

LL |     if Some(3) == foo {} |                ^^ <del> error: aborting due to 5 previous errors </del> <ins> error: aborting due to 4 previous errors </ins> Some errors have detailed explanations: E0308, E0425. For more information about an error, try `rustc --explain E0308`.