Skip to content

Cannot derive Facet for recursive types #203

@mkeeter

Description

@mkeeter

It looks like we can't derive Facet for a recursive type:

#[derive(Facet)]
pub struct Recursive {
    next: Option<std::sync::Arc<Recursive>>,
}

This produces a long error message, which begins:

error[E0391]: cycle detected when simplifying constant for the type system `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE`
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
   |

...and continues:

The rest of the message
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires caching mir of `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE` for CTFE...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires elaborating drops for `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires simplifying constant for the type system `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::promoted[0]`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires const-evaluating + checking `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::promoted[0]`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires optimizing promoted MIR for `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires simplifying constant for the type system `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::{constant#0}`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires const-evaluating + checking `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::{constant#0}`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires simplifying constant for the type system `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::{constant#0}::{constant#0}`...
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
note: ...which requires const-evaluating + checking `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE::{constant#0}::{constant#0}`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/macros.rs:5:5
   |
5  |     TField::SHAPE
   |     ^^^^^^^^^^^^^
note: ...which requires simplifying constant for the type system `facet_core::_trait::impls::option_impl::<impl facet_core::_trait::Facet for core::option::Option<T>>::SHAPE`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/option_impl.rs:6:5
   |
6  |     const SHAPE: &'static Shape = &const {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `facet_core::_trait::impls::option_impl::<impl facet_core::_trait::Facet for core::option::Option<T>>::SHAPE`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/option_impl.rs:6:36
   |
6  |       const SHAPE: &'static Shape = &const {
   |  ____________________________________^
7  | |         Shape::builder()
8  | |             .id(ConstTypeId::of::<Self>())
9  | |             .layout(Layout::new::<Self>())
...  |
45 | |             .build()
46 | |     };
   | |_____^
note: ...which requires simplifying constant for the type system `facet_core::_trait::impls::option_impl::<impl facet_core::_trait::Facet for core::option::Option<T>>::SHAPE::{constant#0}`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/option_impl.rs:6:42
   |
6  |       const SHAPE: &'static Shape = &const {
   |  __________________________________________^
7  | |         Shape::builder()
8  | |             .id(ConstTypeId::of::<Self>())
9  | |             .layout(Layout::new::<Self>())
...  |
45 | |             .build()
46 | |     };
   | |_____^
note: ...which requires const-evaluating + checking `facet_core::_trait::impls::option_impl::<impl facet_core::_trait::Facet for core::option::Option<T>>::SHAPE::{constant#0}`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/option_impl.rs:12:24
   |
12 |                     .t(T::SHAPE)
   |                        ^^^^^^^^
note: ...which requires simplifying constant for the type system `facet_core::_trait::impls::smart_pointer_impls::<impl facet_core::_trait::Facet for alloc::sync::Arc<T>>::SHAPE`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/smart_pointer_impls.rs:10:5
   |
10 |     const SHAPE: &'static crate::Shape = &const {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `facet_core::_trait::impls::smart_pointer_impls::<impl facet_core::_trait::Facet for alloc::sync::Arc<T>>::SHAPE`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/smart_pointer_impls.rs:10:43
   |
10 |       const SHAPE: &'static crate::Shape = &const {
   |  ___________________________________________^
11 | |         crate::Shape::builder()
12 | |             .id(ConstTypeId::of::<Self>())
13 | |             .layout(Layout::new::<Self>())
...  |
40 | |             .build()
41 | |     };
   | |_____^
note: ...which requires simplifying constant for the type system `facet_core::_trait::impls::smart_pointer_impls::<impl facet_core::_trait::Facet for alloc::sync::Arc<T>>::SHAPE::{constant#0}`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/smart_pointer_impls.rs:10:49
   |
10 |       const SHAPE: &'static crate::Shape = &const {
   |  _________________________________________________^
11 | |         crate::Shape::builder()
12 | |             .id(ConstTypeId::of::<Self>())
13 | |             .layout(Layout::new::<Self>())
...  |
40 | |             .build()
41 | |     };
   | |_____^
note: ...which requires const-evaluating + checking `facet_core::_trait::impls::smart_pointer_impls::<impl facet_core::_trait::Facet for alloc::sync::Arc<T>>::SHAPE::{constant#0}`...
  --> /Users/mkeeter/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/facet-core-0.5.3/src/_trait/impls/smart_pointer_impls.rs:16:24
   |
16 |                     .t(T::SHAPE)
   |                        ^^^^^^^^
   = note: ...which again requires simplifying constant for the type system `shapes::<impl at fidget/src/shapes/mod.rs:24:10: 24:15>::SHAPE`, completing the cycle
note: cycle used when evaluating initializer of static `shapes::RECURSIVE_A_SHAPE`
  --> fidget/src/shapes/mod.rs:24:10
   |
24 | #[derive(Facet)]
   |          ^^^^^
   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
   = note: this error originates in the derive macro `Facet` (in Nightly builds, run with -Z macro-backtrace for more info)

On one hand, this makes sense – the SHAPE would have to be recursive – but on the other hand, this is an unfortunate limitation!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions