crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.42k stars 1.62k forks source link

Crystal::Def#owner cannot be nil (NilAssertionError) #11870

Open elebow opened 2 years ago

elebow commented 2 years ago

Bug Report

Minimal reproduction code

module GreatApp
  ->{ super }
end
$ crystal run crystal_bug.cr
Crystal::Def#owner cannot be nil (NilAssertionError)
  from /crystal/src/compiler/crystal/syntax/ast.cr:179:20 in 'lookup_matches_without_splat'
  from /crystal/src/compiler/crystal/semantic/call.cr:130:17 in 'lookup_matches:with_autocast'
  from /crystal/src/compiler/crystal/semantic/call.cr:96:5 in 'recalculate'
  from /crystal/src/compiler/crystal/semantic/main_visitor.cr:1461:7 in 'visit'
  from /crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from /crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from /crystal/src/compiler/crystal/semantic/semantic_visitor.cr:562:5 in 'accept'
  from /crystal/src/compiler/crystal/semantic/main_visitor.cr:697:11 in 'visit'
  from /crystal/src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from /crystal/src/compiler/crystal/semantic/main_visitor.cr:6:7 in 'semantic:cleanup'
  from /crystal/src/compiler/crystal/compiler.cr:172:14 in 'compile'
  from /crystal/src/compiler/crystal/command.cr:220:5 in 'run_command'
  from /crystal/src/compiler/crystal/command.cr:64:5 in '__crystal_main'
  from /crystal/src/crystal/main.cr:115:5 in 'main'
  from src/env/__libc_start_main.c:94:2 in 'libc_start_main_stage2'
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues
$ crystal -v
Crystal 1.3.2 [932f193ae] (2022-01-18)

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

OS is Debian stable (11.2)

straight-shoota commented 2 years ago

Just to be clear: This should be a syntax error when super is used outside a def.

It might be more complicated when the proc literal is actually used in side a def. However, the following code actually works - which is a bit surprising to me (but probably fine?):

class Foo
  def bar
    "Foo#bar"
  end
end
class Bar < Foo
  def bar
    -> { super }
  end
end
Bar.new.bar.call # => "Foo#bar"

previous_def is similar, but it has a nicer error message already:

->{ previous_def } # Error: there is no previous definition of '->'

Although it's a semantic error. It should already be a syntax error when previous_def is used outside a def.