diff --git a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs
index 942f5d78b27f2a62286eacff305fc1064272889d..c959328def4c140abfdcdbb9a630d1de73aa0a91 100644
--- a/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Emitter/Model/PEModuleBuilder.cs
@@ -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))
diff --git a/src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb b/src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
index 9761f5718c12035b81cf754d0bab57978d92a95d..64bbf4c0003fdbb287e39d85b8413898981ffbe5 100644
--- a/src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
+++ b/src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
@@ -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]
diff --git a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
index 68a5e217e8553b0662d80804e3f5b22fa6908228..3aa7f5306cc32d3db41d3a77ed82c821caeb0918 100644
--- a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
+++ b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb
@@ -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
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Tuples/TupleTypeSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Tuples/TupleTypeSymbol.vb
index 229e5d088aad871f9c6da0a29071559a0956a307..409e43cb7481cfe2a170e37ff1b52cdb05b2bcb4 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Tuples/TupleTypeSymbol.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Tuples/TupleTypeSymbol.vb
@@ -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
diff --git a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb
index d0a885c657ac76d44da6dd7a4840ee87c5282052..46bb30f4fe6058532f3e874bf2bdc913e019c190 100644
--- a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb
+++ b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb
@@ -9117,6 +9117,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
+ '''
+ ''' Looks up a localized string similar to Predefined type '{0}' must be a structure..
+ '''
+ Friend ReadOnly Property ERR_PredefinedValueTupleTypeMustBeStruct() As String
+ Get
+ Return ResourceManager.GetString("ERR_PredefinedValueTupleTypeMustBeStruct", resourceCulture)
+ End Get
+ End Property
+
'''
''' Looks up a localized string similar to SecurityAction value '{0}' is invalid for PrincipalPermission attribute..
'''
diff --git a/src/Compilers/VisualBasic/Portable/VBResources.resx b/src/Compilers/VisualBasic/Portable/VBResources.resx
index b12095e6c74af28032a1696d55fa68bc4ba43f76..5e5d6d3b4d20f0fdec87c9e3101b3d7767053359 100644
--- a/src/Compilers/VisualBasic/Portable/VBResources.resx
+++ b/src/Compilers/VisualBasic/Portable/VBResources.resx
@@ -3169,6 +3169,9 @@
'New' cannot be used with tuple type. Use a tuple literal expression instead.
+
+ Predefined type '{0}' must be a structure.
+
Extension method '{0}' has type constraints that can never be satisfied.
diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
index 9892e93db78753fedbaad6811c7e3017df017336..914c5590ea0d2a7453db082e6467088908984a37 100644
--- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
+++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
@@ -51,6 +51,19 @@ namespace System.Runtime.CompilerServices
End Namespace
"
+
+ ReadOnly s_tupleattributes As String = "
+namespace System.Runtime.CompilerServices
+
+ 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
)
End Sub
+
+
+ Public Sub ValueTupleNotStruct0()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+,
+options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+BC37272: Predefined type 'ValueTuple`2' must be a structure.
+ Dim x as (a As Integer, b As String)
+ ~
+)
+
+ End Sub
+
+
+
+ Public Sub ValueTupleNotStruct1()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+ ,
+ options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+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)
+ ~
+)
+ End Sub
+
Public Sub ConversionToBase()
Dim compilation1 = CompilationUtils.CreateCompilationWithMscorlib(
@@ -15582,6 +15706,163 @@ BC33030: Conversion operators cannot convert from a base type.
)
End Sub
+
+
+ Public Sub ValueTupleNotStruct2()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+,
+options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+BC37272: Predefined type 'ValueTuple`2' must be a structure.
+)
+
+ End Sub
+
+
+
+ Public Sub ValueTupleNotStruct2i()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+,
+options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+BC37272: Predefined type 'ValueTuple`2' must be a structure.
+)
+
+ End Sub
+
+
+
+
+ Public Sub ValueTupleNotStruct3()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+,
+options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+BC37272: Predefined type 'ValueTuple`2' must be a structure.
+ Dim x as (a As Integer, b As String)() = Nothing
+ ~
+)
+
+ End Sub
+
+
+
+ Public Sub ValueTupleNotStruct4()
+
+ Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
+
+
+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 %>
+
+,
+options:=TestOptions.DebugExe)
+
+ comp.AssertTheseEmitDiagnostics(
+
+BC37272: Predefined type 'ValueTuple`2' must be a structure.
+ Shared Function Test2()as (a As Integer, b As Integer)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+)
+
+ End Sub
+
Public Sub IsBaseOf_WithoutCustomModifiers()
' The IL is from this code, but with modifiers