diff --git a/spec/compiler/macro/macro_methods_spec.cr b/spec/compiler/macro/macro_methods_spec.cr index 4e9b48a4802d..20367bfdbb27 100644 --- a/spec/compiler/macro/macro_methods_spec.cr +++ b/spec/compiler/macro/macro_methods_spec.cr @@ -140,6 +140,20 @@ module Crystal assert_macro "x", "{{x.class_name}}", [ArrayLiteral.new([Path.new("Foo"), Path.new("Bar")] of ASTNode)] of ASTNode, "\"ArrayLiteral\"" end end + + describe "#nil?" do + it "NumberLiteral" do + assert_macro "", "{{ 1.nil? }}", [] of ASTNode, "false" + end + + it "NilLiteral" do + assert_macro "", "{{ nil.nil? }}", [] of ASTNode, "true" + end + + it "Nop" do + assert_macro "x", "{{ x.nil? }}", [Nop.new] of ASTNode, "true" + end + end end describe "number methods" do diff --git a/src/compiler/crystal/macros.cr b/src/compiler/crystal/macros.cr index bd7609538b0f..7e7956f6ffb0 100644 --- a/src/compiler/crystal/macros.cr +++ b/src/compiler/crystal/macros.cr @@ -272,6 +272,10 @@ module Crystal::Macros # highlight this node in the error message. def raise(message) : NoReturn end + + # Returns `true` if this node is a `NilLiteral` or `Nop`. + def __crystal_pseudo_nil? : BoolLiteral + end end # The empty node. Similar to a `NilLiteral` but its textual representation diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 41604c10d586..aaa66b0f184c 100644 --- a/src/compiler/crystal/macros/methods.cr +++ b/src/compiler/crystal/macros/methods.cr @@ -382,6 +382,10 @@ module Crystal end when "!" BoolLiteral.new(!truthy?) + when "nil?" + interpret_argless_method("nil?", args) do + BoolLiteral.new(is_a?(NilLiteral) || is_a?(Nop)) + end else raise "undefined macro method '#{class_desc}##{method}'", exception_type: Crystal::UndefinedMacroMethodError end