Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using constants where a type is expected #11371

Open
HertzDevil opened this issue Oct 27, 2021 · 3 comments
Open

Using constants where a type is expected #11371

HertzDevil opened this issue Oct 27, 2021 · 3 comments

Comments

@HertzDevil
Copy link
Contributor

Because types and constants are both named by Path nodes, the latter can be used in certain contexts that normally expect a type. In those cases the constant behaves as if it is the type of its initializer:

X = 1

fn : -> X
"".is_a?(X)
"".as(X)
sizeof(X)

# the above are equivalent to:

fn : -> Int32
"".is_a?(Int32)
"".as(Int32)
sizeof(Int32)

# but the following are syntax errors:

fn : -> 1
"".is_a?(1)
"".as(1)
sizeof(1)

I think we should disallow such uses of constant Paths.

One problem is that the literal expander transforms while expressions into is_a?:

case ""
when Int32
when X
end

# the above is equivalent to:

__temp = ""
if __temp.is_a?(Int32)
elsif __temp.is_a?(X)
end

Afterwards Crystal::MainVisitor transforms __temp.is_a?(X) into X === __temp, because the literal expander doesn't know which Paths are constants and which are types. So a workaround is needed if we want to phase out this usage of is_a?.

@straight-shoota
Copy link
Member

Maybe the literal expander could just create a call to === directly? Class#=== delegates to is_a? anyways.

@asterite
Copy link
Member

But === doesn’t do type filtering. is_a? is special

@straight-shoota
Copy link
Member

straight-shoota commented Oct 27, 2021

Yeah, that was just a brain dump. I was previously thinking about the literal expander using a faux method to tell the main visitor that it's supposed to turn it into is_a for types and === for constants.

But I suppose we could just add a flag to IsA which signals that it was created as condition of a when branch and the main visitor should not error on a constant and instead transform to ===.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants