An indecipherable error

Hi all ! May be I’ve spent too much time on my code and there’s something I don’t see but how the hell is this possible ?

pp @program.class
output : AST::NodeProgram

Ok, let’s continue
pp @program
output (only meaningful part) :

#<AST::NodeProgram:0x10132ae70
... bunch of things
@scope=
  #<Scope:0x10132aea0
   @idents=
    {"foo" =>
      #<Ident:0x10132ae40
       @name="foo",
       @offset=0,
       @type_ident=TypeIdent::FN,
       @type_info=
        #<TypeInfo:0x101332fe0
         @array_size=0,
         @bytes=0,
         @type_base=TypeBase::VOID,
         @type_sub=0>>},
   @main=true,
   @name="main",
   @offset=0>,
 @token=nil>

So, we’re good - It’s an AST::NodeProgram, and it have a scope

Now, the indecipherable error

pp @program.scope

Compile time error :
undefined method 'scope' for AST::NodeKeywordReturn (compile-time type is AST::Node+)

How can a legitimate AST::NodeProgram, checked as such at runtime suddenly become an AST::NodeKeywordReturn at compile time ?

That’s beyond me

So, @program is passed from one class to another, and in the second one I’ve defined the receiving class variable as
@program : AST::Node which is an abstract class from which AST::NodeProgram inherits

defining @program in the second class as @program : AST::NodeProgram solves the problem

I’ll be glad If someone have few minutes to tell me what’s happening

What is the type of @progress?

Unless I’m missing something, the challenge is that you’re stating here that @program can be any AST::Node type, including potentially AST::NodeKeywordReturn. The value at runtime happens to be AST::NodeProgram at runtime, but the compiler only sees the potential for it to be that, or anything else under the AST::Node umbrella. Hence it “helping” you in this case with the error message. Limiting the type of @program like you did, or using @program.as(AST::NodeProgram).scope, or wrapping the call in a

if @program.is_a?(AST::NodeProgram)
    pp @program.scope
end

Should all help the compiler see that you intend the variable to be a AST::NodeProgram at that point in the code.

1 Like

This. The compiler doesn’t know what concrete types it will be when it’s running, so it has to ensure that everything it can be is accounted for.

I wonder if the error message could be improved here to say something like:

Undefined method 'scope' for AST::NodeKeywordReturn. Compile-time type is AST::Node+, which has the following subclasses that implement 'scope`:

- AST::NodeProgram

You can downcast '@program' to one or more of those types or implement the 'scope' method on the following types:

- AST::NodeKeywordReturn

Thanks for the explanations ! That totally makes sense and it was not indicepherable at all ;-)

I still don’t have the right habits/reflexes, but I’ll make progress - at the end all of this will become natural

1 Like

What it is currently is not very interesting. What it could be is a lot more interesting for the compiler. So in this case the interesting way to check what it is is to do a puts typeof(@program). It will likely be some sort of union type, and then it will require all the types in the union to support that method.