Rollup merge of #132939 - uellenberg:suggest-deref, r=oli-obk

Suggest using deref in patterns

Fixes #132784

This changes the following code:
```rs
use std::sync::Arc;
fn main() {
    let mut x = Arc::new(Some(1));
    match x {
        Some(_) => {}
        None => {}
    }
}
```

to output
```rs
error[E0308]: mismatched types
  --> src/main.rs:5:9
   |
LL |     match x {
   |           - this expression has type `Arc<Option<{integer}>>`
...
LL |         Some(_) => {}
   |         ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
   |
   = note: expected struct `Arc<Option<{integer}>>`
                found enum `Option<_>`
help: consider dereferencing to access the inner value using the Deref trait
   |
LL |     match *x {
   |           ~~
```

instead of
```rs
error[E0308]: mismatched types
 --> src/main.rs:5:9
  |
4 |     match x {
  |           - this expression has type `Arc<Option<{integer}>>`
5 |         Some(_) => {}
  |         ^^^^^^^ expected `Arc<Option<{integer}>>`, found `Option<_>`
  |
  = note: expected struct `Arc<Option<{integer}>>`
               found enum `Option<_>`
```

This makes it more obvious that a Deref is available, and gives a suggestion on how to use it in order to fix the issue at hand.
This commit is contained in:
Matthias Krüger 2024-12-14 23:56:28 +01:00 committed by GitHub
commit db77788dc5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 544 additions and 64 deletions

View file

@ -2025,6 +2025,22 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
}
}
/// Checks if the specified expression needs parentheses for prefix
/// or postfix suggestions to be valid.
/// For example, `a + b` requires parentheses to suggest `&(a + b)`,
/// but just `a` does not.
/// Similarly, `(a + b).c()` also requires parentheses.
/// This should not be used for other types of suggestions.
pub fn expr_needs_parens(expr: &Expr<'_>) -> bool {
match expr.kind {
// parenthesize if needed (Issue #46756)
ExprKind::Cast(_, _) | ExprKind::Binary(_, _, _) => true,
// parenthesize borrows of range literals (Issue #54505)
_ if is_range_literal(expr) => true,
_ => false,
}
}
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ExprKind<'hir> {
/// Allow anonymous constants from an inline `const` block