Skip to content

Commit 8de9341

Browse files
committed
improve some diagnostics and bless some tests
1 parent de8a305 commit 8de9341

File tree

26 files changed

+129
-373
lines changed

26 files changed

+129
-373
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
141141
capture_clause,
142142
closure_node_id,
143143
None,
144-
block.span,
144+
e.span,
145145
hir::AsyncGeneratorKind::Block,
146146
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
147147
);
@@ -694,11 +694,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
694694
}
695695
}
696696
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
697-
let gen_future_span = self.mark_span_with_reason(
698-
DesugaringKind::Await,
699-
full_span,
700-
self.allow_gen_future.clone(),
701-
);
697+
let gen_future_span = self.mark_span_with_reason(DesugaringKind::Await, full_span, None);
702698
let expr = self.lower_expr_mut(expr);
703699
let expr_hir_id = expr.hir_id;
704700

compiler/rustc_ast_lowering/src/item.rs

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
8686
impl_trait_defs: Vec::new(),
8787
impl_trait_bounds: Vec::new(),
8888
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
89-
allow_gen_future: Some([sym::gen_future][..].into()),
9089
allow_into_future: Some([sym::into_future][..].into()),
9190
generics_def_id_map: Default::default(),
9291
};

compiler/rustc_ast_lowering/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ struct LoweringContext<'a, 'hir> {
137137
node_id_to_local_id: FxHashMap<NodeId, hir::ItemLocalId>,
138138

139139
allow_try_trait: Option<Lrc<[Symbol]>>,
140-
allow_gen_future: Option<Lrc<[Symbol]>>,
141140
allow_into_future: Option<Lrc<[Symbol]>>,
142141

143142
/// Mapping from generics `def_id`s to TAIT generics `def_id`s.

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts;
2121
use rustc_middle::ty::Region;
2222
use rustc_middle::ty::TypeVisitor;
2323
use rustc_middle::ty::{self, RegionVid, Ty};
24-
use rustc_span::symbol::{kw, sym, Ident};
24+
use rustc_span::symbol::{kw, Ident};
2525
use rustc_span::Span;
2626

2727
use crate::borrowck_errors;
@@ -514,8 +514,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
514514
span: *span,
515515
ty_err: match output_ty.kind() {
516516
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
517-
ty::Adt(def, _)
518-
if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
517+
ty::Generator(def, ..)
518+
if matches!(
519+
self.infcx.tcx.generator_kind(def),
520+
Some(hir::GeneratorKind::Async(_))
521+
) =>
519522
{
520523
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
521524
}

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
888888
return;
889889
}
890890

891+
// FIXME(swatinem): figure out how to handle async blocks not going through `from_generator`
891892
// `async` blocks get lowered to `std::future::from_generator(/* a closure */)`.
892893
let is_async_block = Some(callee) == tcx.lang_items().from_generator_fn();
893894
if is_async_block {

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ language_item_table! {
274274
PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None;
275275
PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None;
276276

277+
// FIXME(swatinem): remove `from_generator` and `get_context` once other non-rustc users are updated
277278
FromGenerator, sym::from_generator, from_generator_fn, Target::Fn, GenericRequirement::None;
278279
Context, sym::Context, context, Target::Struct, GenericRequirement::None;
279280
GetContext, sym::get_context, get_context_fn, Target::Fn, GenericRequirement::None;

compiler/rustc_hir_typeck/src/callee.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -302,9 +302,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
302302
let fn_decl_span = if hir.body(body).generator_kind
303303
== Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure))
304304
{
305-
// Actually need to unwrap a few more layers of HIR to get to
305+
// Actually need to unwrap one more layer of HIR to get to
306306
// the _real_ closure...
307-
let async_closure = hir.get_parent_node(hir.get_parent_node(parent_hir_id));
307+
let async_closure = hir.get_parent_node(parent_hir_id);
308308
if let hir::Node::Expr(hir::Expr {
309309
kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
310310
..

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

-8
Original file line numberDiff line numberDiff line change
@@ -1723,14 +1723,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17231723
let hir = self.tcx.hir();
17241724
let hir::Node::Expr(expr) = hir.get(hir_id) else { return false; };
17251725

1726-
// Skip over mentioning async lang item
1727-
if Some(def_id) == self.tcx.lang_items().from_generator_fn()
1728-
&& error.obligation.cause.span.desugaring_kind()
1729-
== Some(rustc_span::DesugaringKind::Async)
1730-
{
1731-
return false;
1732-
}
1733-
17341726
let Some(unsubstituted_pred) =
17351727
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
17361728
else { return false; };

compiler/rustc_middle/src/ty/print/pretty.rs

+11
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,17 @@ pub trait PrettyPrinter<'tcx>:
679679
}
680680
ty::Str => p!("str"),
681681
ty::Generator(did, substs, movability) => {
682+
// FIXME(swatinem): async constructs used to be pretty printed
683+
// as `impl Future` previously due to the `from_generator` wrapping.
684+
// lets special case this here for now to avoid churn in diagnostics.
685+
let generator_kind = self.tcx().generator_kind(did);
686+
if matches!(generator_kind, Some(hir::GeneratorKind::Async(..))) {
687+
let return_ty = substs.as_generator().return_ty();
688+
p!(write("impl Future<Output = {}>", return_ty));
689+
690+
return Ok(self);
691+
}
692+
682693
p!(write("["));
683694
match movability {
684695
hir::Movability::Movable => {}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+36-73
Original file line numberDiff line numberDiff line change
@@ -1890,12 +1890,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
18901890
//
18911891
// - `BuiltinDerivedObligation` with a generator witness (B)
18921892
// - `BuiltinDerivedObligation` with a generator (B)
1893-
// - `BuiltinDerivedObligation` with `std::future::GenFuture` (B)
18941893
// - `BuiltinDerivedObligation` with `impl std::future::Future` (B)
18951894
// - `BuiltinDerivedObligation` with `impl std::future::Future` (B)
18961895
// - `BuiltinDerivedObligation` with a generator witness (A)
18971896
// - `BuiltinDerivedObligation` with a generator (A)
1898-
// - `BuiltinDerivedObligation` with `std::future::GenFuture` (A)
18991897
// - `BuiltinDerivedObligation` with `impl std::future::Future` (A)
19001898
// - `BuiltinDerivedObligation` with `impl std::future::Future` (A)
19011899
// - `BindingObligation` with `impl_send (Send requirement)
@@ -2637,79 +2635,44 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
26372635
}
26382636
};
26392637

2640-
let from_generator = tcx.lang_items().from_generator_fn().unwrap();
2641-
26422638
// Don't print the tuple of capture types
2643-
'print: {
2644-
if !is_upvar_tys_infer_tuple {
2645-
let msg = format!("required because it appears within the type `{}`", ty);
2646-
match ty.kind() {
2647-
ty::Adt(def, _) => {
2648-
// `gen_future` is used in all async functions; it doesn't add any additional info.
2649-
if self.tcx.is_diagnostic_item(sym::gen_future, def.did()) {
2650-
break 'print;
2651-
}
2652-
match self.tcx.opt_item_ident(def.did()) {
2653-
Some(ident) => err.span_note(ident.span, &msg),
2654-
None => err.note(&msg),
2655-
}
2656-
}
2657-
ty::Opaque(def_id, _) => {
2658-
// Avoid printing the future from `core::future::from_generator`, it's not helpful
2659-
if tcx.parent(*def_id) == from_generator {
2660-
break 'print;
2661-
}
2662-
2663-
// If the previous type is `from_generator`, this is the future generated by the body of an async function.
2664-
// Avoid printing it twice (it was already printed in the `ty::Generator` arm below).
2665-
let is_future = tcx.ty_is_opaque_future(ty);
2666-
debug!(
2667-
?obligated_types,
2668-
?is_future,
2669-
"note_obligation_cause_code: check for async fn"
2670-
);
2671-
if is_future
2672-
&& obligated_types.last().map_or(false, |ty| match ty.kind() {
2673-
ty::Opaque(last_def_id, _) => {
2674-
tcx.parent(*last_def_id) == from_generator
2675-
}
2676-
_ => false,
2677-
})
2678-
{
2679-
break 'print;
2680-
}
2681-
err.span_note(self.tcx.def_span(def_id), &msg)
2682-
}
2683-
ty::GeneratorWitness(bound_tys) => {
2684-
use std::fmt::Write;
2685-
2686-
// FIXME: this is kind of an unusual format for rustc, can we make it more clear?
2687-
// Maybe we should just remove this note altogether?
2688-
// FIXME: only print types which don't meet the trait requirement
2689-
let mut msg =
2690-
"required because it captures the following types: ".to_owned();
2691-
for ty in bound_tys.skip_binder() {
2692-
write!(msg, "`{}`, ", ty).unwrap();
2693-
}
2694-
err.note(msg.trim_end_matches(", "))
2695-
}
2696-
ty::Generator(def_id, _, _) => {
2697-
let sp = self.tcx.def_span(def_id);
2698-
2699-
// Special-case this to say "async block" instead of `[static generator]`.
2700-
let kind = tcx.generator_kind(def_id).unwrap();
2701-
err.span_note(
2702-
sp,
2703-
&format!("required because it's used within this {}", kind),
2704-
)
2639+
if !is_upvar_tys_infer_tuple {
2640+
let msg = format!("required because it appears within the type `{}`", ty);
2641+
match ty.kind() {
2642+
ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) {
2643+
Some(ident) => err.span_note(ident.span, &msg),
2644+
None => err.note(&msg),
2645+
},
2646+
ty::Opaque(def_id, _) => err.span_note(self.tcx.def_span(def_id), &msg),
2647+
ty::GeneratorWitness(bound_tys) => {
2648+
use std::fmt::Write;
2649+
2650+
// FIXME: this is kind of an unusual format for rustc, can we make it more clear?
2651+
// Maybe we should just remove this note altogether?
2652+
// FIXME: only print types which don't meet the trait requirement
2653+
let mut msg =
2654+
"required because it captures the following types: ".to_owned();
2655+
for ty in bound_tys.skip_binder() {
2656+
write!(msg, "`{}`, ", ty).unwrap();
27052657
}
2706-
ty::Closure(def_id, _) => err.span_note(
2707-
self.tcx.def_span(def_id),
2708-
&format!("required because it's used within this closure"),
2709-
),
2710-
_ => err.note(&msg),
2711-
};
2712-
}
2658+
err.note(msg.trim_end_matches(", "))
2659+
}
2660+
ty::Generator(def_id, _, _) => {
2661+
let sp = self.tcx.def_span(def_id);
2662+
2663+
// Special-case this to say "async block" instead of `[static generator]`.
2664+
let kind = tcx.generator_kind(def_id).unwrap();
2665+
err.span_note(
2666+
sp,
2667+
&format!("required because it's used within this {}", kind),
2668+
)
2669+
}
2670+
ty::Closure(def_id, _) => err.span_note(
2671+
self.tcx.def_span(def_id),
2672+
&format!("required because it's used within this closure"),
2673+
),
2674+
_ => err.note(&msg),
2675+
};
27132676
}
27142677

27152678
obligated_types.push(ty);

src/test/codegen/async-fn-debug-awaitee-field.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ async fn async_fn_test() {
1515
// MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
1616
// CHECK: [[SUSPEND_STRUCT:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend0", scope: [[GEN]],
1717
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "__awaitee", scope: [[SUSPEND_STRUCT]], {{.*}}, baseType: [[AWAITEE_TYPE:![0-9]*]],
18-
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<async_fn_debug_awaitee_field::foo::{async_fn_env#0}>",
19-
// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "GenFuture<enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0> >",
18+
// NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "async_fn_debug_awaitee_field::foo::{async_fn_env#0}",
19+
// MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
2020

2121
fn main() {
2222
let _fn = async_fn_test();

src/test/run-make/coverage-reports/expected_show_coverage.async2.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
67| | }
7373
68| 2| }
7474
------------------
75-
| async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func::{closure#0}>>:
75+
| async2::executor::block_on::<async2::async_func::{closure#0}>:
7676
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
7777
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
7878
| 53| 1| use std::hint::unreachable_unchecked;
@@ -92,7 +92,7 @@
9292
| 67| | }
9393
| 68| 1| }
9494
------------------
95-
| async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func_just_println::{closure#0}>>:
95+
| async2::executor::block_on::<async2::async_func_just_println::{closure#0}>:
9696
| 51| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output {
9797
| 52| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) };
9898
| 53| 1| use std::hint::unreachable_unchecked;

src/test/ui/async-await/async-block-control-flow-static-semantics.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
error[E0267]: `break` inside of an `async` block
22
--> $DIR/async-block-control-flow-static-semantics.rs:32:9
33
|
4-
LL | async {
5-
| ___________-
4+
LL | / async {
65
LL | | break 0u8;
76
| | ^^^^^^^^^ cannot `break` inside of an `async` block
87
LL | | };
@@ -11,8 +10,7 @@ LL | | };
1110
error[E0267]: `break` inside of an `async` block
1211
--> $DIR/async-block-control-flow-static-semantics.rs:39:13
1312
|
14-
LL | async {
15-
| _______________-
13+
LL | / async {
1614
LL | | break 0u8;
1715
| | ^^^^^^^^^ cannot `break` inside of an `async` block
1816
LL | | };

src/test/ui/async-await/async-borrowck-escaping-block-error.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
2-
--> $DIR/async-borrowck-escaping-block-error.rs:6:20
2+
--> $DIR/async-borrowck-escaping-block-error.rs:6:14
33
|
44
LL | Box::new(async { x } )
5-
| ^^-^^
6-
| | |
7-
| | `x` is borrowed here
8-
| may outlive borrowed value `x`
5+
| ^^^^^^^^-^^
6+
| | |
7+
| | `x` is borrowed here
8+
| may outlive borrowed value `x`
99
|
1010
note: async block is returned here
1111
--> $DIR/async-borrowck-escaping-block-error.rs:6:5
@@ -18,13 +18,13 @@ LL | Box::new(async move { x } )
1818
| ++++
1919

2020
error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
21-
--> $DIR/async-borrowck-escaping-block-error.rs:11:11
21+
--> $DIR/async-borrowck-escaping-block-error.rs:11:5
2222
|
2323
LL | async { *x }
24-
| ^^--^^
25-
| | |
26-
| | `x` is borrowed here
27-
| may outlive borrowed value `x`
24+
| ^^^^^^^^--^^
25+
| | |
26+
| | `x` is borrowed here
27+
| may outlive borrowed value `x`
2828
|
2929
note: async block is returned here
3030
--> $DIR/async-borrowck-escaping-block-error.rs:11:5

src/test/ui/async-await/generator-desc.stderr

+12-21
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
error[E0308]: mismatched types
2-
--> $DIR/generator-desc.rs:10:25
2+
--> $DIR/generator-desc.rs:10:19
33
|
44
LL | fun(async {}, async {});
5-
| -- ^^
6-
| | |
7-
| | expected `async` block, found a different `async` block
8-
| | arguments to this function are incorrect
9-
| the expected `async` block
5+
| --- -------- ^^^^^^^^ expected `async` block, found a different `async` block
6+
| | |
7+
| | the expected `async` block
8+
| arguments to this function are incorrect
109
|
11-
= note: expected `async` block `[static generator@$DIR/generator-desc.rs:10:15: 10:17]`
12-
found `async` block `[static generator@$DIR/generator-desc.rs:10:25: 10:27]`
10+
= note: expected `async` block `impl Future<Output = ()>` (`async` block)
11+
found `async` block `impl Future<Output = ()>` (`async` block)
1312
note: function defined here
14-
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
13+
--> $DIR/generator-desc.rs:8:4
1514
|
16-
LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
17-
| ^^^^^^^^^^^^^^
15+
LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
16+
| ^^^ -----
1817

1918
error[E0308]: mismatched types
2019
--> $DIR/generator-desc.rs:12:16
@@ -53,16 +52,8 @@ LL | fun((async || {})(), (async || {})());
5352
| | the expected `async` closure body
5453
| arguments to this function are incorrect
5554
|
56-
::: $SRC_DIR/core/src/future/mod.rs:LL:COL
57-
|
58-
LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
59-
| -------------------------------
60-
| |
61-
| the expected opaque type
62-
| the found opaque type
63-
|
64-
= note: expected opaque type `impl Future<Output = ()>` (`async` closure body)
65-
found opaque type `impl Future<Output = ()>` (`async` closure body)
55+
= note: expected `async` closure body `impl Future<Output = ()>` (`async` closure body)
56+
found `async` closure body `impl Future<Output = ()>` (`async` closure body)
6657
note: function defined here
6758
--> $DIR/generator-desc.rs:8:4
6859
|

0 commit comments

Comments
 (0)