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
Fix restriction of valid type vs free vars #7536
Fix restriction of valid type vs free vars #7536
Conversation
I'll review it tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bew Another great PR! Thank you!
Thanks for the review 😃 Just a note, since I currently can't check from the restriction method if the type is really a free var, this happens: # No free vars here, and Foo doesn't exist
def bar(a : Foo.class)
puts "Hello from Foo"
end
def bar(a : Int32.class)
puts "Hello from Int32"
end
# Before:
bar(Int32) # Error: undefined constant Foo
# After
bar(Int32) # "Hello from Int32" |
@bew Yes, I'm not sure. I think it's bad that if you don't invoke the method you don't get the "undefined constant Foo" either way. We should probably have a pass to compute those types before analyzing calls, and then in the restriction you would know whether a type is a free var or not. For now maybe this is fine. |
I think the new behavior is fine. I'm not sure how you could fix that, since you could have: def bar(a : Foo.class)
puts "Hello from Foo"
end
def bar(a : Int32.class) # restriction happens here when this method is processed
puts "Hello from Int32"
end
record Foo # define Foo here!
bar(Foo) # => "Hello from Foo" But maybe if there's first a pass to find all types, then a pass to process al methods that could do it, but there will be other problems I think, like macros that creates types / create methods / use |
@bew Macros run on the very first pass. This second pass would check the types of all method arguments to see if they exist (they must either be in scope or declared as free variables). I'm almost sure it's something doable. But it's tricky because methods are also added on the first pass (though they are not type-checked there, and this is why it's tricky to compute which one is stricter than the other). We should probably also have some context of But let's merge this for now. |
Yes that's what I was thinking, for example the |
* 'master' of github.com:crystal-lang/crystal: Change the font-weight used in Playground (crystal-lang#7552) Fix formatting absolute paths (crystal-lang#7560) Refactor IO::Syscall as IO::Evented (crystal-lang#7505) YAML: fix test checking serialization of slices for libyaml 0.2.2 (crystal-lang#7555) Let Array#sort only use `<=>`, and let `<=>` return `nil` for partial comparability (crystal-lang#6611) Update `to_s` and `inspect` to have similar signatures accross the stdlib (crystal-lang#7528) Fix restriction of valid type vs free vars (crystal-lang#7536) Rewrite macro spec without executing a shell command (crystal-lang#6962) Suggest `next` when trying to break from captured block (crystal-lang#7406) Fix GenericClassType vs GenericClassInstanceType restrictions (crystal-lang#7537) Add human readable formatting for numbers (crystal-lang#6314) Add command and args to execvp error message (crystal-lang#7511) Implement Set#add? method (crystal-lang#7495)
Fixes #6446
Compiler hacking is fun 🎉