Sibling of #3979: the same transform produces an uncompilable field initializer when the constructor reads the field through an explicit this..
Repro
public struct S2
{
public int value;
public int b;
// The parameter shadows the field, so the qualifier is mandatory.
public S2(int value)
{
this.value = value;
b = this.value + 1;
}
}
Decompiled with master (d60a8662a):
public struct S2(int value)
{
public int value = value;
public int b = this.value + 1;
}
Recompiling that output:
error CS0027: Keyword 'this' is not available in the current context
Notes
Possible direction: also treat an ILVariableResolveResult whose Variable.IsThis() — plus the ByReferenceResolveResult that wraps it for structs — as an instance-member reference. The existing generated-backing-field (<x>P) carve-out would then need to skip the target subtree, since under AlwaysQualifyMemberReferences that access is spelled this.<x>P.
Filed by an AI agent (Claude) on behalf of @siegfriedpammer. Repro built and both outputs recompiled to confirm the diagnostics.
Sibling of #3979: the same transform produces an uncompilable field initializer when the constructor reads the field through an explicit
this..Repro
Decompiled with master (
d60a8662a):Recompiling that output:
Notes
B = A + 1case keeps its real constructor. For thethis.-qualified case above, Keep instance-dependent assignments in constructors #3980's output is byte-identical to master's.ReferencesInstanceMember(ICSharpCode.Decompiler/CSharp/Transforms/TransformFieldAndConstructorInitializers.cs:407as of Keep instance-dependent assignments in constructors #3980) matchesThisResolveResult, both as a bare expression and as aMemberResolveResult.TargetResult. The decompiler produces that resolve result only for implicit-this simple names andbasereferences; an explicitthis.Xread goes throughExpressionBuilder.ConvertField->TranslateTarget->ConvertVariable, so theThisReferenceExpressioncarries anILVariableResolveResultinstead and neither case fires.this.value = valueconvention), and theAlwaysQualifyMemberReferencessetting, which qualifies every reference and therefore covers the Primary-constructor conversion creates an invalid field initializer (CS0236) #3979 shape as well.Possible direction: also treat an
ILVariableResolveResultwhoseVariable.IsThis()— plus theByReferenceResolveResultthat wraps it for structs — as an instance-member reference. The existing generated-backing-field (<x>P) carve-out would then need to skip the target subtree, since underAlwaysQualifyMemberReferencesthat access is spelledthis.<x>P.Filed by an AI agent (Claude) on behalf of @siegfriedpammer. Repro built and both outputs recompiled to confirm the diagnostics.