{"record":{"id":"c7766d7eca41d9c7","repo":"dotnet/BenchmarkDotNet","slug":"passing-ref-readonly-structs-by-ref-is-not-support","errorCode":null,"errorMessage":"Passing ref readonly structs by ref is not supported (cannot store {0} as a class field).","messagePattern":"Passing ref readonly structs by ref is not supported \\(cannot store (.+?) as a class field\\)\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs","lineNumber":317,"sourceCode":"                    else if (parameterType.IsByRefLike() && argValue.Value != null)\n                    {\n                        argLocalsType = parameterType;\n\n                        // Use conversion on load; store passed value\n                        var passedArgType = argValue.Value.GetType();\n                        opConversion = GetImplicitConversionOpFromTo(passedArgType, argLocalsType)\n                            ?? throw new InvalidOperationException($\"Bug: No conversion from {passedArgType} to {argLocalsType}.\");\n                        argFieldType = passedArgType;\n                    }\n                    else\n                    {\n                        // No conversion; load ref to arg field;\n                        argLocalsType = parameterType;\n                        argFieldType = parameterType;\n                    }\n\n                    if (argFieldType.IsByRefLike())\n                        throw new NotSupportedException($\"Passing ref readonly structs by ref is not supported (cannot store {argFieldType} as a class field).\");\n\n                    var argField = fieldsContainerBuilder.DefineField(\n                        ArgFieldPrefix + parameter.Position,\n                        argFieldType,\n                        FieldAttributes.Public);\n\n                    argFields.Add(new(argField, argLocalsType, opConversion));\n                }\n\n                EmitExtraFields(fieldsContainerBuilder);\n\n                // private FieldsContainer __fieldsContainer;\n                fieldsContainerField = runnableBuilder.DefineField(\n                    FieldsContainerName,\n                    fieldsContainerBuilder,\n                    FieldAttributes.Private);\n            }\n        }","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/dotnet/BenchmarkDotNet/blob/b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3/src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs#L299-L335","documentation":"The InProcess emit-based runner stores arguments in class fields, which is impossible for ref readonly structs; passing such parameters by ref is therefore unsupported.","triggerScenarios":"Thrown at src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters/RunnableEmitter.cs:317 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Avoid passing ref readonly structs (e.g. Span<T>, ReadOnlySpan<T>) as ref arguments to the benchmark method.","Pass the ref struct by value, or wrap the state in a reference type / field of the benchmark class instead.","Use the out-of-process (default) toolchain if ref-by-ref struct passing is unavoidable."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"b515068b61ad1c9c9aa938b8ece4af1e7d6d85a3","analyzedAt":"2026-08-13T19:12:24.196Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}