crystal icon indicating copy to clipboard operation
crystal copied to clipboard

False positive for "Recursive struct detected"

Open jgaskins opened this issue 1 year ago • 2 comments

The compiler thinks it detects a recursive struct with this code:

abstract struct Content
end

record Text < Content
record Image < Content
record Result < Content, content : Text | Image

The Result type can't hold an instance of itself, though, even via cyclical recursion. It is intended to be able to hold an instance of one of the other types, but since they can't hold a Result (and nothing else in this code can, for that matter), there's no way for this to actually be a recursive struct.

The recursive struct detection appears to be over-extrapolating from the Text | Image union type to all Content subtypes.

jgaskins avatar May 30 '24 00:05 jgaskins

Yeah, this is essentially #2661.

As a workaround you can introduce a named type for Text | Image, i.e. without Content. In contrast to an unnamed union this won't be unified then.

abstract struct Content
end

abstract struct TextOrImageContent < Content
end

record Text < TextOrImageContent
record Image < TextOrImageContent
record Result < Content, content : Text | Image

As you can see, the union Text | Image even works when there's a closer type that it can unify as.

straight-shoota avatar May 30 '24 13:05 straight-shoota

Well, it's still unified, but we introduced an intermediary type to unify to (TextOrImageContent+), instead of the top one (Content+) :)

ysbaddaden avatar May 31 '24 09:05 ysbaddaden