Improve error msgs when found type is deref of expected
This improves help messages in two cases: - When expected type is `T` and found type is `&T`, we now look through blocks and suggest dereferencing the expression of the block, rather than the whole block. - In the above case, if the expression is an `&`, we not suggest removing the `&` instead of adding `*`. Both of these are demonstrated in the regression test. Before this patch the first error in the test would be: error[E0308]: `if` and `else` have incompatible types --> test.rs:8:9 | 5 | / if true { 6 | | a | | - expected because of this 7 | | } else { 8 | | b | | ^ expected `usize`, found `&usize` 9 | | }; | |_____- `if` and `else` have incompatible types | help: consider dereferencing the borrow | 7 | } else *{ 8 | b 9 | }; | Now: error[E0308]: `if` and `else` have incompatible types --> test.rs:8:9 | 5 | / if true { 6 | | a | | - expected because of this 7 | | } else { 8 | | b | | ^ | | | | | expected `usize`, found `&usize` | | help: consider dereferencing the borrow: `*b` 9 | | }; | |_____- `if` and `else` have incompatible types The second error: error[E0308]: `if` and `else` have incompatible types --> test.rs:14:9 | 11 | / if true { 12 | | 1 | | - expected because of this 13 | | } else { 14 | | &1 | | ^^ expected integer, found `&{integer}` 15 | | }; | |_____- `if` and `else` have incompatible types | help: consider dereferencing the borrow | 13 | } else *{ 14 | &1 15 | }; | now: error[E0308]: `if` and `else` have incompatible types --> test.rs:14:9 | 11 | / if true { 12 | | 1 | | - expected because of this 13 | | } else { 14 | | &1 | | ^- | | || | | |help: consider removing the `&`: `1` | | expected integer, found `&{integer}` 15 | | }; | |_____- `if` and `else` have incompatible types Fixes #82361
This commit is contained in:
parent
a4e595db8f
commit
fa74d489a2
5 changed files with 128 additions and 4 deletions
|
@ -1577,6 +1577,14 @@ impl Expr<'_> {
|
|||
expr
|
||||
}
|
||||
|
||||
pub fn peel_blocks(&self) -> &Self {
|
||||
let mut expr = self;
|
||||
while let ExprKind::Block(Block { expr: Some(inner), .. }, _) = &expr.kind {
|
||||
expr = inner;
|
||||
}
|
||||
expr
|
||||
}
|
||||
|
||||
pub fn can_have_side_effects(&self) -> bool {
|
||||
match self.peel_drop_temps().kind {
|
||||
ExprKind::Path(_) | ExprKind::Lit(_) => false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue