Skip to content

Commit b1a1df2

Browse files
Fix consider borrowing for else-if
1 parent a261d16 commit b1a1df2

File tree

4 files changed

+29
-11
lines changed

4 files changed

+29
-11
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,6 +2713,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27132713
));
27142714
}
27152715

2716+
// Don't try to suggest ref/deref on an `if` expression, because:
2717+
// - The `if` could be part of a desugared `if else` statement,
2718+
// which would create impossible suggestions such as `if ... { ... } else &if { ... } else { ... }`.
2719+
// - In general the suggestions it creates such as `&if ... { ... } else { ... }` are not very helpful.
2720+
// We try to generate a suggestion such as `if ... { &... } else { &... }` instead.
2721+
if let hir::ExprKind::If(_c, then, els) = expr.kind {
2722+
// The `then` of a `Expr::If` always contains a block, and that block may have a final expression that we can borrow
2723+
// If the block does not have a final expression, it will return () and we do not make a suggestion to borrow that.
2724+
let ExprKind::Block(then, _) = then.kind else { return None };
2725+
let Some(then) = then.expr else { return None };
2726+
let (mut suggs, help, app, verbose, mutref) =
2727+
self.suggest_deref_or_ref(then, checked_ty, expected)?;
2728+
2729+
// If there is no `else`, the return type of this `if` will be (), so suggesting to change the `then` block is useless
2730+
let els_expr = match els?.kind {
2731+
ExprKind::Block(block, _) => block.expr?,
2732+
_ => els?,
2733+
};
2734+
let (else_suggs, ..) =
2735+
self.suggest_deref_or_ref(els_expr, checked_ty, expected)?;
2736+
suggs.extend(else_suggs);
2737+
2738+
return Some((suggs, help, app, verbose, mutref));
2739+
}
2740+
27162741
if let Some((sugg, msg)) = self.can_use_as_ref(expr) {
27172742
return Some((
27182743
sugg,

tests/ui/typeck/consider-borrowing-141810-1.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ LL | || };
1818
|
1919
help: consider borrowing here
2020
|
21-
LL | } else &if false {
22-
| +
21+
LL ~ &true
22+
LL | } else {
23+
LL ~ &true
24+
|
2325

2426
error: aborting due to 1 previous error
2527

tests/ui/typeck/consider-borrowing-141810-2.stderr

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ LL | || };
1313
| ||_____|
1414
| |_____`if` and `else` have incompatible types
1515
| expected `&()`, found `()`
16-
|
17-
help: consider borrowing here
18-
|
19-
LL | } else &if false {
20-
| +
2116

2217
error: aborting due to 1 previous error
2318

tests/ui/typeck/consider-borrowing-141810-3.stderr

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ LL | || };
1616
|
1717
= note: `if` expressions without `else` evaluate to `()`
1818
= note: consider adding an `else` block that evaluates to the expected type
19-
help: consider borrowing here
20-
|
21-
LL | } else &if false {
22-
| +
2319

2420
error: aborting due to 1 previous error
2521

0 commit comments

Comments
 (0)