未验证 提交 27353432 编写于 作者: A AlekseyTs 提交者: GitHub

Use-site diagnostics for a type should include information for type arguments...

Use-site diagnostics for a type should include information for type arguments of contaning types. (#45663)

Fixes #45625.
上级 a75d0d67
......@@ -1223,13 +1223,21 @@ internal override DiagnosticInfo GetUseSiteDiagnostic()
private bool DeriveUseSiteDiagnosticFromTypeArguments(ref DiagnosticInfo result)
{
foreach (TypeWithAnnotations arg in this.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics)
NamedTypeSymbol currentType = this;
do
{
if (DeriveUseSiteDiagnosticFromType(ref result, arg, AllowedRequiredModifierType.None))
foreach (TypeWithAnnotations arg in currentType.TypeArgumentsWithAnnotationsNoUseSiteDiagnostics)
{
return true;
if (DeriveUseSiteDiagnosticFromType(ref result, arg, AllowedRequiredModifierType.None))
{
return true;
}
}
currentType = currentType.ContainingType;
}
while (currentType?.IsDefinition == false);
return false;
}
......
......@@ -311,11 +311,11 @@ private static string GenerateEnum(int n, Func<int, int, string> getMemberValue)
[WorkItem(45625, "https://github.com/dotnet/roslyn/issues/45625")]
[Fact]
public void UseSiteError()
public void UseSiteError_01()
{
var sourceA =
@"public class A { }";
var comp = CreateCompilation(sourceA);
var comp = CreateCompilation(sourceA, assemblyName: "UseSiteError_sourceA");
var refA = comp.EmitToImageReference();
var sourceB =
......@@ -340,17 +340,62 @@ static void Main()
}
}";
comp = CreateCompilation(sourceC, references: new[] { refB });
// https://github.com/dotnet/roslyn/issues/45625: A use-site error should be reported for C.F.
comp.VerifyDiagnostics();
CompileAndVerify(comp);
comp.VerifyDiagnostics(
// (5,31): error CS0012: The type 'A' is defined in an assembly that is not referenced. You must add a reference to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// const int x = (int)~C.F;
Diagnostic(ErrorCode.ERR_NoTypeDef, "F").WithArguments("A", "UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(5, 31)
);
var tree = comp.SyntaxTrees[0];
var model = comp.GetSemanticModel(tree);
var expr = tree.GetRoot().DescendantNodes().Single(n => n.Kind() == SyntaxKind.BitwiseNotExpression);
var value = model.GetConstantValue(expr);
// https://github.com/dotnet/roslyn/issues/45625: Binder.FoldUnaryOperator() should return null if C.F has a use-site error.
Assert.True(value.HasValue);
Assert.Equal(-1, value.Value);
Assert.False(value.HasValue);
}
[WorkItem(45625, "https://github.com/dotnet/roslyn/issues/45625")]
[Fact]
public void UseSiteError_02()
{
var sourceA =
@"public class A { }";
var comp = CreateCompilation(sourceA, assemblyName: "UseSiteError_sourceA");
var refA = comp.EmitToImageReference();
var sourceB =
@"public class B<T>
{
public enum E { F }
}
public class C
{
public const B<A>.E F = default;
}";
comp = CreateCompilation(sourceB, references: new[] { refA });
var refB = comp.EmitToImageReference();
var sourceC =
@"class Program
{
static void Main()
{
var x = ~C.F;
System.Console.WriteLine(x);
}
}";
comp = CreateCompilation(sourceC, references: new[] { refB }, options: TestOptions.ReleaseExe);
comp.VerifyDiagnostics(
// (5,20): error CS0012: The type 'A' is defined in an assembly that is not referenced. You must add a reference to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// var x = ~C.F;
Diagnostic(ErrorCode.ERR_NoTypeDef, "F").WithArguments("A", "UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(5, 20)
);
comp = CreateCompilation(sourceC, references: new[] { refB }, options: TestOptions.DebugExe);
comp.VerifyDiagnostics(
// (5,20): error CS0012: The type 'A' is defined in an assembly that is not referenced. You must add a reference to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
// var x = ~C.F;
Diagnostic(ErrorCode.ERR_NoTypeDef, "F").WithArguments("A", "UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null").WithLocation(5, 20)
);
}
}
}
......@@ -1007,30 +1007,43 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Private Function DeriveUseSiteErrorInfoFromTypeArguments() As DiagnosticInfo
Dim argsErrorInfo As DiagnosticInfo = Nothing
Dim currentType As NamedTypeSymbol = Me
For Each arg As TypeSymbol In Me.TypeArgumentsNoUseSiteDiagnostics
Dim errorInfo As DiagnosticInfo = DeriveUseSiteErrorInfoFromType(arg)
Do
For Each arg As TypeSymbol In currentType.TypeArgumentsNoUseSiteDiagnostics
Dim errorInfo As DiagnosticInfo = DeriveUseSiteErrorInfoFromType(arg)
If errorInfo IsNot Nothing Then
If errorInfo.Code = ERRID.ERR_UnsupportedType1 Then
Return errorInfo
End If
If errorInfo IsNot Nothing Then
If errorInfo.Code = ERRID.ERR_UnsupportedType1 Then
Return errorInfo
End If
If argsErrorInfo Is Nothing Then
argsErrorInfo = errorInfo
If argsErrorInfo Is Nothing Then
argsErrorInfo = errorInfo
End If
End If
End If
Next
Next
If Me.HasTypeArgumentsCustomModifiers Then
Dim modifiersErrorInfo As DiagnosticInfo = Nothing
If currentType.HasTypeArgumentsCustomModifiers Then
Dim modifiersErrorInfo As DiagnosticInfo = Nothing
For i As Integer = 0 To Me.Arity - 1
modifiersErrorInfo = MergeUseSiteErrorInfo(modifiersErrorInfo, DeriveUseSiteErrorInfoFromCustomModifiers(Me.GetTypeArgumentCustomModifiers(i)))
Next
For i As Integer = 0 To currentType.Arity - 1
modifiersErrorInfo = MergeUseSiteErrorInfo(modifiersErrorInfo, DeriveUseSiteErrorInfoFromCustomModifiers(currentType.GetTypeArgumentCustomModifiers(i)))
Next
Return MergeUseSiteErrorInfo(argsErrorInfo, modifiersErrorInfo)
End If
If modifiersErrorInfo IsNot Nothing Then
If modifiersErrorInfo.Code = ERRID.ERR_UnsupportedType1 Then
Return modifiersErrorInfo
End If
If argsErrorInfo Is Nothing Then
argsErrorInfo = modifiersErrorInfo
End If
End If
End If
currentType = currentType.ContainingType
Loop While currentType IsNot Nothing AndAlso Not currentType.IsDefinition
Return argsErrorInfo
End Function
......
......@@ -1404,6 +1404,107 @@ BC30060: Conversion from 'E' to 'Integer' cannot occur in a constant expression.
Return currentSymbol
End Function
<WorkItem(45625, "https://github.com/dotnet/roslyn/issues/45625")>
<Fact>
Public Sub UseSiteError_01()
Dim sourceA =
"
public class A
End Class
"
Dim comp = CreateCompilation(sourceA, assemblyName:="UseSiteError_sourceA")
Dim refA = comp.EmitToImageReference()
Dim sourceB =
"
public class B( Of T)
public enum E
F
end enum
end class
public class C
public const F as B(Of A).E = Nothing
end class
"
comp = CreateCompilation(sourceB, references:={refA})
Dim refB = comp.EmitToImageReference()
Dim sourceC =
"
class Program
Shared Sub Main()
const x As Integer = CType(Not C.F, Integer)
System.Console.WriteLine(x)
End Sub
end class
"
comp = CreateCompilation(sourceC, references:={refB})
comp.AssertTheseDiagnostics(
<expected>
BC30652: Reference required to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'A'. Add one to your project.
const x As Integer = CType(Not C.F, Integer)
~~~
</expected>)
Dim tree = comp.SyntaxTrees(0)
Dim model = comp.GetSemanticModel(tree)
Dim expr = tree.GetRoot().DescendantNodes().Single(Function(n) n.Kind() = SyntaxKind.NotExpression)
Dim value = model.GetConstantValue(expr)
Assert.True(value.HasValue)
Assert.Equal(-1, value.Value)
End Sub
<WorkItem(45625, "https://github.com/dotnet/roslyn/issues/45625")>
<Fact>
Public Sub UseSiteError_02()
Dim sourceA =
"
public class A
End Class
"
Dim comp = CreateCompilation(sourceA, assemblyName:="UseSiteError_sourceA")
Dim refA = comp.EmitToImageReference()
Dim sourceB =
"
public class B( Of T)
public enum E
F
end enum
end class
public class C
public const F as B(Of A).E = Nothing
end class
"
comp = CreateCompilation(sourceB, references:={refA})
Dim refB = comp.EmitToImageReference()
Dim sourceC =
"
Option Infer On
class Program
Shared Sub Main()
Dim x = Not C.F
System.Console.WriteLine(x)
End Sub
end class
"
comp = CreateCompilation(sourceC, references:={refB}, options:=TestOptions.ReleaseExe)
comp.AssertTheseDiagnostics(
<expected>
BC30652: Reference required to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'A'. Add one to your project.
Dim x = Not C.F
~~~
</expected>)
comp = CreateCompilation(sourceC, references:={refB}, options:=TestOptions.DebugExe)
comp.AssertTheseDiagnostics(
<expected>
BC30652: Reference required to assembly 'UseSiteError_sourceA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' containing the type 'A'. Add one to your project.
Dim x = Not C.F
~~~
</expected>)
End Sub
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册