Rollup merge of #117110 - estebank:deref-field-suggestion, r=b-naber

Suggest field typo through derefs

Take into account implicit dereferences when suggesting fields.

```
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`
```

CC https://github.com/rust-lang/rust/issues/78374#issuecomment-719564114
This commit is contained in:
Takayuki Maeda 2023-11-19 04:14:41 +09:00 committed by GitHub
commit 9e84f6d86a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 491 additions and 241 deletions

View File

@ -2191,7 +2191,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(field_name) =
find_best_match_for_name(&available_field_names, field.ident.name, None)
{
err.span_suggestion(
err.span_label(field.ident.span, "unknown field");
err.span_suggestion_verbose(
field.ident.span,
"a field with a similar name exists",
field_name,
@ -2420,35 +2421,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
) {
let Some(output_ty) = self.get_impl_future_output_ty(ty) else {
err.span_label(field_ident.span, "unknown field");
return;
};
let mut add_label = true;
if let ty::Adt(def, _) = output_ty.kind() {
// no field access on enum type
if !def.is_enum() {
if def
.non_enum_variant()
.fields
.iter()
.any(|field| field.ident(self.tcx) == field_ident)
{
add_label = false;
err.span_label(
field_ident.span,
"field not available in `impl Future`, but it is available in its `Output`",
);
err.span_suggestion_verbose(
base.span.shrink_to_hi(),
"consider `await`ing on the `Future` and access the field of its `Output`",
".await",
Applicability::MaybeIncorrect,
);
}
}
let ty::Adt(def, _) = output_ty.kind() else {
err.span_label(field_ident.span, "unknown field");
return;
};
// no field access on enum type
if def.is_enum() {
err.span_label(field_ident.span, "unknown field");
return;
}
if add_label {
err.span_label(field_ident.span, format!("field not found in `{ty}`"));
if !def.non_enum_variant().fields.iter().any(|field| field.ident(self.tcx) == field_ident) {
err.span_label(field_ident.span, "unknown field");
return;
}
err.span_label(
field_ident.span,
"field not available in `impl Future`, but it is available in its `Output`",
);
err.span_suggestion_verbose(
base.span.shrink_to_hi(),
"consider `await`ing on the `Future` and access the field of its `Output`",
".await",
Applicability::MaybeIncorrect,
);
}
fn ban_nonexisting_field(
@ -2471,16 +2469,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::RawPtr(..) => {
self.suggest_first_deref_field(&mut err, expr, base, ident);
}
ty::Adt(def, _) if !def.is_enum() => {
self.suggest_fields_on_recordish(&mut err, expr, def, ident);
}
ty::Param(param_ty) => {
err.span_label(ident.span, "unknown field");
self.point_at_param_definition(&mut err, param_ty);
}
ty::Alias(ty::Opaque, _) => {
self.suggest_await_on_field_access(&mut err, ident, base, base_ty.peel_refs());
}
_ => {}
_ => {
err.span_label(ident.span, "unknown field");
}
}
self.suggest_fn_call(&mut err, base, base_ty, |output_ty| {
@ -2633,34 +2631,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_label(param_span, format!("type parameter '{param_name}' declared here"));
}
fn suggest_fields_on_recordish(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
def: ty::AdtDef<'tcx>,
field: Ident,
) {
let available_field_names = self.available_field_names(def.non_enum_variant(), expr, &[]);
if let Some(suggested_field_name) =
find_best_match_for_name(&available_field_names, field.name, None)
{
err.span_suggestion(
field.span,
"a field with a similar name exists",
suggested_field_name,
Applicability::MaybeIncorrect,
);
} else {
err.span_label(field.span, "unknown field");
if !available_field_names.is_empty() {
err.note(format!(
"available fields are: {}",
self.name_series_display(available_field_names),
));
}
}
}
fn maybe_suggest_array_indexing(
&self,
err: &mut Diagnostic,
@ -2669,6 +2639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field: Ident,
len: ty::Const<'tcx>,
) {
err.span_label(field.span, "unknown field");
if let (Some(len), Ok(user_index)) =
(len.try_eval_target_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
&& let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span)
@ -2691,6 +2662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base: &hir::Expr<'_>,
field: Ident,
) {
err.span_label(field.span, "unknown field");
if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
let msg = format!("`{base}` is a raw pointer; try dereferencing it");
let suggestion = format!("(*{base}).{field}");
@ -2709,7 +2681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut err = type_error_struct!(
self.tcx().sess,
field.span,
span,
expr_t,
E0609,
"no field `{field}` on type `{expr_t}`",
@ -2717,10 +2689,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 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();
if let Some((fields, args)) =
self.get_field_candidates_considering_privacy(span, expr_t, mod_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()
{
let candidate_fields: Vec<_> = fields
(ty, "unwrap().")
} else {
(expr_t, "")
};
for (found_fields, args) in
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
.into_iter()
.filter_map(|candidate_field| {
self.check_for_nested_field_satisfying(
span,
@ -2729,15 +2713,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
args,
vec![],
mod_id,
id,
)
})
.map(|mut field_path| {
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<_>>();
@ -2750,9 +2734,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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_verbose(
field.span,
"a field with a similar name exists",
format!("{unwrap}{}", field_name),
Applicability::MaybeIncorrect,
);
} else if !field_names.is_empty() {
let is = if field_names.len() == 1 { " is" } else { "s are" };
err.note(format!(
"available field{is}: {}",
self.name_series_display(field_names),
));
}
}
}
err
@ -2781,33 +2780,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
base_ty: Ty<'tcx>,
mod_id: DefId,
) -> Option<(impl Iterator<Item = &'tcx ty::FieldDef> + 'tcx, GenericArgsRef<'tcx>)> {
hir_id: hir::HirId,
) -> Vec<(Vec<&'tcx ty::FieldDef>, GenericArgsRef<'tcx>)> {
debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty);
for (base_t, _) in self.autoderef(span, base_ty) {
match base_t.kind() {
ty::Adt(base_def, args) if !base_def.is_enum() => {
let tcx = self.tcx;
let fields = &base_def.non_enum_variant().fields;
// Some struct, e.g. some that impl `Deref`, have all private fields
// because you're expected to deref them to access the _real_ fields.
// This, for example, will help us suggest accessing a field through a `Box<T>`.
if fields.iter().all(|field| !field.vis.is_accessible_from(mod_id, tcx)) {
continue;
self.autoderef(span, base_ty)
.filter_map(move |(base_t, _)| {
match base_t.kind() {
ty::Adt(base_def, args) if !base_def.is_enum() => {
let tcx = self.tcx;
let fields = &base_def.non_enum_variant().fields;
// Some struct, e.g. some that impl `Deref`, have all private fields
// because you're expected to deref them to access the _real_ fields.
// This, for example, will help us suggest accessing a field through a `Box<T>`.
if fields.iter().all(|field| !field.vis.is_accessible_from(mod_id, tcx)) {
return None;
}
return Some((
fields
.iter()
.filter(move |field| {
field.vis.is_accessible_from(mod_id, tcx)
&& self.is_field_suggestable(field, hir_id, span)
})
// For compile-time reasons put a limit on number of fields we search
.take(100)
.collect::<Vec<_>>(),
*args,
));
}
return Some((
fields
.iter()
.filter(move |field| field.vis.is_accessible_from(mod_id, tcx))
// For compile-time reasons put a limit on number of fields we search
.take(100),
args,
));
_ => None,
}
_ => {}
}
}
None
})
.collect()
}
/// This method is called after we have encountered a missing field error to recursively
@ -2820,6 +2825,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
subst: GenericArgsRef<'tcx>,
mut field_path: Vec<Ident>,
mod_id: DefId,
hir_id: HirId,
) -> Option<Vec<Ident>> {
debug!(
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
@ -2835,20 +2841,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let field_ty = candidate_field.ty(self.tcx, subst);
if matches(candidate_field, field_ty) {
return Some(field_path);
} else if let Some((nested_fields, subst)) =
self.get_field_candidates_considering_privacy(span, field_ty, mod_id)
{
// recursively search fields of `candidate_field` if it's a ty::Adt
for field in nested_fields {
if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
matches,
field,
subst,
field_path.clone(),
mod_id,
) {
return Some(field_path);
} else {
for (nested_fields, subst) in
self.get_field_candidates_considering_privacy(span, field_ty, mod_id, hir_id)
{
// recursively search fields of `candidate_field` if it's a ty::Adt
for field in nested_fields {
if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
matches,
field,
subst,
field_path.clone(),
mod_id,
hir_id,
) {
return Some(field_path);
}
}
}
}

View File

@ -1983,69 +1983,72 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
item_name: Ident,
return_type: Option<Ty<'tcx>>,
) {
if let SelfSource::MethodCall(expr) = source
&& let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id()
&& let Some((fields, args)) =
self.get_field_candidates_considering_privacy(span, actual, mod_id)
{
let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
if let SelfSource::MethodCall(expr) = source {
let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id();
for (fields, args) in
self.get_field_candidates_considering_privacy(span, actual, mod_id, expr.hir_id)
{
let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
let lang_items = self.tcx.lang_items();
let never_mention_traits = [
lang_items.clone_trait(),
lang_items.deref_trait(),
lang_items.deref_mut_trait(),
self.tcx.get_diagnostic_item(sym::AsRef),
self.tcx.get_diagnostic_item(sym::AsMut),
self.tcx.get_diagnostic_item(sym::Borrow),
self.tcx.get_diagnostic_item(sym::BorrowMut),
];
let candidate_fields: Vec<_> = fields
.filter_map(|candidate_field| {
self.check_for_nested_field_satisfying(
span,
&|_, field_ty| {
self.lookup_probe_for_diagnostic(
item_name,
field_ty,
call_expr,
ProbeScope::TraitsInScope,
return_type,
)
.is_ok_and(|pick| {
!never_mention_traits
.iter()
.flatten()
.any(|def_id| self.tcx.parent(pick.item.def_id) == *def_id)
})
},
candidate_field,
args,
vec![],
mod_id,
)
})
.map(|field_path| {
field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
.join(".")
})
.collect();
let lang_items = self.tcx.lang_items();
let never_mention_traits = [
lang_items.clone_trait(),
lang_items.deref_trait(),
lang_items.deref_mut_trait(),
self.tcx.get_diagnostic_item(sym::AsRef),
self.tcx.get_diagnostic_item(sym::AsMut),
self.tcx.get_diagnostic_item(sym::Borrow),
self.tcx.get_diagnostic_item(sym::BorrowMut),
];
let candidate_fields: Vec<_> = fields
.iter()
.filter_map(|candidate_field| {
self.check_for_nested_field_satisfying(
span,
&|_, field_ty| {
self.lookup_probe_for_diagnostic(
item_name,
field_ty,
call_expr,
ProbeScope::TraitsInScope,
return_type,
)
.is_ok_and(|pick| {
!never_mention_traits
.iter()
.flatten()
.any(|def_id| self.tcx.parent(pick.item.def_id) == *def_id)
})
},
candidate_field,
args,
vec![],
mod_id,
expr.hir_id,
)
})
.map(|field_path| {
field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
.join(".")
})
.collect();
let len = candidate_fields.len();
if len > 0 {
err.span_suggestions(
item_name.span.shrink_to_lo(),
format!(
"{} of the expressions' fields {} a method of the same name",
if len > 1 { "some" } else { "one" },
if len > 1 { "have" } else { "has" },
),
candidate_fields.iter().map(|path| format!("{path}.")),
Applicability::MaybeIncorrect,
);
let len = candidate_fields.len();
if len > 0 {
err.span_suggestions(
item_name.span.shrink_to_lo(),
format!(
"{} of the expressions' fields {} a method of the same name",
if len > 1 { "some" } else { "one" },
if len > 1 { "have" } else { "has" },
),
candidate_fields.iter().map(|path| format!("{path}.")),
Applicability::MaybeIncorrect,
);
}
}
}
}

View File

@ -23,6 +23,7 @@ fn await_on_struct_similar() {
let x = S { awai: 42 };
x.await;
//~^ ERROR no field `await` on type
//~| NOTE unknown field
//~| HELP a field with a similar name exists
//~| NOTE to `.await` a `Future`, switch to Rust 2018
//~| HELP set `edition = "2021"` in `Cargo.toml`
@ -41,6 +42,7 @@ fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
fn await_on_apit(x: impl Future<Output = ()>) {
x.await;
//~^ ERROR no field `await` on type
//~| NOTE unknown field
//~| NOTE to `.await` a `Future`, switch to Rust 2018
//~| HELP set `edition = "2021"` in `Cargo.toml`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide

View File

@ -12,14 +12,18 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
--> $DIR/suggest-switching-edition-on-await-cargo.rs:24:7
|
LL | x.await;
| ^^^^^ help: a field with a similar name exists: `awai`
| ^^^^^ unknown field
|
= 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:33:7
--> $DIR/suggest-switching-edition-on-await-cargo.rs:34:7
|
LL | x.await;
| ^^^^^ unknown field
@ -29,10 +33,10 @@ LL | x.await;
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
error[E0609]: no field `await` on type `impl Future<Output = ()>`
--> $DIR/suggest-switching-edition-on-await-cargo.rs:42:7
--> $DIR/suggest-switching-edition-on-await-cargo.rs:43:7
|
LL | x.await;
| ^^^^^
| ^^^^^ unknown field
|
= note: to `.await` a `Future`, switch to Rust 2018 or later
= help: set `edition = "2021"` in `Cargo.toml`

View File

@ -21,6 +21,7 @@ fn await_on_struct_similar() {
let x = S { awai: 42 };
x.await;
//~^ ERROR no field `await` on type
//~| NOTE unknown field
//~| HELP a field with a similar name exists
//~| NOTE to `.await` a `Future`, switch to Rust 2018
//~| HELP pass `--edition 2021` to `rustc`
@ -39,6 +40,7 @@ fn await_on_63533(x: Pin<&mut dyn Future<Output = ()>>) {
fn await_on_apit(x: impl Future<Output = ()>) {
x.await;
//~^ ERROR no field `await` on type
//~| NOTE unknown field
//~| NOTE to `.await` a `Future`, switch to Rust 2018
//~| HELP pass `--edition 2021` to `rustc`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide

View File

@ -12,14 +12,18 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
--> $DIR/suggest-switching-edition-on-await.rs:22:7
|
LL | x.await;
| ^^^^^ help: a field with a similar name exists: `awai`
| ^^^^^ unknown field
|
= 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:31:7
--> $DIR/suggest-switching-edition-on-await.rs:32:7
|
LL | x.await;
| ^^^^^ unknown field
@ -29,10 +33,10 @@ LL | x.await;
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
error[E0609]: no field `await` on type `impl Future<Output = ()>`
--> $DIR/suggest-switching-edition-on-await.rs:40:7
--> $DIR/suggest-switching-edition-on-await.rs:41:7
|
LL | x.await;
| ^^^^^
| ^^^^^ unknown field
|
= note: to `.await` a `Future`, switch to Rust 2018 or later
= help: pass `--edition 2021` to `rustc`

View File

@ -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`
| ^ unknown field
|
help: a field with a similar name exists
|
LL | b.a;
| ~
error: aborting due to previous error

