提交 a4239cbc 编写于 作者: A AlekseyTs 提交者: GitHub

Ensure complete information is consistently captured in a bound tree for an...

Ensure complete information is consistently captured in a bound tree for an explicit C# conversion implicitly applied by compiler. (#22703)

Fixes #7299. Fixes #19878
上级 9a09a707
......@@ -6463,15 +6463,9 @@ private BoundExpression ConvertToArrayIndex(BoundExpression index, SyntaxNode no
Conversion failedConversion = this.Conversions.ClassifyConversionFromExpression(index, int32, ref useSiteDiagnostics);
diagnostics.Add(node, useSiteDiagnostics);
GenerateImplicitConversionError(diagnostics, node, failedConversion, index, int32);
return new BoundConversion(
index.Syntax,
index,
failedConversion,
CheckOverflowAtRuntime,
explicitCastInCode: false,
constantValueOpt: ConstantValue.NotAvailable,
type: int32,
hasErrors: true);
// Suppress any additional diagnostics
return CreateConversion(index.Syntax, index, failedConversion, isCast: false, destination: int32, diagnostics: new DiagnosticBag());
}
return result;
......
......@@ -1518,23 +1518,8 @@ internal BoundExpression GenerateConversionForAssignment(TypeSymbol targetType,
GenerateImplicitConversionError(diagnostics, expression.Syntax, conversion, expression, targetType);
}
if (conversion.IsTupleLiteralConversion ||
(conversion.IsNullable && conversion.UnderlyingConversions[0].IsTupleLiteralConversion))
{
// Follow-up issue https://github.com/dotnet/roslyn/issues/19878
// How should we represent the tuple or nullable+tuple conversion in this case?
conversion = Conversion.NoConversion;
}
return new BoundConversion(
expression.Syntax,
expression,
conversion,
@checked: CheckOverflowAtRuntime,
explicitCastInCode: false,
constantValueOpt: ConstantValue.NotAvailable,
type: targetType,
hasErrors: true);
// Suppress any additional diagnostics
diagnostics = new DiagnosticBag();
}
return CreateConversion(expression.Syntax, expression, conversion, false, targetType, diagnostics);
......
......@@ -15,7 +15,7 @@ internal sealed partial class CSharpOperationFactory
{
private static Optional<object> ConvertToOptional(ConstantValue value)
{
return value != null ? new Optional<object>(value.Value) : default(Optional<object>);
return value != null && !value.IsBad ? new Optional<object>(value.Value) : default(Optional<object>);
}
private ImmutableArray<IOperation> ToStatements(BoundStatement statement)
......
......@@ -6391,7 +6391,13 @@ static void Main()
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, @"((long c, string d))(1, ""hello"")").WithArguments("(long c, string d)", "(short a, string b)").WithLocation(13, 34),
// (7,25): warning CS0219: The variable 'x1' is assigned but its value is never used
// (short, string) x1 = (1, "hello");
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x1").WithArguments("x1").WithLocation(7, 25)
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x1").WithArguments("x1").WithLocation(7, 25),
// (10,25): warning CS0219: The variable 'x2' is assigned but its value is never used
// (short, string) x2 = ((long, string))(1, "hello");
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x2").WithArguments("x2").WithLocation(10, 25),
// (13,29): warning CS0219: The variable 'x3' is assigned but its value is never used
// (short a, string b) x3 = ((long c, string d))(1, "hello");
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x3").WithArguments("x3").WithLocation(13, 29)
);
}
......@@ -7454,7 +7460,13 @@ static void Main()
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "((int c, int d))(e: 1, f:2)").WithArguments("(int c, int d)", "(short a, short b)").WithLocation(9, 33),
// (12,56): error CS0030: Cannot convert type 'string' to 'long'
// (int a, int b) x3 = ((long c, long d))(e: 1, f:"qq");
Diagnostic(ErrorCode.ERR_NoExplicitConv, @"""qq""").WithArguments("string", "long").WithLocation(12, 56)
Diagnostic(ErrorCode.ERR_NoExplicitConv, @"""qq""").WithArguments("string", "long").WithLocation(12, 56),
// (7,24): warning CS0219: The variable 'x1' is assigned but its value is never used
// (int a, int b) x1 = ((long c, long d))(e: 1, f:2);
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x1").WithArguments("x1").WithLocation(7, 24),
// (9,28): warning CS0219: The variable 'x2' is assigned but its value is never used
// (short a, short b) x2 = ((int c, int d))(e: 1, f:2);
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "x2").WithArguments("x2").WithLocation(9, 28)
);
}
......@@ -23664,7 +23676,7 @@ .maxstack 3
[Fact]
[WorkItem(18738, "https://github.com/dotnet/roslyn/issues/18738")]
public void TypelessTupleWithNoImplicitConversion()
public void TypelessTupleWithNoImplicitConversion_01()
{
var source = @"
class C
......@@ -23684,27 +23696,58 @@ void M()
// (int, string) y = (e, null);
Diagnostic(ErrorCode.ERR_NoImplicitConv, "e").WithArguments("int?", "int").WithLocation(7, 28)
);
VerifySemanticModelTypelessTupleWithNoImplicitConversion(comp);
}
private static void VerifySemanticModelTypelessTupleWithNoImplicitConversion(CSharpCompilation comp)
{
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var tuple = tree.GetRoot().DescendantNodes().OfType<TupleExpressionSyntax>().Single();
Assert.Null(model.GetTypeInfo(tuple).Type);
Assert.Equal("(System.Int32, System.String)", model.GetTypeInfo(tuple).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.NoConversion, model.GetConversion(tuple).Kind);
Assert.Equal(ConversionKind.ExplicitTupleLiteral, model.GetConversion(tuple).Kind);
var first = tuple.Arguments[0].Expression;
Assert.Equal("System.Int32?", model.GetTypeInfo(first).Type.ToTestDisplayString());
Assert.Equal("System.Int32?", model.GetTypeInfo(first).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.Identity, model.GetConversion(first).Kind);
Assert.Equal("System.Int32", model.GetTypeInfo(first).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.ExplicitNullable, model.GetConversion(first).Kind);
var second = tuple.Arguments[1].Expression;
Assert.Null(model.GetTypeInfo(second).Type);
Assert.Null(model.GetTypeInfo(second).ConvertedType);
Assert.Equal(ConversionKind.Identity, model.GetConversion(second).Kind);
Assert.Equal("System.String", model.GetTypeInfo(second).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.ImplicitReference, model.GetConversion(second).Kind);
}
[Fact]
[WorkItem(18738, "https://github.com/dotnet/roslyn/issues/18738")]
public void TypelessTupleWithNoImplicitConversion_02()
{
var source = @"
class C
{
(int, string) M()
{
int? e = 5;
return (e, null); // the only conversion we find is an explicit conversion
}
}
";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1),
references: new[] { MscorlibRef, ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
// (7,17): error CS0029: Cannot implicitly convert type 'int?' to 'int'
// return (e, null); // the only conversion we find is an explicit conversion
Diagnostic(ErrorCode.ERR_NoImplicitConv, "e").WithArguments("int?", "int").WithLocation(7, 17)
);
VerifySemanticModelTypelessTupleWithNoImplicitConversion(comp);
}
[Fact]
[WorkItem(18738, "https://github.com/dotnet/roslyn/issues/18738")]
public void TypelessTupleWithNoImplicitConversion2()
public void TypelessTupleWithNoImplicitConversion2_01()
{
var source = @"
class C
......@@ -23724,22 +23767,53 @@ void M()
// (int, string)? y = (e, null); // the only conversion we find is an explicit conversion
Diagnostic(ErrorCode.ERR_ConversionNotTupleCompatible, "(e, null)").WithArguments("2", "(int, string)?").WithLocation(7, 28)
);
VerifySemanticModelTypelessTupleWithNoImplicitConversion2(comp);
}
private static void VerifySemanticModelTypelessTupleWithNoImplicitConversion2(CSharpCompilation comp)
{
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var tuple = tree.GetRoot().DescendantNodes().OfType<TupleExpressionSyntax>().Single();
Assert.Null(model.GetTypeInfo(tuple).Type);
Assert.Equal("(System.Int32, System.String)?", model.GetTypeInfo(tuple).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.NoConversion, model.GetConversion(tuple).Kind);
Assert.Equal(ConversionKind.ExplicitNullable, model.GetConversion(tuple).Kind);
var first = tuple.Arguments[0].Expression;
Assert.Equal("System.Int32?", model.GetTypeInfo(first).Type.ToTestDisplayString());
Assert.Equal("System.Int32?", model.GetTypeInfo(first).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.Identity, model.GetConversion(first).Kind);
Assert.Equal("System.Int32", model.GetTypeInfo(first).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.ExplicitNullable, model.GetConversion(first).Kind);
var second = tuple.Arguments[1].Expression;
Assert.Null(model.GetTypeInfo(second).Type);
Assert.Null(model.GetTypeInfo(second).ConvertedType);
Assert.Equal(ConversionKind.Identity, model.GetConversion(second).Kind);
Assert.Equal("System.String", model.GetTypeInfo(second).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.ImplicitReference, model.GetConversion(second).Kind);
}
[Fact]
[WorkItem(18738, "https://github.com/dotnet/roslyn/issues/18738")]
public void TypelessTupleWithNoImplicitConversion2_02()
{
var source = @"
class C
{
(int, string)? M()
{
int? e = 5;
return (e, null); // the only conversion we find is an explicit conversion
}
}
";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1),
references: new[] { MscorlibRef, ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyDiagnostics(
// (7,16): error CS8135: Tuple with 2 elements cannot be converted to type '(int, string)?'.
// return (e, null); // the only conversion we find is an explicit conversion
Diagnostic(ErrorCode.ERR_ConversionNotTupleCompatible, "(e, null)").WithArguments("2", "(int, string)?").WithLocation(7, 16)
);
VerifySemanticModelTypelessTupleWithNoImplicitConversion2(comp);
}
[Fact]
......
......@@ -912,5 +912,36 @@ public void F()
VerifyOperationTreeAndDiagnosticsForTest<ArrayCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")]
public void SimpleArrayCreation_ConstantConversion()
{
string source = @"
class C
{
public void F()
{
var a = /*<bind>*/new string[0.0]/*</bind>*/;
}
}
";
string expectedOperationTree = @"
IArrayCreationExpression (OperationKind.ArrayCreationExpression, Type: System.String[], IsInvalid) (Syntax: 'new string[0.0]')
Dimension Sizes(1):
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
Initializer:
null
";
var expectedDiagnostics = new DiagnosticDescription[] {
// (6,27): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
// var a = /*<bind>*/new string[0.0]/*</bind>*/;
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "new string[0.0]").WithArguments("double", "int").WithLocation(6, 27)
};
VerifyOperationTreeAndDiagnosticsForTest<ArrayCreationExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......@@ -1397,7 +1397,7 @@ void M2(int x = ""string"")
IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: P, IsImplicit) (Syntax: 'M2')
Arguments(1):
IArgument (ArgumentKind.DefaultValue, Matching Parameter: x) (OperationKind.Argument, IsImplicit) (Syntax: 'M2()')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: null) (Syntax: 'M2()')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32) (Syntax: 'M2()')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
";
......
......@@ -264,15 +264,18 @@ enum Enum1
Variables: Local_1: Enum1 e1
Initializer:
IVariableInitializer (OperationKind.VariableInitializer, IsInvalid) (Syntax: '= 1')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: Enum1, IsInvalid, IsImplicit) (Syntax: '1')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: Enum1, Constant: 1, IsInvalid, IsImplicit) (Syntax: '1')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1, IsInvalid) (Syntax: '1')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0266: Cannot implicitly convert type 'int' to 'Program.Enum1'. An explicit conversion exists (are you missing a cast?)
// (5,30): error CS0266: Cannot implicitly convert type 'int' to 'Enum1'. An explicit conversion exists (are you missing a cast?)
// Enum1 /*<bind>*/e1 = 1/*</bind>*/;
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1").WithArguments("int", "Enum1").WithLocation(5, 30),
// (5,25): warning CS0219: The variable 'e1' is assigned but its value is never used
// Enum1 /*<bind>*/e1 = 1/*</bind>*/;
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1").WithArguments("int", "Enum1").WithLocation(5, 30)
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "e1").WithArguments("e1").WithLocation(5, 25)
};
VerifyOperationTreeAndDiagnosticsForTest<VariableDeclaratorSyntax>(source, expectedOperationTree, expectedDiagnostics,
......@@ -2671,9 +2674,12 @@ void M1()
ILocalReferenceExpression: i1 (OperationKind.LocalReferenceExpression, Type: System.Int32, Constant: 4096, IsInvalid) (Syntax: 'i1')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0031: Constant value '4096' cannot be converted to a 'sbyte'
// (7,36): error CS0031: Constant value '4096' cannot be converted to a 'sbyte'
// const sbyte /*<bind>*/s1 = i1/*</bind>*/;
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "i1").WithArguments("4096", "sbyte").WithLocation(7, 36),
// (7,31): warning CS0219: The variable 's1' is assigned but its value is never used
// const sbyte /*<bind>*/s1 = i1/*</bind>*/;
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "i1").WithArguments("4096", "sbyte").WithLocation(7, 36)
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s1").WithArguments("s1").WithLocation(7, 31)
};
VerifyOperationTreeAndDiagnosticsForTest<VariableDeclaratorSyntax>(source, expectedOperationTree, expectedDiagnostics,
......@@ -3485,7 +3491,7 @@ public void M1()
Variables: Local_1: System.Int32 i
Initializer:
IVariableInitializer (OperationKind.VariableInitializer, IsInvalid) (Syntax: '= (float)1.0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid, IsImplicit) (Syntax: '(float)1.0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 1, IsInvalid, IsImplicit) (Syntax: '(float)1.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Single, Constant: 1, IsInvalid) (Syntax: '(float)1.0')
......@@ -3494,9 +3500,12 @@ public void M1()
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 1, IsInvalid) (Syntax: '1.0')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?)
// (6,27): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?)
// int /*<bind>*/i = (float)1.0/*</bind>*/;
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(float)1.0").WithArguments("float", "int").WithLocation(6, 27)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(float)1.0").WithArguments("float", "int").WithLocation(6, 27),
// (6,23): warning CS0219: The variable 'i' is assigned but its value is never used
// int /*<bind>*/i = (float)1.0/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "i").WithArguments("i").WithLocation(6, 23)
};
VerifyOperationTreeAndDiagnosticsForTest<VariableDeclaratorSyntax>(source, expectedOperationTree, expectedDiagnostics);
......@@ -3689,7 +3698,7 @@ enum E2 : byte
Variables: Local_1: E2 e2
Initializer:
IVariableInitializer (OperationKind.VariableInitializer, IsInvalid) (Syntax: '= (E2)E1.One')
IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: E2, Constant: null, IsInvalid) (Syntax: '(E2)E1.One')
IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: E2, IsInvalid) (Syntax: '(E2)E1.One')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
IFieldReferenceExpression: E1.One (Static) (OperationKind.FieldReferenceExpression, Type: E1, Constant: 1000, IsInvalid) (Syntax: 'E1.One')
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......@@ -104,5 +104,35 @@ static IEnumerable<int> Method()
VerifyOperationTreeAndDiagnosticsForTest<YieldStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")]
public void Return_ConstantConversions_01()
{
string source = @"
class C
{
static float Method()
{
/*<bind>*/return 0.0;/*</bind>*/
}
}
";
string expectedOperationTree = @"
IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'return 0.0;')
ReturnedValue:
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Single, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// (6,26): error CS0664: Literal of type double cannot be implicitly converted to type 'float'; use an 'F' suffix to create a literal of this type
// /*<bind>*/return 0.0;/*</bind>*/
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "0.0").WithArguments("F", "float").WithLocation(6, 26)
};
VerifyOperationTreeAndDiagnosticsForTest<ReturnStatementSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
......@@ -372,5 +372,60 @@ class C
VerifyOperationTreeAndDiagnosticsForTest<EqualsValueClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")]
public void FieldInitializer_ConstantConversions_01()
{
string source = @"
class C
{
private float f /*<bind>*/= 0.0/*</bind>*/;
}
";
string expectedOperationTree = @"
IFieldInitializer (Field: System.Single C.f) (OperationKind.FieldInitializer, IsInvalid) (Syntax: '= 0.0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Single, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// (4,33): error CS0664: Literal of type double cannot be implicitly converted to type 'float'; use an 'F' suffix to create a literal of this type
// private float f /*<bind>*/= 0.0/*</bind>*/;
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "0.0").WithArguments("F", "float").WithLocation(4, 33),
// (4,19): warning CS0414: The field 'C.f' is assigned but its value is never used
// private float f /*<bind>*/= 0.0/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "f").WithArguments("C.f").WithLocation(4, 19)
};
VerifyOperationTreeAndDiagnosticsForTest<EqualsValueClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")]
public void FieldInitializer_ConstantConversions_02()
{
string source = @"
class C
{
private float f /*<bind>*/= 0/*</bind>*/;
}
";
string expectedOperationTree = @"
IFieldInitializer (Field: System.Single C.f) (OperationKind.FieldInitializer) (Syntax: '= 0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Single, Constant: 0, IsImplicit) (Syntax: '0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// (4,19): warning CS0414: The field 'C.f' is assigned but its value is never used
// private float f /*<bind>*/= 0/*</bind>*/;
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "f").WithArguments("C.f").WithLocation(4, 19)
};
VerifyOperationTreeAndDiagnosticsForTest<EqualsValueClauseSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
......@@ -863,17 +863,26 @@ public void M(C c1)
}
";
string expectedOperationTree = @"
ITupleExpression (OperationKind.TupleExpression, Type: (C, C c1), IsInvalid) (Syntax: '(new C(0), c1)')
ITupleExpression (OperationKind.TupleExpression, Type: (System.Int16, System.String c1), IsInvalid) (Syntax: '(new C(0), c1)')
Elements(2):
IObjectCreationExpression (Constructor: C..ctor(System.Int32 x)) (OperationKind.ObjectCreationExpression, Type: C, IsInvalid) (Syntax: 'new C(0)')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, IsInvalid) (Syntax: '0')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
IParameterReferenceExpression: c1 (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'c1')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int16, IsInvalid, IsImplicit) (Syntax: 'new C(0)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperatorMethod: System.Int32 C.op_Implicit(C c)) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid, IsImplicit) (Syntax: 'new C(0)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: True) (MethodSymbol: System.Int32 C.op_Implicit(C c))
Operand:
IObjectCreationExpression (Constructor: C..ctor(System.Int32 x)) (OperationKind.ObjectCreationExpression, Type: C, IsInvalid) (Syntax: 'new C(0)')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, IsInvalid) (Syntax: '0')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperatorMethod: System.String C.op_Implicit(C c)) (OperationKind.ConversionExpression, Type: System.String, IsImplicit) (Syntax: 'c1')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: True) (MethodSymbol: System.String C.op_Implicit(C c))
Operand:
IParameterReferenceExpression: c1 (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'c1')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0029: Cannot implicitly convert type 'C' to 'short'
......@@ -928,19 +937,28 @@ public void M(C c1)
Initializer:
IVariableInitializer (OperationKind.VariableInitializer, IsInvalid) (Syntax: '= (new C(0), c1)')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: (System.Int16, System.String), IsInvalid, IsImplicit) (Syntax: '(new C(0), c1)')
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ITupleExpression (OperationKind.TupleExpression, Type: (C, C c1), IsInvalid) (Syntax: '(new C(0), c1)')
ITupleExpression (OperationKind.TupleExpression, Type: (System.Int16, System.String c1), IsInvalid) (Syntax: '(new C(0), c1)')
Elements(2):
IObjectCreationExpression (Constructor: C..ctor(System.Int32 x)) (OperationKind.ObjectCreationExpression, Type: C, IsInvalid) (Syntax: 'new C(0)')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, IsInvalid) (Syntax: '0')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
IParameterReferenceExpression: c1 (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'c1')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int16, IsInvalid, IsImplicit) (Syntax: 'new C(0)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperatorMethod: System.Int32 C.op_Implicit(C c)) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid, IsImplicit) (Syntax: 'new C(0)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: True) (MethodSymbol: System.Int32 C.op_Implicit(C c))
Operand:
IObjectCreationExpression (Constructor: C..ctor(System.Int32 x)) (OperationKind.ObjectCreationExpression, Type: C, IsInvalid) (Syntax: 'new C(0)')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, IsInvalid) (Syntax: '0')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0, IsInvalid) (Syntax: '0')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Initializer:
null
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperatorMethod: System.String C.op_Implicit(C c)) (OperationKind.ConversionExpression, Type: System.String, IsImplicit) (Syntax: 'c1')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: True) (MethodSymbol: System.String C.op_Implicit(C c))
Operand:
IParameterReferenceExpression: c1 (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'c1')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0029: Cannot implicitly convert type 'C' to 'short'
......
......@@ -2967,9 +2967,15 @@ static void Main(string[] args)
// (21,18): error CS0266: Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
// case (object)null:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "(object)null").WithArguments("object", "string").WithLocation(21, 18),
// (21,13): error CS0152: The switch statement contains multiple cases with the label value 'null'
// case (object)null:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case (object)null:").WithArguments("null").WithLocation(21, 13),
// (23,18): error CS0266: Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)
// case (object)"b":
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, @"(object)""b""").WithArguments("object", "string").WithLocation(23, 18));
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, @"(object)""b""").WithArguments("object", "string").WithLocation(23, 18),
// (23,18): error CS0150: A constant value is expected
// case (object)"b":
Diagnostic(ErrorCode.ERR_ConstantExpected, @"(object)""b""").WithLocation(23, 18));
}
}
......
......@@ -548,12 +548,22 @@ public void BadAlignment()
static void Main()
{
var s = $""{1,1E10}"";
var t = $""{1,(int)1E10}"";
}
}";
CreateCompilationWithMscorlib45(source).VerifyDiagnostics(
// (5,22): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
// var s = $"{1,1E10}";
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1E10").WithArguments("double", "int").WithLocation(5, 22)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1E10").WithArguments("double", "int").WithLocation(5, 22),
// (5,22): error CS0150: A constant value is expected
// var s = $"{1,1E10}";
Diagnostic(ErrorCode.ERR_ConstantExpected, "1E10").WithLocation(5, 22),
// (6,22): error CS0221: Constant value '10000000000' cannot be converted to a 'int' (use 'unchecked' syntax to override)
// var t = $"{1,(int)1E10}";
Diagnostic(ErrorCode.ERR_ConstOutOfRangeChecked, "(int)1E10").WithArguments("10000000000", "int").WithLocation(6, 22),
// (6,22): error CS0150: A constant value is expected
// var t = $"{1,(int)1E10}";
Diagnostic(ErrorCode.ERR_ConstantExpected, "(int)1E10").WithLocation(6, 22)
);
}
......
......@@ -839,10 +839,7 @@ public static void Main()
Diagnostic(ErrorCode.WRN_GotoCaseShouldConvert, "goto case 3;").WithArguments("Color").WithLocation(15, 17),
// (15,17): error CS0159: No such label 'case 3:' within the scope of the goto statement
// goto case 3; // warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 3;").WithArguments("case 3:").WithLocation(15, 17),
// (15,17): warning CS0162: Unreachable code detected
// goto case 3; // warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
Diagnostic(ErrorCode.WRN_UnreachableCode, "goto").WithLocation(15, 17)
Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 3;").WithArguments("case 3:").WithLocation(15, 17)
);
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
......@@ -857,10 +854,7 @@ public static void Main()
Diagnostic(ErrorCode.WRN_GotoCaseShouldConvert, "goto case 3;").WithArguments("Color").WithLocation(15, 17),
// (15,17): error CS0159: No such label 'case 3:' within the scope of the goto statement
// goto case 3; // warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 3;").WithArguments("case 3:").WithLocation(15, 17),
// (15,17): warning CS0162: Unreachable code detected
// goto case 3; // warning CS0469: The 'goto case' value is not implicitly convertible to type 'Color'
Diagnostic(ErrorCode.WRN_UnreachableCode, "goto").WithLocation(15, 17)
Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 3;").WithArguments("case 3:").WithLocation(15, 17)
);
}
......
......@@ -1582,18 +1582,21 @@ class A
}
";
CreateStandardCompilation(text).VerifyDiagnostics(
// (10,9): error CS0031: Constant value '240' cannot be converted to a 'sbyte'
// B = 0xf0, // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "0xf0").WithArguments("240", "sbyte"),
// (5,9): error CS0031: Constant value '-1' cannot be converted to a 'ushort'
// B = -1 // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "-1").WithArguments("-1", "ushort"),
// (13,10): error CS0031: Constant value '128' cannot be converted to a 'sbyte'
// E = (A + 1), // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "A + 1").WithArguments("128", "sbyte"),
// (17,15): error CS0031: Constant value '256' cannot be converted to a 'byte'
// byte bt = 256;
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "256").WithArguments("256", "byte"));
// (5,9): error CS0031: Constant value '-1' cannot be converted to a 'ushort'
// B = -1 // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "-1").WithArguments("-1", "ushort").WithLocation(5, 9),
// (10,9): error CS0031: Constant value '240' cannot be converted to a 'sbyte'
// B = 0xf0, // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "0xf0").WithArguments("240", "sbyte").WithLocation(10, 9),
// (13,10): error CS0031: Constant value '128' cannot be converted to a 'sbyte'
// E = (A + 1), // CS0031
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "A + 1").WithArguments("128", "sbyte").WithLocation(13, 10),
// (17,15): error CS0031: Constant value '256' cannot be converted to a 'byte'
// byte bt = 256;
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "256").WithArguments("256", "byte").WithLocation(17, 15),
// (17,10): warning CS0414: The field 'A.bt' is assigned but its value is never used
// byte bt = 256;
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "bt").WithArguments("A.bt").WithLocation(17, 10));
}
[Fact]
......@@ -3648,6 +3651,9 @@ public static int G()
// (4,9): error CS0266: Cannot implicitly convert type 'E' to 'int'. An explicit conversion exists (are you missing a cast?)
// Y = C.F(),
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "C.F()").WithArguments("E", "int").WithLocation(4, 9),
// (4,9): error CS0133: The expression being assigned to 'E.Y' must be constant
// Y = C.F(),
Diagnostic(ErrorCode.ERR_NotConstantExpression, "C.F()").WithArguments("E.Y").WithLocation(4, 9),
// (5,9): error CS0133: The expression being assigned to 'E.Z' must be constant
// Z = C.G() + 1,
Diagnostic(ErrorCode.ERR_NotConstantExpression, "C.G() + 1").WithArguments("E.Z").WithLocation(5, 9));
......@@ -8633,7 +8639,10 @@ static void M()
CreateStandardCompilation(source).VerifyDiagnostics(
// (5,25): error CS0266: Cannot implicitly convert type 'long' to 'short'. An explicit conversion exists (are you missing a cast?)
// const short s = 1L;
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1L").WithArguments("long", "short").WithLocation(5, 25));
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1L").WithArguments("long", "short").WithLocation(5, 25),
// (5,21): warning CS0219: The variable 's' is assigned but its value is never used
// const short s = 1L;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "s").WithArguments("s").WithLocation(5, 21));
}
[Fact]
......@@ -8658,7 +8667,13 @@ void M()
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "2").WithArguments("int", "E").WithLocation(4, 11),
// (9,13): error CS0266: Cannot implicitly convert type 'char' to 'E'. An explicit conversion exists (are you missing a cast?)
// g = 'c'; // CS0266
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "'c'").WithArguments("char", "E").WithLocation(9, 13));
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "'c'").WithArguments("char", "E").WithLocation(9, 13),
// (4,7): warning CS0414: The field 'C.f' is assigned but its value is never used
// E f = 2; // CS0266
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "f").WithArguments("C.f").WithLocation(4, 7),
// (5,7): warning CS0414: The field 'C.g' is assigned but its value is never used
// E g = E.A;
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "g").WithArguments("C.g").WithLocation(5, 7));
}
[Fact]
......@@ -10992,8 +11007,18 @@ static void Main()
}";
var compilation = CreateStandardCompilation(text);
compilation.VerifyDiagnostics(
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "1.0").WithArguments("M", "decimal"),
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "2.0").WithArguments("F", "float"));
// (7,22): error CS0664: Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type
// decimal d1 = 1.0;
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "1.0").WithArguments("M", "decimal").WithLocation(7, 22),
// (8,20): error CS0664: Literal of type double cannot be implicitly converted to type 'float'; use an 'F' suffix to create a literal of this type
// float f1 = 2.0;
Diagnostic(ErrorCode.ERR_LiteralDoubleCast, "2.0").WithArguments("F", "float").WithLocation(8, 20),
// (7,17): warning CS0219: The variable 'd1' is assigned but its value is never used
// decimal d1 = 1.0;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "d1").WithArguments("d1").WithLocation(7, 17),
// (8,15): warning CS0219: The variable 'f1' is assigned but its value is never used
// float f1 = 2.0;
Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "f1").WithArguments("f1").WithLocation(8, 15));
}
[Fact]
......
......@@ -299,9 +299,18 @@ public void goo2(char i)
// (34,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97.0f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(34, 18),
// (34,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97.0f:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97.0f:").WithArguments("a").WithLocation(34, 13),
// (36,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 'a':
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'a':").WithArguments("a").WithLocation(36, 13),
// (38,18): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18),
// (38,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("a").WithLocation(38, 13)
);
CreateStandardCompilation(text, parseOptions: TestOptions.Regular6WithV7SwitchBinder).VerifyDiagnostics(
// (11,13): error CS0152: The switch statement contains multiple cases with the label value '1'
......@@ -322,15 +331,24 @@ public void goo2(char i)
// (34,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97.0f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(34, 18),
// (34,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97.0f:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97.0f:").WithArguments("a").WithLocation(34, 13),
// (36,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 'a':
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'a':").WithArguments("a").WithLocation(36, 13),
// (38,18): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char"),
// (33,17): warning CS0162: Unreachable code detected
// break;
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(33, 17),
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18),
// (38,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("a").WithLocation(38, 13),
// (35,17): warning CS0162: Unreachable code detected
// break;
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(35, 17),
// (37,17): warning CS0162: Unreachable code detected
// break;
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(37, 17),
// (39,17): warning CS0162: Unreachable code detected
// break;
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(39, 17)
......@@ -348,9 +366,18 @@ public void goo2(char i)
// (34,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97.0f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(34, 18),
// (34,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97.0f:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97.0f:").WithArguments("a").WithLocation(34, 13),
// (36,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 'a':
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'a':").WithArguments("a").WithLocation(36, 13),
// (38,18): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?)
// case 97:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18),
// (38,13): error CS0152: The switch statement contains multiple cases with the label value 'a'
// case 97:
Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("a").WithLocation(38, 13)
);
}
......@@ -1228,26 +1255,17 @@ public static int Main(string [] args)
CreateStandardCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(
// (10,12): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?)
// case 1.2f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12),
// (13,5): warning CS0162: Unreachable code detected
// return 0;
Diagnostic(ErrorCode.WRN_UnreachableCode, "return").WithLocation(13, 5)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12)
);
CreateStandardCompilation(text, parseOptions: TestOptions.Regular6WithV7SwitchBinder).VerifyDiagnostics(
// (10,12): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?)
// case 1.2f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12),
// (11,9): warning CS0162: Unreachable code detected
// return 1;
Diagnostic(ErrorCode.WRN_UnreachableCode, "return").WithLocation(11, 9)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12)
);
CreateStandardCompilation(text).VerifyDiagnostics(
// (10,12): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?)
// case 1.2f:
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12),
// (13,5): warning CS0162: Unreachable code detected
// return 0;
Diagnostic(ErrorCode.WRN_UnreachableCode, "return").WithLocation(13, 5)
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12)
);
}
......
......@@ -843,6 +843,24 @@ static void Main()
Diagnostic(ErrorCode.ERR_AmbigUDConv, "(A)b").WithArguments("B.explicit operator A(B)", "A.implicit operator A(B)", "B", "A"));
}
[Fact]
public void NoImplicitConversionsDefaultParameter_01()
{
var source = @"
class C
{
void Goo(float x = 0.0)
{
}
}";
CreateStandardCompilation(source).VerifyDiagnostics(
// (4,20): error CS1750: A value of type 'double' cannot be used as a default parameter because there are no standard conversions to type 'float'
// void Goo(float x = 0.0)
Diagnostic(ErrorCode.ERR_NoConversionForDefaultParam, "x").WithArguments("double", "float").WithLocation(4, 20)
);
}
[Fact]
public void NoUserDefinedConversionsDefaultParameter1()
{
......
......@@ -74,11 +74,30 @@ public void OutOfUnderlyingRange()
};
";
var comp = CreateStandardCompilation(text);
VerifyEnumsValue(comp, "Suits", SpecialType.System_Byte, null, null, null);
VerifyEnumsValue(comp, "Suits", SpecialType.System_Byte, null, (byte)2, null);
comp.VerifyDiagnostics(
// (3,10): error CS0029: Cannot implicitly convert type 'string' to 'byte'
// ValueA = "3", // Can't implicitly convert
Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""3""").WithArguments("string", "byte").WithLocation(3, 10),
// (4,10): error CS0266: Cannot implicitly convert type 'double' to 'byte'. An explicit conversion exists (are you missing a cast?)
// ValueB = 2.2, // Can't implicitly convert
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "2.2").WithArguments("double", "byte").WithLocation(4, 10),
// (5,10): error CS0031: Constant value '257' cannot be converted to a 'byte'
// ValueC = 257 // Out of underlying range
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "257").WithArguments("257", "byte").WithLocation(5, 10)
);
text =
@"enum Suits : short { a, b, c, d = -65536, e, f }";
comp = CreateStandardCompilation(text);
VerifyEnumsValue(comp, "Suits", SpecialType.System_Int16, (short)0, (short)1, (short)2, null, null, null);
comp.VerifyDiagnostics(
// (1,35): error CS0031: Constant value '-65536' cannot be converted to a 'short'
// enum Suits : short { a, b, c, d = -65536, e, f }
Diagnostic(ErrorCode.ERR_ConstOutOfRange, "-65536").WithArguments("-65536", "short").WithLocation(1, 35)
);
}
// Explicit associated value
......
......@@ -9,7 +9,7 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.Semantics
Partial Friend NotInheritable Class VisualBasicOperationFactory
Private Shared Function ConvertToOptional(value As ConstantValue) As [Optional](Of Object)
Return If(value Is Nothing, New [Optional](Of Object)(), New [Optional](Of Object)(value.Value))
Return If(value Is Nothing OrElse value.IsBad, New [Optional](Of Object)(), New [Optional](Of Object)(value.Value))
End Function
Private Shared Function GetAssignmentKind(value As BoundAssignmentOperator) As OperationKind
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Test.Utilities
......@@ -1221,5 +1221,41 @@ IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclaratio
VerifyOperationTreeAndDiagnosticsForTest(Of LocalDeclarationStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")>
Public Sub SimpleArrayCreation_ConstantConversion()
Dim source = <![CDATA[
Option Strict On
Class C
Public Sub F()
Dim a = New String(0.0) {}'BIND:"New String(0.0) {}"
End Sub
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IArrayCreationExpression (OperationKind.ArrayCreationExpression, Type: System.String(), IsInvalid) (Syntax: 'New String(0.0) {}')
Dimension Sizes(1):
IBinaryOperatorExpression (BinaryOperatorKind.Add, Checked) (OperationKind.BinaryOperatorExpression, Type: System.Int32, Constant: 1, IsInvalid, IsImplicit) (Syntax: '0.0')
Left:
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
Right:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1, IsInvalid, IsImplicit) (Syntax: '0.0')
Initializer:
IArrayInitializer (0 elements) (OperationKind.ArrayInitializer) (Syntax: '{}')
Element Values(0)
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30512: Option Strict On disallows implicit conversions from 'Double' to 'Integer'.
Dim a = New String(0.0) {}'BIND:"New String(0.0) {}"
~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of ArrayCreationExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.Test.Utilities
......@@ -94,6 +94,36 @@ IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'Return')
VerifyOperationTreeAndDiagnosticsForTest(Of ReturnStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")>
Public Sub Return_ConstantConversions_01()
Dim source = <![CDATA[
Option Strict On
Class C
Function M() As Byte
Return 0.0'BIND:"Return 0.0"
End Function
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'Return 0.0')
ReturnedValue:
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Byte, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30512: Option Strict On disallows implicit conversions from 'Double' to 'Byte'.
Return 0.0'BIND:"Return 0.0"
~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of ReturnStatementSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
......@@ -319,5 +319,55 @@ IFieldInitializer (Field: C.i2 As System.Int32) (OperationKind.FieldInitializer)
VerifyOperationTreeAndDiagnosticsForTest(Of EqualsValueSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")>
Public Sub FieldInitializer_ConstantConversions_01()
Dim source = <![CDATA[
Option Strict On
Class C
Private s1 As Byte = 0.0'BIND:"= 0.0"
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IFieldInitializer (Field: C.s1 As System.Byte) (OperationKind.FieldInitializer, IsInvalid) (Syntax: '= 0.0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Byte, Constant: 0, IsInvalid, IsImplicit) (Syntax: '0.0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 0, IsInvalid) (Syntax: '0.0')
]]>.Value
Dim expectedDiagnostics = <![CDATA[
BC30512: Option Strict On disallows implicit conversions from 'Double' to 'Byte'.
Private s1 As Byte = 0.0'BIND:"= 0.0"
~~~
]]>.Value
VerifyOperationTreeAndDiagnosticsForTest(Of EqualsValueSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
<CompilerTrait(CompilerFeature.IOperation)>
<Fact, WorkItem(7299, "https://github.com/dotnet/roslyn/issues/7299")>
Public Sub FieldInitializer_ConstantConversions_02()
Dim source = <![CDATA[
Option Strict On
Class C
Private s1 As Byte = 0'BIND:"= 0"
End Class
]]>.Value
Dim expectedOperationTree = <![CDATA[
IFieldInitializer (Field: C.s1 As System.Byte) (OperationKind.FieldInitializer) (Syntax: '= 0')
IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Byte, Constant: 0, IsImplicit) (Syntax: '0')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
]]>.Value
Dim expectedDiagnostics = String.Empty
VerifyOperationTreeAndDiagnosticsForTest(Of EqualsValueSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
......@@ -105,7 +105,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
' There are diagnostics for these values (see EnumErrorsInValues test),
' but as long as the value is constant (including the needed conversion), the constant value is used
' (see conversion of 2.2 vs. conversion of "3").
VerifyEnumsValue(text, "Suits", SpecialType.System_Byte, Nothing, CByte(2), Nothing)
Dim fields = VerifyEnumsValue(text, "Suits", SpecialType.System_Byte, Nothing, CByte(2), Nothing)
fields.First.DeclaringCompilation.AssertTheseDiagnostics(
<expected>
BC30060: Conversion from 'String' to 'Byte' cannot occur in a constant expression.
ValueA = "3" ' Can't implicitly convert
~~~
BC30439: Constant expression not representable in type 'Byte'.
ValueC = 257 ' Out of underlying range
~~~
</expected>)
text =
<compilation name="C">
......@@ -122,7 +132,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
' There are diagnostics for these values (see EnumErrorsInValues test),
' but as long as the value is constant (including the needed conversion), the constant value is used
' (see conversion of 2.2 vs. conversion of "3").
VerifyEnumsValue(text, "Suits", SpecialType.System_Byte, Nothing, CByte(2), Nothing)
fields = VerifyEnumsValue(text, "Suits", SpecialType.System_Byte, Nothing, CByte(2), Nothing)
fields.First.DeclaringCompilation.AssertTheseDiagnostics(
<expected>
BC30512: Option Strict On disallows implicit conversions from 'String' to 'Byte'.
ValueA = "3" ' Can't implicitly convert
~~~
BC30512: Option Strict On disallows implicit conversions from 'Double' to 'Byte'.
ValueB = 2.2 ' Can't implicitly convert: [Option Strict On] disallows implicit conversion
~~~
BC30439: Constant expression not representable in type 'Byte'.
ValueC = 257 ' Out of underlying range
~~~
</expected>)
text =
<compilation name="C">
......@@ -138,7 +161,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests
</file>
</compilation>
VerifyEnumsValue(text, "Suits", SpecialType.System_Int16, CShort(0), CShort(1), CShort(2), Nothing, Nothing, Nothing)
fields = VerifyEnumsValue(text, "Suits", SpecialType.System_Int16, CShort(0), CShort(1), CShort(2), Nothing, Nothing, Nothing)
fields.First.DeclaringCompilation.AssertTheseDiagnostics(
<expected>
BC30439: Constant expression not representable in type 'Short'.
d = -65536
~~~~~~
</expected>)
End Sub
<Fact>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册