Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
2bded28b
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2bded28b
编写于
9月 16, 2016
作者:
A
AlekseyTs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Ensure proper validation of operator signatures when tuple types are involved.
Fixes #11986. Fixes #11530.
上级
d1780905
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
1163 addition
and
26 deletion
+1163
-26
src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs
...ble/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs
+2
-3
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
+672
-15
src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
+9
-7
src/Compilers/VisualBasic/Portable/Semantics/Operators.vb
src/Compilers/VisualBasic/Portable/Semantics/Operators.vb
+1
-1
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
+479
-0
未找到文件。
src/Compilers/CSharp/Portable/Symbols/Source/SourceUserDefinedOperatorSymbolBase.cs
浏览文件 @
2bded28b
...
...
@@ -285,10 +285,9 @@ private void CheckUserDefinedConversionSignature(DiagnosticBag diagnostics)
// SPEC: Either S0 or T0 is the class or struct type in which the operator
// SPEC: declaration takes place.
if
(
source0
!=
this
.
ContainingType
&&
target0
!=
this
.
ContainingType
&&
if
(
source0
.
TupleUnderlyingTypeOrSelf
()
!=
this
.
ContainingType
&&
target0
.
TupleUnderlyingTypeOrSelf
()
!=
this
.
ContainingType
&&
// allow conversion between T and Nullable<T> in declaration of Nullable<T>
source
.
TupleUnderlyingTypeOrSelf
()
!=
this
.
ContainingType
&&
target
.
TupleUnderlyingTypeOrSelf
()
!=
this
.
ContainingType
)
source
!=
this
.
ContainingType
&&
target
!=
this
.
ContainingType
)
{
// CS0556: User-defined conversion must convert to or from the enclosing type
diagnostics
.
Add
(
ErrorCode
.
ERR_ConversionNotInvolvingContainedType
,
this
.
Locations
[
0
]);
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs
浏览文件 @
2bded28b
...
...
@@ -11466,8 +11466,9 @@ static void Main()
System.Console.WriteLine(x <= 1);
}
}
";
var tuple = @"
namespace System
{
// struct with two values
...
...
@@ -11640,11 +11641,7 @@ public override int GetHashCode()
}
";
var comp = CompileAndVerify(source,
additionalRefs: s_valueTupleRefs,
parseOptions: TestOptions.Regular,
options: TestOptions.ReleaseExe.WithAllowUnsafe(true),
expectedOutput:
var expectedOutput =
@"{1, 3}
4
{2, 4}
...
...
@@ -11673,7 +11670,15 @@ public override int GetHashCode()
False
True
False
");
";
var lib = CreateCompilationWithMscorlib(tuple, options: TestOptions.ReleaseDll);
lib.VerifyDiagnostics();
var consumer1 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.ToMetadataReference() });
CompileAndVerify(consumer1, expectedOutput: expectedOutput).VerifyDiagnostics();
var consumer2 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.EmitToImageReference() });
CompileAndVerify(consumer2, expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
...
...
@@ -11723,8 +11728,8 @@ static void Main()
System.Console.WriteLine(x <= 1);
}
}
";
var tuple = @"
namespace System
{
// struct with two values
...
...
@@ -11897,11 +11902,7 @@ public override int GetHashCode()
}
";
var comp = CompileAndVerify(source,
additionalRefs: s_valueTupleRefs,
parseOptions: TestOptions.Regular,
options: TestOptions.ReleaseExe.WithAllowUnsafe(true),
expectedOutput:
var expectedOutput =
@"{1, 3}
4
{2, 4}
...
...
@@ -11930,7 +11931,663 @@ public override int GetHashCode()
False
True
False
");
";
var lib = CreateCompilationWithMscorlib(tuple, options: TestOptions.ReleaseDll);
lib.VerifyDiagnostics();
var consumer1 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.ToMetadataReference() });
CompileAndVerify(consumer1, expectedOutput: expectedOutput).VerifyDiagnostics();
var consumer2 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.EmitToImageReference() });
CompileAndVerify(consumer2, expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
[WorkItem(11530, "https://github.com/dotnet/roslyn/issues/11530")]
public void UnifyUnderlyingWithTuple_10()
{
var source = @"
using System.Collections.Generic;
class Test
{
static void Main()
{
var a = new KeyValuePair<int, long>(1, 2);
(int, long) b = a;
System.Console.WriteLine(b.Item1);
System.Console.WriteLine(b.Item2);
b.Item1++;
b.Item2++;
a = b;
System.Console.WriteLine(a.Key);
System.Console.WriteLine(a.Value);
}
}
namespace System
{
public struct ValueTuple<T1, T2>
{
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public static implicit operator KeyValuePair<T1, T2>(ValueTuple<T1, T2> tuple)
{
T1 k;
T2 v;
(k, v) = tuple;
return new KeyValuePair<T1, T2>(k, v);
}
public static implicit operator ValueTuple<T1, T2>(KeyValuePair<T1, T2> kvp)
{
return (kvp.Key, kvp.Value);
}
}
}
";
var comp = CompileAndVerify(source,
parseOptions: TestOptions.Regular,
options: TestOptions.ReleaseExe,
expectedOutput:
@"1
2
2
3");
}
[Fact]
[WorkItem(11986, "https://github.com/dotnet/roslyn/issues/11986")]
public void UnifyUnderlyingWithTuple_11()
{
var source = @"
using System.Collections.Generic;
class Test
{
static void Main()
{
var a = (1, 2);
System.Console.WriteLine((int)a);
System.Console.WriteLine((long)a);
System.Console.WriteLine((string)a);
System.Console.WriteLine((double)a);
}
}
namespace System
{
public struct ValueTuple<T1, T2>
{
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public static explicit operator int((T1, T2)? source)
{
return 1;
}
public static explicit operator long(Nullable<(T1, T2)> source)
{
return 2;
}
public static explicit operator string(Nullable<ValueTuple<T1, T2>> source)
{
return ""3"";
}
public static explicit operator double(ValueTuple<T1, T2>? source)
{
return 4;
}
}
}
";
var comp = CompileAndVerify(source,
parseOptions: TestOptions.Regular,
options: TestOptions.ReleaseExe,
expectedOutput:
@"1
2
3
4");
}
[Fact]
public void UnifyUnderlyingWithTuple_12()
{
var source = @"
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
(int, int)? x = (1, 3);
string s = x;
System.Console.WriteLine(s);
System.Console.WriteLine((long)x);
(int, string)? y = new KeyValuePair<int, string>(2, ""4"");
System.Console.WriteLine(y);
System.Console.WriteLine((ValueTuple<string, string>)""5"");
System.Console.WriteLine(+x);
System.Console.WriteLine(-x);
System.Console.WriteLine(!x);
System.Console.WriteLine(~x);
System.Console.WriteLine(++x);
System.Console.WriteLine(--x);
System.Console.WriteLine(x ? true : false);
System.Console.WriteLine(!x ? true : false);
System.Console.WriteLine(x + 1);
System.Console.WriteLine(x - 1);
System.Console.WriteLine(x * 3);
System.Console.WriteLine(x / 2);
System.Console.WriteLine(x % 3);
System.Console.WriteLine(x & 3);
System.Console.WriteLine(x | 15);
System.Console.WriteLine(x ^ 4);
System.Console.WriteLine(x << 1);
System.Console.WriteLine(x >> 1);
System.Console.WriteLine(x == 1);
System.Console.WriteLine(x != 1);
System.Console.WriteLine(x > 1);
System.Console.WriteLine(x < 1);
System.Console.WriteLine(x >= 1);
System.Console.WriteLine(x <= 1);
}
}
";
var tuple = @"
namespace System
{
// struct with two values
public struct ValueTuple<T1, T2>
{
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public override string ToString()
{
return '{' + Item1?.ToString() + "", "" + Item2?.ToString() + '}';
}
public static implicit operator string(ValueTuple<T1, T2>? arg)
{
return arg.ToString();
}
public static explicit operator long(ValueTuple<T1, T2>? arg)
{
return ((long)(int)(object)arg.Value.Item1 + (long)(int)(object)arg.Value.Item2);
}
public static implicit operator ValueTuple<T1, T2>?(System.Collections.Generic.KeyValuePair<T1, T2> arg)
{
return new ValueTuple<T1, T2>(arg.Key, arg.Value);
}
public static explicit operator ValueTuple<T1, T2>?(string arg)
{
return new ValueTuple<T1, T2>((T1)(object)arg, (T2)(object)arg);
}
public static ValueTuple<T1, T2>? operator +(ValueTuple<T1, T2>? arg)
{
return arg;
}
public static long operator -(ValueTuple<T1, T2>? arg)
{
return -(long)arg;
}
public static bool operator !(ValueTuple<T1, T2>? arg)
{
return (long)arg == 0;
}
public static long operator ~(ValueTuple<T1, T2>? arg)
{
return -(long)arg;
}
public static ValueTuple<T1, T2>? operator ++(ValueTuple<T1, T2>? arg)
{
return new ValueTuple<T1, T2>((T1)(object)((int)(object)arg.Value.Item1+1), (T2)(object)((int)(object)arg.Value.Item2+1));
}
public static ValueTuple<T1, T2>? operator --(ValueTuple<T1, T2>? arg)
{
return new ValueTuple<T1, T2>((T1)(object)((int)(object)arg.Value.Item1 - 1), (T2)(object)((int)(object)arg.Value.Item2 - 1));
}
public static bool operator true(ValueTuple<T1, T2>? arg)
{
return (long)arg != 0;
}
public static bool operator false(ValueTuple<T1, T2>? arg)
{
return (long)arg == 0;
}
public static long operator + (ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 + arg2;
}
public static long operator -(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 - arg2;
}
public static long operator *(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 * arg2;
}
public static long operator /(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 / arg2;
}
public static long operator %(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 % arg2;
}
public static long operator &(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 & arg2;
}
public static long operator |(ValueTuple<T1, T2>? arg1, long arg2)
{
return (long)arg1 | arg2;
}
public static long operator ^(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 ^ arg2;
}
public static long operator <<(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 << arg2;
}
public static long operator >>(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 >> arg2;
}
public static bool operator ==(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 == arg2;
}
public static bool operator !=(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 != arg2;
}
public static bool operator >(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 > arg2;
}
public static bool operator <(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 < arg2;
}
public static bool operator >=(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 >= arg2;
}
public static bool operator <=(ValueTuple<T1, T2>? arg1, int arg2)
{
return (long)arg1 <= arg2;
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
";
var expectedOutput =
@"{1, 3}
4
{2, 4}
{5, 5}
{1, 3}
-4
False
-4
{2, 4}
{1, 3}
True
False
5
3
12
2
1
0
15
0
8
2
False
True
True
False
True
False
";
var lib = CreateCompilationWithMscorlib(tuple, options: TestOptions.ReleaseDll);
lib.VerifyDiagnostics();
var consumer1 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.ToMetadataReference() });
CompileAndVerify(consumer1, expectedOutput: expectedOutput).VerifyDiagnostics();
var consumer2 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.EmitToImageReference() });
CompileAndVerify(consumer2, expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
public void UnifyUnderlyingWithTuple_13()
{
var source = @"
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
(int, int)? x = (1, 3);
string s = x;
System.Console.WriteLine(s);
System.Console.WriteLine((long)x);
(int, string)? y = new KeyValuePair<int, string>(2, ""4"");
System.Console.WriteLine(y);
System.Console.WriteLine((ValueTuple<string, string>)""5"");
System.Console.WriteLine(+x);
System.Console.WriteLine(-x);
System.Console.WriteLine(!x);
System.Console.WriteLine(~x);
System.Console.WriteLine(++x);
System.Console.WriteLine(--x);
System.Console.WriteLine(x ? true : false);
System.Console.WriteLine(!x ? true : false);
System.Console.WriteLine(x + 1);
System.Console.WriteLine(x - 1);
System.Console.WriteLine(x * 3);
System.Console.WriteLine(x / 2);
System.Console.WriteLine(x % 3);
System.Console.WriteLine(x & 3);
System.Console.WriteLine(x | 15);
System.Console.WriteLine(x ^ 4);
System.Console.WriteLine(x << 1);
System.Console.WriteLine(x >> 1);
System.Console.WriteLine(x == 1);
System.Console.WriteLine(x != 1);
System.Console.WriteLine(x > 1);
System.Console.WriteLine(x < 1);
System.Console.WriteLine(x >= 1);
System.Console.WriteLine(x <= 1);
}
}
";
var tuple = @"
namespace System
{
// struct with two values
public struct ValueTuple<T1, T2>
{
public T1 Item1;
public T2 Item2;
public ValueTuple(T1 item1, T2 item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public override string ToString()
{
return '{' + Item1?.ToString() + "", "" + Item2?.ToString() + '}';
}
public static implicit operator string((T1, T2)? arg)
{
return arg.ToString();
}
public static explicit operator long((T1, T2)? arg)
{
return ((long)(int)(object)arg.Value.Item1 + (long)(int)(object)arg.Value.Item2);
}
public static implicit operator (T1, T2)?(System.Collections.Generic.KeyValuePair<T1, T2> arg)
{
return new (T1, T2)(arg.Key, arg.Value);
}
public static explicit operator (T1, T2)?(string arg)
{
return new (T1, T2)((T1)(object)arg, (T2)(object)arg);
}
public static (T1, T2)? operator +((T1, T2)? arg)
{
return arg;
}
public static long operator -((T1, T2)? arg)
{
return -(long)arg;
}
public static bool operator !((T1, T2)? arg)
{
return (long)arg == 0;
}
public static long operator ~((T1, T2)? arg)
{
return -(long)arg;
}
public static (T1, T2)? operator ++((T1, T2)? arg)
{
return new ValueTuple<T1, T2>((T1)(object)((int)(object)arg.Value.Item1+1), (T2)(object)((int)(object)arg.Value.Item2+1));
}
public static (T1, T2)? operator --((T1, T2)? arg)
{
return new ValueTuple<T1, T2>((T1)(object)((int)(object)arg.Value.Item1 - 1), (T2)(object)((int)(object)arg.Value.Item2 - 1));
}
public static bool operator true((T1, T2)? arg)
{
return (long)arg != 0;
}
public static bool operator false((T1, T2)? arg)
{
return (long)arg == 0;
}
public static long operator + ((T1, T2)? arg1, int arg2)
{
return (long)arg1 + arg2;
}
public static long operator -((T1, T2)? arg1, int arg2)
{
return (long)arg1 - arg2;
}
public static long operator *((T1, T2)? arg1, int arg2)
{
return (long)arg1 * arg2;
}
public static long operator /((T1, T2)? arg1, int arg2)
{
return (long)arg1 / arg2;
}
public static long operator %((T1, T2)? arg1, int arg2)
{
return (long)arg1 % arg2;
}
public static long operator &((T1, T2)? arg1, int arg2)
{
return (long)arg1 & arg2;
}
public static long operator |((T1, T2)? arg1, long arg2)
{
return (long)arg1 | arg2;
}
public static long operator ^((T1, T2)? arg1, int arg2)
{
return (long)arg1 ^ arg2;
}
public static long operator <<((T1, T2)? arg1, int arg2)
{
return (long)arg1 << arg2;
}
public static long operator >>((T1, T2)? arg1, int arg2)
{
return (long)arg1 >> arg2;
}
public static bool operator ==((T1, T2)? arg1, int arg2)
{
return (long)arg1 == arg2;
}
public static bool operator !=((T1, T2)? arg1, int arg2)
{
return (long)arg1 != arg2;
}
public static bool operator >((T1, T2)? arg1, int arg2)
{
return (long)arg1 > arg2;
}
public static bool operator <((T1, T2)? arg1, int arg2)
{
return (long)arg1 < arg2;
}
public static bool operator >=((T1, T2)? arg1, int arg2)
{
return (long)arg1 >= arg2;
}
public static bool operator <=((T1, T2)? arg1, int arg2)
{
return (long)arg1 <= arg2;
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
}
";
var expectedOutput =
@"{1, 3}
4
{2, 4}
{5, 5}
{1, 3}
-4
False
-4
{2, 4}
{1, 3}
True
False
5
3
12
2
1
0
15
0
8
2
False
True
True
False
True
False
";
var lib = CreateCompilationWithMscorlib(tuple, options: TestOptions.ReleaseDll);
lib.VerifyDiagnostics();
var consumer1 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.ToMetadataReference() });
CompileAndVerify(consumer1, expectedOutput: expectedOutput).VerifyDiagnostics();
var consumer2 = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseExe, references: new[] { lib.EmitToImageReference() });
CompileAndVerify(consumer2, expectedOutput: expectedOutput).VerifyDiagnostics();
}
[Fact]
...
...
src/Compilers/VisualBasic/Portable/Emit/SymbolTranslator.vb
浏览文件 @
2bded28b
...
...
@@ -116,7 +116,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
' Anonymous type being translated
If
namedTypeSymbol
.
IsAnonymousType
Then
namedTypeSymbol
=
AnonymousTypeManager
.
TranslateAnonymousTypeSymbol
(
namedTypeSymbol
)
ElseIf
(
namedTypeSymbol
.
IsTupleType
)
Then
ElseIf
namedTypeSymbol
.
IsTupleType
Then
Debug
.
Assert
(
Not
needDeclaration
)
namedTypeSymbol
=
namedTypeSymbol
.
TupleUnderlyingType
End
If
...
...
@@ -232,10 +232,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
Optional
needDeclaration
As
Boolean
=
False
)
As
Microsoft
.
Cci
.
IFieldReference
Debug
.
Assert
(
fieldSymbol
Is
fieldSymbol
.
OriginalDefinition
OrElse
Not
fieldSymbol
.
Equals
(
fieldSymbol
.
OriginalDefinition
))
If
fieldSymbol
.
IsTupleField
Then
fieldSymbol
=
fieldSymbol
.
TupleUnderlyingField
End
If
Not
fieldSymbol
.
Equals
(
fieldSymbol
.
OriginalDefinition
))
Debug
.
Assert
(
Not
fieldSymbol
.
IsTupleField
,
"tuple fields should be rewritten to underlying by now"
)
Me
.
ProcessReferencedSymbol
(
fieldSymbol
)
...
...
@@ -339,12 +337,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit
' Method of anonymous type being translated
If
container
.
IsAnonymousType
Then
methodSymbol
=
AnonymousTypeManager
.
TranslateAnonymousTypeMethodSymbol
(
methodSymbol
)
End
If
If
methodSymbol
.
IsTupleMethod
Then
ElseIf
methodSymbol
.
IsTupleMethod
Then
Debug
.
Assert
(
Not
needDeclaration
)
Debug
.
Assert
(
container
.
IsTupleType
)
container
=
container
.
TupleUnderlyingType
methodSymbol
=
methodSymbol
.
TupleUnderlyingMethod
End
If
Debug
.
Assert
(
Not
container
.
IsTupleType
)
Me
.
ProcessReferencedSymbol
(
methodSymbol
)
If
methodSymbol
.
OriginalDefinition
IsNot
methodSymbol
Then
...
...
src/Compilers/VisualBasic/Portable/Semantics/Operators.vb
浏览文件 @
2bded28b
...
...
@@ -453,7 +453,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If
containingType
.
SpecialType
=
SpecialType
.
System_Nullable_T
Then
Return
typeFromSignature
Is
containingType
Else
Return
typeFromSignature
.
GetNullableUnderlyingTypeOrSelf
()
Is
containingType
Return
typeFromSignature
.
GetNullableUnderlyingTypeOrSelf
()
.
GetTupleUnderlyingTypeOrSelf
()
=
containingType
.
GetTupleUnderlyingTypeOrSelf
()
End
If
End
Function
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
浏览文件 @
2bded28b
...
...
@@ -8232,6 +8232,485 @@ End Module
End
Sub
<
Fact
>
Public
Sub
UnifyUnderlyingWithTuple_08
()
Dim
source
=
<
compilation
>
<
file
name
=
"a.vb"
><
!
[
CDATA
[
Imports
System
Imports
System.Collections.Generic
Module
Module1
Sub
Main
()
Dim
x
=
(
1
,
3
)
Dim
s
As
String
=
x
System
.
Console
.
WriteLine
(
s
)
System
.
Console
.
WriteLine
(
CType
(
x
,
Long
))
Dim
y
As
(
Integer
,
String
)
=
New
KeyValuePair
(
Of
Integer
,
String
)(
2
,
"4"
)
System
.
Console
.
WriteLine
(
y
)
System
.
Console
.
WriteLine
(
CType
(
"5"
,
ValueTuple
(
Of
String
,
String
)))
System
.
Console
.
WriteLine
(
+
x
)
System
.
Console
.
WriteLine
(
-
x
)
System
.
Console
.
WriteLine
(
Not
x
)
System
.
Console
.
WriteLine
(
If
(
x
,
True
,
False
))
System
.
Console
.
WriteLine
(
If
(
Not
x
,
True
,
False
))
System
.
Console
.
WriteLine
(
x
+
1
)
System
.
Console
.
WriteLine
(
x
-
1
)
System
.
Console
.
WriteLine
(
x
*
3
)
System
.
Console
.
WriteLine
(
x
/
2
)
System
.
Console
.
WriteLine
(
x
\
2
)
System
.
Console
.
WriteLine
(
x
Mod
3
)
System
.
Console
.
WriteLine
(
x
&
3
)
System
.
Console
.
WriteLine
(
x
And
3
)
System
.
Console
.
WriteLine
(
x
Or
15
)
System
.
Console
.
WriteLine
(
x
Xor
3
)
System
.
Console
.
WriteLine
(
x
Like
15
)
System
.
Console
.
WriteLine
(
x
^
4
)
System
.
Console
.
WriteLine
(
x
<<
1
)
System
.
Console
.
WriteLine
(
x
>>
1
)
System
.
Console
.
WriteLine
(
x
=
1
)
System
.
Console
.
WriteLine
(
x
<>
1
)
System
.
Console
.
WriteLine
(
x
>
1
)
System
.
Console
.
WriteLine
(
x
<
1
)
System
.
Console
.
WriteLine
(
x
>=
1
)
System
.
Console
.
WriteLine
(
x
<=
1
)
End
Sub
End
Module
]]
></
file
>
</
compilation
>
Dim
tuple
=
<
compilation
>
<
file
name
=
"a.vb"
><
!
[
CDATA
[
Namespace
System
Public
Structure
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
Public
Overrides
Function
ToString
()
As
String
Return
"{"
+
Item1
?
.
ToString
()
+
", "
+
Item2
?
.
ToString
()
+
"}"
End
Function
Public
Shared
Widening
Operator
CType
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
String
Return
arg
.
ToString
()
End
Operator
Public
Shared
Narrowing
Operator
CType
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
Long
Return
CLng
(
CObj
(
arg
.
Item1
)
+
CObj
(
arg
.
Item2
))
End
Operator
Public
Shared
Widening
Operator
CType
(
arg
As
System
.
Collections
.
Generic
.
KeyValuePair
(
Of
T1
,
T2
))
As
ValueTuple
(
Of
T1
,
T2
)
Return
New
ValueTuple
(
Of
T1
,
T2
)(
arg
.
Key
,
arg
.
Value
)
End
Operator
Public
Shared
Narrowing
Operator
CType
(
arg
As
String
)
As
ValueTuple
(
Of
T1
,
T2
)
Return
New
ValueTuple
(
Of
T1
,
T2
)(
CType
(
CObj
(
arg
),
T1
),
CType
(
CObj
(
arg
),
T2
))
End
Operator
Public
Shared
Operator
+
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
ValueTuple
(
Of
T1
,
T2
)
Return
arg
End
Operator
Public
Shared
Operator
-
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
Long
Return
-
CType
(
arg
,
Long
)
End
Operator
Public
Shared
Operator
Not
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
Boolean
Return
CType
(
arg
,
Long
)
=
0
End
Operator
Public
Shared
Operator
IsTrue
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
Boolean
Return
CType
(
arg
,
Long
)
<>
0
End
Operator
Public
Shared
Operator
IsFalse
(
arg
As
ValueTuple
(
Of
T1
,
T2
))
As
Boolean
Return
CType
(
arg
,
Long
)
=
0
End
Operator
Public
Shared
Operator
+
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
+
arg2
End
Operator
Public
Shared
Operator
-
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
-
arg2
End
Operator
Public
Shared
Operator
*
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
*
arg2
End
Operator
Public
Shared
Operator
/
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
/
arg2
End
Operator
Public
Shared
Operator
\
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
\
arg2
End
Operator
Public
Shared
Operator
Mod
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
Mod
arg2
End
Operator
Public
Shared
Operator
&
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
&
arg2
End
Operator
Public
Shared
Operator
And
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
And
arg2
End
Operator
Public
Shared
Operator
Or
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Or
arg2
End
Operator
Public
Shared
Operator
Xor
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Xor
arg2
End
Operator
Public
Shared
Operator
Like
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Or
arg2
End
Operator
Public
Shared
Operator
^
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
^
arg2
End
Operator
Public
Shared
Operator
<<
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
<<
arg2
End
Operator
Public
Shared
Operator
>>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
>>
arg2
End
Operator
Public
Shared
Operator
=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
=
arg2
End
Operator
Public
Shared
Operator
<>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<>
arg2
End
Operator
Public
Shared
Operator
>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
>
arg2
End
Operator
Public
Shared
Operator
<
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<
arg2
End
Operator
Public
Shared
Operator
>=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
>=
arg2
End
Operator
Public
Shared
Operator
<=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
),
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<=
arg2
End
Operator
Public
Overrides
Function
Equals
(
obj
As
Object
)
As
Boolean
Return
False
End
Function
Public
Overrides
Function
GetHashCode
()
As
Integer
Return
0
End
Function
End
Structure
End
Namespace
]]
></
file
>
</
compilation
>
Dim
expectedOutput
=
"{1, 3}
4
{2, 4}
{5, 5}
{1, 3}
-4
False
True
False
5
3
12
2
2
1
43
0
15
7
15
256
8
2
False
True
True
False
True
False
"
Dim
[
lib
]
=
CreateCompilationWithMscorlibAndVBRuntime
(
tuple
,
options
:
=
TestOptions
.
ReleaseDll
)
[
lib
]
.
VerifyEmitDiagnostics
()
Dim
consumer1
=
CreateCompilationWithMscorlibAndVBRuntime
(
source
,
options
:
=
TestOptions
.
ReleaseExe
,
additionalRefs
:
=
{
[
lib
]
.
ToMetadataReference
()})
CompileAndVerify
(
consumer1
,
expectedOutput
:
=
expectedOutput
).
VerifyDiagnostics
()
Dim
consumer2
=
CreateCompilationWithMscorlibAndVBRuntime
(
source
,
options
:
=
TestOptions
.
ReleaseExe
,
additionalRefs
:
=
{
[
lib
]
.
EmitToImageReference
()})
CompileAndVerify
(
consumer2
,
expectedOutput
:
=
expectedOutput
).
VerifyDiagnostics
()
End
Sub
<
Fact
>
Public
Sub
UnifyUnderlyingWithTuple_12
()
Dim
source
=
<
compilation
>
<
file
name
=
"a.vb"
><
!
[
CDATA
[
Imports
System
Imports
System.Collections.Generic
Module
Module1
Sub
Main
()
Dim
x
?
=
(
1
,
3
)
Dim
s
As
String
=
x
System
.
Console
.
WriteLine
(
s
)
System
.
Console
.
WriteLine
(
CType
(
x
,
Long
))
Dim
y
As
(
Integer
,
String
)
?
=
New
KeyValuePair
(
Of
Integer
,
String
)(
2
,
"4"
)
System
.
Console
.
WriteLine
(
y
)
System
.
Console
.
WriteLine
(
CType
(
"5"
,
ValueTuple
(
Of
String
,
String
)))
System
.
Console
.
WriteLine
(
+
x
)
System
.
Console
.
WriteLine
(
-
x
)
System
.
Console
.
WriteLine
(
Not
x
)
System
.
Console
.
WriteLine
(
If
(
x
,
True
,
False
))
System
.
Console
.
WriteLine
(
If
(
Not
x
,
True
,
False
))
System
.
Console
.
WriteLine
(
x
+
1
)
System
.
Console
.
WriteLine
(
x
-
1
)
System
.
Console
.
WriteLine
(
x
*
3
)
System
.
Console
.
WriteLine
(
x
/
2
)
System
.
Console
.
WriteLine
(
x
\
2
)
System
.
Console
.
WriteLine
(
x
Mod
3
)
System
.
Console
.
WriteLine
(
x
&
3
)
System
.
Console
.
WriteLine
(
x
And
3
)
System
.
Console
.
WriteLine
(
x
Or
15
)
System
.
Console
.
WriteLine
(
x
Xor
3
)
System
.
Console
.
WriteLine
(
x
Like
15
)
System
.
Console
.
WriteLine
(
x
^
4
)
System
.
Console
.
WriteLine
(
x
<<
1
)
System
.
Console
.
WriteLine
(
x
>>
1
)
System
.
Console
.
WriteLine
(
x
=
1
)
System
.
Console
.
WriteLine
(
x
<>
1
)
System
.
Console
.
WriteLine
(
x
>
1
)
System
.
Console
.
WriteLine
(
x
<
1
)
System
.
Console
.
WriteLine
(
x
>=
1
)
System
.
Console
.
WriteLine
(
x
<=
1
)
End
Sub
End
Module
]]
></
file
>
</
compilation
>
Dim
tuple
=
<
compilation
>
<
file
name
=
"a.vb"
><
!
[
CDATA
[
Namespace
System
Public
Structure
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
Public
Overrides
Function
ToString
()
As
String
Return
"{"
+
Item1
?
.
ToString
()
+
", "
+
Item2
?
.
ToString
()
+
"}"
End
Function
Public
Shared
Widening
Operator
CType
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
String
Return
arg
.
ToString
()
End
Operator
Public
Shared
Narrowing
Operator
CType
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
Long
Return
CLng
(
CObj
(
arg
.
Value
.
Item1
)
+
CObj
(
arg
.
Value
.
Item2
))
End
Operator
Public
Shared
Widening
Operator
CType
(
arg
As
System
.
Collections
.
Generic
.
KeyValuePair
(
Of
T1
,
T2
))
As
ValueTuple
(
Of
T1
,
T2
)
?
Return
New
ValueTuple
(
Of
T1
,
T2
)(
arg
.
Key
,
arg
.
Value
)
End
Operator
Public
Shared
Narrowing
Operator
CType
(
arg
As
String
)
As
ValueTuple
(
Of
T1
,
T2
)
?
Return
New
ValueTuple
(
Of
T1
,
T2
)(
CType
(
CObj
(
arg
),
T1
),
CType
(
CObj
(
arg
),
T2
))
End
Operator
Public
Shared
Operator
+
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
ValueTuple
(
Of
T1
,
T2
)
?
Return
arg
End
Operator
Public
Shared
Operator
-
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
Long
Return
-
CType
(
arg
,
Long
)
End
Operator
Public
Shared
Operator
Not
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
Boolean
Return
CType
(
arg
,
Long
)
=
0
End
Operator
Public
Shared
Operator
IsTrue
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
Boolean
Return
CType
(
arg
,
Long
)
<>
0
End
Operator
Public
Shared
Operator
IsFalse
(
arg
As
ValueTuple
(
Of
T1
,
T2
)
?
)
As
Boolean
Return
CType
(
arg
,
Long
)
=
0
End
Operator
Public
Shared
Operator
+
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
+
arg2
End
Operator
Public
Shared
Operator
-
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
-
arg2
End
Operator
Public
Shared
Operator
*
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
*
arg2
End
Operator
Public
Shared
Operator
/
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
/
arg2
End
Operator
Public
Shared
Operator
\
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
\
arg2
End
Operator
Public
Shared
Operator
Mod
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
Mod
arg2
End
Operator
Public
Shared
Operator
&
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
&
arg2
End
Operator
Public
Shared
Operator
And
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
And
arg2
End
Operator
Public
Shared
Operator
Or
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Or
arg2
End
Operator
Public
Shared
Operator
Xor
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Xor
arg2
End
Operator
Public
Shared
Operator
Like
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Long
)
As
Long
Return
CType
(
arg1
,
Long
)
Or
arg2
End
Operator
Public
Shared
Operator
^
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
^
arg2
End
Operator
Public
Shared
Operator
<<
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
<<
arg2
End
Operator
Public
Shared
Operator
>>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Long
Return
CType
(
arg1
,
Long
)
>>
arg2
End
Operator
Public
Shared
Operator
=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
=
arg2
End
Operator
Public
Shared
Operator
<>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<>
arg2
End
Operator
Public
Shared
Operator
>
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
>
arg2
End
Operator
Public
Shared
Operator
<
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<
arg2
End
Operator
Public
Shared
Operator
>=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
>=
arg2
End
Operator
Public
Shared
Operator
<=
(
arg1
As
ValueTuple
(
Of
T1
,
T2
)
?
,
arg2
As
Integer
)
As
Boolean
Return
CType
(
arg1
,
Long
)
<=
arg2
End
Operator
Public
Overrides
Function
Equals
(
obj
As
Object
)
As
Boolean
Return
False
End
Function
Public
Overrides
Function
GetHashCode
()
As
Integer
Return
0
End
Function
End
Structure
End
Namespace
]]
></
file
>
</
compilation
>
Dim
expectedOutput
=
"{1, 3}
4
{2, 4}
{5, 5}
{1, 3}
-4
False
True
False
5
3
12
2
2
1
43
0
15
7
15
256
8
2
False
True
True
False
True
False
"
Dim
[
lib
]
=
CreateCompilationWithMscorlibAndVBRuntime
(
tuple
,
options
:
=
TestOptions
.
ReleaseDll
)
[
lib
]
.
VerifyEmitDiagnostics
()
Dim
consumer1
=
CreateCompilationWithMscorlibAndVBRuntime
(
source
,
options
:
=
TestOptions
.
ReleaseExe
,
additionalRefs
:
=
{
[
lib
]
.
ToMetadataReference
()})
CompileAndVerify
(
consumer1
,
expectedOutput
:
=
expectedOutput
).
VerifyDiagnostics
()
Dim
consumer2
=
CreateCompilationWithMscorlibAndVBRuntime
(
source
,
options
:
=
TestOptions
.
ReleaseExe
,
additionalRefs
:
=
{
[
lib
]
.
EmitToImageReference
()})
CompileAndVerify
(
consumer2
,
expectedOutput
:
=
expectedOutput
).
VerifyDiagnostics
()
End
Sub
End
Class
End
Namespace
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录