View File

@ -29,7 +29,7 @@ fn main() {
doc_hidden_fields::B::default().hey;
//~^ ERROR no field `hey` on type `B`
//~| NOTE unknown field
//~| NOTE available fields are: `bye`
//~| NOTE available field is: `bye`
C::default().hey;
//~^ ERROR no field `hey` on type `C`

View File

@ -12,7 +12,7 @@ error[E0609]: no field `hey` on type `B`
LL | doc_hidden_fields::B::default().hey;
| ^^^ unknown field
|
= note: available fields are: `bye`
= note: available field is: `bye`
error[E0609]: no field `hey` on type `C`
--> $DIR/dont-suggest-doc-hidden-fields.rs:34:18

View File

@ -5,9 +5,13 @@ LL | environment!();
| -------------- in this macro invocation
...
LL | const CRATE: Crate = Crate { fiel: () };
| ^^^^ help: a field with a similar name exists: `field`
| ^^^^ unknown field
|
= note: this error originates in the macro `environment` (in Nightly builds, run with -Z macro-backtrace for more info)
help: a field with a similar name exists
|
LL | const CRATE: Crate = Crate { field: () };
| ~~~~~
error[E0609]: no field `field` on type `Compound`
--> $DIR/dont-suggest-hygienic-fields.rs:24:16

View File

@ -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`
| ^^^ unknown field
|
help: a field with a similar name exists
|
LL | f.bar;
| ~~~
error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0609]: no field `zz` on type `Foo`
LL | f.zz;
| ^^ unknown field
|
= note: available fields are: `bar`
= note: available field is: `bar`
error: aborting due to previous error

View File

@ -2,7 +2,12 @@ error[E0560]: struct `Demo` has no field named `inocently_mispellable`
--> $DIR/issue-42599_available_fields_note.rs:16:39
|
LL | Self { secret_integer: 2, inocently_mispellable: () }
| ^^^^^^^^^^^^^^^^^^^^^ help: a field with a similar name exists: `innocently_misspellable`
| ^^^^^^^^^^^^^^^^^^^^^ unknown field
|
help: a field with a similar name exists
|
LL | Self { secret_integer: 2, innocently_misspellable: () }
| ~~~~~~~~~~~~~~~~~~~~~~~
error[E0560]: struct `Demo` has no field named `egregiously_nonexistent_field`
--> $DIR/issue-42599_available_fields_note.rs:21:39
@ -16,7 +21,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`
| ^^^^^^^^^^^^^^^^^^^^^ unknown field
|
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

View File

@ -4,7 +4,7 @@ error[E0609]: no field `foo` on type `Foo`
LL | let _ = x.foo;
| ^^^ unknown field
|
= note: available fields are: `x`
= note: available field is: `x`
error[E0609]: no field `1` on type `Bar`
--> $DIR/E0609.rs:11:7

View File

@ -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`
| ^ unknown field
|
help: a field with a similar name exists
|
LL | y.0;
| ~
error: aborting due to previous error

View File

@ -3,7 +3,8 @@ error[E0609]: no field `x` on type `*mut A`
|
LL | let x : i32 = n.x;
| --^
| |
| | |
| | unknown field
| help: `n` is a raw pointer; try dereferencing it: `(*n).x`
error[E0609]: no field `y` on type `*mut A`
@ -11,7 +12,8 @@ error[E0609]: no field `y` on type `*mut A`
|
LL | let y : f64 = n.y;
| --^
| |
| | |
| | unknown field
| help: `n` is a raw pointer; try dereferencing it: `(*n).y`
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0609]: no field `is_failure` on type `!`
--> $DIR/issue-13847.rs:2:12
|
LL | return.is_failure
| ^^^^^^^^^^
| ^^^^^^^^^^ unknown field
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0609]: no field `desc` on type `&str`
--> $DIR/issue-14721.rs:3:24
|
LL | println!("{}", foo.desc);
| ^^^^
| ^^^^ unknown field
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0609]: no field `1` on type `(usize,)`
--> $DIR/issue-19244-1.rs:4:24
|
LL | let a: [isize; TUP.1];
| ^
| ^ unknown field
error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0609]: no field `nonexistent_field` on type `MyStruct`
LL | let a: [isize; STRUCT.nonexistent_field];
| ^^^^^^^^^^^^^^^^^ unknown field
|
= note: available fields are: `field`
= note: available field is: `field`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0609]: no field `a` on type `Foo`
--> $DIR/issue-23253.rs:4:14
|
LL | Foo::Bar.a;
| ^
| ^ unknown field
error: aborting due to previous error

View File

@ -2,19 +2,19 @@ error[E0609]: no field `b` on type `Foo`
--> $DIR/issue-24365.rs:10:22
|
LL | println!("{}", a.b);
| ^
| ^ unknown field
error[E0609]: no field `attr_name_idx` on type `&Attribute`
--> $DIR/issue-24365.rs:17:18
|
LL | let z = (&x).attr_name_idx;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ unknown field
error[E0609]: no field `attr_name_idx` on type `Attribute`
--> $DIR/issue-24365.rs:18:15
|
LL | let y = x.attr_name_idx;
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ unknown field
error: aborting due to 3 previous errors

View File

@ -2,7 +2,7 @@ error[E0609]: no field `trace` on type `&T`
--> $DIR/issue-31011.rs:3:17
|
LL | if $ctx.trace {
| ^^^^^
| ^^^^^ unknown field
...
LL | fn wrap<T>(context: &T) -> ()
| - type parameter 'T' declared here

View File

@ -8,13 +8,13 @@ error[E0609]: no field `lorem` on type `&'static str`
--> $DIR/issue-33525.rs:3:8
|
LL | "".lorem;
| ^^^^^
| ^^^^^ unknown field
error[E0609]: no field `ipsum` on type `&'static str`
--> $DIR/issue-33525.rs:4:8
|
LL | "".ipsum;
| ^^^^^
| ^^^^^ unknown field
error: aborting due to 3 previous errors

View File

@ -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`
| ^^ unknown field
|
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

View File

@ -18,7 +18,7 @@ error[E0609]: no field `f` on type `fn() {main}`
--> $DIR/cast-rfc0401.rs:65:18
|
LL | let _ = main.f as *const u32;
| ^
| ^ unknown field
error[E0605]: non-primitive cast: `*const u8` as `&u8`
--> $DIR/cast-rfc0401.rs:29:13

View File

@ -54,6 +54,8 @@ error[E0609]: no field `Self` on type `S`
|
LL | offset_of!(S, Self);
| ^^^^
|
= note: available fields are: `v`, `w`
error[E0616]: field `v` of struct `T` is private
--> $DIR/offset-of-self.rs:41:30
@ -66,6 +68,8 @@ error[E0609]: no field `self` on type `S`
|
LL | offset_of!(S, self);
| ^^^^
|
= note: available fields are: `v`, `w`
error[E0609]: no field `self` on type `u8`
--> $DIR/offset-of-self.rs:56:21

View File

@ -274,7 +274,7 @@ error[E0609]: no field `1e1` on type `(u8, u8)`
--> $DIR/float-field.rs:9:9
|
LL | s.1.1e1;
| ^^^
| ^^^ unknown field
error[E0609]: no field `0x1e1` on type `S`
--> $DIR/float-field.rs:24:7
@ -336,13 +336,13 @@ error[E0609]: no field `f32` on type `(u8, u8)`
--> $DIR/float-field.rs:44:9
|
LL | s.1.f32;
| ^^^
| ^^^ unknown field
error[E0609]: no field `1e1` on type `(u8, u8)`
--> $DIR/float-field.rs:46:7
|
LL | s.1.1e1f32;
| ^^^^^^^^
| ^^^^^^^^ unknown field
error: aborting due to 55 previous errors

View File

@ -2,7 +2,12 @@ error[E0560]: struct `Foo` has no field named `field2`
--> $DIR/rmeta_meta_main.rs:13:19
|
LL | let _ = Foo { field2: 42 };
| ^^^^^^ help: a field with a similar name exists: `field`
| ^^^^^^ unknown field
|
help: a field with a similar name exists
|
LL | let _ = Foo { field: 42 };
| ~~~~~
error: aborting due to previous error

View File

@ -2,7 +2,12 @@ error[E0560]: struct `A` has no field named `bar`
--> $DIR/struct-fields-hints-no-dupe.rs:10:9
|
LL | bar : 42,
| ^^^ help: a field with a similar name exists: `barr`
| ^^^ unknown field
|
help: a field with a similar name exists
|
LL | barr : 42,
| ~~~~
error: aborting due to previous error

View File

@ -2,7 +2,12 @@ error[E0560]: struct `A` has no field named `bar`
--> $DIR/struct-fields-hints.rs:10:9
|
LL | bar : 42,
| ^^^ help: a field with a similar name exists: `car`
| ^^^ unknown field
|
help: a field with a similar name exists
|
LL | car : 42,
| ~~~
error: aborting due to previous error

View File

@ -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`
| ^^^ unknown field
|
help: a field with a similar name exists
|
LL | let x = foo.bar;
| ~~~
error: aborting due to previous error

View File

@ -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`
| ^ unknown field
|
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

View File

@ -2,7 +2,12 @@ error[E0560]: struct `B` has no field named `aa`
--> $DIR/suggest-private-fields.rs:15:9
|
LL | aa: 20,
| ^^ help: a field with a similar name exists: `a`
| ^^ unknown field
|
help: a field with a similar name exists
|
LL | a: 20,
| ~
error[E0560]: struct `B` has no field named `bb`
--> $DIR/suggest-private-fields.rs:17:9
@ -16,13 +21,23 @@ error[E0560]: struct `A` has no field named `aa`
--> $DIR/suggest-private-fields.rs:22:9
|
LL | aa: 20,
| ^^ help: a field with a similar name exists: `a`
| ^^ unknown field
|
help: a field with a similar name exists
|
LL | a: 20,
| ~
error[E0560]: struct `A` has no field named `bb`
--> $DIR/suggest-private-fields.rs:24:9
|
LL | bb: 20,
| ^^ help: a field with a similar name exists: `b`
| ^^ unknown field
|
help: a field with a similar name exists
|
LL | b: 20,
| ~
error: aborting due to 4 previous errors

View File

@ -13,7 +13,7 @@ error[E0609]: no field `i` on type `fn() -> Foo {foo}`
--> $DIR/call-on-missing.rs:16:9
|
LL | foo.i;
| ^
| ^ unknown field
|
help: use parentheses to call this function
|
@ -62,7 +62,7 @@ LL | fn type_param<T: Fn() -> Foo>(t: T) {
| - type parameter 'T' declared here
...
LL | t.i;
| ^
| ^ unknown field
|
help: use parentheses to call this type parameter
|

View File

@ -4,7 +4,6 @@ error[E0609]: no field `c` on type `Foo`
LL | let _test = &fooer.c;
| ^ unknown field
|
= note: available fields are: `first`, `_second`, `_third`
help: one of the expressions' fields has a field of the same name
|
LL | let _test = &fooer.first.bar.c;
@ -16,7 +15,6 @@ error[E0609]: no field `test` on type `Foo`
LL | let _test2 = fooer.test;
| ^^^^ unknown field
|
= note: available fields are: `first`, `_second`, `_third`
help: one of the expressions' fields has a field of the same name
|
LL | let _test2 = fooer.first.bar.c.test;

View File

@ -2,7 +2,7 @@ error[E0609]: no field `opts` on type `*const Session`
--> $DIR/parenthesized-deref-suggestion.rs:7:30
|
LL | (sess as *const Session).opts;
| ^^^^
| ^^^^ unknown field
|
help: `(sess as *const Session)` is a raw pointer; try dereferencing it
|
@ -14,7 +14,8 @@ error[E0609]: no field `0` on type `[u32; 1]`
|
LL | (x as [u32; 1]).0;
| ----------------^
| |
| | |
| | unknown field
| help: instead of using tuple indexing, use array indexing: `(x as [u32; 1])[0]`
error: aborting due to 2 previous errors

View File

@ -4,7 +4,7 @@ error[E0609]: no field `cap` on type `S`
LL | dbg!(s.cap)
| ^^^ unknown field
|
= note: available fields are: `val`
= note: available field is: `val`
error: aborting due to previous error

View File

@ -0,0 +1,21 @@
// run-rustfix
#![allow(dead_code)]
use std::sync::Arc;
struct S {
long_name: (),
foo: (),
}
fn main() {
let x = Arc::new(S { long_name: (), foo: () });
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`
}

