[GH-ISSUE #6687] [Bug] IL2CPP nested generic names attach enclosing arguments to the innermost type #4063

Closed
opened 2026-10-31 00:46:30 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 23, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6687

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

inspect-il2cpp-metadata --binary renders Outer<int>.Inner<string> as Game.Outer`1+Inner<int, string> and Outer<int>.Leaf as Game.Outer`1+Leaf<int>. The outer type keeps its uninstantiated arity suffix and its arguments appear on the nested type. The top-level Outer<int> control renders as Game.Outer<int>. The same names appear in return, field and parameter type Evidence.

Reproduction

Run from the source revision below with locked dependencies installed. These complete inline, zlib-compressed base64 fixtures are self-authored byte-only inputs: version-31 metadata and a 64-bit Mach-O native registration fixture. REA only reads them; no target, Unity runtime or native provider is launched.

case_dir=$(mktemp -d)
python3 - "$case_dir" <<'PYFIX'
import base64, pathlib, sys, zlib
fixtures = {
    'nested-inherited-only.dat': 'eNqtkr9Lw0AUx99dUnVw6CAoOOjoYrGtYxFKhTooFtruTZtTK5emXK5oJxcHBwVxcRHEv8AKIu79Bxwc/UscrC/JVa4xqYsP8j733vveu195XH76XAE0ApBGpJGzyEXkA/KVQGA6n5GchvE0ziNPkUvIa+QqcqDqAxW/IU3ku8rrnEN+IBu4ZgFFFYwvzbD+X0yFAKrGO4xzd/RV9DzmNHl/vVQ9skQ3Y3MOjtdyBW83g6DCrT4TULYcBlXuStzhnmv3ONuCshi+DO8x3fckcyDTkq6Aete2JIOibUPNrUrR7hyC588rub2OBMsJsN+TTDSysMusA6hBHcpMbvgu67uc7/K+24QLmLSRMjzHzDh3laAhmuYmfPpfOuNHQ+AWvfFHn7sEjb6frlZn2vg4sv55MH+8+mQMkf0SLSaR2gl+axD+XyPNoj30vK6jMT1xTM+QOZU3J+8DxnNopJduJObOUU/zqm8qZi6Z0k/ff9TwTWgBuQ3hQyT1Nab0pzF9zfCI+jqg36FeW1DnNRSTdN9IbipC',
    'nested-inherited-only.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4t2Bm7x4helJwKF/AedouToKRsEoGJwAAOOEG0A=',
    'nested-own-parameter.dat': 'eNqtkr1Lw0AUwF8uqTo4dBAUHHR0sfTDsQhFoTpIC233ps2hlUuuJFekODiKuAji4tLFXQRxceyf4uDo7mB8SS56bZO6+CDvd+/j3r27l8f1p88NQNEAsogschG5inxAvmoQispnJCeRPY/LyHPkGvIWmUeOZTzgJvINaSDfpV/lEvID2cYza5hUR3tkRPH/YiYCELk+oIxx/6viedTusOH2XuPEdPs5izGwvS53Wa8TGnVmDqkLVdOm0GBcAJSPuDVgdBeq7vhlPEL30BPUhlxXcBdafcsUFCqWBU3eEG7POQYv2LfHB44A0w5RGwjqtgtw6Dghm9CCKhX5QBUCVQxUKVA7cA2T4kvBqyzEvpuUHE3JuYumP5On/+RocI9a/6POKCVH7aevxKmyPp06/zLcH58+a19JO+5b7V+T44zXauwMvy2Ifjlfkekaql/NIwk1cU0ukEXpNybfB4jSk58iWsIMMJ+UZN1Mwl5tTj21/2nBGZEych+iwaTV1efUJwl1jd9nj88B9Q3V2Iq8ry6ZlvcNOp0vfQ==',
    'nested-own-parameter.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4t2Bm7x4hYV3Ag796OlpFIyCUTAKBgsAAD7jG/s=',
    'top-level-control.dat': 'eNqtkr1Lw0AUwF8uqTo4dBAUHHR0sfTDsQhFoTpIC233ps2hlUuuJFekODiKuAji4tLFXQRxceyf4uDo7mB8SS56bZO6+CDvd+/j3r27l8f1p88NQNEAsogschG5inxAvmoQispnJCeRPY/LyHPkGvIWmUeOZTzgJvINaSDfpV/lEvID2cYza5hUR3tkRPH/YiYCELk+oIxx/6viedTusOH2XuPEdPs5izGwvS53Wa8TGnVmDqkLVdOm0GBcAJSPuDVgdBeq7vhlPEL30BPUhlxXcBdafcsUFCqWBU3eEG7POQYv2LfHB44A0w5RGwjqtgtw6Dghm9CCKhX5QBUCVQxUKVA7cA2T4kvBqyzEvpuUHE3JuYumP5On/+RocI9a/6POKCVH7aevxKmyPp06/zLcH58+a19JO+5b7V+T44zXauwMvy2Ifjlfkekaql/NIwk1cU0ukEXpNybfB4jSk58iWsIMMJ+UZN1Mwl5tTj21/2nBGZEych+iwaTV1efUJwl1jd9nj88B9Q3V2Iq8ry6ZlvcNOp0vfQ==',
    'top-level-control.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4teBm7x4helJwKF/AedouToKRsEoGJwAANOTG3A=',
}
for name, encoded in fixtures.items():
    pathlib.Path(sys.argv[1], name).write_bytes(zlib.decompress(base64.b64decode(encoded)))
PYFIX
node --import tsx --input-type=module - "$case_dir" <<'JS'
import { createCli } from './src/cli.ts';
for (const name of ['top-level-control', 'nested-own-parameter', 'nested-inherited-only']) {
  const stem = process.argv[2] + '/' + name;
  let output = '', exitCode = 0;
  await createCli({}).serve(
    ['inspect-il2cpp-metadata', stem + '.dat', '--binary', stem + '.dylib', '--json'],
    {env: {}, exit: code => {exitCode = code;}, stdout: text => {output += text;}}
  );
  const r = JSON.parse(output).normalized_result;
  console.log(JSON.stringify({name, exitCode, return_type: r.return_types[0],
    field_types: r.field_types, parameter_types: r.parameter_types}));
}
JS

The fixtures include the declaring-type relationship, generic containers and generic parameter owners. Outer declares one argument. Inner declares one additional argument, and its container/native instance each has the two inherited-plus-own arguments. Leaf declares none of its own; its container/native instance each has one inherited argument. Type records and argument arrays are file-mapped. Methods have ordinary names and may return the selected generic instance.

A delegated researcher observed all three cases through the shared production service and registered source CLI. I independently ran all three through the registered source CLI on the same fixture bytes before writing this report. Every CLI case exited 0. The packaged executable, MCP transport and real Unity-produced binaries were not executed. The inline byte serialization preserves the inspected inputs; it is not a source build of a Unity project.

Expected behavior

Render each generic argument on the type component that declares it: Game.Outer<int>+Inner<string> and Game.Outer<int>+Leaf, retaining REA's documented + delimiter. The exact preferred nested-generic spelling is inferred; REA has no explicit example of this combination. The semantic requirement is that an enclosing type's argument must not be presented as a newly declared parameter of the inner type.

REA explicitly promises C#-like native type names and documents nested definition and generic-instance forms. Microsoft's nested generic argument rules explain why the native argument vector contains enclosing arguments first; its constructed nested type naming guidance assigns them to their respective type components. A flattened native argument vector is therefore valid input, not a reason to render every argument on the final component.

Impact and scope

Type-name Evidence shows a different distribution of type arguments for nested generic types, including a nested type with no parameters of its own. Raw type indices remain available, so this does not lose all underlying type identity. Observed on two self-authored nested cases with a working top-level control; prevalence in real Unity artifacts and downstream consumer effects were not measured. No workaround was demonstrated. The impact estimate is provisional because the exact nested-generic display format is not explicitly specified.

REA version

rea-agents 6.7.0; source revision a7f967cf240eba8309cbf4526b2fc6338a52a617. npm latest was checked as 6.7.0 by the parent investigator.

Runtime and platform

Delegated production service and source CLI probes: Node.js v24.22.1, Linux x64, locked tsx 4.23.15. Independent registered source CLI probe: Node.js v26.12.1, Linux x64, the same locked tsx. No Unity, Hopper or Ghidra runtime was used.

Target and artifact context

Self-authored IL2CPP metadata version 31 paired with Mach-O x86_64 native byte fixtures. Metadata inputs are 1,183 bytes for the top-level/own-parameter cases and 1,164 bytes for the inherited-only case; each native fixture is 4,096 bytes. No proprietary or downloaded target artifacts are required.

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

Focused projection from the registered source CLI; all three cases returned exitCode: 0:

top-level-control       return_types[0].name = Game.Outer<int>
nested-own-parameter    return_types[0].name = Game.Outer`1+Inner<int, string>
nested-inherited-only   return_types[0].name = Game.Outer`1+Leaf<int>

field_types and parameter_types contain the same respective names, with type: 0 retained. The CLI invokes the shared service at il2cppCommands.ts. The renderer first joins raw enclosing names, then removes only the final arity suffix and appends the full argument vector. This source explanation agrees with both executed paths.

Typed outcome or recovery expected

Preserve the full argument vector while assigning each argument to its enclosing or nested declaring component in the C#-like name. Keep the top-level control and raw type indices unchanged. If that name cannot be rendered faithfully, make the limitation explicit instead of projecting misleading argument ownership.

Analysis or suspected cause

Source-derived cause: the generic renderer receives one string for the whole nested definition, strips a trailing arity once, and appends all arguments at the end. It never distributes them across enclosing definitions.

Additional context

Open/closed issue searches covered il2cpp, generic, nested, arity, enclosing, Outer, and Il2cppBinaryTypes. No matching report was found. Nearby #6534 concerns rank-one multidimensional arrays; #5751 concerns version-39 generic-container section counts. Neither addresses nested generic argument ownership.

Restoration check: both nested fixtures render their enclosing arguments on Outer, Inner keeps only its own argument, Leaf gains no argument list, and the top-level control remains Game.Outer<int>. These are proposed passing checks; no fix was implemented or tested. Real Unity-produced fixture parity remains untested.

Triage assessment

  • Impact level: P2
  • Assessment status: provisional
  • Impact basis: Executed service and registered CLI probes display enclosing generic arguments on the final nested component in return, field and parameter type Evidence. Raw indices remain available; real-artifact frequency and downstream consequences are unmeasured, and the exact nested-generic spelling is inferred from the existing C#-like contract.
  • Workaround status: unverified
  • Workaround basis: No existing REA option that renders the same nested instantiation faithfully was demonstrated. Manual reconstruction from retained indices and metadata may be possible but was not verified as a workflow.
Originally created by @coygeek on GitHub (Oct 23, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6687 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `inspect-il2cpp-metadata --binary` renders `Outer<int>.Inner<string>` as ``Game.Outer`1+Inner<int, string>`` and `Outer<int>.Leaf` as ``Game.Outer`1+Leaf<int>``. The outer type keeps its uninstantiated arity suffix and its arguments appear on the nested type. The top-level `Outer<int>` control renders as `Game.Outer<int>`. The same names appear in return, field and parameter type Evidence. ### Reproduction Run from the source revision below with locked dependencies installed. These complete inline, zlib-compressed base64 fixtures are self-authored byte-only inputs: version-31 metadata and a 64-bit Mach-O native registration fixture. REA only reads them; no target, Unity runtime or native provider is launched. ```sh case_dir=$(mktemp -d) python3 - "$case_dir" <<'PYFIX' import base64, pathlib, sys, zlib fixtures = { 'nested-inherited-only.dat': 'eNqtkr9Lw0AUx99dUnVw6CAoOOjoYrGtYxFKhTooFtruTZtTK5emXK5oJxcHBwVxcRHEv8AKIu79Bxwc/UscrC/JVa4xqYsP8j733vveu195XH76XAE0ApBGpJGzyEXkA/KVQGA6n5GchvE0ziNPkUvIa+QqcqDqAxW/IU3ku8rrnEN+IBu4ZgFFFYwvzbD+X0yFAKrGO4xzd/RV9DzmNHl/vVQ9skQ3Y3MOjtdyBW83g6DCrT4TULYcBlXuStzhnmv3ONuCshi+DO8x3fckcyDTkq6Aete2JIOibUPNrUrR7hyC588rub2OBMsJsN+TTDSysMusA6hBHcpMbvgu67uc7/K+24QLmLSRMjzHzDh3laAhmuYmfPpfOuNHQ+AWvfFHn7sEjb6frlZn2vg4sv55MH+8+mQMkf0SLSaR2gl+axD+XyPNoj30vK6jMT1xTM+QOZU3J+8DxnNopJduJObOUU/zqm8qZi6Z0k/ff9TwTWgBuQ3hQyT1Nab0pzF9zfCI+jqg36FeW1DnNRSTdN9IbipC', 'nested-inherited-only.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4t2Bm7x4helJwKF/AedouToKRsEoGJwAAOOEG0A=', 'nested-own-parameter.dat': 'eNqtkr1Lw0AUwF8uqTo4dBAUHHR0sfTDsQhFoTpIC233ps2hlUuuJFekODiKuAji4tLFXQRxceyf4uDo7mB8SS56bZO6+CDvd+/j3r27l8f1p88NQNEAsogschG5inxAvmoQispnJCeRPY/LyHPkGvIWmUeOZTzgJvINaSDfpV/lEvID2cYza5hUR3tkRPH/YiYCELk+oIxx/6viedTusOH2XuPEdPs5izGwvS53Wa8TGnVmDqkLVdOm0GBcAJSPuDVgdBeq7vhlPEL30BPUhlxXcBdafcsUFCqWBU3eEG7POQYv2LfHB44A0w5RGwjqtgtw6Dghm9CCKhX5QBUCVQxUKVA7cA2T4kvBqyzEvpuUHE3JuYumP5On/+RocI9a/6POKCVH7aevxKmyPp06/zLcH58+a19JO+5b7V+T44zXauwMvy2Ifjlfkekaql/NIwk1cU0ukEXpNybfB4jSk58iWsIMMJ+UZN1Mwl5tTj21/2nBGZEych+iwaTV1efUJwl1jd9nj88B9Q3V2Iq8ry6ZlvcNOp0vfQ==', 'nested-own-parameter.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4t2Bm7x4hYV3Ag796OlpFIyCUTAKBgsAAD7jG/s=', 'top-level-control.dat': 'eNqtkr1Lw0AUwF8uqTo4dBAUHHR0sfTDsQhFoTpIC233ps2hlUuuJFekODiKuAji4tLFXQRxceyf4uDo7mB8SS56bZO6+CDvd+/j3r27l8f1p88NQNEAsogschG5inxAvmoQispnJCeRPY/LyHPkGvIWmUeOZTzgJvINaSDfpV/lEvID2cYza5hUR3tkRPH/YiYCELk+oIxx/6viedTusOH2XuPEdPs5izGwvS53Wa8TGnVmDqkLVdOm0GBcAJSPuDVgdBeq7vhlPEL30BPUhlxXcBdafcsUFCqWBU3eEG7POQYv2LfHB44A0w5RGwjqtgtw6Dghm9CCKhX5QBUCVQxUKVA7cA2T4kvBqyzEvpuUHE3JuYumP5On/+RocI9a/6POKCVH7aevxKmyPp06/zLcH58+a19JO+5b7V+T44zXauwMvy2Ifjlfkekaql/NIwk1cU0ukEXpNybfB4jSk58iWsIMMJ+UZN1Mwl5tTj21/2nBGZEych+iwaTV1efUJwl1jd9nj88B9Q3V2Iq8ry6ZlvcNOp0vfQ==', 'top-level-control.dylib': 'eNo7/+vtPx4GBkYGIGBjgDA8GBBAEsqPjw9xjQhhQAFgTQKoYjA+KxQPeuBYXJyam5RTqescnJFYVKCXkpPDwJBbnJxflJOZBOGNguELBJig6RhKK0BpA5j4MAeMjBB/MsMEmEnztxhUPxOUL8E8xMKNBeJeB5aREd/oABZvoMKacbQ4GAUEADuMwYk9vbCgybMQUD/QoAHqrglQegGU3gClD0DpC1D6AbX9wQ0zTxTRpgIDITSFHGh8PjS+EGp+hvKZcZo3ChiQ4teBm7x4helJwKF/AedouToKRsEoGJwAANOTG3A=', } for name, encoded in fixtures.items(): pathlib.Path(sys.argv[1], name).write_bytes(zlib.decompress(base64.b64decode(encoded))) PYFIX node --import tsx --input-type=module - "$case_dir" <<'JS' import { createCli } from './src/cli.ts'; for (const name of ['top-level-control', 'nested-own-parameter', 'nested-inherited-only']) { const stem = process.argv[2] + '/' + name; let output = '', exitCode = 0; await createCli({}).serve( ['inspect-il2cpp-metadata', stem + '.dat', '--binary', stem + '.dylib', '--json'], {env: {}, exit: code => {exitCode = code;}, stdout: text => {output += text;}} ); const r = JSON.parse(output).normalized_result; console.log(JSON.stringify({name, exitCode, return_type: r.return_types[0], field_types: r.field_types, parameter_types: r.parameter_types})); } JS ``` The fixtures include the declaring-type relationship, generic containers and generic parameter owners. `Outer` declares one argument. `Inner` declares one additional argument, and its container/native instance each has the two inherited-plus-own arguments. `Leaf` declares none of its own; its container/native instance each has one inherited argument. Type records and argument arrays are file-mapped. Methods have ordinary names and may return the selected generic instance. A delegated researcher observed all three cases through the shared production service and registered source CLI. I independently ran all three through the registered source CLI on the same fixture bytes before writing this report. Every CLI case exited 0. The packaged executable, MCP transport and real Unity-produced binaries were not executed. The inline byte serialization preserves the inspected inputs; it is not a source build of a Unity project. ### Expected behavior Render each generic argument on the type component that declares it: `Game.Outer<int>+Inner<string>` and `Game.Outer<int>+Leaf`, retaining REA's documented `+` delimiter. The exact preferred nested-generic spelling is inferred; REA has no explicit example of this combination. The semantic requirement is that an enclosing type's argument must not be presented as a newly declared parameter of the inner type. REA explicitly promises [C#-like native type names](https://github.com/morluto/rea/blob/a7f967cf240eba8309cbf4526b2fc6338a52a617/src/il2cpp/Il2cppMetadataProvider.ts#L534-L538) and documents [nested definition and generic-instance forms](https://github.com/morluto/rea/blob/a7f967cf240eba8309cbf4526b2fc6338a52a617/docs/il2cpp-metadata.md#L251-L259). Microsoft's [nested generic argument rules](https://learn.microsoft.com/en-us/dotnet/api/system.type.makegenerictype?view=net-10.0#nested-types) explain why the native argument vector contains enclosing arguments first; its [constructed nested type naming guidance](https://learn.microsoft.com/en-us/cpp/extensions/generic-classes-cpp-cli?view=msvc-170#using-nested-types-in-generic-classes) assigns them to their respective type components. A flattened native argument vector is therefore valid input, not a reason to render every argument on the final component. ### Impact and scope Type-name Evidence shows a different distribution of type arguments for nested generic types, including a nested type with no parameters of its own. Raw type indices remain available, so this does not lose all underlying type identity. Observed on two self-authored nested cases with a working top-level control; prevalence in real Unity artifacts and downstream consumer effects were not measured. No workaround was demonstrated. The impact estimate is provisional because the exact nested-generic display format is not explicitly specified. ### REA version `rea-agents` 6.7.0; source revision `a7f967cf240eba8309cbf4526b2fc6338a52a617`. npm latest was checked as 6.7.0 by the parent investigator. ### Runtime and platform Delegated production service and source CLI probes: Node.js `v24.22.1`, Linux x64, locked tsx `4.23.15`. Independent registered source CLI probe: Node.js `v26.12.1`, Linux x64, the same locked tsx. No Unity, Hopper or Ghidra runtime was used. ### Target and artifact context Self-authored IL2CPP metadata version 31 paired with Mach-O x86_64 native byte fixtures. Metadata inputs are 1,183 bytes for the top-level/own-parameter cases and 1,164 bytes for the inherited-only case; each native fixture is 4,096 bytes. No proprietary or downloaded target artifacts are required. ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence Focused projection from the registered source CLI; all three cases returned `exitCode: 0`: ```text top-level-control return_types[0].name = Game.Outer<int> nested-own-parameter return_types[0].name = Game.Outer`1+Inner<int, string> nested-inherited-only return_types[0].name = Game.Outer`1+Leaf<int> ``` `field_types` and `parameter_types` contain the same respective names, with `type: 0` retained. The CLI invokes the shared service at [il2cppCommands.ts](https://github.com/morluto/rea/blob/a7f967cf240eba8309cbf4526b2fc6338a52a617/src/cli/il2cppCommands.ts#L55-L98). The renderer first [joins raw enclosing names](https://github.com/morluto/rea/blob/a7f967cf240eba8309cbf4526b2fc6338a52a617/src/il2cpp/Il2cppBinaryTypes.ts#L73-L88), then [removes only the final arity suffix and appends the full argument vector](https://github.com/morluto/rea/blob/a7f967cf240eba8309cbf4526b2fc6338a52a617/src/il2cpp/Il2cppBinaryTypes.ts#L147-L170). This source explanation agrees with both executed paths. ### Typed outcome or recovery expected Preserve the full argument vector while assigning each argument to its enclosing or nested declaring component in the C#-like name. Keep the top-level control and raw type indices unchanged. If that name cannot be rendered faithfully, make the limitation explicit instead of projecting misleading argument ownership. ### Analysis or suspected cause Source-derived cause: the generic renderer receives one string for the whole nested definition, strips a trailing arity once, and appends all arguments at the end. It never distributes them across enclosing definitions. ### Additional context Open/closed issue searches covered `il2cpp`, `generic`, `nested`, `arity`, `enclosing`, `Outer`, and `Il2cppBinaryTypes`. No matching report was found. Nearby [#6534](https://github.com/morluto/rea/issues/6534) concerns rank-one multidimensional arrays; [#5751](https://github.com/morluto/rea/issues/5751) concerns version-39 generic-container section counts. Neither addresses nested generic argument ownership. Restoration check: both nested fixtures render their enclosing arguments on `Outer`, `Inner` keeps only its own argument, `Leaf` gains no argument list, and the top-level control remains `Game.Outer<int>`. These are proposed passing checks; no fix was implemented or tested. Real Unity-produced fixture parity remains untested. ## Triage assessment - Impact level: P2 - Assessment status: provisional - Impact basis: Executed service and registered CLI probes display enclosing generic arguments on the final nested component in return, field and parameter type Evidence. Raw indices remain available; real-artifact frequency and downstream consequences are unmeasured, and the exact nested-generic spelling is inferred from the existing C#-like contract. - Workaround status: unverified - Workaround basis: No existing REA option that renders the same nested instantiation faithfully was demonstrated. Manual reconstruction from retained indices and metadata may be possible but was not verified as a workflow.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4063
No description provided.