Cysharp / Cysharp/MemoryPack

The 'scoped' modifier of parameter 'value' doesn't match overridden or implemented member

Open
#378 4 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
4.7k
Forks
313
PR merge metrics
No merged PRs in 30d

Description

Description

When compiling the project, the following error occurs:

MemoryPack.Generator\MemoryPack.Generator.MemoryPackGenerator\dto.MemoryPackFormatter.g.cs(172,30): error CS8987: The 'scoped' modifier of parameter 'value' doesn't match overridden or implemented member.

This error arises because the scoped modifier in the generated CurrencyFormatter class doesn't align with the overridden or implemented member in the base class MemoryPackFormatter. The inconsistency stems from differing checks within the generator for .NET version (NET7_0_OR_GREATER) and language version (C# 11).

Enviroment

Unity6, language version 11

Code

Generated Code:

[global::MemoryPack.Internal.Preserve]
sealed class CurrencyFormatter : MemoryPackFormatter<Currency>
{
    [global::MemoryPack.Internal.Preserve]
    public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref Currency value)
    {
        Currency.Serialize(ref writer, ref value);
    }

    [global::MemoryPack.Internal.Preserve]
    public override void Deserialize(ref MemoryPackReader reader, scoped ref Currency value)
    {
        Currency.Deserialize(ref reader, ref value);
    }
}

Base Class:

[Preserve]
public abstract class MemoryPackFormatter<T> : IMemoryPackFormatter<T>, IMemoryPackFormatter
{
    // ...

    [Preserve]                                                                                                                       
    void IMemoryPackFormatter.Deserialize(ref MemoryPackReader reader, [ScopedRef] ref object? value)
    {
        T obj = value == null ? default (T) : (T) value;
        this.Deserialize(ref reader, ref obj);
        value = (object) obj;
    }
}
Root Cause

The code generator uses inconsistent logic for determining when to apply the scoped modifier. Specifically, it checks for NET7_0_OR_GREATER in one part of the generator, and language version 11 in another part. This discrepancy leads to the scoped modifier being applied in the generated code when it's incompatible with the base class definition.

Proposed Solution

Ensure consistent logic within the code generator for applying the scoped modifier. Unify the checks for .NET version and language version to avoid inconsistencies. Specifically, review the following code in the generator:

var net7 = csOptions.PreprocessorSymbolNames.Contains("NET7_0_OR_GREATER");

and the language version check, and ensure they are aligned. The scoped modifier should only be added if both checks pass, or if a single check correctly determines the need for the modifier.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the generator code that emits MemoryPack.Generator\MemoryPack.Generator.MemoryPackGenerator\dto.MemoryPackFormatter.g.cs, including the NET7_0_OR_GREATER symbol check and the language-version check. Verify the generated CurrencyFormatter against MemoryPackFormatter under Unity 6, and confirm that compilation no longer reports CS8987 when the scoped modifier is emitted.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, unity
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.