diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-12-14 23:56:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-14 23:56:28 +0100 |
| commit | db77788dc5d72da6dc2077e59d9ff321cbda1cec (patch) | |
| tree | c66a72aeeff0f31ff9a70e4a3b0b9c49fb0c9569 /compiler/rustc_middle | |
| parent | 0aeaa5eb22180fdf12a8489e63c4daa18da6f236 (diff) | |
| parent | 831f4549cd1b23915729cbd2f1dd841621c4e8b8 (diff) | |
| download | rust-db77788dc5d72da6dc2077e59d9ff321cbda1cec.tar.gz rust-db77788dc5d72da6dc2077e59d9ff321cbda1cec.zip | |
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.
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/traits/mod.rs | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 0a77c3bc42f..8c434265d27 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -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> { |
