Also note for fields

This commit is contained in:
Michael Goulet 2024-10-12 06:11:11 -04:00
parent 5e8820caaa
commit c8b71ef3dd
4 changed files with 53 additions and 9 deletions

View File

@ -10,7 +10,8 @@
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_errors::{ use rustc_errors::{
Applicability, Diag, ErrorGuaranteed, StashKey, Subdiagnostic, pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, Subdiagnostic, pluralize,
struct_span_code_err,
}; };
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -2757,12 +2758,25 @@ fn suggest_await_on_field_access(
field_ident.span, field_ident.span,
"field not available in `impl Future`, but it is available in its `Output`", "field not available in `impl Future`, but it is available in its `Output`",
); );
err.span_suggestion_verbose( match self.tcx.coroutine_kind(self.body_id) {
base.span.shrink_to_hi(), Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
"consider `await`ing on the `Future` and access the field of its `Output`", err.span_suggestion_verbose(
".await", base.span.shrink_to_hi(),
Applicability::MaybeIncorrect, "consider `await`ing on the `Future` to access the field",
); ".await",
Applicability::MaybeIncorrect,
);
}
_ => {
let mut span: MultiSpan = base.span.into();
span.push_span_label(self.tcx.def_span(self.body_id), "this is not `async`");
err.span_note(
span,
"this implements `Future` and its output type has the field, \
but the future cannot be awaited in a synchronous function",
);
}
}
} }
fn ban_nonexisting_field( fn ban_nonexisting_field(

View File

@ -0,0 +1,13 @@
//@ edition: 2021
struct S {
field: (),
}
async fn foo() -> S { todo!() }
fn main() -> Result<(), ()> {
foo().field;
//~^ ERROR no field `field` on type `impl Future<Output = S>`
Ok(())
}

View File

@ -0,0 +1,17 @@
error[E0609]: no field `field` on type `impl Future<Output = S>`
--> $DIR/field-in-sync.rs:10:11
|
LL | foo().field;
| ^^^^^ field not available in `impl Future`, but it is available in its `Output`
|
note: this implements `Future` and its output type has the field, but the future cannot be awaited in a synchronous function
--> $DIR/field-in-sync.rs:10:5
|
LL | fn main() -> Result<(), ()> {
| --------------------------- this is not `async`
LL | foo().field;
| ^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0609`.

View File

@ -28,7 +28,7 @@ error[E0609]: no field `0` on type `impl Future<Output = Tuple>`
LL | let _: i32 = tuple().0; LL | let _: i32 = tuple().0;
| ^ field not available in `impl Future`, but it is available in its `Output` | ^ field not available in `impl Future`, but it is available in its `Output`
| |
help: consider `await`ing on the `Future` and access the field of its `Output` help: consider `await`ing on the `Future` to access the field
| |
LL | let _: i32 = tuple().await.0; LL | let _: i32 = tuple().await.0;
| ++++++ | ++++++
@ -39,7 +39,7 @@ error[E0609]: no field `a` on type `impl Future<Output = Struct>`
LL | let _: i32 = struct_().a; LL | let _: i32 = struct_().a;
| ^ field not available in `impl Future`, but it is available in its `Output` | ^ field not available in `impl Future`, but it is available in its `Output`
| |
help: consider `await`ing on the `Future` and access the field of its `Output` help: consider `await`ing on the `Future` to access the field
| |
LL | let _: i32 = struct_().await.a; LL | let _: i32 = struct_().await.a;
| ++++++ | ++++++