castToRefSkippingReferences error passing std::notes in struct init
Closed this issue · 4 comments
Minimum Reproduction Steps
- Define a
struct
that has astd::notes::NoteOn
member. - Initialize the struct using the “parenthesized list of member values” form
- Note it’s not necessary to actually pass a value with the parens. Using empty parens to get the default zero’d values still causes the error.
- Run the patch. Note the error:
error: Internal compiler error: "castToRefSkippingReferences:87"
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.
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.
Yes, looks like an interesting failure case, i'll investigate further
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