Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
b7913a66
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,发现更多精彩内容 >>
未验证
提交
b7913a66
编写于
8月 04, 2020
作者:
A
AlekseyTs
提交者:
GitHub
8月 04, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Enable `with` expression on generic type paramteres constrained to a record type. (#46531)
Fixes #46249.
上级
e1ba4121
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
256 addition
and
20 deletion
+256
-20
src/Compilers/CSharp/Portable/Binder/Binder_WithExpression.cs
...Compilers/CSharp/Portable/Binder/Binder_WithExpression.cs
+1
-1
src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
+255
-19
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_WithExpression.cs
浏览文件 @
b7913a66
...
@@ -38,7 +38,7 @@ private BoundExpression BindWithExpression(WithExpressionSyntax syntax, Diagnost
...
@@ -38,7 +38,7 @@ private BoundExpression BindWithExpression(WithExpressionSyntax syntax, Diagnost
{
{
HashSet
<
DiagnosticInfo
>?
useSiteDiagnostics
=
null
;
HashSet
<
DiagnosticInfo
>?
useSiteDiagnostics
=
null
;
cloneMethod
=
SynthesizedRecordClone
.
FindValidCloneMethod
(
receiverType
,
ref
useSiteDiagnostics
);
cloneMethod
=
SynthesizedRecordClone
.
FindValidCloneMethod
(
receiverType
is
TypeParameterSymbol
typeParameter
?
typeParameter
.
EffectiveBaseClass
(
ref
useSiteDiagnostics
)
:
receiverType
,
ref
useSiteDiagnostics
);
if
(
cloneMethod
is
null
)
if
(
cloneMethod
is
null
)
{
{
hasErrors
=
true
;
hasErrors
=
true
;
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/RecordTests.cs
浏览文件 @
b7913a66
...
@@ -1604,7 +1604,7 @@ public static void Main()
...
@@ -1604,7 +1604,7 @@ public static void Main()
);
);
}
}
[Fact, WorkItem(46427, "https://github.com/dotnet/roslyn/issues/46427")]
[Fact, WorkItem(46427, "https://github.com/dotnet/roslyn/issues/46427")
, WorkItem(46249, "https://github.com/dotnet/roslyn/issues/46249")
]
public void WithExpr25_TypeParameterWithRecordConstraint()
public void WithExpr25_TypeParameterWithRecordConstraint()
{
{
var src = @"
var src = @"
...
@@ -1612,39 +1612,91 @@ public void WithExpr25_TypeParameterWithRecordConstraint()
...
@@ -1612,39 +1612,91 @@ public void WithExpr25_TypeParameterWithRecordConstraint()
class C
class C
{
{
public static
void
M<T>(T t) where T : R
public static
T
M<T>(T t) where T : R
{
{
_ = t with { X = 2 };
return t with { X = 2 };
}
static void Main()
{
System.Console.Write(M(new R(-1)).X);
}
}
}";
}";
var comp = CreateCompilation(src);
comp.VerifyDiagnostics(
var verifier = CompileAndVerify(src, expectedOutput: "2").VerifyDiagnostics();
// (8,13): error CS8858: The receiver type 'T' is not a valid record type.
verifier.VerifyIL("C.M<T>(T)", @"
// _ = t with { X = 2 };
{
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("T").WithLocation(8, 13)
// Code size 29 (0x1d)
);
.maxstack 3
IL_0000: ldarg.0
IL_0001: box ""T""
IL_0006: callvirt ""R R.<Clone>$()""
IL_000b: unbox.any ""T""
IL_0010: dup
IL_0011: box ""T""
IL_0016: ldc.i4.2
IL_0017: callvirt ""void R.X.init""
IL_001c: ret
}
");
}
}
[Fact, WorkItem(46427, "https://github.com/dotnet/roslyn/issues/46427")]
[Fact, WorkItem(46427, "https://github.com/dotnet/roslyn/issues/46427")
, WorkItem(46249, "https://github.com/dotnet/roslyn/issues/46249")
]
public void WithExpr26_TypeParameterWithRecordAndInterfaceConstraint()
public void WithExpr26_TypeParameterWithRecordAndInterfaceConstraint()
{
{
var src = @"
var src = @"
record R(int X);
record R
{
public int X { get; set; }
}
interface I { int Property { get; set; } }
interface I { int Property { get; set; } }
record T : R, I
{
public int Property { get; set; }
}
class C
class C
{
{
public static
void
M<T>(T t) where T : R, I
public static
T
M<T>(T t) where T : R, I
{
{
_ = t with { X = 2, Property = 3 };
return t with { X = 2, Property = 3 };
}
static void Main()
{
System.Console.WriteLine(M(new T()).X);
System.Console.WriteLine(M(new T()).Property);
}
}
}";
}";
var comp = CreateCompilation(src);
comp.VerifyDiagnostics(
var verifier = CompileAndVerify(
// (9,13): error CS8858: The receiver type 'T' is not a valid record type.
new[] { src, IsExternalInitTypeDefinition },
// _ = t with { X = 2, Property = 3 };
parseOptions: TestOptions.RegularPreview,
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("T").WithLocation(9, 13)
verify: Verification.Passes,
);
expectedOutput:
@"2
3").VerifyDiagnostics();
verifier.VerifyIL("C.M<T>(T)", @"
{
// Code size 41 (0x29)
.maxstack 3
IL_0000: ldarg.0
IL_0001: box ""T""
IL_0006: callvirt ""R R.<Clone>$()""
IL_000b: unbox.any ""T""
IL_0010: dup
IL_0011: box ""T""
IL_0016: ldc.i4.2
IL_0017: callvirt ""void R.X.set""
IL_001c: dup
IL_001d: box ""T""
IL_0022: ldc.i4.3
IL_0023: callvirt ""void I.Property.set""
IL_0028: ret
}
");
}
}
[Fact]
[Fact]
...
@@ -1727,6 +1779,190 @@ void M()
...
@@ -1727,6 +1779,190 @@ void M()
);
);
}
}
[Fact]
public void WithExpr30_TypeParameterNoConstraint()
{
var src = @"
class C
{
public static void M<T>(T t)
{
_ = t with { X = 2 };
}
}";
var comp = CreateCompilation(src);
comp.VerifyDiagnostics(
// (6,13): error CS8858: The receiver type 'T' is not a valid record type.
// _ = t with { X = 2 };
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("T").WithLocation(6, 13),
// (6,22): error CS0117: 'T' does not contain a definition for 'X'
// _ = t with { X = 2 };
Diagnostic(ErrorCode.ERR_NoSuchMember, "X").WithArguments("T", "X").WithLocation(6, 22)
);
}
[Fact]
public void WithExpr31_TypeParameterWithInterfaceConstraint()
{
var src = @"
interface I { int Property { get; set; } }
class C
{
public static void M<T>(T t) where T : I
{
_ = t with { X = 2, Property = 3 };
}
}";
var comp = CreateCompilation(src);
comp.VerifyDiagnostics(
// (8,13): error CS8858: The receiver type 'T' is not a valid record type.
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("T").WithLocation(8, 13),
// (8,22): error CS0117: 'T' does not contain a definition for 'X'
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSuchMember, "X").WithArguments("T", "X").WithLocation(8, 22)
);
}
[Fact]
public void WithExpr32_TypeParameterWithInterfaceConstraint()
{
var ilSource = @"
.class interface public auto ansi abstract I
{
// Methods
.method public hidebysig specialname newslot abstract virtual
instance class I '" + WellKnownMemberNames.CloneMethodName + @"' () cil managed
{
} // end of method I::'" + WellKnownMemberNames.CloneMethodName + @"'
.method public hidebysig specialname newslot abstract virtual
instance int32 get_Property () cil managed
{
} // end of method I::get_Property
.method public hidebysig specialname newslot abstract virtual
instance void set_Property (
int32 'value'
) cil managed
{
} // end of method I::set_Property
// Properties
.property instance int32 Property()
{
.get instance int32 I::get_Property()
.set instance void I::set_Property(int32)
}
} // end of class I
";
var src = @"
class C
{
public static void M<T>(T t) where T : I
{
_ = t with { X = 2, Property = 3 };
}
}";
var comp = CreateCompilationWithIL(new[] { src, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (6,13): error CS8858: The receiver type 'T' is not a valid record type.
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("T").WithLocation(6, 13),
// (6,22): error CS0117: 'T' does not contain a definition for 'X'
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSuchMember, "X").WithArguments("T", "X").WithLocation(6, 22)
);
}
[Fact]
public void WithExpr33_TypeParameterWithStructureConstraint()
{
var ilSource = @"
.class public sequential ansi sealed beforefieldinit S
extends System.ValueType
{
.pack 0
.size 1
// Methods
.method public hidebysig
instance valuetype S '" + WellKnownMemberNames.CloneMethodName + @"' () cil managed
{
// Method begins at RVA 0x2150
// Code size 2 (0x2)
.maxstack 1
.locals init (
[0] valuetype S
)
IL_0000: ldnull
IL_0001: throw
} // end of method S::'" + WellKnownMemberNames.CloneMethodName + @"'
.method public hidebysig specialname
instance int32 get_Property () cil managed
{
// Method begins at RVA 0x215e
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: throw
} // end of method S::get_Property
.method public hidebysig specialname
instance void set_Property (
int32 'value'
) cil managed
{
// Method begins at RVA 0x215e
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: throw
} // end of method S::set_Property
// Properties
.property instance int32 Property()
{
.get instance int32 S::get_Property()
.set instance void S::set_Property(int32)
}
} // end of class S
";
var src = @"
abstract class Base<T>
{
public abstract void M<U>(U t) where U : T;
}
class C : Base<S>
{
public override void M<U>(U t)
{
_ = t with { X = 2, Property = 3 };
}
}";
var comp = CreateCompilationWithIL(new[] { src, IsExternalInitTypeDefinition }, ilSource: ilSource, parseOptions: TestOptions.RegularPreview);
comp.VerifyDiagnostics(
// (11,13): error CS8858: The receiver type 'U' is not a valid record type.
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSingleCloneMethod, "t").WithArguments("U").WithLocation(11, 13),
// (11,22): error CS0117: 'U' does not contain a definition for 'X'
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSuchMember, "X").WithArguments("U", "X").WithLocation(11, 22),
// (11,29): error CS0117: 'U' does not contain a definition for 'Property'
// _ = t with { X = 2, Property = 3 };
Diagnostic(ErrorCode.ERR_NoSuchMember, "Property").WithArguments("U", "Property").WithLocation(11, 29)
);
}
[Fact]
[Fact]
public void TypeNamedRecord()
public void TypeNamedRecord()
{
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录