Skip to content
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

Make the type_of return a generic type for generators #68884

Merged
merged 2 commits into from
Mar 24, 2020
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
3 changes: 2 additions & 1 deletion src/librustc_mir_build/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
let arguments = implicit_argument.into_iter().chain(explicit_arguments);

let (yield_ty, return_ty) = if body.generator_kind.is_some() {
let gen_sig = match ty.kind {
let gen_ty = tcx.body_tables(body_id).node_type(id);
let gen_sig = match gen_ty.kind {
ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
_ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
};
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_typeck/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
Node::Field(field) => icx.to_ty(&field.ty),

Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
if gen.is_some() {
return tcx.typeck_tables_of(def_id).node_type(hir_id);
}
Comment on lines -191 to -193
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's funny, I almost did the opposite last week, trying to make #69968 work.
(It was a bad idea and the solution was to fix the actual code that couldn't handle unsubstitued closure types)


let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_closure(def_id, substs)
if let Some(movability) = gen {
tcx.mk_generator(def_id, substs, movability)
} else {
tcx.mk_closure(def_id, substs)
}
}

Node::AnonConst(_) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,6 @@ LL | | break 0u8;
LL | | };
| |_________- enclosing `async` block

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

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:22:58
|
Expand All @@ -55,6 +39,22 @@ LL | let _: &dyn Future<Output = ()> = &block;
|
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

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

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:18:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected `()`, found `u8`
|
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:48:44
|
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/async-await/async-error-span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use std::future::Future;

fn get_future() -> impl Future<Output = ()> {
//~^ ERROR the trait bound `(): std::future::Future` is not satisfied
panic!()
}

Expand Down
20 changes: 16 additions & 4 deletions src/test/ui/async-await/async-error-span.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
error[E0277]: the trait bound `(): std::future::Future` is not satisfied
--> $DIR/async-error-span.rs:7:20
|
LL | fn get_future() -> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
LL |
LL | panic!()
| -------- this returned value is of type `!`
|
= note: the return type of a function must have a statically known size

error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/async-error-span.rs:12:9
--> $DIR/async-error-span.rs:13:9
|
LL | let a;
| ^ cannot infer type
|
note: the type is part of the `async fn` body because of this `await`
--> $DIR/async-error-span.rs:13:5
--> $DIR/async-error-span.rs:14:5
|
LL | get_future().await;
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0698`.
Some errors have detailed explanations: E0277, E0698.
For more information about an error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn foo10() -> Result<(), ()> {
fn foo11() -> Result<(), ()> {
let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
//~^ ERROR incorrect use of `await`
//~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
Ok(())
}
fn foo12() -> Result<(), ()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,63 +71,63 @@ LL | let _ = await bar()?;
| ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:68:14
--> $DIR/incorrect-syntax-suggestions.rs:69:14
|
LL | let _ = (await bar())?;
| ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:73:24
--> $DIR/incorrect-syntax-suggestions.rs:74:24
|
LL | let _ = bar().await();
| ^^ help: `await` is not a method call, remove the parentheses

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:78:24
--> $DIR/incorrect-syntax-suggestions.rs:79:24
|
LL | let _ = bar().await()?;
| ^^ help: `await` is not a method call, remove the parentheses

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:106:13
--> $DIR/incorrect-syntax-suggestions.rs:107:13
|
LL | let _ = await!(bar());
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:110:13
--> $DIR/incorrect-syntax-suggestions.rs:111:13
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:115:17
--> $DIR/incorrect-syntax-suggestions.rs:116:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:123:17
--> $DIR/incorrect-syntax-suggestions.rs:124:17
|
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`

error: expected expression, found `=>`
--> $DIR/incorrect-syntax-suggestions.rs:131:25
--> $DIR/incorrect-syntax-suggestions.rs:132:25
|
LL | match await { await => () }
| ----- ^^ expected expression
| |
| while parsing this incorrect await expression

error: incorrect use of `await`
--> $DIR/incorrect-syntax-suggestions.rs:131:11
--> $DIR/incorrect-syntax-suggestions.rs:132:11
|
LL | match await { await => () }
| ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`

error: expected one of `.`, `?`, `{`, or an operator, found `}`
--> $DIR/incorrect-syntax-suggestions.rs:134:1
--> $DIR/incorrect-syntax-suggestions.rs:135:1
|
LL | match await { await => () }
| ----- - expected one of `.`, `?`, `{`, or an operator
Expand Down Expand Up @@ -162,71 +162,71 @@ LL | let _ = await bar()?;
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:68:14
--> $DIR/incorrect-syntax-suggestions.rs:69:14
|
LL | fn foo12() -> Result<(), ()> {
| ----- this is not `async`
LL | let _ = (await bar())?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:73:13
--> $DIR/incorrect-syntax-suggestions.rs:74:13
|
LL | fn foo13() -> Result<(), ()> {
| ----- this is not `async`
LL | let _ = bar().await();
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:78:13
--> $DIR/incorrect-syntax-suggestions.rs:79:13
|
LL | fn foo14() -> Result<(), ()> {
| ----- this is not `async`
LL | let _ = bar().await()?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:83:13
--> $DIR/incorrect-syntax-suggestions.rs:84:13
|
LL | fn foo15() -> Result<(), ()> {
| ----- this is not `async`
LL | let _ = bar().await;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:87:13
--> $DIR/incorrect-syntax-suggestions.rs:88:13
|
LL | fn foo16() -> Result<(), ()> {
| ----- this is not `async`
LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:92:17
--> $DIR/incorrect-syntax-suggestions.rs:93:17
|
LL | fn foo() -> Result<(), ()> {
| --- this is not `async`
LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:99:17
--> $DIR/incorrect-syntax-suggestions.rs:100:17
|
LL | let foo = || {
| -- this is not `async`
LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:115:17
--> $DIR/incorrect-syntax-suggestions.rs:116:17
|
LL | fn foo() -> Result<(), ()> {
| --- this is not `async`
LL | let _ = await!(bar())?;
| ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks

error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:123:17
--> $DIR/incorrect-syntax-suggestions.rs:124:17
|
LL | let foo = || {
| -- this is not `async`
Expand All @@ -242,7 +242,16 @@ LL | let _ = await bar()?;
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
= note: required by `std::ops::Try::into_result`

error: aborting due to 35 previous errors
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
--> $DIR/incorrect-syntax-suggestions.rs:63:19
|
LL | let _ = await bar()?;
| ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
|
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
= note: required by `std::ops::Try::into_result`

error: aborting due to 36 previous errors

Some errors have detailed explanations: E0277, E0728.
For more information about an error, try `rustc --explain E0277`.
20 changes: 20 additions & 0 deletions src/test/ui/async-await/issue-67651.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// edition:2018

trait From {
fn from();
}

impl From for () {
fn from() {}
}

impl From for () {
//~^ ERROR conflicting implementations of trait
fn from() {}
}

fn bar() -> impl core::future::Future<Output = ()> {
async move { From::from() }
}

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/async-await/issue-67651.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0119]: conflicting implementations of trait `From` for type `()`:
--> $DIR/issue-67651.rs:11:1
|
LL | impl From for () {
| ---------------- first implementation here
...
LL | impl From for () {
| ^^^^^^^^^^^^^^^^ conflicting implementation for `()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
13 changes: 0 additions & 13 deletions src/test/ui/async-await/issues/issue-63388-2.nll.stderr

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/async-await/issues/issue-63388-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ trait Foo {}

impl Xyz {
async fn do_sth<'a>(
foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer
foo: &dyn Foo, bar: &'a dyn Foo
) -> &dyn Foo //~ ERROR missing lifetime specifier
{
foo
Expand Down
17 changes: 1 addition & 16 deletions src/test/ui/async-await/issues/issue-63388-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,6 @@ LL | ) -> &dyn Foo
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`

error: cannot infer an appropriate lifetime
--> $DIR/issue-63388-2.rs:11:9
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^^^ ...but this borrow...
...
LL | foo
| --- this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14
--> $DIR/issue-63388-2.rs:11:14
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^

error: aborting due to 2 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0106`.
1 change: 1 addition & 0 deletions src/test/ui/async-await/issues/issue-65159.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
{
Ok(())
//~^ type annotations needed
}

fn main() { }
11 changes: 9 additions & 2 deletions src/test/ui/async-await/issues/issue-65159.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1
LL | async fn copy() -> Result<()>
| ^^^^^^^^^^ expected 2 type arguments

error: aborting due to previous error
error[E0282]: type annotations needed
--> $DIR/issue-65159.rs:7:5
|
LL | Ok(())
| ^^ cannot infer type for type parameter `E` declared on the enum `Result`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0107`.
Some errors have detailed explanations: E0107, E0282.
For more information about an error, try `rustc --explain E0107`.
Loading