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

Check impl trait substs when checking for recursive types #64038

Merged
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
6 changes: 4 additions & 2 deletions src/librustc/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
substs: SubstsRef<'tcx>,
) -> Option<Ty<'tcx>> {
if self.found_recursion {
None
} else if self.seen_opaque_tys.insert(def_id) {
return None;
}
let substs = substs.fold_with(self);
if self.seen_opaque_tys.insert(def_id) {
let generic_ty = self.tcx.type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx, substs);
let expanded_ty = self.fold_ty(concrete_ty);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
tcx.sess, span, E0733,
"recursion in an `async fn` requires boxing",
)
.span_label(span, "an `async fn` cannot invoke itself directly")
.note("a recursive `async fn` must be rewritten to return a boxed future.")
.span_label(span, "recursive `async fn`")
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
.emit();
} else {
let mut err = struct_span_err!(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// edition:2018
// Test that impl trait does not allow creating recursive types that are
// otherwise forbidden when using `async` and `await`.

async fn rec_1() { //~ ERROR recursion in an `async fn`
rec_2().await;
}

async fn rec_2() { //~ ERROR recursion in an `async fn`
rec_1().await;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
|
LL | async fn rec_1() {
| ^ recursive `async fn`
Copy link
Member

Choose a reason for hiding this comment

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

It'd be nice if we could point out where the recursion is coming from, but that can be left for a follow up diagnostics improvement.

|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.

error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
|
LL | async fn rec_2() {
| ^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0733`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/recursive-async-impl-trait-type.rs:5:40
|
LL | async fn recursive_async_function() -> () {
| ^^ an `async fn` cannot invoke itself directly
| ^^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed future.
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Test that impl trait does not allow creating recursive types that are
// otherwise forbidden. Even when there's an opaque type in another crate
// hiding this.

fn id<T>(t: T) -> impl Sized { t }

fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
id(recursive_id2())
}

fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
id(recursive_id())
}

fn wrap<T>(t: T) -> impl Sized { (t,) }

fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
wrap(recursive_wrap2())
}

fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
wrap(recursive_wrap())
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22
|
LL | fn recursive_id() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: type resolves to itself

error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23
|
LL | fn recursive_id2() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: type resolves to itself

error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24
|
LL | fn recursive_wrap() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `((impl Sized,),)`

error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
|
LL | fn recursive_wrap2() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `((impl Sized,),)`

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0720`.