Skip to content

Commit 575bdf4

Browse files
author
Julien Couvreur
committed
Recognize attributes on ref/out parameter, misc fixes
1 parent e1d978f commit 575bdf4

3 files changed

Lines changed: 1230 additions & 39 deletions

File tree

src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2900,6 +2900,32 @@ private static TypeWithAnnotations ApplyLValueAnnotations(TypeWithAnnotations de
29002900
return declaredType;
29012901
}
29022902

2903+
private static TypeWithAnnotations ApplyRValueAnnotations(TypeWithAnnotations declaredType, FlowAnalysisAnnotations flowAnalysisAnnotations)
2904+
{
2905+
if ((flowAnalysisAnnotations & FlowAnalysisAnnotations.NotNull) == FlowAnalysisAnnotations.NotNull)
2906+
{
2907+
var typeSymbol = declaredType.Type;
2908+
if (declaredType.NullableAnnotation.IsNotAnnotated() || (typeSymbol.IsValueType && !typeSymbol.IsNullableType()))
2909+
{
2910+
return declaredType;
2911+
}
2912+
2913+
return TypeWithAnnotations.Create(typeSymbol, NullableAnnotation.NotAnnotated, declaredType.CustomModifiers);
2914+
}
2915+
else if ((flowAnalysisAnnotations & FlowAnalysisAnnotations.MaybeNull) == FlowAnalysisAnnotations.MaybeNull)
2916+
{
2917+
var typeSymbol = declaredType.Type;
2918+
if (!declaredType.NullableAnnotation.IsNotAnnotated() || (typeSymbol.IsValueType && typeSymbol.IsNullableType()))
2919+
{
2920+
return declaredType;
2921+
}
2922+
2923+
return TypeWithAnnotations.Create(typeSymbol, NullableAnnotation.Annotated, declaredType.CustomModifiers);
2924+
}
2925+
2926+
return declaredType;
2927+
}
2928+
29032929
// https://github.com/dotnet/roslyn/issues/29863 Record in the node whether type
29042930
// arguments were implicit, to allow for cases where the syntax is not an
29052931
// invocation (such as a synthesized call from a query interpretation).
@@ -3268,12 +3294,12 @@ private void VisitArgumentConversion(
32683294
else
32693295
{
32703296
// types match, but state would let a null in
3271-
ReportNullableAssignmentIfNecessary(argumentNoConversion, parameterType, resultType, useLegacyWarnings: false);
3297+
ReportNullableAssignmentIfNecessary(argumentNoConversion, ApplyLValueAnnotations(parameterType, parameterAnnotations), resultType, useLegacyWarnings: false);
32723298
}
32733299
}
32743300

32753301
// Check assignment from a fictional value from the parameter to the argument.
3276-
var parameterWithState = parameterType.ToTypeWithState();
3302+
var parameterWithState = TypeWithState.Create(parameterType, parameterAnnotations);
32773303
if (argumentNoConversion.IsSuppressed)
32783304
{
32793305
parameterWithState = parameterWithState.WithNotNullState();
@@ -3289,13 +3315,15 @@ private void VisitArgumentConversion(
32893315
break;
32903316
case RefKind.Out:
32913317
{
3292-
var parameterWithState = parameterType.ToTypeWithState();
3318+
var lValueType = result.LValueType;
3319+
var parameterWithAnnotations = ApplyRValueAnnotations(parameterType, parameterAnnotations);
3320+
var parameterWithState = TypeWithState.Create(parameterWithAnnotations, parameterAnnotations);
32933321
if (argumentNoConversion is BoundLocal local && local.DeclarationKind == BoundLocalDeclarationKind.WithInferredType)
32943322
{
3295-
_variableTypes[local.LocalSymbol] = parameterType;
3323+
_variableTypes[local.LocalSymbol] = parameterWithAnnotations;
3324+
lValueType = parameterWithAnnotations;
32963325
}
32973326

3298-
var lValueType = result.LValueType;
32993327
// Check assignment from a fictional value from the parameter to the argument.
33003328
var parameterValue = new BoundParameter(argumentNoConversion.Syntax, parameter);
33013329

src/Compilers/CSharp/Portable/Symbols/TypeWithState.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ public static TypeWithState Create(TypeWithAnnotations typeWithAnnotations, Flow
4040
NullableFlowState state;
4141
if (type.CanContainNull())
4242
{
43-
if ((annotations & FlowAnalysisAnnotations.MaybeNull) != 0)
43+
if ((annotations & FlowAnalysisAnnotations.MaybeNull) == FlowAnalysisAnnotations.MaybeNull)
4444
{
4545
state = NullableFlowState.MaybeNull;
4646
}
47-
else if ((annotations & FlowAnalysisAnnotations.NotNull) != 0)
47+
else if ((annotations & FlowAnalysisAnnotations.NotNull) == FlowAnalysisAnnotations.NotNull)
4848
{
4949
state = NullableFlowState.NotNull;
5050
}

0 commit comments

Comments
 (0)