diff --git a/docs/compilers/CSharp/Warnversion Warning Waves.md b/docs/compilers/CSharp/Warnversion Warning Waves.md
index 65d25e8b1b52..19be76b7d8ef 100644
--- a/docs/compilers/CSharp/Warnversion Warning Waves.md
+++ b/docs/compilers/CSharp/Warnversion Warning Waves.md
@@ -13,6 +13,14 @@ In a typical project, this setting is controlled by the `AnalysisLevel` property
which determines the `WarningLevel` property (passed to the `Csc` task).
For more information on `AnalysisLevel`, see https://devblogs.microsoft.com/dotnet/automatically-find-latent-bugs-in-your-code-with-net-5/
+## Warning level 10
+
+The compiler shipped with .NET 10 (the C# 14 compiler) contains the following warnings which are reported only under `/warn:10` or higher.
+
+| Warning ID | Description |
+|------------|-------------|
+| CS9265 | [Field is never ref-assigned to, and will always have its default value (null reference)](https://github.com/dotnet/roslyn/issues/75315) |
+
## Warning level 8
The compiler shipped with .NET 8 (the C# 12 compiler) contains the following warnings which are reported only under `/warn:8` or higher.
diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 4210d8664c20..351d86738930 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -1916,6 +1916,12 @@ If such a class is used as a base class and if the deriving class defines a dest
Field is never assigned to, and will always have its default value
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
Bad array declarator: To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type.
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index 7c07bb82d271..ddf9033bcbfb 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -2346,6 +2346,7 @@ internal enum ErrorCode
ERR_PartialPropertyDuplicateInitializer = 9263,
WRN_UninitializedNonNullableBackingField = 9264,
+ WRN_UnassignedInternalRefField = 9265,
// Note: you will need to do the following after adding errors:
// 1) Update ErrorFacts.IsBuildOnlyDiagnostic (src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs)
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
index 4c8a7e03fa39..36c061058fae 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorFacts.cs
@@ -210,6 +210,10 @@ internal static int GetWarningLevel(ErrorCode code)
// docs/compilers/CSharp/Warnversion Warning Waves.md
switch (code)
{
+ case ErrorCode.WRN_UnassignedInternalRefField:
+ // Warning level 10 is exclusively for warnings introduced in the compiler
+ // shipped with dotnet 10 (C# 14) and that can be reported for pre-existing code.
+ return 10;
case ErrorCode.WRN_AddressOfInAsync:
case ErrorCode.WRN_ByValArraySizeConstRequired:
// Warning level 8 is exclusively for warnings introduced in the compiler
@@ -2460,6 +2464,7 @@ or ErrorCode.ERR_CannotApplyOverloadResolutionPriorityToOverride
or ErrorCode.ERR_CannotApplyOverloadResolutionPriorityToMember
or ErrorCode.ERR_PartialPropertyDuplicateInitializer
or ErrorCode.WRN_UninitializedNonNullableBackingField
+ or ErrorCode.WRN_UnassignedInternalRefField
=> false,
};
#pragma warning restore CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
index cdb93dcbf2bf..9688c7c4084c 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs
@@ -1545,10 +1545,20 @@ private void VisitArgumentsAfterCall(ImmutableArray arguments,
for (int i = 0; i < arguments.Length; i++)
{
RefKind refKind = GetRefKind(refKindsOpt, i);
- // passing as a byref argument is also a potential write
- if (refKind != RefKind.None)
+ switch (refKind)
{
- WriteArgument(arguments[i], refKind, method);
+ case RefKind.None:
+ case RefKind.In:
+ case RefKind.RefReadOnlyParameter:
+ case RefKindExtensions.StrictIn:
+ break;
+ case RefKind.Ref:
+ case RefKind.Out:
+ // passing as a byref argument is also a potential write
+ WriteArgument(arguments[i], refKind, method);
+ break;
+ default:
+ throw ExceptionUtilities.UnexpectedValue(refKind);
}
}
}
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DataFlowsOutWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DataFlowsOutWalker.cs
index be797584c893..9bbb8f5efa01 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/DataFlowsOutWalker.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DataFlowsOutWalker.cs
@@ -88,7 +88,7 @@ protected override void EnterRegion()
base.EnterRegion();
}
- protected override void NoteWrite(Symbol variable, BoundExpression value, bool read)
+ protected override void NoteWrite(Symbol variable, BoundExpression value, bool read, bool isRef)
{
// any reachable assignment to a ref or out parameter can be visible to the caller in the face of exceptions.
if (this.State.Reachable && IsInside)
@@ -107,7 +107,7 @@ protected override void NoteWrite(Symbol variable, BoundExpression value, bool r
#endif
}
- base.NoteWrite(variable, value, read);
+ base.NoteWrite(variable, value, read: read, isRef: isRef);
}
#if DEBUG
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs
index e009b16967e5..568b2c4d01aa 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs
@@ -346,7 +346,7 @@ protected override ImmutableArray Scan(ref bool badRegion)
// All primary constructor parameters are definitely assigned outside of the primary constructor
foreach (var parameter in primaryConstructor.Parameters)
{
- NoteWrite(parameter, value: null, read: true);
+ NoteWrite(parameter, value: null, read: true, isRef: parameter.RefKind != RefKind.None);
}
CurrentSymbol = save;
@@ -846,7 +846,7 @@ private void NoteRead(BoundNode fieldOrEventAccess)
}
}
- protected virtual void NoteWrite(Symbol variable, BoundExpression value, bool read)
+ protected virtual void NoteWrite(Symbol variable, BoundExpression value, bool read, bool isRef)
{
if ((object)variable != null)
{
@@ -854,7 +854,9 @@ protected virtual void NoteWrite(Symbol variable, BoundExpression value, bool re
if ((object)_sourceAssembly != null && variable.Kind == SymbolKind.Field)
{
var field = (FieldSymbol)variable.OriginalDefinition;
- _sourceAssembly.NoteFieldAccess(field, read: read && WriteConsideredUse(field.Type, value), write: true);
+ _sourceAssembly.NoteFieldAccess(field,
+ read: read && WriteConsideredUse(field.Type, value),
+ write: field.RefKind == RefKind.None || isRef);
}
var local = variable as LocalSymbol;
@@ -949,7 +951,10 @@ internal static bool WriteConsideredUse(TypeSymbol type, BoundExpression value)
}
}
- private void NoteWrite(BoundExpression n, BoundExpression value, bool read)
+ ///
+ /// Whether this write represents a ref-assignment.
+ ///
+ private void NoteWrite(BoundExpression n, BoundExpression value, bool read, bool isRef)
{
while (n != null)
{
@@ -961,12 +966,15 @@ private void NoteWrite(BoundExpression n, BoundExpression value, bool read)
if ((object)_sourceAssembly != null)
{
var field = fieldAccess.FieldSymbol.OriginalDefinition;
- _sourceAssembly.NoteFieldAccess(field, read: value == null || WriteConsideredUse(fieldAccess.FieldSymbol.Type, value), write: true);
+ _sourceAssembly.NoteFieldAccess(field,
+ read: value == null || WriteConsideredUse(fieldAccess.FieldSymbol.Type, value),
+ write: field.RefKind == RefKind.None || isRef);
}
if (MayRequireTracking(fieldAccess.ReceiverOpt, fieldAccess.FieldSymbol))
{
n = fieldAccess.ReceiverOpt;
+ isRef = false;
if (n.Kind == BoundKind.Local)
{
_usedVariables.Add(((BoundLocal)n).LocalSymbol);
@@ -1001,19 +1009,19 @@ private void NoteWrite(BoundExpression n, BoundExpression value, bool read)
}
case BoundKind.ThisReference:
- NoteWrite(MethodThisParameter, value, read);
+ NoteWrite(MethodThisParameter, value, read: read, isRef: isRef);
return;
case BoundKind.Local:
- NoteWrite(((BoundLocal)n).LocalSymbol, value, read);
+ NoteWrite(((BoundLocal)n).LocalSymbol, value, read: read, isRef: isRef);
return;
case BoundKind.Parameter:
- NoteWrite(((BoundParameter)n).ParameterSymbol, value, read);
+ NoteWrite(((BoundParameter)n).ParameterSymbol, value, read: read, isRef: isRef);
return;
case BoundKind.RangeVariable:
- NoteWrite(((BoundRangeVariable)n).Value, value, read);
+ NoteWrite(((BoundRangeVariable)n).Value, value, read: read, isRef: isRef);
return;
case BoundKind.InlineArrayAccess:
@@ -1542,7 +1550,7 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
SetSlotState(slot, assigned: written || !this.State.Reachable);
}
- if (written) NoteWrite(pattern.VariableAccess, value, read);
+ if (written) NoteWrite(pattern.VariableAccess, value, read: read, isRef: isRef);
break;
}
@@ -1553,7 +1561,7 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
LocalSymbol symbol = local.LocalSymbol;
int slot = GetOrCreateSlot(symbol);
SetSlotState(slot, assigned: written || !this.State.Reachable);
- if (written) NoteWrite(symbol, value, read);
+ if (written) NoteWrite(symbol, value, read: read, isRef: isRef);
break;
}
@@ -1570,7 +1578,7 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
{
int slot = MakeSlot(local);
SetSlotState(slot, written);
- if (written) NoteWrite(local, value, read);
+ if (written) NoteWrite(local, value, read: read, isRef: isRef);
}
break;
}
@@ -1580,7 +1588,7 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
var elementAccess = (BoundInlineArrayAccess)node;
if (written)
{
- NoteWrite(elementAccess.Expression, value: null, read);
+ NoteWrite(elementAccess.Expression, value: null, read: read, isRef: isRef);
}
if (elementAccess.Expression.Type.HasInlineArrayAttribute(out int length) &&
@@ -1618,7 +1626,19 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
int slot = MakeSlot(paramExpr);
SetSlotState(slot, written);
- if (written) NoteWrite(paramExpr, value, read);
+ if (written) NoteWrite(paramExpr, value, read: read, isRef: isRef);
+ break;
+ }
+
+ case BoundKind.ObjectInitializerMember:
+ {
+ var member = (BoundObjectInitializerMember)node;
+ if (_sourceAssembly is not null && member.MemberSymbol is FieldSymbol field)
+ {
+ _sourceAssembly.NoteFieldAccess(field.OriginalDefinition,
+ read: false,
+ write: field.RefKind == RefKind.None || isRef);
+ }
break;
}
@@ -1630,7 +1650,7 @@ protected virtual void AssignImpl(BoundNode node, BoundExpression value, bool is
var expression = (BoundExpression)node;
int slot = MakeSlot(expression);
SetSlotState(slot, written);
- if (written) NoteWrite(expression, value, read);
+ if (written) NoteWrite(expression, value, read: read, isRef: isRef);
break;
}
@@ -1864,7 +1884,7 @@ protected override void EnterParameter(ParameterSymbol parameter)
{
// this code has no effect except in region analysis APIs such as DataFlowsOut where we unassign things
if (slot > 0) SetSlotState(slot, true);
- NoteWrite(parameter, value: null, read: true);
+ NoteWrite(parameter, value: null, read: true, isRef: parameter.RefKind != RefKind.None);
}
if (parameter is SourceComplexParameterSymbolBase { ContainingSymbol: LocalFunctionSymbol or LambdaSymbol } sourceComplexParam)
@@ -2748,20 +2768,8 @@ public override void VisitForEachIterationVariables(BoundForEachStatement node)
int slot = GetOrCreateSlot(iterationVariable);
if (slot > 0) SetSlotAssigned(slot);
// NOTE: do not report unused iteration variables. They are always considered used.
- NoteWrite(iterationVariable, null, read: true);
- }
- }
-
- public override BoundNode VisitObjectInitializerMember(BoundObjectInitializerMember node)
- {
- var result = base.VisitObjectInitializerMember(node);
-
- if ((object)_sourceAssembly != null && node.MemberSymbol != null && node.MemberSymbol.Kind == SymbolKind.Field)
- {
- _sourceAssembly.NoteFieldAccess((FieldSymbol)node.MemberSymbol.OriginalDefinition, read: false, write: true);
+ NoteWrite(iterationVariable, null, read: true, isRef: iterationVariable.RefKind != RefKind.None);
}
-
- return result;
}
public override BoundNode VisitDynamicObjectInitializerMember(BoundDynamicObjectInitializerMember node)
@@ -2790,7 +2798,7 @@ protected override void AfterVisitInlineArrayAccess(BoundInlineArrayAccess node)
if (node.GetItemOrSliceHelper == WellKnownMember.System_Span_T__Slice_Int_Int)
{
// exposing ref is a potential write
- NoteWrite(node.Expression, value: null, read: false);
+ NoteWrite(node.Expression, value: null, read: false, isRef: false);
}
}
@@ -2800,7 +2808,7 @@ protected override void AfterVisitConversion(BoundConversion node)
node.Type.OriginalDefinition.Equals(compilation.GetWellKnownType(WellKnownType.System_Span_T), TypeCompareKind.AllIgnoreOptions))
{
// exposing ref is a potential write
- NoteWrite(node.Operand, value: null, read: false);
+ NoteWrite(node.Operand, value: null, read: false, isRef: false);
}
}
diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/ReadWriteWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/ReadWriteWalker.cs
index c5a3ed6f8ab2..427d6080634f 100644
--- a/src/Compilers/CSharp/Portable/FlowAnalysis/ReadWriteWalker.cs
+++ b/src/Compilers/CSharp/Portable/FlowAnalysis/ReadWriteWalker.cs
@@ -129,11 +129,11 @@ protected override void NoteRead(Symbol variable, ParameterSymbol rangeVariableU
base.NoteRead(variable, rangeVariableUnderlyingParameter);
}
- protected override void NoteWrite(Symbol variable, BoundExpression value, bool read)
+ protected override void NoteWrite(Symbol variable, BoundExpression value, bool read, bool isRef)
{
if ((object)variable == null) return;
(IsInside ? _writtenInside : _writtenOutside).Add(variable);
- base.NoteWrite(variable, value, read);
+ base.NoteWrite(variable, value, read: read, isRef: isRef);
}
protected override void CheckAssigned(BoundExpression expr, FieldSymbol fieldSymbol, SyntaxNode node)
@@ -233,7 +233,7 @@ protected override void AssignImpl(BoundNode node, BoundExpression value, bool i
switch (node.Kind)
{
case BoundKind.RangeVariable:
- if (written) NoteWrite(((BoundRangeVariable)node).RangeVariableSymbol, value, read);
+ if (written) NoteWrite(((BoundRangeVariable)node).RangeVariableSymbol, value, read: read, isRef: isRef);
break;
case BoundKind.QueryClause:
@@ -242,7 +242,7 @@ protected override void AssignImpl(BoundNode node, BoundExpression value, bool i
var symbol = ((BoundQueryClause)node).DefinedSymbol;
if ((object)symbol != null)
{
- if (written) NoteWrite(symbol, value, read);
+ if (written) NoteWrite(symbol, value, read: read, isRef: isRef);
}
}
break;
diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
index 1d3dab8bda75..c339c5db7559 100644
--- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
@@ -341,6 +341,7 @@ public static bool IsWarning(ErrorCode code)
case ErrorCode.WRN_PartialPropertySignatureDifference:
case ErrorCode.WRN_FieldIsAmbiguous:
case ErrorCode.WRN_UninitializedNonNullableBackingField:
+ case ErrorCode.WRN_UnassignedInternalRefField:
return true;
default:
return false;
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
index c0bbc5a77fba..916a8a348eac 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs
@@ -2740,6 +2740,10 @@ internal ImmutableArray GetUnusedFieldWarnings(CancellationToken can
{
diagnostics.Add(ErrorCode.WRN_UnreferencedField, field.GetFirstLocationOrNone(), field);
}
+ else if (field.RefKind != RefKind.None)
+ {
+ diagnostics.Add(ErrorCode.WRN_UnassignedInternalRefField, field.GetFirstLocationOrNone(), field);
+ }
else
{
diagnostics.Add(ErrorCode.WRN_UnassignedInternalField, field.GetFirstLocationOrNone(), field, DefaultValue(field.Type));
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 88e737c1beb2..8da755efedfc 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -5218,6 +5218,16 @@
Parametr typu má stejný typ jako parametr typu z vnější metody.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Volajícímu se vrátí ovládací prvek před explicitním přiřazením automaticky implementované vlastnosti {0}, což způsobí předchozí implicitní přiřazení default.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 7791b4941b49..70c26711d632 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -5218,6 +5218,16 @@
Der Typparameter und der Typparameter der äußeren Methode weisen denselben Typ auf.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Das Steuerelement wird an den Aufrufer zurückgegeben, bevor die automatisch implementierte Eigenschaft "{0}" explizit zugewiesen wird. Dies führt zu einer vorherigen impliziten Zuweisung von "default".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 49dc784c465a..645883895770 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -5218,6 +5218,16 @@
El parámetro de tipo tiene el mismo tipo que el parámetro de tipo del método externo.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.El control se devuelve al autor de la llamada antes de que la propiedad implementada automáticamente '{0}' se asigne explícitamente, lo que provoca una asignación implícita anterior de 'default'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index ebc8306793f1..3b841bfa2536 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -5218,6 +5218,16 @@
Le paramètre de type a le même type que le paramètre de type de la méthode externe.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Le contrôle est retourné à l’appelant avant que la propriété implémentée automatiquement '{0}' soit explicitement affectée, ce qui provoque une attribution implicite précédente de 'default'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 268e0502cd45..460061a51f15 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -5218,6 +5218,16 @@ target:module Compila un modulo che può essere aggiunto ad altro
Il tipo del parametro di tipo è lo stesso del parametro di tipo del metodo esterno.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Il controllo viene restituito al chiamante prima che la proprietà implementata automaticamente '{0}' sia assegnata in modo esplicito, determinando un'assegnazione implicita precedente di 'default'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index 7ac7b47912be..7e8b8fb563eb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -5218,6 +5218,16 @@
型パラメーターの型は、外のメソッドからの型パラメーターと同じ型です。
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.フィールド '{0}' が明示的に割り当てられる前に自動実装プロパティが呼び出し元に返され、先行する暗黙的な代入が 'default' になります。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 1c3127f91222..a0238290697a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -5218,6 +5218,16 @@
형식 매개 변수가 외부 메서드의 형식 매개 변수와 형식이 같습니다.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.자동 구현 속성 '{0}'이(가) 명시적으로 할당되기 전에 제어가 호출자에게 반환되어 'default'의 선행 암시적 할당이 발생합니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 4a0500365e1e..6722677775ae 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -5218,6 +5218,16 @@
Parametr typu ma ten sam typ co parametr typu z metody zewnętrznej.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Kontrolka jest zwracana do obiektu wywołującego przed jawnym przypisaniem właściwości „{0}”, co powoduje wcześniejsze niejawne przypisanie wartości „default”.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 2c3070ffc18a..f445eed9fbd8 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -5218,6 +5218,16 @@
O parâmetro de tipo tem o mesmo tipo que o parâmetro de tipo do método externo.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.O controle é devolvido ao chamador antes que a propriedade auto-implementada seja '{0}' explicitamente atribuída, causando uma atribuição implícita anterior de 'default'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 5ad07dbfa517..71b229fe58f9 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -5219,6 +5219,16 @@
Параметр типа имеет то же имя, что и параметр типа во внешнем методе.
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Контроль возвращается вызывающему элементу до явного назначения автоматически реализуемого свойства "{0}", что приводит к предшествующему неявному назначению "default"
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index f6b9d136c9e3..565e34cb8ecb 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -5218,6 +5218,16 @@
Tür parametresi dış metottaki tür parametresi ile aynı türe sahip
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.Denetim, otomatik uygulanan '{0}' özelliği açıkça atanmadan önce çağırana döndürülür ve bu da 'default' öğesinin önceki örtük ataması ile sonuçlanır.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 430ad886cfb0..17d1e6454862 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -5218,6 +5218,16 @@
类型参数与外部方法中的类型参数有相同的类型。
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.在显式分配自动实现的属性'{0}'之前,将向调用方返回控件,从而导致前面隐式分配了“default”。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index 6d362a02305c..1c593dcfbf53 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -5218,6 +5218,16 @@ strument:TestCoverage 產生檢測要收集
類型參數與外部方法的類型參數,類型相同。
+
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+ Field '{0}' is never ref-assigned to, and will always have its default value (null reference)
+
+
+
+ Field is never ref-assigned to, and will always have its default value (null reference)
+ Field is never ref-assigned to, and will always have its default value (null reference)
+
+ Control is returned to caller before auto-implemented property '{0}' is explicitly assigned, causing a preceding implicit assignment of 'default'.在明確指派自動實作屬性 '{0}' 之前會先將控制項傳回呼叫者,導致先前隱含的指派為 'default'。
diff --git a/src/Compilers/CSharp/Test/Emit3/FlowAnalysis/RegionAnalysisTests.cs b/src/Compilers/CSharp/Test/Emit3/FlowAnalysis/RegionAnalysisTests.cs
index 3c381b5eef66..d911a0f87609 100644
--- a/src/Compilers/CSharp/Test/Emit3/FlowAnalysis/RegionAnalysisTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/FlowAnalysis/RegionAnalysisTests.cs
@@ -14109,6 +14109,9 @@ ref struct RS
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyEmitDiagnostics(
+ // (3,13): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
+ // ref int ri;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(3, 13),
// (4,20): warning CS9201: Ref field 'ri' should be ref-assigned before use.
// public RS() => ri = 0;
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(4, 20));
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/InlineArrayTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/InlineArrayTests.cs
index 745c0e4d1c16..18754727921a 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/InlineArrayTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/InlineArrayTests.cs
@@ -4676,7 +4676,10 @@ static async Task FromResult(T r)
}
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
- var verifier = CompileAndVerify(comp, expectedOutput: "111", verify: Verification.Fails).VerifyDiagnostics();
+ var verifier = CompileAndVerify(comp, expectedOutput: "111", verify: Verification.Fails).VerifyDiagnostics(
+ // (6,45): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value
+ // public readonly Buffer10> F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "").WithLocation(6, 45));
verifier.VerifyIL("Program.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext",
@"
@@ -4832,6 +4835,9 @@ static async Task FromResult(T r)
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
comp.VerifyEmitDiagnostics(
+ // (8,45): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value
+ // public readonly Buffer10> F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "").WithLocation(8, 45),
// (20,12): error CS4007: Instance of type 'System.ReadOnlySpan>' cannot be preserved across 'await' or 'yield' boundary.
// => MemoryMarshal.CreateReadOnlySpan(
Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan(
@@ -4887,6 +4893,9 @@ static async Task FromResult(T r)
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
comp.VerifyEmitDiagnostics(
+ // (8,45): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value
+ // public readonly Buffer10> F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "").WithLocation(8, 45),
// (20,12): error CS4007: Instance of type 'System.ReadOnlySpan' cannot be preserved across 'await' or 'yield' boundary.
// => MemoryMarshal.CreateReadOnlySpan(
Diagnostic(ErrorCode.ERR_ByRefTypeAndAwait, @"MemoryMarshal.CreateReadOnlySpan(
@@ -4940,6 +4949,9 @@ static async Task FromResult(T r)
";
var comp = CreateCompilation(src + Buffer10Definition, targetFramework: TargetFramework.Net80, options: TestOptions.ReleaseExe);
comp.VerifyEmitDiagnostics(
+ // (8,45): warning CS0649: Field 'C.F' is never assigned to, and will always have its default value
+ // public readonly Buffer10> F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("C.F", "").WithLocation(8, 45),
// (20,12): error CS8178: A reference returned by a call to 'Program.GetItem(ReadOnlySpan>, int)' cannot be preserved across 'await' or 'yield' boundary.
// => GetItem(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As>, Buffer10>(ref Unsafe.AsRef(in GetC(x).F)),10), Get01())[await FromResult(Get02(x))];
Diagnostic(ErrorCode.ERR_RefReturningCallAndAwait, "GetItem(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As>, Buffer10>(ref Unsafe.AsRef(in GetC(x).F)),10), Get01())").WithArguments("Program.GetItem(System.ReadOnlySpan>, int)").WithLocation(20, 12)
diff --git a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
index b35dc0ce5acd..64063d8c36f3 100644
--- a/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
+++ b/src/Compilers/CSharp/Test/Emit3/Semantics/PrimaryConstructorTests.cs
@@ -20114,7 +20114,7 @@ public void IllegalCapturingDueToRefness_01(string keyword, string tag, TestFlag
[Fact]
public void IllegalCapturingDueToRefness_02()
{
- var source = @"#pragma warning disable CS0649 // Field 'R1.F1' is never assigned to, and will always have its default value 0
+ var source = @"#pragma warning disable CS0649, CS9265 // Field 'R1.F1' is never assigned to, and will always have its default value 0
ref struct R1
{
public int F1;
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
index 524e3e7ab5cb..e1b2e1cceaae 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefFieldTests.cs
@@ -1798,9 +1798,9 @@ public R()
""";
var comp = CreateCompilation(source, options: TestOptions.ReleaseExe, targetFramework: TargetFramework.Net70);
comp.VerifyDiagnostics(
- // (7,29): warning CS0649: Field 'R.field' is never assigned to, and will always have its default value 0
+ // (7,29): warning CS9265: Field 'R.field' is never ref-assigned to, and will always have its default value (null reference)
// public readonly ref int field;
- Diagnostic(ErrorCode.WRN_UnassignedInternalField, "field").WithArguments("R.field", "0").WithLocation(7, 29)
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "field").WithArguments("R.field").WithLocation(7, 29)
);
var verifier = CompileAndVerify(comp, verify: Verification.Skipped, expectedOutput: IncludeExpectedOutput("explicit ctor"));
@@ -2279,7 +2279,7 @@ public void RequiredField_01(LanguageVersion languageVersion)
{
var source = """
#pragma warning disable 169
- #pragma warning disable 649
+ #pragma warning disable 9265
ref struct R
{
public required ref T F1;
@@ -5213,7 +5213,10 @@ class Program
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
- // (4,25): warning CS9201: 'ref' field '_t' should be ref-assigned before use.
+ // (3,19): warning CS9265: Field 'R._t' is never ref-assigned to, and will always have its default value (null reference)
+ // private ref T _t;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "_t").WithArguments("R._t").WithLocation(3, 19),
+ // (4,25): warning CS9201: Ref field '_t' should be ref-assigned before use.
// public R(ref T t) { _t = t; }
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "_t").WithArguments("_t").WithLocation(4, 25));
}
@@ -5461,11 +5464,371 @@ public S(ref T t)
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
- // (6,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use.
+ // (3,18): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 18),
+ // (6,9): warning CS9201: Ref field 'F' should be ref-assigned before use.
// F = t;
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(6, 9));
}
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_WarningWave()
+ {
+ var source = """
+ ref struct R
+ {
+ public ref int F;
+ }
+ """;
+ CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(9), targetFramework: TargetFramework.Net70).VerifyDiagnostics();
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20)
+ };
+
+ CreateCompilation(source, options: TestOptions.ReleaseDll.WithWarningLevel(10), targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics);
+ CreateCompilation(source, targetFramework: TargetFramework.Net70).VerifyDiagnostics(expectedDiagnostics);
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Unassigned_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(R r)
+ {
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_RefAssigned_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(scoped R r, ref int x)
+ {
+ r.F = ref x;
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_RefAssignedInObjectInitializer_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(ref int x)
+ {
+ var r = new R { F = ref x };
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Assigned_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(R r, int x)
+ {
+ r.F = x;
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Assigned_Nested()
+ {
+ var comp = CreateCompilation("""
+ ref struct R1
+ {
+ public ref R2 F;
+ }
+
+ ref struct R2
+ {
+ public ref int F;
+ }
+
+ class C
+ {
+ static void Test(R1 r, int x)
+ {
+ r.F.F = x;
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,12): error CS9050: A ref field cannot refer to a ref struct.
+ // public ref R2 F;
+ Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref R2").WithLocation(3, 12),
+ // (3,19): warning CS9265: Field 'R1.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref R2 F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R1.F").WithLocation(3, 19),
+ // (8,20): warning CS9265: Field 'R2.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R2.F").WithLocation(8, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_RefAssigned_Nested()
+ {
+ var comp = CreateCompilation("""
+ ref struct R1
+ {
+ public ref R2 F;
+ }
+
+ ref struct R2
+ {
+ public ref int F;
+ }
+
+ class C
+ {
+ static void Test(scoped R1 r, ref int x)
+ {
+ r.F.F = ref x;
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,12): error CS9050: A ref field cannot refer to a ref struct.
+ // public ref R2 F;
+ Diagnostic(ErrorCode.ERR_RefFieldCannotReferToRefStruct, "ref R2").WithLocation(3, 12),
+ // (3,19): warning CS9265: Field 'R1.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref R2 F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R1.F").WithLocation(3, 19));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_AssignedInObjectInitializer_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(int x)
+ {
+ var r = new R { F = x };
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_ValueField_Unassigned_InAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public int F;
+
+ static void M(in int x) { }
+
+ static void Test(R r)
+ {
+ M(in r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,16): warning CS0649: Field 'R.F' is never assigned to, and will always have its default value 0
+ // public int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("R.F", "0").WithLocation(3, 16));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Unassigned_PlainAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(in int x) { }
+
+ static void Test(R r)
+ {
+ M(r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_ValueField_Unassigned_PlainAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public int F;
+
+ static void M(in int x) { }
+
+ static void Test(R r)
+ {
+ M(r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,16): warning CS0649: Field 'R.F' is never assigned to, and will always have its default value 0
+ // public int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalField, "F").WithArguments("R.F", "0").WithLocation(3, 16));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Unassigned_RefAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(ref int x) { }
+
+ static void Test(R r)
+ {
+ M(ref r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_ValueField_Unassigned_RefAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public int F;
+
+ static void M(ref int x) { }
+
+ static void Test(R r)
+ {
+ M(ref r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics();
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_RefField_Unassigned_OutAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public ref int F;
+
+ static void M(out int x) => throw null;
+
+ static void Test(R r)
+ {
+ M(out r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
+ }
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75315")]
+ public void DefiniteAssignment_ValueField_Unassigned_OutAtCallSite()
+ {
+ var comp = CreateCompilation("""
+ ref struct R
+ {
+ public int F;
+
+ static void M(out int x) => throw null;
+
+ static void Test(R r)
+ {
+ M(out r.F);
+ }
+ }
+ """,
+ targetFramework: TargetFramework.NetCoreApp);
+ comp.VerifyDiagnostics();
+ }
+
[Fact]
public void AssignLocal()
{
@@ -5571,7 +5934,10 @@ object P
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
- // 0.cs(7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use.
+ // 0.cs(3,18): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 18),
+ // 0.cs(7,9): warning CS9201: Ref field 'F' should be ref-assigned before use.
// F = tValue;
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9));
}
@@ -5606,10 +5972,13 @@ object P
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27),
// (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
// F = tValue; // 1
Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9),
- // (7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use.
+ // (7,9): warning CS9201: Ref field 'F' should be ref-assigned before use.
// F = tValue; // 1
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9),
// (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
@@ -5662,7 +6031,10 @@ object P
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
- // 0.cs(7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use.
+ // 0.cs(3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27),
+ // 0.cs(7,9): warning CS9201: Ref field 'F' should be ref-assigned before use.
// F = tValue;
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9));
}
@@ -5697,10 +6069,13 @@ object P
}";
var comp = CreateCompilation(new[] { source, IsExternalInitTypeDefinition }, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,36): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 36),
// (7,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
// F = tValue; // 1
Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "F").WithArguments("field", "F").WithLocation(7, 9),
- // (7,9): warning CS9201: 'ref' field 'F' should be ref-assigned before use.
+ // (7,9): warning CS9201: Ref field 'F' should be ref-assigned before use.
// F = tValue; // 1
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "F").WithArguments("F").WithLocation(7, 9),
// (8,9): error CS8331: Cannot assign to field 'F' or use it as the right hand side of a ref assignment because it is a readonly variable
@@ -7136,7 +7511,7 @@ class Program
public void AssignOutParameterFrom_RefField()
{
var source =
-@"#pragma warning disable 649
+@"#pragma warning disable 9265
ref struct S
{
public ref T Ref;
@@ -7207,6 +7582,18 @@ class Program
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,18): warning CS9265: Field 'S.Ref' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T Ref;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "Ref").WithArguments("S.Ref").WithLocation(3, 18),
+ // (4,27): warning CS9265: Field 'S.RefReadonly' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T RefReadonly;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "RefReadonly").WithArguments("S.RefReadonly").WithLocation(4, 27),
+ // (5,27): warning CS9265: Field 'S.ReadonlyRef' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref T ReadonlyRef;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ReadonlyRef").WithArguments("S.ReadonlyRef").WithLocation(5, 27),
+ // (6,36): warning CS9265: Field 'S.ReadonlyRefReadonly' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref readonly T ReadonlyRefReadonly;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ReadonlyRefReadonly").WithArguments("S.ReadonlyRefReadonly").WithLocation(6, 36),
// (12,73): error CS8329: Cannot use field 'RefReadonly' as a ref or out value because it is a readonly variable
// static void FromValueRefReadonly(S s) { ref T t = ref s.RefReadonly; } // 1
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.RefReadonly").WithArguments("field", "RefReadonly").WithLocation(12, 73),
@@ -7268,7 +7655,19 @@ class Program
static void FromInReadonlyRefReadonly(in S s) { ref readonly T t = ref s.ReadonlyRefReadonly; }
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (3,18): warning CS9265: Field 'S.Ref' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T Ref;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "Ref").WithArguments("S.Ref").WithLocation(3, 18),
+ // (4,27): warning CS9265: Field 'S.RefReadonly' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T RefReadonly;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "RefReadonly").WithArguments("S.RefReadonly").WithLocation(4, 27),
+ // (5,27): warning CS9265: Field 'S.ReadonlyRef' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref T ReadonlyRef;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ReadonlyRef").WithArguments("S.ReadonlyRef").WithLocation(5, 27),
+ // (6,36): warning CS9265: Field 'S.ReadonlyRefReadonly' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref readonly T ReadonlyRefReadonly;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ReadonlyRefReadonly").WithArguments("S.ReadonlyRefReadonly").WithLocation(6, 36));
}
[Fact]
@@ -7327,7 +7726,10 @@ class Program
static ref readonly T F10(in S s) => ref s.F;
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (3,18): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 18));
}
[Fact]
@@ -7353,6 +7755,9 @@ class Program
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27),
// (4,30): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
// public ref T F1() => ref F;
Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(4, 30),
@@ -7392,7 +7797,10 @@ class Program
static ref readonly T F10(in S s) => ref s.F;
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27));
}
[Fact]
@@ -7418,6 +7826,9 @@ class Program
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,36): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 36),
// (4,30): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
// public ref T F1() => ref F;
Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(4, 30),
@@ -7688,7 +8099,10 @@ static void M4(in T t) { }
static void FromIn4B(in S s) { M4(s.F); }
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (3,18): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 18));
}
[Fact]
@@ -7733,6 +8147,9 @@ static void M4(in T t) { }
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27),
// (14,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
// static void FromValue2(S s) { M2(ref s.F); } // 1
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(14, 49),
@@ -7800,7 +8217,10 @@ static void M4(in T t) { }
static void FromIn4B(in S s) { M4(s.F); }
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyEmitDiagnostics();
+ comp.VerifyEmitDiagnostics(
+ // (3,27): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 27));
}
[Fact]
@@ -7845,6 +8265,9 @@ static void M4(in T t) { }
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyEmitDiagnostics(
+ // (3,36): warning CS9265: Field 'S.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("S.F").WithLocation(3, 36),
// (14,49): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
// static void FromValue2(S s) { M2(ref s.F); } // 1
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "s.F").WithArguments("field", "F").WithLocation(14, 49),
@@ -7875,7 +8298,7 @@ static void M4(in T t) { }
public void RefParameter_ReadonlyRefReadonly_PEVerifyCompat()
{
var source =
-@"#pragma warning disable 649
+@"#pragma warning disable 9265
ref struct S
{
public readonly ref readonly T F;
@@ -9601,7 +10024,10 @@ public R(){}
Diagnostic(ErrorCode.ERR_RefProperty, "c.N").WithLocation(12, 12),
// (14,12): error CS0206: A non ref-returning property or indexer may not be used as an out or ref value
// _ = M2(out c[0]); //CS0206
- Diagnostic(ErrorCode.ERR_RefProperty, "c[0]").WithLocation(14, 12)
+ Diagnostic(ErrorCode.ERR_RefProperty, "c[0]").WithLocation(14, 12),
+ // (28,21): warning CS9265: Field 'R.n' is never ref-assigned to, and will always have its default value (null reference)
+ // private ref int n;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "n").WithArguments("R.n").WithLocation(28, 21)
);
}
@@ -9819,9 +10245,9 @@ public static void M() where T : unmanaged { }
// (10,36): warning CS0649: Field 'StructWithIndirectRefField.Field' is never assigned to, and will always have its default value
// public StructWithRefField Field;
Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Field").WithArguments("StructWithIndirectRefField.Field", "").WithLocation(10, 36),
- // (14,18): warning CS0649: Field 'StructWithRefField.RefField' is never assigned to, and will always have its default value
+ // (14,18): warning CS9265: Field 'StructWithRefField.RefField' is never ref-assigned to, and will always have its default value (null reference)
// public ref T RefField;
- Diagnostic(ErrorCode.WRN_UnassignedInternalField, "RefField").WithArguments("StructWithRefField.RefField", "").WithLocation(14, 18)
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "RefField").WithArguments("StructWithRefField.RefField").WithLocation(14, 18)
);
Assert.True(comp.GetTypeByMetadataName("StructWithIndirectRefField").IsManagedTypeNoUseSiteDiagnostics);
@@ -18266,7 +18692,10 @@ public void ReturnRefField()
public ref readonly T GetRefReadonly() => ref F;
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,18): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 18));
}
[Fact]
@@ -18282,6 +18711,9 @@ public void ReturnRefReadonlyField()
}";
var comp = CreateCompilation(source, targetFramework: TargetFramework.Net70);
comp.VerifyDiagnostics(
+ // (3,27): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly T F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 27),
// (5,34): error CS8333: Cannot return field 'F' by writable reference because it is a readonly variable
// public ref T GetRef() => ref F; // 1
Diagnostic(ErrorCode.ERR_RefReturnReadonlyNotField, "F").WithArguments("field", "F").WithLocation(5, 34));
@@ -29883,6 +30315,9 @@ ref struct RS
expectedOutput: "1");
verifier.VerifyDiagnostics(
+ // (14,13): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
+ // ref int ri;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(14, 13),
// (15,20): warning CS9201: Ref field 'ri' should be ref-assigned before use.
// public RS() => ri = 0;
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(15, 20));
@@ -29934,9 +30369,9 @@ public RS()
expectedOutput: "1");
verifier.VerifyDiagnostics(
- // (14,13): warning CS0649: Field 'RS.ri' is never assigned to, and will always have its default value 0
+ // (14,13): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
// ref int ri;
- Diagnostic(ErrorCode.WRN_UnassignedInternalField, "ri").WithArguments("RS.ri", "0").WithLocation(14, 13),
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(14, 13),
// (15,12): warning CS9022: Control is returned to caller before field 'RS.ri' is explicitly assigned, causing a preceding implicit assignment of 'default'.
// public RS()
Diagnostic(ErrorCode.WRN_UnassignedThisSupportedVersion, "RS").WithArguments("RS.ri").WithLocation(15, 12),
@@ -30002,6 +30437,9 @@ public RS(bool ignored)
expectedOutput: "12");
verifier.VerifyDiagnostics(
+ // (17,13): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
+ // ref int ri;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(17, 13),
// (20,29): warning CS9201: Ref field 'ri' should be ref-assigned before use.
// ref int local = ref ri; // 1
Diagnostic(ErrorCode.WRN_UseDefViolationRefField, "ri").WithArguments("ri").WithLocation(20, 29),
@@ -30077,6 +30515,9 @@ ref struct RS
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
+ // (3,22): warning CS9265: Field 'RS.ri' is never ref-assigned to, and will always have its default value (null reference)
+ // ref readonly int ri;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "ri").WithArguments("RS.ri").WithLocation(3, 22),
// (4,20): error CS8331: Cannot assign to field 'ri' or use it as the right hand side of a ref assignment because it is a readonly variable
// public RS() => ri = 0;
Diagnostic(ErrorCode.ERR_AssignReadonlyNotField, "ri").WithArguments("field", "ri").WithLocation(4, 20),
@@ -30106,7 +30547,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 20));
verifier.VerifyIL("S.Test1",
@"
@@ -30145,6 +30589,9 @@ static void Test1()
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29),
// (11,15): error CS8329: Cannot use field 'F1' as a ref or out value because it is a readonly variable
// M(ref GetS().F1);
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "GetS().F1").WithArguments("field", "F1").WithLocation(11, 15)
@@ -30174,7 +30621,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1", """
{
@@ -30212,6 +30662,9 @@ static void Test1()
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29),
// (11,15): error CS8329: Cannot use field 'F1' as a ref or out value because it is a readonly variable
// M(ref GetS().F1);
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "GetS().F1").WithArguments("field", "F1").WithLocation(11, 15)
@@ -30241,7 +30694,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1", """
{
@@ -30262,7 +30718,7 @@ .locals init (S V_0)
public void RefField_AsRefArgument_06()
{
var verifier = CompileAndVerify("""
- #pragma warning disable CS0649 // Field 'S.F1' is never assigned to, and will always have its default value 0
+ #pragma warning disable CS9265 // Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
ref struct S
{
@@ -30320,7 +30776,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1",
@"
@@ -30359,7 +30818,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1",
@"
@@ -30400,7 +30862,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1", """
{
@@ -30439,6 +30904,9 @@ static void Test1()
targetFramework: TargetFramework.NetCoreApp);
verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29),
// (11,15): warning CS9191: The 'ref' modifier for argument 1 corresponding to 'in' parameter is equivalent to 'in'. Consider using 'in' instead.
// M(ref GetS().F1);
Diagnostic(ErrorCode.WRN_BadArgRef, "GetS().F1").WithArguments("1").WithLocation(11, 15)
@@ -30483,7 +30951,10 @@ static void Test1()
verify: Verification.Skipped,
targetFramework: TargetFramework.NetCoreApp);
- verifier.VerifyDiagnostics();
+ verifier.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
+ // public readonly ref int F1;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F1").WithArguments("S.F1").WithLocation(3, 29));
verifier.VerifyIL("S.Test1", """
{
@@ -30504,7 +30975,7 @@ .locals init (S V_0)
public void RefField_AsRefArgument_12()
{
var verifier = CompileAndVerify("""
- #pragma warning disable CS0649 // Field 'S.F1' is never assigned to, and will always have its default value 0
+ #pragma warning disable CS9265 // Field 'S.F1' is never ref-assigned to, and will always have its default value (null reference)
ref struct S
{
@@ -30560,7 +31031,10 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
@@ -30582,7 +31056,10 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
@@ -30606,7 +31083,10 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
@@ -30628,15 +31108,16 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
public void ThroughValue_ValueOfRef_ToRefReadonly()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref int F;
@@ -30653,17 +31134,18 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
- // (13,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20),
+ // (11,11): warning CS9192: Argument 1 should be passed with 'ref' or 'in' keyword
// M(GetValue().F);
- Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "GetValue().F").WithArguments("1").WithLocation(13, 11));
+ Diagnostic(ErrorCode.WRN_ArgExpectedRefOrIn, "GetValue().F").WithArguments("1").WithLocation(11, 11));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
public void ThroughValue_ValueOfRef_ToIn()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref int F;
@@ -30679,15 +31161,16 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
public void ThroughValue_ValueOfRef_ToRef()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref int F;
@@ -30704,9 +31187,12 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
- // (13,11): error CS1620: Argument 1 must be passed with the 'ref' keyword
+ // (3,20): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 20),
+ // (11,11): error CS1620: Argument 1 must be passed with the 'ref' keyword
// M(GetValue().F);
- Diagnostic(ErrorCode.ERR_BadArgRef, "GetValue().F").WithArguments("1", "ref").WithLocation(13, 11));
+ Diagnostic(ErrorCode.ERR_BadArgRef, "GetValue().F").WithArguments("1", "ref").WithLocation(11, 11));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
@@ -30729,6 +31215,9 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29),
// (11,15): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
// M(ref GetValue().F);
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "GetValue().F").WithArguments("field", "F").WithLocation(11, 15));
@@ -30753,7 +31242,10 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
@@ -30776,6 +31268,9 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29),
// (11,15): error CS8329: Cannot use field 'F' as a ref or out value because it is a readonly variable
// M(out GetValue().F);
Diagnostic(ErrorCode.ERR_RefReadonlyNotField, "GetValue().F").WithArguments("field", "F").WithLocation(11, 15));
@@ -30785,8 +31280,6 @@ static void Test()
public void ThroughValue_ValueOfRefReadonly_ToRefReadonly()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref readonly int F;
@@ -30803,17 +31296,18 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
- // (13,11): warning CS9195: Argument 1 should be passed with the 'in' keyword
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29),
+ // (11,11): warning CS9195: Argument 1 should be passed with the 'in' keyword
// M(GetValue().F);
- Diagnostic(ErrorCode.WRN_ArgExpectedIn, "GetValue().F").WithArguments("1").WithLocation(13, 11));
+ Diagnostic(ErrorCode.WRN_ArgExpectedIn, "GetValue().F").WithArguments("1").WithLocation(11, 11));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
public void ThroughValue_ValueOfRefReadonly_ToIn()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref readonly int F;
@@ -30829,15 +31323,16 @@ static void Test()
}
""",
targetFramework: TargetFramework.NetCoreApp);
- comp.VerifyDiagnostics();
+ comp.VerifyDiagnostics(
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29));
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/75082")]
public void ThroughValue_ValueOfRefReadonly_ToRef()
{
var comp = CreateCompilation("""
- #pragma warning disable CS0649 // Field 'R.F' is never assigned to, and will always have its default value 0
-
ref struct R
{
public ref readonly int F;
@@ -30854,9 +31349,12 @@ static void Test()
""",
targetFramework: TargetFramework.NetCoreApp);
comp.VerifyDiagnostics(
- // (13,11): error CS1620: Argument 1 must be passed with the 'ref' keyword
+ // (3,29): warning CS9265: Field 'R.F' is never ref-assigned to, and will always have its default value (null reference)
+ // public ref readonly int F;
+ Diagnostic(ErrorCode.WRN_UnassignedInternalRefField, "F").WithArguments("R.F").WithLocation(3, 29),
+ // (11,11): error CS1620: Argument 1 must be passed with the 'ref' keyword
// M(GetValue().F);
- Diagnostic(ErrorCode.ERR_BadArgRef, "GetValue().F").WithArguments("1", "ref").WithLocation(13, 11));
+ Diagnostic(ErrorCode.ERR_BadArgRef, "GetValue().F").WithArguments("1", "ref").WithLocation(11, 11));
}
}
}
diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
index c70afdb79199..63df7b20d52b 100644
--- a/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/Symbols/RequiredMembersTests.cs
@@ -1364,7 +1364,7 @@ class C
public void RefFields()
{
var source = """
- #pragma warning disable 649
+ #pragma warning disable 9265
internal ref struct R1
{
internal required ref T F1;
diff --git a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
index 47c197cb0330..4bd091c5823d 100644
--- a/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Diagnostics/DiagnosticTest.cs
@@ -471,6 +471,10 @@ public void WarningLevel_2()
// These are the warnings introduced with the warning "wave" shipped with dotnet 8 and C# 12.
Assert.Equal(8, ErrorFacts.GetWarningLevel(errorCode));
break;
+ case ErrorCode.WRN_UnassignedInternalRefField:
+ // These are the warnings introduced with the warning "wave" shipped with dotnet 10 and C# 14.
+ Assert.Equal(10, ErrorFacts.GetWarningLevel(errorCode));
+ break;
default:
// If a new warning is added, this test will fail
// and whoever is adding the new warning will have to update it with the expected error level.