mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-07 04:23:30 +00:00
Suggest accessing field when code compiles with it
This commit is contained in:
parent
e32f372c42
commit
9e4ed337c7
@ -1661,6 +1661,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
debug!("exp_found {:?} terr {:?}", exp_found, terr);
|
||||
if let Some(exp_found) = exp_found {
|
||||
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
|
||||
self.suggest_field_where_appropriate(cause, &exp_found, diag);
|
||||
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
|
||||
}
|
||||
|
||||
@ -1819,6 +1820,46 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_field_where_appropriate(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
|
||||
diag: &mut DiagnosticBuilder<'tcx>,
|
||||
) {
|
||||
debug!("suggest_field_where_appropriate(cause={:?}, exp_found={:?})", cause, exp_found);
|
||||
if let ty::Adt(expected_def, expected_substs) = exp_found.expected.kind() {
|
||||
if expected_def.is_enum() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some((name, ty)) = expected_def
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.iter()
|
||||
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
|
||||
.map(|field| (field.ident.name, field.ty(self.tcx, expected_substs)))
|
||||
.inspect(|(name, ty)| {
|
||||
debug!("suggest_field_where_appropriate: name={:?}, ty={:?}", name, ty)
|
||||
})
|
||||
.find(|(_, ty)| ty::TyS::same_type(ty, exp_found.found))
|
||||
{
|
||||
if let ObligationCauseCode::Pattern { span: Some(span), .. } = cause.code {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"you might have meant to use field `{}` of type `{}`",
|
||||
name, ty
|
||||
),
|
||||
format!("{}.{}", snippet, name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// When encountering a case where `.as_ref()` on a `Result` or `Option` would be appropriate,
|
||||
/// suggests it.
|
||||
fn suggest_as_ref_where_appropriate(
|
||||
|
15
src/test/ui/suggestions/field-access.rs
Normal file
15
src/test/ui/suggestions/field-access.rs
Normal file
@ -0,0 +1,15 @@
|
||||
struct A {
|
||||
b: B,
|
||||
}
|
||||
|
||||
enum B {
|
||||
Fst,
|
||||
Snd,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = A { b: B::Fst };
|
||||
if let B::Fst = a {};
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
// note: you might have meant to use field `b` of type `B`
|
||||
}
|
19
src/test/ui/suggestions/field-access.stderr
Normal file
19
src/test/ui/suggestions/field-access.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/field-access.rs:12:12
|
||||
|
|
||||
LL | Fst,
|
||||
| --- unit variant defined here
|
||||
...
|
||||
LL | if let B::Fst = a {};
|
||||
| ^^^^^^ - this expression has type `A`
|
||||
| |
|
||||
| expected struct `A`, found enum `B`
|
||||
|
|
||||
help: you might have meant to use field `b` of type `B`
|
||||
|
|
||||
LL | if let B::Fst = a.b {};
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user