View File

@ -0,0 +1,21 @@
// run-rustfix
#![allow(dead_code)]
use std::sync::Arc;
struct S {
long_name: (),
foo: (),
}
fn main() {
let x = Arc::new(S { long_name: (), foo: () });
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`
}

View File

@ -0,0 +1,69 @@
error[E0609]: no field `longname` on type `Arc<S>`
--> $DIR/suggest-field-through-deref.rs:10:15
|
LL | let _ = x.longname;
| ^^^^^^^^ unknown field
|
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;
| ^^^^^^^^ unknown field
|
help: a field with a similar name exists
|
LL | let _ = y.long_name;
| ~~~~~~~~~
error[E0609]: no field `longname` on type `Option<Arc<S>>`
--> $DIR/suggest-field-through-deref.rs:14:15
|
LL | let _ = a.longname;
| ^^^^^^^^ unknown field
|
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;
| ^^^^^^^^^ unknown field
|
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;
| ^^^^^^^^ unknown field
|
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;
| ^^^^^^^^^ unknown field
|
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`.

View File

@ -25,7 +25,6 @@ error[E0609]: no field `field` on type `Thing`
LL | t.field;
| ^^^^^ unknown field
|
= note: available fields are: `a0`, `a1`, `a2`, `a3`, `a4` ... and 5 others
help: some of the expressions' fields have a field of the same name
|
LL | t.a0.field;

View File

@ -24,7 +24,12 @@ error[E0560]: struct `RGB` has no field named `c`
--> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:25
|
LL | let _ = RGB { r, g, c };
| ^ help: a field with a similar name exists: `b`
| ^ unknown field
|
help: a field with a similar name exists
|
LL | let _ = RGB { r, g, b };
| ~
error: aborting due to 3 previous errors

View File

@ -2,19 +2,19 @@ error[E0609]: no field `1` on type `(((),),)`
--> $DIR/index-invalid.rs:2:22
|
LL | let _ = (((),),).1.0;
| ^
| ^ unknown field
error[E0609]: no field `1` on type `((),)`
--> $DIR/index-invalid.rs:4:24
|
LL | let _ = (((),),).0.1;
| ^
| ^ unknown field
error[E0609]: no field `000` on type `(((),),)`
--> $DIR/index-invalid.rs:6:22
|
LL | let _ = (((),),).000.000;
| ^^^
| ^^^ unknown field
error: aborting due to 3 previous errors

View File

@ -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`
| ^ unknown field
|
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

View File

@ -2,13 +2,18 @@ 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`
| ^ unknown field
|
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
|
LL | tuple.2;
| ^
| ^ unknown field
error: aborting due to 2 previous errors

View File

@ -5,7 +5,7 @@ LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `x` on type `&Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:18
@ -14,7 +14,7 @@ LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `y` on type `&Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:25
@ -23,7 +23,7 @@ LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `y` on type `&Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:31:32
@ -32,7 +32,7 @@ LL | fn equals_ref<Point>(a: &Point, b: &Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `x` on type `Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:11
@ -41,7 +41,7 @@ LL | fn equals_val<Point>(a: Point, b: Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `x` on type `Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:18
@ -50,7 +50,7 @@ LL | fn equals_val<Point>(a: Point, b: Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `y` on type `Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:25
@ -59,7 +59,7 @@ LL | fn equals_val<Point>(a: Point, b: Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error[E0609]: no field `y` on type `Point`
--> $DIR/issue-52082-type-param-shadows-existing-type.rs:39:32
@ -68,7 +68,7 @@ LL | fn equals_val<Point>(a: Point, b: Point) -> bool
| ----- type parameter 'Point' declared here
LL | {
LL | a.x == b.x && a.y == b.y
| ^
| ^ unknown field
error: aborting due to 8 previous errors

View File

@ -3,7 +3,8 @@ error[E0609]: no field `0` on type `[{integer}; 5]`
|
LL | arr.0;
| ----^
| |
| | |
| | unknown field
| help: instead of using tuple indexing, use array indexing: `arr[0]`
error: aborting due to previous error

View File

@ -8,7 +8,7 @@ error[E0609]: no field `0` on type `&_`
--> $DIR/issue-65611.rs:59:36
|
LL | let x = buffer.last().unwrap().0.clone();
| ^
| ^ unknown field
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}`
--> $DIR/tuple-field.rs:12:15
|
LL | thing.bar.0;
| ^
| ^ unknown field
|
help: use parentheses to construct this tuple struct
|

View File

@ -8,7 +8,7 @@ error[E0609]: no field `nonexistent_field` on type `fn(_) -> Option<_> {Option::
--> $DIR/issue-96738.rs:3:10
|
LL | Some.nonexistent_field;
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ unknown field
error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error[E0609]: no field `homura` on type `&'static str`
--> $DIR/no-type-for-node-ice.rs:4:8
|
LL | "".homura[""];
| ^^^^^^
| ^^^^^^ unknown field
error: aborting due to previous error

View File

@ -2,13 +2,23 @@ error[E0560]: union `U` has no field named `principle`
--> $DIR/union-suggest-field.rs:13:17
|
LL | let u = U { principle: 0 };
| ^^^^^^^^^ help: a field with a similar name exists: `principal`
| ^^^^^^^^^ unknown field
|
help: a field with a similar name exists
|
LL | let u = U { principal: 0 };
| ~~~~~~~~~
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`
| ^^^^^^^^^^ unknown field
|
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

View File

@ -2,13 +2,23 @@ error[E0560]: union `U` has no field named `principle`
--> $DIR/union-suggest-field.rs:13:17
|
LL | let u = U { principle: 0 };
| ^^^^^^^^^ help: a field with a similar name exists: `principal`
| ^^^^^^^^^ unknown field
|
help: a field with a similar name exists
|
LL | let u = U { principal: 0 };
| ~~~~~~~~~
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`
| ^^^^^^^^^^ unknown field
|
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

View File

@ -3,7 +3,8 @@ error[E0609]: no field `f` on type `*const Rec`
|
LL | return p.f;
| --^
| |
| | |
| | unknown field
| help: `p` is a raw pointer; try dereferencing it: `(*p).f`
error: aborting due to previous error