Skip to content

Commit

Permalink
Merge pull request #54045 from dotnet/merges/main-to-main-vs-deps
Browse files Browse the repository at this point in the history
Merge main to main-vs-deps
  • Loading branch information
RikkiGibson authored Jun 11, 2021
2 parents 9374a23 + f6a05ee commit 6244077
Show file tree
Hide file tree
Showing 6 changed files with 462 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1634,17 +1634,25 @@ private BoundNode RewriteLambdaConversion(BoundLambda node)
// different from the local variable `type`, which has the node's type substituted for the current container.
var cacheVariableType = containerAsFrame.TypeMap.SubstituteType(node.Type).Type;

var cacheVariableName = GeneratedNames.MakeLambdaCacheFieldName(
// If we are generating the field into a display class created exclusively for the lambda the lambdaOrdinal itself is unique already,
// no need to include the top-level method ordinal in the field name.
(closureKind == ClosureKind.General) ? -1 : topLevelMethodId.Ordinal,
topLevelMethodId.Generation,
lambdaId.Ordinal,
lambdaId.Generation);

var cacheField = new SynthesizedLambdaCacheFieldSymbol(translatedLambdaContainer, cacheVariableType, cacheVariableName, _topLevelMethod, isReadOnly: false, isStatic: closureKind == ClosureKind.Singleton);
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, cacheField.GetCciAdapter());
cache = F.Field(receiver, cacheField.AsMember(constructedFrame)); //NOTE: the field was added to the unconstructed frame type.
var hasTypeParametersFromAnyMethod = cacheVariableType.ContainsMethodTypeParameter();

// If we want to cache a variable by moving its value into a field,
// the variable cannot use any type parameter from the method it is currently declared within.
if (!hasTypeParametersFromAnyMethod)
{
var cacheVariableName = GeneratedNames.MakeLambdaCacheFieldName(
// If we are generating the field into a display class created exclusively for the lambda the lambdaOrdinal itself is unique already,
// no need to include the top-level method ordinal in the field name.
(closureKind == ClosureKind.General) ? -1 : topLevelMethodId.Ordinal,
topLevelMethodId.Generation,
lambdaId.Ordinal,
lambdaId.Generation);

var cacheField = new SynthesizedLambdaCacheFieldSymbol(translatedLambdaContainer, cacheVariableType, cacheVariableName, _topLevelMethod, isReadOnly: false, isStatic: closureKind == ClosureKind.Singleton);
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(translatedLambdaContainer, cacheField.GetCciAdapter());
cache = F.Field(receiver, cacheField.AsMember(constructedFrame)); //NOTE: the field was added to the unconstructed frame type.
result = F.Coalesce(cache, F.AssignmentExpression(cache, result));
}
}
else
{
Expand All @@ -1655,9 +1663,8 @@ private BoundNode RewriteLambdaConversion(BoundLambda node)
if (_addedStatements == null) _addedStatements = ArrayBuilder<BoundStatement>.GetInstance();
cache = F.Local(cacheLocal);
_addedStatements.Add(F.Assignment(cache, F.Null(type)));
result = F.Coalesce(cache, F.AssignmentExpression(cache, result));
}

result = F.Coalesce(cache, F.AssignmentExpression(cache, result));
}
catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
{
Expand Down
9 changes: 9 additions & 0 deletions src/Compilers/CSharp/Portable/Symbols/TypeSymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,15 @@ public static bool ContainsTypeParameters(this TypeSymbol type, HashSet<TypePara
private static readonly Func<TypeSymbol, HashSet<TypeParameterSymbol>, bool, bool> s_containsTypeParametersPredicate =
(type, parameters, unused) => type.TypeKind == TypeKind.TypeParameter && parameters.Contains((TypeParameterSymbol)type);

public static bool ContainsMethodTypeParameter(this TypeSymbol type)
{
var result = type.VisitType(s_containsMethodTypeParameterPredicate, null);
return result is object;
}

private static readonly Func<TypeSymbol, object?, bool, bool> s_containsMethodTypeParameterPredicate =
(type, _, _) => type.TypeKind == TypeKind.TypeParameter && type.ContainingSymbol is MethodSymbol;

/// <summary>
/// Return true if the type contains any dynamic type reference.
/// </summary>
Expand Down
Loading

0 comments on commit 6244077

Please sign in to comment.