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 GetSymbolInfo on ValueTuple declaration #43467

Merged
merged 7 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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 @@ -1060,7 +1060,7 @@ private MemberSemanticModel CreateMemberModel(CSharpSyntaxNode node)
case SyntaxKind.VariableDeclarator:
{
var variableDecl = (VariableDeclaratorSyntax)node.Parent;
SourceMemberFieldSymbol fieldSymbol = GetDeclaredFieldSymbol(variableDecl);
FieldSymbol fieldSymbol = GetDeclaredFieldSymbol(variableDecl);

return InitializerSemanticModel.Create(
this,
Expand Down Expand Up @@ -1194,7 +1194,7 @@ private AttributeSemanticModel CreateModelForAttribute(Binder enclosingBinder, A
containingModel?.GetRemappedSymbols());
}

private SourceMemberFieldSymbol GetDeclaredFieldSymbol(VariableDeclaratorSyntax variableDecl)
private FieldSymbol GetDeclaredFieldSymbol(VariableDeclaratorSyntax variableDecl)
{
var declaredSymbol = GetDeclaredSymbol(variableDecl);

Expand All @@ -1203,10 +1203,10 @@ private SourceMemberFieldSymbol GetDeclaredFieldSymbol(VariableDeclaratorSyntax
switch (variableDecl.Parent.Parent.Kind())
{
case SyntaxKind.FieldDeclaration:
return declaredSymbol.GetSymbol<SourceMemberFieldSymbol>();
return declaredSymbol.GetSymbol<FieldSymbol>();

case SyntaxKind.EventFieldDeclaration:
return (SourceMemberFieldSymbol)(declaredSymbol.GetSymbol<EventSymbol>()).AssociatedField;
return (declaredSymbol.GetSymbol<EventSymbol>()).AssociatedField;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ private void CompileNamedType(NamedTypeSymbol containingType)

case SymbolKind.Field:
{
SourceMemberFieldSymbol fieldSymbol = member as SourceMemberFieldSymbol;
FieldSymbol fieldSymbol = member as FieldSymbol;
if ((object)fieldSymbol != null)
{
if (fieldSymbol.IsConst)
Expand Down
74 changes: 74 additions & 0 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26757,6 +26757,80 @@ private void Method(IInterface inter, Func<(Type, Type), string> keySelector)
CompileAndVerify(comp2);
}

[Fact]
[WorkItem(1090920, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/1090920")]
public void GetSymbolInfoOnInitializerOfValueTupleField()
{

var source = @"
namespace System
{
public struct ValueTuple<T1>
{
public T1 Item1 = default;
public ValueTuple(T1 item1) { }
}
}
";

var comp = CreateCompilation(new[] { source }, options: TestOptions.DebugDll);

var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree, ignoreAccessibility: false);
var literal = tree.GetRoot().DescendantNodes().OfType<LiteralExpressionSyntax>().Single();
Assert.True(model.GetSymbolInfo(literal).IsEmpty);
}

[Fact, WorkItem(1090920, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems/edit/1090920")]
public void NameofFixedBuffer()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NameofFixedBuffer [](start = 20, length = 17)

Is this test added to cover changes in MethodCompiler?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it covers the handling in if (fieldSymbol.IsFixedSizeBuffer && compilationState.Emitting) that is now reachable.

{
var source = @"
namespace System
{
public class C
{
public static void Main()
{
ValueTuple<int> myStruct = default;
Console.Write(myStruct.ToString());
char[] o;
myStruct.DoSomething(out o);
Console.Write(Other.GetFromExternal());
}
}

public unsafe struct ValueTuple<T1>
{
public fixed char MessageType[50];

public override string ToString()
{
return nameof(MessageType);
}

public void DoSomething(out char[] x)
{
x = new char[] { };
Action a = () => { System.Console.Write($"" {nameof(x)} ""); };
a();
}
}

class Other
{
public static string GetFromExternal()
{
ValueTuple<int> myStruct = default;
return nameof(myStruct.MessageType);
}
}
}
";
var compilation = CreateCompilationWithMscorlib45(source, null, new CSharpCompilationOptions(OutputKind.ConsoleApplication).WithAllowUnsafe(true));
CompileAndVerify(compilation, expectedOutput:
"MessageType x MessageType").VerifyDiagnostics();
}

[Fact]
[WorkItem(27322, "https://github.com/dotnet/roslyn/issues/27322")]
public void ExpressionTreeWithTuple()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4210,6 +4210,51 @@ public void M2(C c)
);
}

[Fact]
public void TestInConstructorOverloadWithUseSiteError()
{
var missing = @"public class Missing { }";
var missingComp = CreateCompilation(missing, assemblyName: "missing");

var lib = @"
public class C
{
public C(Missing m) => throw null;
public C(D d) => throw null;
}
public class D { }
";
var libComp = CreateCompilation(lib, references: new[] { missingComp.EmitToImageReference() });

var source = @"
class D
{
public void M()
{
new C(new());
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new C [](start = 8, length = 5)

This is also not quite the scenario, the errors are not reported due to target typed new. We want the target typed new to be the only source of errors. Here we are mixing too much together. #Closed

new C(default);
new C(null);
Copy link
Contributor

@AlekseyTs AlekseyTs Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This scenarios are not interesting (were not requested) because they are not using target typed new #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, duh! My bad

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reacted too quickly. This test is testing target-typed new (first scenario) and comparing with default and null behavior with regards to use-site diagnostics.

I can also test C c = new(null); which will be ambiguous. Is that what you had in mind?

C c = new(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C c = new(null); [](start = 8, length = 16)

Please add a test for a target typed new as an argument of a call that would assert use-site errors caused by the target typed new.

}
}
";
var comp = CreateCompilation(source, references: new[] { libComp.EmitToImageReference() });
comp.VerifyDiagnostics(
// (6,13): error CS0012: The type 'Missing' is defined in an assembly that is not referenced. You must add a reference to assembly 'missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// new C(new());
Diagnostic(ErrorCode.ERR_NoTypeDef, "C").WithArguments("Missing", "missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(6, 13),
// (7,13): error CS0012: The type 'Missing' is defined in an assembly that is not referenced. You must add a reference to assembly 'missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// new C(default);
Diagnostic(ErrorCode.ERR_NoTypeDef, "C").WithArguments("Missing", "missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(7, 13),
// (8,13): error CS0012: The type 'Missing' is defined in an assembly that is not referenced. You must add a reference to assembly 'missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// new C(null);
Diagnostic(ErrorCode.ERR_NoTypeDef, "C").WithArguments("Missing", "missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(8, 13),
// (9,15): error CS0012: The type 'Missing' is defined in an assembly that is not referenced. You must add a reference to assembly 'missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// C c = new(null);
Diagnostic(ErrorCode.ERR_NoTypeDef, "new(null)").WithArguments("Missing", "missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(9, 15)
);
}

[Fact]
public void UseSiteWarning()
{
Expand Down