Skip to content

Pretty-print generators with their generator_kind #104931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
ccx: &ConstCx<'_, 'tcx>,
span: Span,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind());
let msg = format!("{}s are not allowed in {}s", self.0.descr(), ccx.const_kind());
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
ccx.tcx.sess.create_feature_err(
UnallowedOpInConstContext { span, msg },
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1514,9 +1514,9 @@ pub enum AsyncGeneratorKind {
impl fmt::Display for AsyncGeneratorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
AsyncGeneratorKind::Block => "`async` block",
AsyncGeneratorKind::Closure => "`async` closure body",
AsyncGeneratorKind::Fn => "`async fn` body",
AsyncGeneratorKind::Block => "async block",
AsyncGeneratorKind::Closure => "async closure body",
AsyncGeneratorKind::Fn => "async fn body",
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/generator_interior/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
} else {
let note = format!(
"the type is part of the {} because of this {}",
self.kind, yield_data.source
self.kind.descr(),
yield_data.source
);

self.fcx
Expand Down
25 changes: 10 additions & 15 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,25 +681,20 @@ pub trait PrettyPrinter<'tcx>:
}
ty::Str => p!("str"),
ty::Generator(did, substs, movability) => {
// FIXME(swatinem): async constructs used to be pretty printed
// as `impl Future` previously due to the `from_generator` wrapping.
// lets special case this here for now to avoid churn in diagnostics.
let generator_kind = self.tcx().generator_kind(did);
if matches!(generator_kind, Some(hir::GeneratorKind::Async(..))) {
let return_ty = substs.as_generator().return_ty();
p!(write("impl Future<Output = {}>", return_ty));

return Ok(self);
}

p!(write("["));
match movability {
hir::Movability::Movable => {}
hir::Movability::Static => p!("static "),
let generator_kind = self.tcx().generator_kind(did).unwrap();
let should_print_movability =
self.should_print_verbose() || generator_kind == hir::GeneratorKind::Gen;

if should_print_movability {
match movability {
hir::Movability::Movable => {}
hir::Movability::Static => p!("static "),
}
}

if !self.should_print_verbose() {
p!("generator");
p!(write("{}", generator_kind));
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let span = self.tcx().def_span(did);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2677,7 +2677,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let sp = self.tcx.def_span(def_id);

// Special-case this to say "async block" instead of `[static generator]`.
let kind = tcx.generator_kind(def_id).unwrap();
let kind = tcx.generator_kind(def_id).unwrap().descr();
err.span_note(
sp,
&format!("required because it's used within this {}", kind),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn return_targets_async_block_not_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
//~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}

async fn return_targets_async_block_not_async_fn() -> u8 {
Expand All @@ -24,7 +24,7 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
//~^ ERROR to be a future that resolves to `()`, but it resolves to `u8`
}

fn no_break_in_async_block() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ LL | |
LL | | }
| |_^ expected `u8`, found `()`

error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:26:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
Expand All @@ -45,13 +45,13 @@ LL | fn return_targets_async_block_not_fn() -> u8 {
| |
| implicitly returns `()` as its body has no tail or `return` expression

error[E0271]: expected `impl Future<Output = u8>` to be a future that resolves to `()`, but it resolves to `u8`
error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to be a future that resolves to `()`, but it resolves to `u8`
--> $DIR/async-block-control-flow-static-semantics.rs:17:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast from `impl Future<Output = u8>` to the object type `dyn Future<Output = ()>`
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/async-await/generator-desc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ LL | fun(async {}, async {});
| | arguments to this function are incorrect
| the expected `async` block
|
= note: expected `async` block `impl Future<Output = ()>` (`async` block)
found `async` block `impl Future<Output = ()>` (`async` block)
= note: expected `async` block `[async block@$DIR/generator-desc.rs:10:9: 10:17]`
found `async` block `[async block@$DIR/generator-desc.rs:10:19: 10:27]`
note: function defined here
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
Expand Down Expand Up @@ -53,8 +53,8 @@ LL | fun((async || {})(), (async || {})());
| | the expected `async` closure body
| arguments to this function are incorrect
|
= note: expected `async` closure body `impl Future<Output = ()>` (`async` closure body)
found `async` closure body `impl Future<Output = ()>` (`async` closure body)
= note: expected `async` closure body `[async closure body@$DIR/generator-desc.rs:14:19: 14:21]`
found `async` closure body `[async closure body@$DIR/generator-desc.rs:14:36: 14:38]`
note: function defined here
--> $DIR/generator-desc.rs:8:4
|
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issue-67252-unnamed-future.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | | AFuture.await;
LL | | });
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*mut ()`
= help: within `[async block@$DIR/issue-67252-unnamed-future.rs:18:11: 21:6]`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-67252-unnamed-future.rs:20:16
|
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/issue-86507.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
= note: required for the cast from `impl Future<Output = ()>` to the object type `dyn Future<Output = ()> + Send`
= note: required for the cast from `[async block@$DIR/issue-86507.rs:18:17: 20:18]` to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting this bound
|
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LL | | bar(Foo(std::ptr::null())).await;
LL | | })
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `*const u8`
= help: within `[async block@$DIR/issue-65436-raw-ptr-not-send.rs:16:17: 19:6]`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:18:35
|
Expand Down
22 changes: 11 additions & 11 deletions src/test/ui/chalkify/bugs/async.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0277]: `impl Future<Output = u32>` is not a future
error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
Expand All @@ -7,18 +7,18 @@ LL | | x
LL | | }
| | ^
| | |
| |_`impl Future<Output = u32>` is not a future
| |_`[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
| required by a bound introduced by this call
|
= help: the trait `Future` is not implemented for `impl Future<Output = u32>`
= note: impl Future<Output = u32> must be a future or must implement `IntoFuture` to be awaited
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
= note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
| ^^^^^^^^^^^^^^^^^^ required by this bound in `identity_future`

error[E0277]: the size for values of type `<impl Future<Output = u32> as Future>::Output` cannot be known at compilation time
error[E0277]: the size for values of type `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output` cannot be known at compilation time
--> $DIR/async.rs:7:29
|
LL | async fn foo(x: u32) -> u32 {
Expand All @@ -27,23 +27,23 @@ LL | | x
LL | | }
| |_^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `<impl Future<Output = u32> as Future>::Output`
= help: the trait `Sized` is not implemented for `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output`
note: required by a bound in `identity_future`
--> $SRC_DIR/core/src/future/mod.rs:LL:COL
|
LL | pub const fn identity_future<O, Fut: Future<Output = O>>(f: Fut) -> Fut {
| ^ required by this bound in `identity_future`

error[E0277]: `impl Future<Output = u32>` is not a future
error[E0277]: `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
--> $DIR/async.rs:7:25
|
LL | async fn foo(x: u32) -> u32 {
| ^^^ `impl Future<Output = u32>` is not a future
| ^^^ `[async fn body@$DIR/async.rs:7:29: 9:2]` is not a future
|
= help: the trait `Future` is not implemented for `impl Future<Output = u32>`
= note: impl Future<Output = u32> must be a future or must implement `IntoFuture` to be awaited
= help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:7:29: 9:2]`
= note: [async fn body@$DIR/async.rs:7:29: 9:2] must be a future or must implement `IntoFuture` to be awaited

error[E0280]: the requirement `<impl Future<Output = u32> as Future>::Output == u32` is not satisfied
error[E0280]: the requirement `<[async fn body@$DIR/async.rs:7:29: 9:2] as Future>::Output == u32` is not satisfied
--> $DIR/async.rs:7:25
|
LL | async fn foo(x: u32) -> u32 {
Expand Down
27 changes: 13 additions & 14 deletions src/test/ui/generator/clone-impl-async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,42 @@ fn main() {
drop(non_clone);
};
check_copy(&inner_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let non_clone = NonClone;
let outer_non_clone = async move {
drop(non_clone);
};
check_copy(&outer_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let maybe_copy_clone = async move {};
check_copy(&maybe_copy_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let inner_non_clone_fn = the_inner_non_clone_fn();
check_copy(&inner_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&inner_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let outer_non_clone_fn = the_outer_non_clone_fn(NonClone);
check_copy(&outer_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&outer_non_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied

let maybe_copy_clone_fn = the_maybe_copy_clone_fn();
check_copy(&maybe_copy_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Copy` is not satisfied
//~^ ERROR : Copy` is not satisfied
check_clone(&maybe_copy_clone_fn);
//~^ ERROR the trait bound `impl Future<Output = ()>: Clone` is not satisfied
//~^ ERROR : Clone` is not satisfied
}

async fn the_inner_non_clone_fn() {
Expand All @@ -64,8 +64,7 @@ async fn the_outer_non_clone_fn(non_clone: NonClone) {
drop(non_clone);
}

async fn the_maybe_copy_clone_fn() {
}
async fn the_maybe_copy_clone_fn() {}

fn check_copy<T: Copy>(_x: &T) {}
fn check_clone<T: Clone>(_x: &T) {}
Loading