First, what we currently have:

When we compile

obj test1() {
   fn m1() { log "hi!"; }
}
obj test2() {
   fn m1() { log "hi!"; }
}
fn test(test2 a) {
}
fn main() {
    auto a = test1();
    test(a)
}

We end up with

@_ZN5test16method2m1E(i1* %arg, %task* %arg1, %1 %arg2)
@_ZN5test26method2m1E(i1* %arg, %task* %arg1, %1 %arg2)

where %1 is the object type:

%1 = type { %2*, %3* }
%2 = type { i8*, void (i1*, %task*, %1)* }

Note that it is recursive.

The call "test(a)" looks like

call fastcc void %tmp8(i1* %tmp4, %task* %arg1, %6* %tmp9, %1 %tmp12)

Note that we depend on test1 and test2 mapping to the same type. In summary, we depend on llvm unifying recursive types. The bad news is: that is gone since Saturday.

Now, do we still want to support:

obj test1() {
   fn m1() { log "hi!"; }
   fn m2() { log "bar"; }
}
obj test2() {
   fn m1() { log "hi!"; }
}
fn test(test2 a) {
}
fn main() {
    auto a = test1();
    test(a)
}

If so, we need to do something better anyway, since the old llvm would not unify those types.

What I would proposed is to introduce a object type

%object = type { {}*, {}*}

and use that for every object, introducing casts as necessary. Would
that be reasonable?

Cheers,
Rafael
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to