Mixin
Mixin copied to clipboard
Super calls to default interface methods are incorrectly transformed
In an example like the following:
@Mixin(BeeEntity.class)
public abstract class ExampleMixin implements IAngerable {
@Override
public void writeAngerNBT(CompoundNBT nbt) {
System.out.println("Test!");
IAngerable.super.writeAngerNBT(nbt);
}
}
The super call to the default method in IAngerable
looks like this:
INVOKESPECIAL net/minecraft/entity/IAngerable.writeAngerNBT (Lnet/minecraft/nbt/CompoundNBT;)V (itf)
However, after the mixin is applied, this becomes:
INVOKESPECIAL net/minecraft/entity/passive/BeeEntity.writeAngerNBT (Lnet/minecraft/nbt/CompoundNBT;)V (itf)
which has different behaviour.
This was reproduced with stock Mixin 0.8.3 and Java 8.
Interesting the link constant remains a InterfaceMethodRef
resulting in the jvm failing to load the class (on fabric at least)
Confirmed with sponge-mixin-0.11.4+mixin.0.8.5.jar
We do not produce Fabric's fork of Mixin -- the only reproductions that add information are those on stock Mixin.
Seems like the issue might be here: MixinTargetContext.java#L570-L576
It doesn't check whether the "methodRef" is on a class or on an interface
Simply changing this line to use getOwner
instead of getImplementor
fixes the issue and doesn't seem to break anything else.
https://github.com/SpongePowered/Mixin/blob/155314e6e91465dad727e621a569906a410cd6f4/src/main/java/org/spongepowered/asm/mixin/transformer/MixinTargetContext.java#L872
Not sure why getImplementor
was introduced in the first place, this is its only usage.
It's also worth noting that this issue only occurs if there is a detached superclass, so if anyone is actually running into it they can most likely avoid it by simply extending the target's superclass.