egametang/ET · error · Exception

[PreservedMethod] method has generic parameters

Error message

[PreservedMethod] method has generic parameters

What it means

Thrown by the second CreateMethodDesc overload (the one without a MethodDef, used for synthetic/anonymous bridge methods) when returnType.ContainsGenericParameter is true. Unlike errors 193/194 this overload is for generated signatures that have no backing MethodDef, so the message omits the method name.

Solutions

  1. Ensure GenericArgumentContext is populated with all needed class and method instantiations before calling this overload.
  2. Run HybridCLR/Generate/AOTGenericReference to collect all instantiations, then regenerate bridges.
  3. If this appears after a code change, review new generic method usage that crosses the AOT boundary.
Defensive patterns

Strategy: validation

Validate before calling

if (returnType != null && returnType.ContainsGenericParameter)
    Debug.LogError("Synthetic method return type has open generic parameter -- inflation incomplete.");

Prevention

When it happens

Trigger: CreateMethodDesc(TypeSig returnType, List<TypeSig> parameters) is called during generation of synthetic bridge methods (e.g. adjust-thunk or wrapper stubs) where the computed return type still contains a generic parameter, indicating the upstream inflation failed.

Common situations: A generic instantiation was not fully resolved before the synthetic method was created; GenericArgumentContext.Inflate left an open generic due to missing type arguments; a code path constructs a bridge signature from an uninstantiated generic method.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/c9de02e36bdd2cfa. Report an issue: GitHub.

Appendix: source

Thrown at Packages/cn.etetet.hybridclr/Scripts/Editor/Share/MethodBridge/Generator.cs:148

                    throw new Exception($"[PreservedMethod] method:{methodDef} has generic parameters");
                }
                paramInfos.Add(new ParamInfo() { Type = GetSharedTypeInfo(paramInfo) });
            }
            var mbs = new MethodDesc()
            {
                MethodDef = methodDef,
                ReturnInfo = new ReturnInfo() { Type = returnType != null ? GetSharedTypeInfo(returnType) : TypeInfo.s_void },
                ParamInfos = paramInfos,
            };
            return mbs;
        }

        private MethodDesc CreateMethodDesc(TypeSig returnType, List<TypeSig> parameters)
        {
            var paramInfos = new List<ParamInfo>();
            if (returnType.ContainsGenericParameter)
            {
                throw new Exception($"[PreservedMethod] method has generic parameters");
            }
            foreach (var paramInfo in parameters)
            {
                if (paramInfo.ContainsGenericParameter)
                {
                    throw new Exception($"[PreservedMethod] method has generic parameters");
                }
                paramInfos.Add(new ParamInfo() { Type = GetSharedTypeInfo(paramInfo) });
            }
            var mbs = new MethodDesc()
            {
                MethodDef = null,
                ReturnInfo = new ReturnInfo() { Type = returnType != null ? GetSharedTypeInfo(returnType) : TypeInfo.s_void },
                ParamInfos = paramInfos,
            };
            return mbs;
        }

View on GitHub (pinned to 5cab01f7a8)