Closed
Description
The following code types on Crystal 1.15 without explicit type annotations, but it's broken in master. This is a regression from #15548.
class Bar
class_getter default_foo do
"foo"
end
getter foo do
Bar.default_foo
end
end
Bar.new.foo # Error: can't infer the type of instance variable '@foo' of Bar
The change in the body of the block variant of class_getter
:
# Crystal 1.15
if (%value = @@{{var_name}}).nil?
@@{{var_name}} = {{yield}}
else
%value
end
# master (#15548)
if (%value = @@{{var_name}}).nil?
::Crystal.once(pointerof(@@__{{var_name}}_flag)) do
@@{{var_name}} = {{yield}} if @@{{var_name}}.nil?
end
@@{{var_name}}.not_nil!
else
%value
end
I suppose the additional logic there makes it impossible for the compiler to type the return value. Although, it's already a bit surprising that it managed to type it in the first place.
Interestingly, the assignment variant class_getter default_foo = "foo"
doesn't type in 1.15, despite being theoretically simpler and therefore should be easier to type 🤷
This error was discovered in test-ecosystem for https://github.com/Sija/backtracer.cr/blob/d461ca301b6ea7a8ac1ada673eacee098e248047/src/backtracer/backtrace/frame.cr#L18