mun-lang / mun

Source code for the Mun language and runtime.
https://mun-lang.org
Other
1.83k stars 73 forks source link

Cyclic type reference causes hang #423

Closed baszalmstra closed 2 years ago

baszalmstra commented 2 years ago

A runtime bug was introduced when loading an assembly that contains a cyclic datastructure. The following code is valid Mun code because Foo is garbage collected type (even though its impossible to create this type at runtime).

pub struct Foo {
    foo: Foo
}

When loading a munlib at runtime that contains this type the runtime hangs. This is due to the code in assembly.rs:

https://github.com/mun-lang/mun/blob/fa07c5c9ae85b27cff5faf7e873583bf10e2de86/crates/mun_runtime/src/assembly.rs#L215-L223

When loading the type Foo, if the type Foo is not yet in the TypeTable loading the above snippet will fail.

We could do something by first creating the Arc<TypeInfo> and then injecting it somehow but it raises another interesting question. By storing the Arc<TypeInfo> in the field, we create a cycle. However, storing the type of a field as a Weak<TypeInfo> is also not an option in a case like this:

pub struct Foo {
    bar: Bar
}

pub struct Bar {
    foo: Foo
}

If in the case above we only hold an Arc<TypeInfo> of Bar, the type info of Foo might be dropped which is not what we want.

I see two approaches in solving this:

The first option is definitely the easiest to implement, I recommend we first take that approach and optimize later. WDYT?

baszalmstra commented 2 years ago

Here is a mun_hir test that hangs currently:

#[test]
fn cyclic_struct() {
    let driver = CompileAndRunTestDriver::new(
        r"
        pub struct Foo {
            foo: Foo
        }
        ",
        |builder| builder,
    );
    driver.unwrap();
}