Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nested in generic type binding issues in enabled nullability context #61182

Merged
merged 4 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6046,7 +6046,7 @@ private BoundExpression BindLeftIdentifierOfPotentialColorColorMemberAccess(Iden
{
var typeDiagnostics = BindingDiagnosticBag.Create(diagnostics);
var boundType = BindNamespaceOrType(left, typeDiagnostics);
if (TypeSymbol.Equals(boundType.Type, leftType, TypeCompareKind.ConsiderEverything2))
if (TypeSymbol.Equals(boundType.Type, leftType, TypeCompareKind.AllIgnoreOptions))
{
// NOTE: ReplaceTypeOrValueReceiver will call CheckValue explicitly.
boundValue = BindToNaturalType(boundValue, valueDiagnostics);
Expand Down
146 changes: 146 additions & 0 deletions src/Compilers/CSharp/Test/Semantic/Semantics/ColorColorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2182,5 +2182,151 @@ class C2
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new System.Action(C2.ReferenceEquals)").WithArguments("ReferenceEquals", "System.Action").WithLocation(9, 13)
);
}

[WorkItem(61171, "https://github.com/dotnet/roslyn/issues/61171")]
[Theory]
[InlineData(null)]
[InlineData("class")]
[InlineData("struct")]
[InlineData("unmanaged")]
[InlineData("notnull")]
public void WorkItem61171_Constraints(string constraint)
{
string constraintLine = $"where TValue : {constraint}";
if (string.IsNullOrEmpty(constraint))
{
constraintLine = "";
}

string source = $@"
#nullable enable

namespace DataStructures.Trees;

public sealed class Tree<TValue>
{constraintLine}
{{
public abstract class Node
{{
public abstract NodeType NodeType {{ get; }}
}}

public sealed class ParentNode : Node
{{
public override NodeType NodeType => Tree<TValue>.NodeType.Parent;
}}

public sealed class LeafNode : Node
{{
public override Tree<TValue>.NodeType NodeType => NodeType.Leaf;
}}

public enum NodeType
{{
Parent,
Leaf,
}}
}}
";

var compilation = CreateCompilation(source);

compilation.VerifyDiagnostics();
}

[WorkItem(61171, "https://github.com/dotnet/roslyn/issues/61171")]
[Theory]
[InlineData("dynamic", "object")]
[InlineData("(int a, int b)", "(int, int)")]
public void WorkItem61171_DynamicObjectTuple(string inheritedArgument, string propertyArgument)
{
string source = $@"
public class Tree<TValue>
{{
public enum NodeType
{{
Parent,
Leaf,
}}
}}

public class Tree1 : Tree<{inheritedArgument}>
{{
}}

public class Tree2 : Tree1
{{
public sealed class LeafNode
{{
public Tree<{propertyArgument}>.NodeType NodeType => NodeType.Leaf;
}}
}}
";

var compilation = CreateCompilation(source);

compilation.VerifyDiagnostics();
}

[WorkItem(61171, "https://github.com/dotnet/roslyn/issues/61171")]
[Fact]
public void WorkItem61171_ModoptObject()
{
string genericTreeDefinitionSource = @"
public class Tree2 : Tree1
{
public sealed class LeafNode
{
public Tree<dynamic>.NodeType NodeType => NodeType.Leaf;
}
}
";

string implementingTreeWithModoptObjectILSource = @"
.class public auto ansi beforefieldinit Tree`1<class TValue>
extends [mscorlib]System.Object
{
// Nested Types
.class nested public auto ansi sealed NodeType<class TValue>
extends [mscorlib]System.Enum
{
// Fields
.field public specialname rtspecialname int32 value__
.field public static literal valuetype Tree`1/NodeType<!TValue> Parent = int32(0)
.field public static literal valuetype Tree`1/NodeType<!TValue> Leaf = int32(1)

} // end of class NodeType


// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
} // end of method Tree`1::.ctor

} // end of class Tree`1

.class public auto ansi beforefieldinit Tree1
extends class Tree`1<object modopt(object)>
{
// Methods
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
ldarg.0
call instance void class Tree`1<object>::.ctor()
ret
} // end of method Tree1::.ctor

} // end of class Tree1
";

var compilation = CreateCompilationWithIL(genericTreeDefinitionSource, implementingTreeWithModoptObjectILSource);

compilation.VerifyDiagnostics();
}
}
}