Skip to content

Witness tables for all enums are shared #6964

Closed
@juliusikkala

Description

@juliusikkala
interface IThing
{
    void declareSelf();
}

enum FirstEnum
{
    A,
    B
};

enum SecondEnum
{
    C,
    D
};

extension FirstEnum: IThing
{
    void declareSelf()
    {
        printf("FirstEnum: %d\n", this);
    }
}

extension SecondEnum: IThing
{
    void declareSelf()
    {
        printf("SecondEnum: %d\n", this);
    }
}

void declareType<T: IThing>(T val)
{
    val.declareSelf();
}

export __extern_cpp int main()
{
    declareType(FirstEnum.A);
    declareType(SecondEnum.C);
    return 0;
}

Surprisingly, this prints "FirstEnum" twice!
Before lowering to IR, the witness tables have distinct pointers. After lowering, they are the same. Perhaps there is some erroneous caching going on here.

The IR witness table is also implemented for Int, but I guess that isn't a problem?

witness_table %199      : witness_table_t(%IThing)(Int)
{
        witness_table_entry(%115,%declareSelf)
}

This issue is blocking #6916, because this prevents disambiguating between separate enums (which should have different witness tables, even if the IR type is the same), so an incorrect catch block can run if there are multiple catches.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions