Skip to content

Commit

Permalink
Disallow converted string as default argument value (#59806)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Mar 1, 2022
1 parent 44956a2 commit d07f2b1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
8 changes: 8 additions & 0 deletions docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,11 @@ https://github.com/dotnet/roslyn/issues/57750
public S() { Y = 0; } // ok
}
```

7. <a name="7"></a>Before Visual Studio 17.2, the C# compiler would accept incorrect default argument values involving a reference conversion of a string constant, and would emit `null` as the constant value instead of the default value specified in source. In Visual Studio 17.2, this becomes an error. See [roslyn#59806](https://github.com/dotnet/roslyn/pull/59806).
For instance, the following results in an error in 17.2:
```csharp
void M(IEnumerable<char> s = "hello")
```

Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,11 @@ internal static bool ReportDefaultParameterErrors(
hasErrors = true;
}
else if (conversion.IsReference &&
(parameterType.SpecialType == SpecialType.System_Object || parameterType.Kind == SymbolKind.DynamicType) &&
(object)defaultExpression.Type != null &&
defaultExpression.Type.SpecialType == SpecialType.System_String ||
conversion.IsBoxing)
{
// We don't allow object x = "hello", object x = 123, dynamic x = "hello", etc.
// We don't allow object x = "hello", object x = 123, dynamic x = "hello", IEnumerable<char> x = "hello", etc.
// error CS1763: '{0}' is of type '{1}'. A default parameter value of a reference type other than string can only be initialized with null
diagnostics.Add(ErrorCode.ERR_NotNullRefDefaultParameter, parameterSyntax.Identifier.GetLocation(),
parameterSyntax.Identifier.ValueText, parameterType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2490,5 +2490,58 @@ void M1(object obj = 1) // 1
// C(object obj = System.DayOfWeek.Monday) // 2
Diagnostic(ErrorCode.ERR_NotNullRefDefaultParameter, "obj").WithArguments("obj", "object").WithLocation(8, 14));
}

[Fact, WorkItem(59789, "https://github.com/dotnet/roslyn/issues/59789")]
public void DefaultValue_NonNullConvertedString()
{
var source = @"
using System.Collections.Generic;
class C
{
const IEnumerable<char> y = ""world""; // 1
const string y2 = ""world"";
const object y3 = ""world""; // 2
const dynamic y4 = ""world""; // 3
void M(IEnumerable<char> x = ""hello"") // 4
{
}
void M2(string x = ""hello"")
{
}
void M3(object x = ""hello"") // 5
{
}
void M4(dynamic x = ""hello"") // 6
{
}
}
";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (6,33): error CS0134: 'C.y' is of type 'IEnumerable<char>'. A const field of a reference type other than string can only be initialized with null.
// const IEnumerable<char> y = "world"; // 1
Diagnostic(ErrorCode.ERR_NotNullConstRefField, @"""world""").WithArguments("C.y", "System.Collections.Generic.IEnumerable<char>").WithLocation(6, 33),
// (8,23): error CS0134: 'C.y3' is of type 'object'. A const field of a reference type other than string can only be initialized with null.
// const object y3 = "world"; // 2
Diagnostic(ErrorCode.ERR_NotNullConstRefField, @"""world""").WithArguments("C.y3", "object").WithLocation(8, 23),
// (9,24): error CS0134: 'C.y4' is of type 'dynamic'. A const field of a reference type other than string can only be initialized with null.
// const dynamic y4 = "world"; // 3
Diagnostic(ErrorCode.ERR_NotNullConstRefField, @"""world""").WithArguments("C.y4", "dynamic").WithLocation(9, 24),
// (11,30): error CS1763: 'x' is of type 'IEnumerable<char>'. A default parameter value of a reference type other than string can only be initialized with null
// void M(IEnumerable<char> x = "hello") // 4
Diagnostic(ErrorCode.ERR_NotNullRefDefaultParameter, "x").WithArguments("x", "System.Collections.Generic.IEnumerable<char>").WithLocation(11, 30),
// (19,20): error CS1763: 'x' is of type 'object'. A default parameter value of a reference type other than string can only be initialized with null
// void M3(object x = "hello") // 5
Diagnostic(ErrorCode.ERR_NotNullRefDefaultParameter, "x").WithArguments("x", "object").WithLocation(19, 20),
// (23,21): error CS1763: 'x' is of type 'dynamic'. A default parameter value of a reference type other than string can only be initialized with null
// void M4(dynamic x = "hello") // 6
Diagnostic(ErrorCode.ERR_NotNullRefDefaultParameter, "x").WithArguments("x", "dynamic").WithLocation(23, 21)
);
}
}
}

0 comments on commit d07f2b1

Please sign in to comment.