Skip to content

impl_trait_in_bindings doesn't interact well with associated types yet #69476

Description

@Boscop

I tried this code:

#![allow(incomplete_features)]
#![feature(impl_trait_in_bindings)]

trait Trait {
    type R;
}

struct A;
impl Trait for A {
    type R = i32;
}

static ARR: [impl Fn(<A as Trait>::R) -> <A as Trait>::R; 1] = [|x| x];

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9aed9cb362dff5db78c7af96567f31ee

I expected to see this happen: It compiles.

Instead, this happened: Compiler error:

error[E0277]: expected a `std::ops::Fn<(i32,)>` closure, found `impl std::ops::Fn<(<A as Trait>::R,)>`
  --> src/lib.rs:13:13
   |
13 | static ARR: [impl Fn(<A as Trait>::R) -> <A as Trait>::R; 1] = [|x| x];
   |             ^-------------------------------------------^^^^
   |             ||
   |             |required by `ARR::{{opaque}}#0`
   |             expected an `Fn<(i32,)>` closure, found `impl std::ops::Fn<(<A as Trait>::R,)>`
   |
   = help: the trait `std::ops::Fn<(i32,)>` is not implemented for `impl std::ops::Fn<(<A as Trait>::R,)>`

error: aborting due to previous error

Btw, this is an abbreviated version of a real world use case of using impl_trait_in_bindings.


Btw, this compiles: static ARR: [impl Fn(i32) -> i32; 1] = [|x| x];

But this static ARR: [impl Fn(i32) -> i32; 0] = []; gives another error:

error[E0391]: cycle detected when processing `ARR::{{opaque}}#0`
 --> src/lib.rs:4:14
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  |              ^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires borrow-checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which requires computing whether `[impl std::ops::Fn<(i32,)>; 0]` is freeze...
  = note: ...which requires evaluating trait selection obligation `[impl std::ops::Fn<(i32,)>; 0]: std::marker::Freeze`...
  = note: ...which again requires processing `ARR::{{opaque}}#0`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | / #![allow(incomplete_features)]
2 | | #![feature(impl_trait_in_bindings)]
3 | |
4 | | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | |__________________________________________^

error[E0391]: cycle detected when processing `ARR::{{opaque}}#0`
 --> src/lib.rs:4:14
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  |              ^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires borrow-checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which requires evaluating trait selection obligation `[impl std::ops::Fn<(i32,)>; 0]: std::marker::Sync`...
  = note: ...which again requires processing `ARR::{{opaque}}#0`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | / #![allow(incomplete_features)]
2 | | #![feature(impl_trait_in_bindings)]
3 | |
4 | | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | |__________________________________________^

error[E0391]: cycle detected when processing `ARR::{{opaque}}#0`
 --> src/lib.rs:4:14
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  |              ^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires borrow-checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const checking `ARR`...
 --> src/lib.rs:4:1
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which again requires processing `ARR::{{opaque}}#0`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | / #![allow(incomplete_features)]
2 | | #![feature(impl_trait_in_bindings)]
3 | |
4 | | static ARR: [impl Fn(i32) -> i32; 0] = [];
  | |__________________________________________^

error: could not find defining uses
 --> src/lib.rs:4:14
  |
4 | static ARR: [impl Fn(i32) -> i32; 0] = [];
  |              ^^^^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=09044d61d101f3ac849534eb9978e7c3

But IMO it should also compile.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)C-bugCategory: This is a bug.F-impl_trait_in_bindings`#![feature(impl_trait_in_bindings)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions