提交 3007969f 编写于 作者: V VSadov

ValueTuple should derive from ValueType or an error.

上级 28a42d8b
......@@ -898,7 +898,8 @@ private void CheckTupleUnderlying(NamedTypeSymbol namedTypeSymbol, SyntaxNode sy
// but if it does happen we should make it a failure.
// NOTE: declaredBase could be null for interfaces
var declaredBase = namedTypeSymbol.BaseTypeNoUseSiteDiagnostics;
if (declaredBase?.SpecialType != SpecialType.System_ValueType && declaredBase?.IsErrorType() != true)
if (declaredBase == null ||
(declaredBase.SpecialType != SpecialType.System_ValueType && !declaredBase.IsErrorType()))
{
// Try to decrease noise by not complaining about the same type over and over again.
if (_reportedErrorTypesMap.Add(namedTypeSymbol))
......
......@@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
' TODO: Need to estimate amount of elements for this map and pass that value to the constructor.
Protected ReadOnly m_AssemblyOrModuleSymbolToModuleRefMap As New ConcurrentDictionary(Of Symbol, Microsoft.Cci.IModuleReference)()
Private ReadOnly _genericInstanceMap As New ConcurrentDictionary(Of Symbol, Object)()
Private ReadOnly _reportedErrorTypesMap As New ConcurrentSet(Of ErrorTypeSymbol)()
Private ReadOnly _reportedErrorTypesMap As New ConcurrentSet(Of TypeSymbol)()
Private ReadOnly _embeddedTypesManagerOpt As NoPia.EmbeddedTypesManager
Public Overrides ReadOnly Property EmbeddedTypesManagerOpt As NoPia.EmbeddedTypesManager
......@@ -119,6 +119,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
ElseIf namedTypeSymbol.IsTupleType Then
Debug.Assert(Not needDeclaration)
namedTypeSymbol = namedTypeSymbol.TupleUnderlyingType
CheckTupleUnderlying(namedTypeSymbol, syntaxNodeOpt, diagnostics)
End If
' Substitute error types with a special singleton object.
......@@ -201,6 +203,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Return namedTypeSymbol
End Function
Private Sub CheckTupleUnderlying(namedTypeSymbol As NamedTypeSymbol, syntaxNodeOpt As SyntaxNode, diagnostics As DiagnosticBag)
' check that underlying type of a ValueTuple is indeed a value type (or error)
' this should never happen, in theory,
' but if it does happen we should make it a failure.
' NOTE: declaredBase could be null for interfaces
Dim declaredBase = namedTypeSymbol.BaseTypeNoUseSiteDiagnostics
If declaredBase Is Nothing OrElse
(declaredBase.SpecialType <> SpecialType.System_ValueType AndAlso Not declaredBase.IsErrorType()) Then
' Try to decrease noise by not complaining about the same type over and over again.
If (_reportedErrorTypesMap.Add(namedTypeSymbol)) Then
diagnostics.Add(New VBDiagnostic(
ErrorFactory.ErrorInfo(ERRID.ERR_PredefinedValueTupleTypeMustBeStruct, namedTypeSymbol.MetadataName),
If(syntaxNodeOpt Is Nothing, NoLocation.Singleton, syntaxNodeOpt.GetLocation())))
End If
End If
End Sub
Friend Overloads Function Translate([param] As TypeParameterSymbol) As Microsoft.Cci.IGenericParameterReference
Debug.Assert(param Is param.OriginalDefinition)
Return [param]
......
......@@ -1707,6 +1707,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_ExplicitTupleElementNamesAttribute = 37269
ERR_TupleLiteralDisallowsTypeChar = 37270
ERR_NewWithTupleTypeSyntax = 37271
ERR_PredefinedValueTupleTypeMustBeStruct = 37272
' Available 37270
ERR_DuplicateProcDefWithDifferentTupleNames2 = 37271
......
......@@ -68,18 +68,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Get
End Property
Public Overrides ReadOnly Property IsReferenceType As Boolean
Get
Return Not Me._underlyingType.IsErrorType() AndAlso Me._underlyingType.IsReferenceType
End Get
End Property
Public Overrides ReadOnly Property IsValueType As Boolean
Get
Return Me._underlyingType.IsErrorType() OrElse Me._underlyingType.IsValueType
End Get
End Property
Public Overrides ReadOnly Property IsImplicitlyDeclared As Boolean
Get
Return False
......@@ -122,7 +110,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Public Overrides ReadOnly Property TypeKind As TypeKind
Get
Return If(Me._underlyingType.TypeKind = TypeKind.Class, TypeKind.Class, TypeKind.Struct)
' From the language perspective tuple is a value type
' composed of its underlying elements
Return TypeKind.Struct
End Get
End Property
......
......@@ -9117,6 +9117,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Predefined type &apos;{0}&apos; must be a structure..
'''</summary>
Friend ReadOnly Property ERR_PredefinedValueTupleTypeMustBeStruct() As String
Get
Return ResourceManager.GetString("ERR_PredefinedValueTupleTypeMustBeStruct", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to SecurityAction value &apos;{0}&apos; is invalid for PrincipalPermission attribute..
'''</summary>
......
......@@ -3169,6 +3169,9 @@
<data name="ERR_NewWithTupleTypeSyntax" xml:space="preserve">
<value>'New' cannot be used with tuple type. Use a tuple literal expression instead.</value>
</data>
<data name="ERR_PredefinedValueTupleTypeMustBeStruct" xml:space="preserve">
<value>Predefined type '{0}' must be a structure.</value>
</data>
<data name="ERR_ExtensionMethodUncallable1" xml:space="preserve">
<value>Extension method '{0}' has type constraints that can never be satisfied.</value>
</data>
......
......@@ -51,6 +51,19 @@ namespace System.Runtime.CompilerServices
End Namespace
"
ReadOnly s_tupleattributes As String = "
namespace System.Runtime.CompilerServices
<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Parameter Or AttributeTargets.Property Or AttributeTargets.ReturnValue Or AttributeTargets.Class Or AttributeTargets.Struct )>
public class TupleElementNamesAttribute : Inherits Attribute
public Sub New(transformNames As String())
End Sub
End Class
End Namespace
"
ReadOnly s_trivial3uple As String = "
Namespace System
Public Structure ValueTuple(Of T1, T2, T3)
......@@ -1089,7 +1102,7 @@ False
IL_0035: ldfld "System.ValueTuple(Of Integer, Integer, Integer, Integer, Integer, Integer, Integer, (Integer, Integer, Integer, Integer)).Item5 As Integer"
IL_003a: call "Sub System.Console.WriteLine(Integer)"
IL_003f: call "Sub C.TestArray()"
IL_0044: call "Sub C.Testullable()"
IL_0044: call "Sub C.TestNullable()"
IL_0049: ret
}
]]>)
......@@ -15549,6 +15562,117 @@ BC30402: 'evtTest3' cannot implement event 'evtTest2' on interface 'I1' because
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct0()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
Dim x as (a As Integer, b As String)
x.Item1 = 1
x.b = "2"
' by the language rules tuple x is definitely assigned
' since all its elements are definitely assigned
System.Console.WriteLine(x)
end sub
end class
namespace System
public class ValueTuple(Of T1, T2)
public Item1 as T1
public Item2 as T2
public Sub New(item1 as T1 , item2 as T2 )
Me.Item1 = item1
Me.Item2 = item2
end sub
End class
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
Dim x as (a As Integer, b As String)
~
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct1()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
Dim x = (1,2,3,4,5,6,7,8,9)
System.Console.WriteLine(x)
end sub
end class
namespace System
public class ValueTuple(Of T1, T2)
public Item1 as T1
public Item2 as T2
public Sub New(item1 as T1 , item2 as T2 )
Me.Item1 = item1
Me.Item2 = item2
end sub
End class
public class ValueTuple(Of T1, T2, T3, T4, T5, T6, T7, TRest)
public Item1 As T1
public Item2 As T2
public Item3 As T3
public Item4 As T4
public Item5 As T5
public Item6 As T6
public Item7 As T7
public Rest As TRest
public Sub New(item1 As T1, item2 As T2, item3 As T3, item4 As T4, item5 As T5, item6 As T6, item7 As T7, rest As TRest)
Item1 = item1
Item2 = item2
Item3 = item3
Item4 = item4
Item5 = item5
Item6 = item6
Item7 = item7
Rest = rest
end Sub
End Class
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
Dim x = (1,2,3,4,5,6,7,8,9)
~
BC37272: Predefined type 'ValueTuple`8' must be a structure.
Dim x = (1,2,3,4,5,6,7,8,9)
~
</errors>)
End Sub
<Fact>
Public Sub ConversionToBase()
Dim compilation1 = CompilationUtils.CreateCompilationWithMscorlib(
......@@ -15582,6 +15706,163 @@ BC33030: Conversion operators cannot convert from a base type.
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct2()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
end sub
Shared Sub Test2(arg as (a As Integer, b As Integer))
End Sub
end class
namespace System
public class ValueTuple(Of T1, T2)
public Item1 as T1
public Item2 as T2
public Sub New(item1 as T1 , item2 as T2 )
Me.Item1 = item1
Me.Item2 = item2
end sub
End class
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct2i()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
end sub
Shared Sub Test2(arg as (a As Integer, b As Integer))
End Sub
end class
namespace System
public interface ValueTuple(Of T1, T2)
End Interface
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct3()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
Dim x as (a As Integer, b As String)() = Nothing
' by the language rules tuple x is definitely assigned
' since all its elements are definitely assigned
System.Console.WriteLine(x)
end sub
end class
namespace System
public class ValueTuple(Of T1, T2)
public Item1 as T1
public Item2 as T2
public Sub New(item1 as T1 , item2 as T2 )
Me.Item1 = item1
Me.Item2 = item2
end sub
End class
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
Dim x as (a As Integer, b As String)() = Nothing
~
</errors>)
End Sub
<WorkItem(11689, "https://github.com/dotnet/roslyn/issues/11689")>
<Fact>
Public Sub ValueTupleNotStruct4()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation name="Tuples">
<file name="a.vb">
class C
Shared Sub Main()
end sub
Shared Function Test2()as (a As Integer, b As Integer)
End Function
end class
namespace System
public class ValueTuple(Of T1, T2)
public Item1 as T1
public Item2 as T2
public Sub New(item1 as T1 , item2 as T2 )
Me.Item1 = item1
Me.Item2 = item2
end sub
End class
end Namespace
<%= s_tupleattributes %>
</file>
</compilation>,
options:=TestOptions.DebugExe)
comp.AssertTheseEmitDiagnostics(
<errors>
BC37272: Predefined type 'ValueTuple`2' must be a structure.
Shared Function Test2()as (a As Integer, b As Integer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</errors>)
End Sub
<Fact>
Public Sub IsBaseOf_WithoutCustomModifiers()
' The IL is from this code, but with modifiers
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册