Skip to content

Commit a79c157

Browse files
committed
Work around dotnet#75002
1 parent 572ec2f commit a79c157

File tree

3 files changed

+142
-4
lines changed

3 files changed

+142
-4
lines changed

src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5019,7 +5019,6 @@ private void AddNonTypeMembers(
50195019

50205020
AddAccessorIfAvailable(builder.NonTypeMembers, property.GetMethod);
50215021
AddAccessorIfAvailable(builder.NonTypeMembers, property.SetMethod);
5022-
50235022
FieldSymbol? backingField = property.DeclaredAutoPropertyInfo.BackingField;
50245023

50255024
// TODO: can we leave this out of the member list?

src/Compilers/CSharp/Portable/Symbols/Source/SourcePropertySymbolBase.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,13 +682,13 @@ internal bool IsAutoPropertyOrUsesFieldKeyword
682682
=> IsAutoProperty || UsesFieldKeyword;
683683

684684
internal bool UsesFieldKeyword
685-
=> _lazyMergedAutoPropertyInfo.UsesFieldKeyword;
685+
=> _Safe_MergedAutoPropertyInfo.UsesFieldKeyword;
686686

687687
protected bool HasExplicitAccessModifier
688688
=> (_propertyFlags & Flags.HasExplicitAccessModifier) != 0;
689689

690690
internal bool IsAutoProperty
691-
=> _lazyMergedAutoPropertyInfo.IsAutoProperty;
691+
=> _Safe_MergedAutoPropertyInfo.IsAutoProperty;
692692

693693
protected bool AccessorsHaveImplementation
694694
=> (_propertyFlags & Flags.AccessorsHaveImplementation) != 0;
@@ -698,7 +698,23 @@ protected bool AccessorsHaveImplementation
698698
/// a property with an accessor using the 'field' keyword, or
699699
/// a property with an initializer.
700700
/// </summary>
701-
internal SynthesizedBackingFieldSymbol BackingField => _lazyMergedAutoPropertyInfo.BackingField;
701+
internal SynthesizedBackingFieldSymbol BackingField => _Safe_MergedAutoPropertyInfo.BackingField;
702+
703+
private AutoPropertyInfo _Safe_MergedAutoPropertyInfo
704+
{
705+
get
706+
{
707+
var autoPropertyInfo = _lazyMergedAutoPropertyInfo;
708+
// When calling through the SemanticModel, partial members are not
709+
// necessarily merged when the containing type includes a primary
710+
// constructor - see https://github.com/dotnet/roslyn/issues/75002.
711+
if (autoPropertyInfo is null && _containingType.PrimaryConstructor is { })
712+
{
713+
autoPropertyInfo = DeclaredAutoPropertyInfo;
714+
}
715+
return autoPropertyInfo;
716+
}
717+
}
702718

703719
#nullable enable
704720
internal AutoPropertyInfo DeclaredAutoPropertyInfo

src/Compilers/CSharp/Test/Emit2/Semantics/PrimaryConstructorTests.cs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19777,6 +19777,129 @@ class C(int p)
1977719777
AssertEx.Equal("System.Int32 C.this[System.Int32 i] { get; }", info.Symbol.ToTestDisplayString());
1977819778
}
1977919779

