cmajor-lang / cmajor

The Cmajor public repository
https://cmajor.dev
Other
522 stars 31 forks source link

castToRefSkippingReferences error passing std::notes in struct init #33

Closed jemmons closed 6 months ago

jemmons commented 6 months ago

Minimum Reproduction Steps

processor Untitled  [[ main ]]
{
  output stream float out;
  struct NoteStruct 
  {
    std::notes::NoteOn note;
  }

  void main() 
  {
    let s = NoteStruct(); //> error: Internal compiler error: "castToRefSkippingReferences:87"
    advance();
  }
}

Of Note

This doesn’t seem to be a general problem with structs in structs. If I make my own nominally equivalent NoteOn struct, there’ no error:

processor Untitled  [[ main ]]
{
  output stream float out;
  struct MyNote 
  {
    int32 channel;
    float32 pitch;
    float32 velocity;
  }
  struct NoteStruct 
  {
    MyNote note;
  }

  void main() 
  {
    let s = NoteStruct(); //> No error.
    advance();
  }
}

Workarounds

This only affects initializing struct members via a parenthesized list. Creating a struct and/or directly assigning values works fine:

    NoteStruct s;
    s = NoteStruct(n); //> Error.

    NoteStruct s;
    s.note = n; //> No error.
jemmons commented 6 months ago

Actually, maybe this is a namespace lookup thing? Given this code:

processor Untitled  [[ main ]]
{
  output stream float out;
  struct NoteStruct 
  {
    NotARealThing note;
  }

  void main() 
  {
    let s = NoteStruct();
    advance();
  }
}

I’d expect it to emit

Cannot find symbol 'NotARealThing'

But instead I get the same

error: Internal compiler error: "castToRefSkippingReferences:87"

Seems like I get this error for any symbol that’s not in the same namespace as the caller — even if it doesn’t exist.

cesaref commented 6 months ago

Yes, looks like an interesting failure case, i'll investigate further

cesaref commented 6 months ago

What's going on here is the constant folder is tripping up, as the type is not yet resolved, but it's attempting to check the types of the members too early. This is being triggered by the declaration using the function call type notation. If you change the code to:

processor Untitled  [[ main ]]
{
    output stream float out;
    struct NoteStruct
    {
        std::notes::NoteOn note;
    }

    void main()
    {
        NoteStruct s;
        advance();
    }
}

it works.

The fix is to ensure the type is resolved before attempting to visit the member types. I'll add a test and a fix for this

cesaref commented 6 months ago

Fix merged: https://github.com/cmajor-lang/cmajor/commit/e94e46d4cbc9d1f18d534e2952e2ddc728c8dcb8