Skip to content

Commit

Permalink
Rollup merge of rust-lang#57981 - Zoxc:fix-57979, r=nikomatsakis
Browse files Browse the repository at this point in the history
  • Loading branch information
Centril authored Feb 14, 2019
2 parents f47ec2a + cce2c89 commit b9efe60
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/librustc_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let Some(ref type_) = data.output {
// `-> Foo` syntax is essentially an associated type binding,
// so it is also allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| visit::walk_ty(this, type_));
self.with_impl_trait(None, |this| this.visit_ty(type_));
}
}
}
Expand Down
42 changes: 42 additions & 0 deletions src/test/ui/issues/issue-57979.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Regression test for #57979. This situation is meant to be an error.
// As noted in the issue thread, we decided to forbid nested impl
// trait of this kind:
//
// ```rust
// fn foo() -> impl Foo<impl Bar> { .. }
// ```
//
// Basically there are two hidden variables here, let's call them `X`
// and `Y`, and we must prove that:
//
// ```
// X: Foo<Y>
// Y: Bar
// ```
//
// However, the user is only giving us the return type `X`. It's true
// that in some cases, we can infer `Y` from `X`, because `X` only
// implements `Foo` for one type (and indeed the compiler does
// inference of this kind), but I do recall that we intended to forbid
// this -- in part because such inference is fragile, and there is not
// necessarily a way for the user to be more explicit should the
// inference fail (so you could get stuck with no way to port your
// code forward if, for example, more impls are added to an existing
// type).
//
// The same seems to apply in this situation. Here there are three impl traits, so we have
//
// ```
// X: IntoIterator<Item = Y>
// Y: Borrow<Data<Z>>
// Z: AsRef<[u8]>
// ```

use std::borrow::Borrow;

pub struct Data<TBody>(TBody);

pub fn collect(_: impl IntoIterator<Item = impl Borrow<Data<impl AsRef<[u8]>>>>) {
//~^ ERROR
unimplemented!()
}
17 changes: 17 additions & 0 deletions src/test/ui/issues/issue-57979.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/issue-57979.rs:39:61
|
LL | pub fn collect(_: impl IntoIterator<Item = impl Borrow<Data<impl AsRef<[u8]>>>>) {
| -----------------^^^^^^^^^^^^^^^^--
| | |
| | nested `impl Trait` here
| outer `impl Trait`

error[E0601]: `main` function not found in crate `issue_57979`
|
= note: consider adding a `main` function to `$DIR/issue-57979.rs`

error: aborting due to 2 previous errors

Some errors occurred: E0601, E0666.
For more information about an error, try `rustc --explain E0601`.

0 comments on commit b9efe60

Please sign in to comment.