1
Fork 0

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

@ -316,8 +316,8 @@ pub enum ObligationCauseCode<'tcx> {
span: Option<Span>,
/// The root expected type induced by a scrutinee or type expression.
root_ty: Ty<'tcx>,
/// Whether the `Span` came from an expression or a type expression.
origin_expr: bool,
/// Information about the `Span`, if it came from an expression, otherwise `None`.
origin_expr: Option<PatternOriginExpr>,
},
/// Computing common supertype in an if expression
@ -530,6 +530,25 @@ pub struct MatchExpressionArmCause<'tcx> {
pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
}
/// Information about the origin expression of a pattern, relevant to diagnostics.
/// Fields here refer to the scrutinee of a pattern.
/// If the scrutinee isn't given in the diagnostic, then this won't exist.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
pub struct PatternOriginExpr {
/// A span representing the scrutinee expression, with all leading references
/// peeled from the expression.
/// Only references in the expression are peeled - if the expression refers to a variable
/// whose type is a reference, then that reference is kept because it wasn't created
/// in the expression.
pub peeled_span: Span,
/// The number of references that were peeled to produce `peeled_span`.
pub peeled_count: usize,
/// Does the peeled expression need to be wrapped in parentheses for
/// a prefix suggestion (i.e., dereference) to be valid.
pub peeled_prefix_suggestion_parentheses: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
pub struct IfExpressionCause<'tcx> {