@@ -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
0 commit comments