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

Interpreter: explicit return conflicts with specified return type #12178

Closed
cyangle opened this issue Jul 1, 2022 · 4 comments · Fixed by #12179
Closed

Interpreter: explicit return conflicts with specified return type #12178

cyangle opened this issue Jul 1, 2022 · 4 comments · Fixed by #12179
Assignees
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:interpreter

Comments

@cyangle
Copy link
Contributor

cyangle commented Jul 1, 2022

Bug Report

Given code below:

def foo : Nil
  return 1
end

puts foo

Running it with the interpreter produces an error:

$ cr i local/return_test.cr 
Using compiled compiler at /home/chao/git/personal/crystal/.build/crystal
In local/return_test.cr:5:6

 5 | puts foo
          ^--



In local/return_test.cr:5:6

 5 | puts foo
          ^--
Error: compiling foo


In local/return_test.cr:2:3

 2 | return 1
     ^
Error: BUG: missing upcast_distinct from Int32 to Nil (Crystal::IntegerType to Crystal::NilType)

There's no problem running it in compiled mode.
System info:

$ cr -v
Using compiled compiler at /home/chao/git/personal/crystal/.build/crystal
Crystal 1.5.0-dev [b7f3f102f] (2022-06-30)

LLVM: 10.0.0
Default target: x86_64-pc-linux-gnu

OS: Ubuntu 20.04

Related to #12177

@asterite @straight-shoota

@cyangle cyangle added the kind:bug A bug in the code. Does not apply to documentation, specs, etc. label Jul 1, 2022
@asterite asterite self-assigned this Jul 1, 2022
@straight-shoota
Copy link
Member

I'm wondering if an explicit return value shouldn't be a semantic error. return 1 obviously conflicts with Nil restriction. IMO this code should be invalid.

We should fix this in the interpreter of course for now.

@cyangle
Copy link
Contributor Author

cyangle commented Jul 3, 2022

@straight-shoota The doc says this is intended: https://crystal-lang.org/reference/1.4/syntax_and_semantics/return_types.html#nil-return-type

Marking a method as returning Nil will make it return nil regardless of what it actually returns:

def some_method : Nil
  1 + 2
end

some_method # => nil

@straight-shoota
Copy link
Member

straight-shoota commented Jul 3, 2022

Yes, that's perfectly fine for implicit return values. Note there is no return in that example. It's essentially a convenience feature for not having to write an explicit nil value at the end of the method.

When you have a method typed to return Nil, an explicit return statement with a non-nil value is somewhat contradictory, though.

@asterite
Copy link
Member

asterite commented Jul 3, 2022

Many times I write return exp instead of exp; return. I don't think we should force users to write the latter when the former is simpler (do this and return immediately)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:interpreter
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants