Why does Struct work but Type not work here?

pub enum Foo<T> {
  Cat(T),
  Dog(),
}

pub struct Good (Rc<Foo<Good>>);
type Bad = Rc<Foo<Bad>>

with type, there seems to be some type of cyclic issue; but there is none with struct

What’s going on here? [My intuition is that I expect both to fail or both to work.]

A struct defines a new type, and you would have a cyclic issue determining the size if the nesting were used by value. In this case, behind the Rc indirection, it’s fine.

A type alias behaves exactly as if you had copied the right hand side everywhere the alias is used. So Bad = Rc<Foo<Bad>> = Rc<Foo<Rc<Foo<Bad>>>> = Rc<Foo<Rc<Foo<Rc<Foo<Bad>>>>>> = …

3 Likes

It might be possible if this allowed Self, like:

pub struct Good (Rc<Foo<Self>>);
type Bad = Rc<Foo<Self>>;
error[E0411]: cannot find type `Self` in this scope
 --> src/lib.rs:9:19
  |
9 | type Bad = Rc<Foo<Self>>;
  |                   ^^^^ `Self` is only available in impls, traits, and type definitions

Here “type definitions” means things like struct or enum, not a type alias. But I think it could be possible to let this work…

Although I suppose you might just call Self a contextual type alias, in which case it’s not much different than the original problem after all.

1 Like

@cuviper : Thanks! This is amazingly clear (I was expecting gnarly details about the Rust type checker.)

1 Like

That’s basically how it works. There needs to be a real named item to stop the infinite type name you mentioned earlier.