Skip to content

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

Closed
@Boscop

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.

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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions