Skip to content

Regression in untyped getter macro #15556

Closed
@straight-shoota

Description

@straight-shoota

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions