提交 59807baf 编写于 作者: N Neal Gafter

Merge pull request #2698 from gafter/fix2549

Fix alpha-substitution for nested lambdas in a generic context.
......@@ -1171,12 +1171,14 @@ private BoundNode RewriteLambdaConversion(BoundLambda node)
BoundExpression cache;
if (shouldCacheForStaticMethod || shouldCacheInLoop && (object)containerAsFrame != null)
{
var cacheVariableType = containerAsFrame?.TypeMap.SubstituteType(type) ?? translatedLambdaContainer;
// 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.
// Since the cache variable will be in a container with possibly alpha-rewritten generic parameters, we need to
// substitute the original type according to the type map for that container. That substituted type may be
// different from the local variable `type`, which has the node's type substituted for the current container.
var cacheVariableType = containerAsFrame.TypeMap.SubstituteType(node.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,
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
//#define DEBUG_ALPHA // turn on DEBUG_ALPHA to help diagnose issues around type parameter alpha-renaming
using System;
using System.Collections.Immutable;
using System.Globalization;
......@@ -14,6 +16,11 @@ internal class SubstitutedTypeParameterSymbol : TypeParameterSymbol
private readonly TypeMap _map;
private readonly TypeParameterSymbol _substitutedFrom;
#if DEBUG_ALPHA
private static int _nextSequence = 1;
private readonly int _mySequence;
#endif
internal SubstitutedTypeParameterSymbol(Symbol newContainer, TypeMap map, TypeParameterSymbol substitutedFrom)
{
_container = newContainer;
......@@ -21,6 +28,9 @@ internal SubstitutedTypeParameterSymbol(Symbol newContainer, TypeMap map, TypePa
// in by TypeMap.WithAlphaRename. Instead, we can use the map lazily when yielding the constraints.
_map = map;
_substitutedFrom = substitutedFrom;
#if DEBUG_ALPHA
_mySequence = _nextSequence++;
#endif
}
public override TypeParameterKind TypeParameterKind
......@@ -130,17 +140,13 @@ public override string Name
get
{
return _substitutedFrom.Name
#if DEBUG_ALPHA // turn on DEBUG_ALPHA to help diagnose issues around type parameter alpha-renaming
+ "-" + nextSequence++
#if DEBUG_ALPHA
+ "#" + _mySequence
#endif
;
}
}
#if DEBUG_ALPHA
private static int nextSequence = 1;
#endif
public override bool IsImplicitlyDeclared
{
get
......
......@@ -5206,5 +5206,24 @@ public void F()
CompileAndVerify(source, new[] { SystemCoreRef });
}
[Fact, WorkItem(2549, "https://github.com/dotnet/roslyn/issues/2549")]
public void NestedLambdaWithExtensionMethodsInGeneric()
{
var source =
@"using System;
using System.Collections.Generic;
using System.Linq;
public class BadBaby
{
IEnumerable<object> Children;
public object Foo<T>()
{
return from child in Children select from T ch in Children select false;
}
}";
CompileAndVerify(source, new[] { SystemCoreRef });
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册