Skip to content

Commit 84e88da

Browse files
committed
Rollup merge of rust-lang#57981 - Zoxc:fix-57979, r=nikomatsakis
Fix rust-lang#57730 cc rust-lang#57730 r? @cramertj
2 parents f058741 + cce2c89 commit 84e88da

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Diff for: src/librustc_passes/ast_validation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
616616
if let Some(ref type_) = data.output {
617617
// `-> Foo` syntax is essentially an associated type binding,
618618
// so it is also allowed to contain nested `impl Trait`.
619-
self.with_impl_trait(None, |this| visit::walk_ty(this, type_));
619+
self.with_impl_trait(None, |this| this.visit_ty(type_));
620620
}
621621
}
622622
}

Diff for: src/test/ui/issues/issue-57979.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Regression test for #57979. This situation is meant to be an error.
2+
// As noted in the issue thread, we decided to forbid nested impl
3+
// trait of this kind:
4+
//
5+
// ```rust
6+
// fn foo() -> impl Foo<impl Bar> { .. }
7+
// ```
8+
//
9+
// Basically there are two hidden variables here, let's call them `X`
10+
// and `Y`, and we must prove that:
11+
//
12+
// ```
13+
// X: Foo<Y>
14+
// Y: Bar
15+
// ```
16+
//
17+
// However, the user is only giving us the return type `X`. It's true
18+
// that in some cases, we can infer `Y` from `X`, because `X` only
19+
// implements `Foo` for one type (and indeed the compiler does
20+
// inference of this kind), but I do recall that we intended to forbid
21+
// this -- in part because such inference is fragile, and there is not
22+
// necessarily a way for the user to be more explicit should the
23+
// inference fail (so you could get stuck with no way to port your
24+
// code forward if, for example, more impls are added to an existing
25+
// type).
26+
//
27+
// The same seems to apply in this situation. Here there are three impl traits, so we have
28+
//
29+
// ```
30+
// X: IntoIterator<Item = Y>
31+
// Y: Borrow<Data<Z>>
32+
// Z: AsRef<[u8]>
33+
// ```
34+
35+
use std::borrow::Borrow;
36+
37+
pub struct Data<TBody>(TBody);
38+
39+
pub fn collect(_: impl IntoIterator<Item = impl Borrow<Data<impl AsRef<[u8]>>>>) {
40+
//~^ ERROR
41+
unimplemented!()
42+
}

Diff for: src/test/ui/issues/issue-57979.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0666]: nested `impl Trait` is not allowed
2+
--> $DIR/issue-57979.rs:39:61
3+
|
4+
LL | pub fn collect(_: impl IntoIterator<Item = impl Borrow<Data<impl AsRef<[u8]>>>>) {
5+
| -----------------^^^^^^^^^^^^^^^^--
6+
| | |
7+
| | nested `impl Trait` here
8+
| outer `impl Trait`
9+
10+
error[E0601]: `main` function not found in crate `issue_57979`
11+
|
12+
= note: consider adding a `main` function to `$DIR/issue-57979.rs`
13+
14+
error: aborting due to 2 previous errors
15+
16+
Some errors occurred: E0601, E0666.
17+
For more information about an error, try `rustc --explain E0601`.

0 commit comments

Comments
 (0)