提交 7e7ea6a9 编写于 作者: V vsadov

rebased onto the recent merge from master

上级 4e84ece8
......@@ -173,7 +173,7 @@ private BoundExpression CheckValue(BoundExpression expr, BindValueKind valueKind
return expr;
case BoundKind.DiscardExpression:
Debug.Assert(valueKind == BindValueKind.Assignable || valueKind == BindValueKind.RefOrOut);
Debug.Assert(valueKind == BindValueKind.Assignable || valueKind == BindValueKind.RefOrOut || diagnostics.HasAnyResolvedErrors());
return expr;
}
......@@ -274,11 +274,6 @@ internal bool CheckValueKind(SyntaxNode node, BoundExpression expr, BindValueKin
case BoundKind.EventAccess:
return CheckEventValueKind((BoundEventAccess)expr, valueKind, diagnostics);
//PROTOTYPE(readonlyeRefs): this is incorrect and fixed in master. Update when merged.
case BoundKind.DynamicMemberAccess:
case BoundKind.DynamicIndexerAccess:
return true;
}
// easy out for a very common RValue case.
......@@ -350,6 +345,19 @@ internal bool CheckValueKind(SyntaxNode node, BoundExpression expr, BindValueKin
}
break;
case BoundKind.DynamicMemberAccess:
case BoundKind.DynamicIndexerAccess:
// dynamic expressions can be read and written to
// can even be passed by reference (which is implemented via a temp)
// it is not valid to return them by reference though.
if (RequiresReturnableReference(valueKind))
{
Error(diagnostics, ErrorCode.ERR_RefReturnLvalueExpected, expr.Syntax);
return false;
}
return true;
case BoundKind.Parameter:
var parameter = (BoundParameter)expr;
return CheckParameterValueKind(node, parameter, valueKind, checkingReceiver, diagnostics);
......
......@@ -582,7 +582,9 @@ private void EmitArgument(BoundExpression argument, RefKind refKind)
else
{
var temp = EmitAddress(argument, AddressKind.Writeable);
Debug.Assert(temp == null, "passing args byref should not clone them into temps");
// Dynamic is allowed to be passed by reference, via a temp.
Debug.Assert(temp == null || argument.Type.IsDynamic(), "passing args byref should not clone them into temps");
}
}
......
......@@ -2836,6 +2836,7 @@ static void Main()
);
}
[Fact]
[WorkItem(16947, "https://github.com/dotnet/roslyn/issues/16947")]
public void Dynamic001()
{
......@@ -2853,18 +2854,28 @@ public void M()
public static ref dynamic F(ref dynamic d)
{
// this is ok
F1(ref d.Length);
// this is an error
return ref d.Length;
}
public static void F1(ref dynamic d)
{
}
}
";
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyEmitDiagnostics(
// (14,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// (18,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref d.Length;
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d.Length").WithLocation(14, 20)
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d.Length").WithLocation(18, 20)
);
}
[Fact]
[WorkItem(16947, "https://github.com/dotnet/roslyn/issues/16947")]
public void Dynamic002()
{
......@@ -2882,19 +2893,27 @@ public void M()
public static ref dynamic F(ref dynamic d)
{
// this is ok
F1(ref d[0]);
return ref d[0];
}
public static void F1(ref dynamic d)
{
}
}
";
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyEmitDiagnostics(
// (14,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// (17,20): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref d[0];
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d[0]").WithLocation(14, 20)
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d[0]").WithLocation(17, 20)
);
}
[Fact]
[WorkItem(16947, "https://github.com/dotnet/roslyn/issues/16947")]
public void Dynamic003()
{
......@@ -2924,13 +2943,12 @@ public void M()
";
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyEmitDiagnostics(
// (14,28): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// (14,26): error CS8156: An expression cannot be used in this context because it may not be returned by reference
// return ref G(ref d.Length);
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d.Length").WithLocation(14, 28),
Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "d.Length").WithLocation(14, 26),
// (14,20): error CS8164: Cannot return by reference a result of 'C.G(ref dynamic)' because the argument passed to parameter 'd' cannot be returned by reference
// return ref G(ref d.Length);
Diagnostic(ErrorCode.ERR_RefReturnCall, "G(ref d.Length)").WithArguments("C.G(ref dynamic)", "d").WithLocation(14, 20)
Diagnostic(ErrorCode.ERR_RefReturnCall, "G(ref d.Length)").WithArguments("C.G(ref dynamic)", "d")
);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册