-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Closed
Copy link
Labels
Milestone
Description
See the behavior in this test:
[Fact]
public void LocalFunctionAttribute()
{
const string text = @"
using System;
class A : Attribute {}
class C
{
static void M()
{
void local<[A]T>() {}
}
}";
var tree = SyntaxFactory.ParseSyntaxTree(text);
var comp = CreateStandardCompilation(tree);
var model = comp.GetSemanticModel(tree);
var a = tree.GetRoot().DescendantNodes()
.OfType<IdentifierNameSyntax>().ElementAt(2);
Assert.Equal("A", a.Identifier.Text);
var attrInfo = model.GetSymbolInfo(a);
var attrType = comp.GlobalNamespace.GetTypeMember("A");
var attrCtor = attrType.GetMember(".ctor");
Assert.Equal(attrCtor, attrInfo.Symbol);
// Assert that this is also true for the speculative semantic model
var newTree = SyntaxFactory.ParseSyntaxTree(text + " ");
var m = newTree.GetRoot()
.DescendantNodes().OfType<MethodDeclarationSyntax>().Single();
Assert.True(model.TryGetSpeculativeSemanticModelForMethodBody(m.Body.SpanStart, m, out model));
a = newTree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().ElementAt(2);
Assert.Equal("A", a.Identifier.Text);
// If we aren't using the right binder here, the compiler crashes going through the binder factory
var info = model.GetSymbolInfo(a);
Assert.Equal(attrType, info.Symbol);
}When using the regular semantic model, the symbol returned by GetSymbolInfo is the attribute constructor. When using the speculative semantic model, the type is returned instead.
The root cause of this seems to be that TryGetSpeculativeSemanticModelForMethodBody directly returns a MethodBody semantic model, which bypasses the GetMemberModel call which may be needed to retrieve a more specific model (like an Attribute or InitializerSemanticModel) that may be needed to bind pieces of local functions.
Reactions are currently unavailable