19780+
[WorkItem("https://github.com/dotnet/roslyn/issues/75002")]
19781+
[Fact]
19782+
public void PartialMembers_01()
19783+
{
19784+
var source1 = """
19785+
C c = null;
19786+
c.M();
19787+
_ = c.P;
19788+
""";
19789+
var source2 = """
19790+
partial class C(int p)
19791+
{
19792+
public partial void M() { }
19793+
public partial void M();
19794+
public partial object P { get; }
19795+
public partial object P { get => null; }
19796+
}
19797+
""";
19798+
var comp = CreateCompilation([source1, source2]);
19799+
var tree = comp.SyntaxTrees[0];
19800+
var model = comp.GetSemanticModel(tree);
19801+
model.GetDiagnostics().Verify(
19802+
// (2,3): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()'
19803+
// c.M();
19804+
Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(2, 3),
19805+
// (3,7): error CS0229: Ambiguity between 'C.P' and 'C.P'
19806+
// _ = c.P;
19807+
Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(3, 7));
19808+
}
19809+
19810+
[Fact]
19811+
public void NullableAttributes_01()
19812+
{
19813+
var source1 = """
19814+
#nullable enable
19815+
C c = null!;
19816+
object o;
19817+
o = c.M();
19818+
o = c.P;
19819+
""";
19820+
var source2 = """
19821+
#nullable enable
19822+
using System.Diagnostics.CodeAnalysis;
19823+
class C(int p)
19824+
{
19825+
[return: MaybeNull] public object M() => new();
19826+
[MaybeNull] public object P { get => new(); }
19827+
}
19828+
""";
19829+
var comp = CreateCompilation([source1, source2]);
19830+
var tree = comp.SyntaxTrees[0];
19831+
var model = comp.GetSemanticModel(tree);
19832+
model.GetDiagnostics().Verify();
19833+
}
19834+
19835+
[WorkItem("https://github.com/dotnet/roslyn/issues/75002")]
19836+
[Fact]
19837+
public void NullableAttributes_PartialMembers_01()
19838+
{
19839+
var source1 = """
19840+
#nullable enable
19841+
C c = null!;
19842+
object o;
19843+
o = c.M();
19844+
o = c.P;
19845+
""";
19846+
var source2 = """
19847+
#nullable enable
19848+
using System.Diagnostics.CodeAnalysis;
19849+
partial class C(int p)
19850+
{
19851+
public partial object M() => new();
19852+
[return: MaybeNull] public partial object M();
19853+
[MaybeNull] public partial object P { get; }
19854+
public partial object P { get => new(); }
19855+
}
19856+
""";
19857+
var comp = CreateCompilation([source1, source2]);
19858+
var tree = comp.SyntaxTrees[0];
19859+
var model = comp.GetSemanticModel(tree);
19860+
model.GetDiagnostics().Verify(
19861+
// (4,7): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()'
19862+
// o = c.M();
19863+
Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(4, 7),
19864+
// (5,7): error CS0229: Ambiguity between 'C.P' and 'C.P'
19865+
// o = c.P;
19866+
Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(5, 7));
19867+
}
19868+
19869+
[WorkItem("https://github.com/dotnet/roslyn/issues/75002")]
19870+
[Fact]
19871+
public void NullableAttributes_PartialMembers_02()
19872+
{
19873+
var source1 = """
19874+
#nullable enable
19875+
C c = null!;
19876+
object o;
19877+
o = c.M();
19878+
o = c.P;
19879+
""";
19880+
var source2 = """
19881+
#nullable enable
19882+
using System.Diagnostics.CodeAnalysis;
19883+
partial class C(int p)
19884+
{
19885+
[return: MaybeNull] public partial object M() => new();
19886+
public partial object M();
19887+
public partial object P { get; }
19888+
[MaybeNull] public partial object P { get => new(); }
19889+
}
19890+
""";
19891+
var comp = CreateCompilation([source1, source2]);
19892+
var tree = comp.SyntaxTrees[0];
19893+
var model = comp.GetSemanticModel(tree);
19894+
model.GetDiagnostics().Verify(
19895+
// (4,7): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()'
19896+
// o = c.M();
19897+
Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(4, 7),
19898+
// (5,7): error CS0229: Ambiguity between 'C.P' and 'C.P'
19899+
// o = c.P;
19900+
Diagnostic(ErrorCode.ERR_AmbigMember, "P").WithArguments("C.P", "C.P").WithLocation(5, 7));
19901+
}
19902+
1978019903
[Fact]
1978119904
public void IllegalCapturingInStruct_01()
1978219905
{

0 commit comments

Comments
 (0)