Skip to content

Commit

Permalink
Rollup merge of #68884 - Zoxc:gen-type, r=nikomatsakis
Browse files Browse the repository at this point in the history
Make the `type_of` return a generic type for generators

Fixes #67651.

r? @nikomatsakis
  • Loading branch information
Centril committed Mar 24, 2020
2 parents 342c5f3 + 47a84f2 commit a130954
Show file tree
Hide file tree
Showing 19 changed files with 231 additions and 95 deletions.
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);
}

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

0 comments on commit a130954

Please sign in to comment.