FabricMC/Mixin

"@Inject not supported in interface mixin" when multiple mixins target the same method with different descriptors

Fourmisain opened this issue · 0 comments

Found this really weird issue that was hard to nail down, I guess it's best to just start with a minimal example.
Consider these 2 mixins:

@Mixin(Recipe.class)
public interface RecipeMixin1<C extends Inventory> {
	@Inject(method = "getRemainder", at = @At("RETURN"))
	default void testInject1(C container, CallbackInfoReturnable<DefaultedList<ItemStack>> cir) {

	}
}
@Mixin(Recipe.class)
public interface RecipeMixin2<C extends Inventory> {
	@Inject(method = "getRemainder(Lnet/minecraft/inventory/Inventory;)Lnet/minecraft/util/collection/DefaultedList;", at = @At("RETURN"))
	default void testInject2(C inventory, CallbackInfoReturnable<DefaultedList<ItemStack>> cir) {

	}
}

They are functionally identical and each of them works by themselves, but together they produce this error:

Mixin apply for mod amixintest1 failed amixintest1.mixins.json:RecipeMixin1 -> net.minecraft.class_1860:
org.spongepowered.asm.mixin.transformer.throwables.InvalidInterfaceMixinException amixintest1.mixins.json:RecipeMixin1->@Inject::testInject2(Lnet/minecraft/class_1263;Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfoReturnable;)V from mod amixintest1 is not supported in interface mixin [ -> PREINJECT Applicator Phase -> amixintest1.mixins.json:RecipeMixin1 -> Prepare Injections]

Now for the really weird part, if both mixins have the exact same target descriptor, then they work perfectly fine in tandem!
If both injectors are in the same mixin class, they also work fine together.
When one or both of them target the intermediary name "method_8111", this issue disappears as well.

This issue also applies when two mods use different mappings, which is how I originally ran into it.
My Retro-Exchange PR modmuss50/Retro-Exchange#22 and a test mod of mine both have a Recipe mixin like above, only difference being that Retro-Exchange uses Mojmaps while the test mod uses yarn.

The InvalidInterfaceMixinException is thrown here

} catch (InvalidInjectionException ex) {
String description = ex.getContext() != null ? ex.getContext().toString() : "Injection";
throw new InvalidInterfaceMixinException(mixin, description + " is not supported in interface mixin");
}

no idea where the original InvalidInjectionException comes from, looking at #51 reveals nothing obvious either.