Suggest unwrap()
on field not found for Result
/Option
When encountering a `Result<T, _>` or `Option<T>` where `T` has a field that's being accessed, suggest calling `.unwrap()` to get to the field.
This commit is contained in:
parent
dfa75391f8
commit
8bd8f3b090
@ -2686,8 +2686,19 @@ fn no_such_field_err(
|
||||
|
||||
// try to add a suggestion in case the field is a nested field of a field of the Adt
|
||||
let mod_id = self.tcx.parent_module(id).to_def_id();
|
||||
let (ty, unwrap) = if let ty::Adt(def, args) = expr_t.kind()
|
||||
&& (self.tcx.is_diagnostic_item(sym::Result, def.did())
|
||||
|| self.tcx.is_diagnostic_item(sym::Option, def.did())
|
||||
)
|
||||
&& let Some(arg) = args.get(0)
|
||||
&& let Some(ty) = arg.as_type()
|
||||
{
|
||||
(ty, "unwrap().")
|
||||
} else {
|
||||
(expr_t, "")
|
||||
};
|
||||
for (found_fields, args) in
|
||||
self.get_field_candidates_considering_privacy(span, expr_t, mod_id, id)
|
||||
self.get_field_candidates_considering_privacy(span, ty, mod_id, id)
|
||||
{
|
||||
let field_names = found_fields.iter().map(|field| field.name).collect::<Vec<_>>();
|
||||
let candidate_fields: Vec<_> = found_fields
|
||||
@ -2707,9 +2718,8 @@ fn no_such_field_err(
|
||||
field_path.pop();
|
||||
field_path
|
||||
.iter()
|
||||
.map(|id| id.name.to_ident_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(".")
|
||||
.map(|id| format!("{}.", id.name.to_ident_string()))
|
||||
.collect::<String>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -2722,15 +2732,15 @@ fn no_such_field_err(
|
||||
if len > 1 { "some" } else { "one" },
|
||||
if len > 1 { "have" } else { "has" },
|
||||
),
|
||||
candidate_fields.iter().map(|path| format!("{path}.")),
|
||||
candidate_fields.iter().map(|path| format!("{unwrap}{path}")),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
if let Some(field_name) = find_best_match_for_name(&field_names, field.name, None) {
|
||||
err.span_suggestion(
|
||||
err.span_suggestion_verbose(
|
||||
field.span,
|
||||
"a field with a similar name exists",
|
||||
field_name,
|
||||
format!("{unwrap}{}", field_name),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if !field_names.is_empty() {
|
||||
|
@ -12,11 +12,15 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
|
||||
--> $DIR/suggest-switching-edition-on-await-cargo.rs:23:7
|
||||
|
|
||||
LL | x.await;
|
||||
| ^^^^^ help: a field with a similar name exists: `awai`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: to `.await` a `Future`, switch to Rust 2018 or later
|
||||
= help: set `edition = "2021"` in `Cargo.toml`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | x.awai;
|
||||
| ~~~~
|
||||
|
||||
error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
|
||||
--> $DIR/suggest-switching-edition-on-await-cargo.rs:32:7
|
||||
|
@ -12,11 +12,15 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
|
||||
--> $DIR/suggest-switching-edition-on-await.rs:21:7
|
||||
|
|
||||
LL | x.await;
|
||||
| ^^^^^ help: a field with a similar name exists: `awai`
|
||||
| ^^^^^
|
||||
|
|
||||
= note: to `.await` a `Future`, switch to Rust 2018 or later
|
||||
= help: pass `--edition 2021` to `rustc`
|
||||
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | x.awai;
|
||||
| ~~~~
|
||||
|
||||
error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
|
||||
--> $DIR/suggest-switching-edition-on-await.rs:30:7
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `c` on type `&Foo`
|
||||
--> $DIR/issue-30580.rs:12:11
|
||||
|
|
||||
LL | b.c;
|
||||
| ^ help: a field with a similar name exists: `a`
|
||||
| ^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | b.a;
|
||||
| ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `baz` on type `Foo`
|
||||
--> $DIR/issue-36798.rs:7:7
|
||||
|
|
||||
LL | f.baz;
|
||||
| ^^^ help: a field with a similar name exists: `bar`
|
||||
| ^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | f.bar;
|
||||
| ~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -16,7 +16,12 @@ error[E0609]: no field `inocently_mispellable` on type `Demo`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:32:41
|
||||
|
|
||||
LL | let innocent_field_misaccess = demo.inocently_mispellable;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let innocent_field_misaccess = demo.innocently_misspellable;
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0609]: no field `egregiously_nonexistent_field` on type `Demo`
|
||||
--> $DIR/issue-42599_available_fields_note.rs:35:42
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `1` on type `Foo`
|
||||
--> $DIR/ex-E0612.rs:5:6
|
||||
|
|
||||
LL | y.1;
|
||||
| ^ help: a field with a similar name exists: `0`
|
||||
| ^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | y.0;
|
||||
| ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `00` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:8:30
|
||||
|
|
||||
LL | let _condemned = justice.00;
|
||||
| ^^ help: a field with a similar name exists: `0`
|
||||
| ^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let _condemned = justice.0;
|
||||
| ~
|
||||
|
||||
error[E0609]: no field `001` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:10:31
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `baa` on type `BuildData`
|
||||
--> $DIR/struct-fields-typo.rs:11:17
|
||||
|
|
||||
LL | let x = foo.baa;
|
||||
| ^^^ help: a field with a similar name exists: `bar`
|
||||
| ^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let x = foo.bar;
|
||||
| ~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `d` on type `&A`
|
||||
--> $DIR/struct-pat-derived-error.rs:8:31
|
||||
|
|
||||
LL | let A { x, y } = self.d;
|
||||
| ^ help: a field with a similar name exists: `b`
|
||||
| ^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let A { x, y } = self.b;
|
||||
| ~
|
||||
|
||||
error[E0026]: struct `A` does not have fields named `x`, `y`
|
||||
--> $DIR/struct-pat-derived-error.rs:8:17
|
||||
|
@ -10,4 +10,12 @@ fn main() {
|
||||
let _ = x.long_name; //~ ERROR no field `longname`
|
||||
let y = S { long_name: (), foo: () };
|
||||
let _ = y.long_name; //~ ERROR no field `longname`
|
||||
let a = Some(Arc::new(S { long_name: (), foo: () }));
|
||||
let _ = a.unwrap().long_name; //~ ERROR no field `longname`
|
||||
let b = Some(S { long_name: (), foo: () });
|
||||
let _ = b.unwrap().long_name; //~ ERROR no field `long_name`
|
||||
let c = Ok::<_, ()>(Arc::new(S { long_name: (), foo: () }));
|
||||
let _ = c.unwrap().long_name; //~ ERROR no field `longname`
|
||||
let d = Ok::<_, ()>(S { long_name: (), foo: () });
|
||||
let _ = d.unwrap().long_name; //~ ERROR no field `long_name`
|
||||
}
|
||||
|
@ -10,4 +10,12 @@ fn main() {
|
||||
let _ = x.longname; //~ ERROR no field `longname`
|
||||
let y = S { long_name: (), foo: () };
|
||||
let _ = y.longname; //~ ERROR no field `longname`
|
||||
let a = Some(Arc::new(S { long_name: (), foo: () }));
|
||||
let _ = a.longname; //~ ERROR no field `longname`
|
||||
let b = Some(S { long_name: (), foo: () });
|
||||
let _ = b.long_name; //~ ERROR no field `long_name`
|
||||
let c = Ok::<_, ()>(Arc::new(S { long_name: (), foo: () }));
|
||||
let _ = c.longname; //~ ERROR no field `longname`
|
||||
let d = Ok::<_, ()>(S { long_name: (), foo: () });
|
||||
let _ = d.long_name; //~ ERROR no field `long_name`
|
||||
}
|
||||
|
@ -2,14 +2,68 @@ error[E0609]: no field `longname` on type `Arc<S>`
|
||||
--> $DIR/suggest-field-through-deref.rs:10:15
|
||||
|
|
||||
LL | let _ = x.longname;
|
||||
| ^^^^^^^^ help: a field with a similar name exists: `long_name`
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let _ = x.long_name;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error[E0609]: no field `longname` on type `S`
|
||||
--> $DIR/suggest-field-through-deref.rs:12:15
|
||||
|
|
||||
LL | let _ = y.longname;
|
||||
| ^^^^^^^^ help: a field with a similar name exists: `long_name`
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let _ = y.long_name;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0609]: no field `longname` on type `Option<Arc<S>>`
|
||||
--> $DIR/suggest-field-through-deref.rs:14:15
|
||||
|
|
||||
LL | let _ = a.longname;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let _ = a.unwrap().long_name;
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0609]: no field `long_name` on type `Option<S>`
|
||||
--> $DIR/suggest-field-through-deref.rs:16:15
|
||||
|
|
||||
LL | let _ = b.long_name;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
help: one of the expressions' fields has a field of the same name
|
||||
|
|
||||
LL | let _ = b.unwrap().long_name;
|
||||
| +++++++++
|
||||
|
||||
error[E0609]: no field `longname` on type `Result<Arc<S>, ()>`
|
||||
--> $DIR/suggest-field-through-deref.rs:18:15
|
||||
|
|
||||
LL | let _ = c.longname;
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let _ = c.unwrap().long_name;
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
|
||||
error[E0609]: no field `long_name` on type `Result<S, ()>`
|
||||
--> $DIR/suggest-field-through-deref.rs:20:15
|
||||
|
|
||||
LL | let _ = d.long_name;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
help: one of the expressions' fields has a field of the same name
|
||||
|
|
||||
LL | let _ = d.unwrap().long_name;
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `0` on type `Point`
|
||||
--> $DIR/tuple-index-not-tuple.rs:6:12
|
||||
|
|
||||
LL | origin.0;
|
||||
| ^ help: a field with a similar name exists: `x`
|
||||
| ^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | origin.x;
|
||||
| ~
|
||||
|
||||
error[E0609]: no field `0` on type `Empty`
|
||||
--> $DIR/tuple-index-not-tuple.rs:8:11
|
||||
|
@ -2,7 +2,12 @@ error[E0609]: no field `2` on type `Point`
|
||||
--> $DIR/tuple-index-out-of-bounds.rs:7:12
|
||||
|
|
||||
LL | origin.2;
|
||||
| ^ help: a field with a similar name exists: `0`
|
||||
| ^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | origin.0;
|
||||
| ~
|
||||
|
||||
error[E0609]: no field `2` on type `({integer}, {integer})`
|
||||
--> $DIR/tuple-index-out-of-bounds.rs:12:11
|
||||
|
@ -8,7 +8,12 @@ error[E0609]: no field `principial` on type `U`
|
||||
--> $DIR/union-suggest-field.rs:17:15
|
||||
|
|
||||
LL | let w = u.principial;
|
||||
| ^^^^^^^^^^ help: a field with a similar name exists: `principal`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let w = u.principal;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error[E0615]: attempted to take value of method `calculate` on type `U`
|
||||
--> $DIR/union-suggest-field.rs:21:15
|
||||
|
@ -8,7 +8,12 @@ error[E0609]: no field `principial` on type `U`
|
||||
--> $DIR/union-suggest-field.rs:17:15
|
||||
|
|
||||
LL | let w = u.principial;
|
||||
| ^^^^^^^^^^ help: a field with a similar name exists: `principal`
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
help: a field with a similar name exists
|
||||
|
|
||||
LL | let w = u.principal;
|
||||
| ~~~~~~~~~
|
||||
|
||||
error[E0615]: attempted to take value of method `calculate` on type `U`
|
||||
--> $DIR/union-suggest-field.rs:21:15
|
||||
|
Loading…
Reference in New Issue
Block a user