Skip to content

Commit

Permalink
Nullable analysis of yield return (#31072)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcouv authored Nov 13, 2018
1 parent c4598d7 commit ff8e1c7
Show file tree
Hide file tree
Showing 6 changed files with 752 additions and 273 deletions.
20 changes: 15 additions & 5 deletions src/Compilers/CSharp/Portable/Binder/InMethodBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,27 +176,37 @@ internal override TypeSymbol GetIteratorElementType(YieldStatementSyntax node, D
}

private TypeSymbol GetIteratorElementTypeFromReturnType(RefKind refKind, TypeSymbol returnType, CSharpSyntaxNode errorLocationNode, DiagnosticBag diagnostics)
{
return GetIteratorElementTypeFromReturnType(Compilation, refKind, returnType, errorLocationNode, diagnostics).TypeSymbol;
}

internal static TypeSymbolWithAnnotations GetIteratorElementTypeFromReturnType(CSharpCompilation compilation, RefKind refKind, TypeSymbol returnType, CSharpSyntaxNode errorLocationNode, DiagnosticBag diagnostics)
{
if (refKind == RefKind.None && returnType.Kind == SymbolKind.NamedType)
{
switch (returnType.OriginalDefinition.SpecialType)
{
case SpecialType.System_Collections_IEnumerable:
case SpecialType.System_Collections_IEnumerator:
return GetSpecialType(SpecialType.System_Object, diagnostics, errorLocationNode);
var objectType = compilation.GetSpecialType(SpecialType.System_Object);
if (diagnostics != null)
{
ReportUseSiteDiagnostics(objectType, diagnostics, errorLocationNode);
}
return TypeSymbolWithAnnotations.Create(objectType);

case SpecialType.System_Collections_Generic_IEnumerable_T:
case SpecialType.System_Collections_Generic_IEnumerator_T:
return ((NamedTypeSymbol)returnType).TypeArgumentsNoUseSiteDiagnostics[0].TypeSymbol;
return ((NamedTypeSymbol)returnType).TypeArgumentsNoUseSiteDiagnostics[0];
}

if (returnType.OriginalDefinition == Compilation.GetWellKnownType(WellKnownType.System_Collections_Generic_IAsyncEnumerable_T))
if (returnType.OriginalDefinition == compilation.GetWellKnownType(WellKnownType.System_Collections_Generic_IAsyncEnumerable_T))
{
return ((NamedTypeSymbol)returnType).TypeArgumentsNoUseSiteDiagnostics[0].TypeSymbol;
return ((NamedTypeSymbol)returnType).TypeArgumentsNoUseSiteDiagnostics[0];
}
}

return null;
return default;
}

internal override void LookupSymbolsInSingleBinder(
Expand Down
13 changes: 13 additions & 0 deletions src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4592,6 +4592,19 @@ public override BoundNode VisitThrowExpression(BoundThrowExpression node)
return result;
}

public override BoundNode VisitYieldReturnStatement(BoundYieldReturnStatement node)
{
BoundExpression expr = node.Expression;
if (expr == null)
{
return null;
}
var method = (MethodSymbol)_member;
TypeSymbolWithAnnotations elementType = InMethodBinder.GetIteratorElementTypeFromReturnType(compilation, RefKind.None, method.ReturnType.TypeSymbol, errorLocationNode: null, diagnostics: null);
VisitOptionalImplicitConversion(expr, elementType, useLegacyWarnings: false, AssignmentKind.Return);
return null;
}

#endregion Visitors

protected override string Dump(LocalState state)
Expand Down
Loading

0 comments on commit ff8e1c7

Please sign in to comment.