Skip to content

Commit ace0477

Browse files
author
Julien Couvreur
committed
Extensions: relax inferrability rule for methods
1 parent 8f8cf6e commit ace0477

18 files changed

+330
-98
lines changed

src/Compilers/CSharp/Portable/CSharpResources.resx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8135,7 +8135,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
81358135
<value>'value': an automatically-generated parameter name conflicts with an extension type parameter name</value>
81368136
</data>
81378137
<data name="ERR_UnderspecifiedExtension" xml:space="preserve">
8138-
<value>The extended type '{0}' must reference all the type parameters declared by the extension, but type parameter '{1}' is not referenced.</value>
8138+
<value>The extended type '{0}' must reference all the type parameters declared by the extension, since the extension block contains a non-method member, but type parameter '{1}' is not referenced.</value>
81398139
</data>
81408140
<data name="ERR_ExpressionTreeContainsExtensionPropertyAccess" xml:space="preserve">
81418141
<value>An expression tree may not contain an extension property access</value>

src/Compilers/CSharp/Portable/Symbols/Extensions/SynthesizedExtensionMarker.cs

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymb
7777

7878
if (parameter is { })
7979
{
80-
checkUnderspecifiedGenericExtension(parameter, ContainingType.TypeParameters, diagnostics);
81-
8280
TypeSymbol parameterType = parameter.TypeWithAnnotations.Type;
8381
RefKind parameterRefKind = parameter.RefKind;
8482
SyntaxNode? parameterTypeSyntax = parameterList.Parameters[0].Type;
@@ -112,34 +110,6 @@ protected override (TypeWithAnnotations ReturnType, ImmutableArray<ParameterSymb
112110

113111
return parameter;
114112
}
115-
116-
static void checkUnderspecifiedGenericExtension(ParameterSymbol parameter, ImmutableArray<TypeParameterSymbol> typeParameters, BindingDiagnosticBag diagnostics)
117-
{
118-
var underlyingType = parameter.Type;
119-
var usedTypeParameters = PooledHashSet<TypeParameterSymbol>.GetInstance();
120-
underlyingType.VisitType(collectTypeParameters, arg: usedTypeParameters);
121-
122-
foreach (var typeParameter in typeParameters)
123-
{
124-
if (!usedTypeParameters.Contains(typeParameter))
125-
{
126-
diagnostics.Add(ErrorCode.ERR_UnderspecifiedExtension, parameter.GetFirstLocation(), underlyingType, typeParameter);
127-
}
128-
}
129-
130-
usedTypeParameters.Free();
131-
}
132-
133-
static bool collectTypeParameters(TypeSymbol type, PooledHashSet<TypeParameterSymbol> typeParameters, bool ignored)
134-
{
135-
if (type is TypeParameterSymbol typeParameter)
136-
{
137-
typeParameters.Add(typeParameter);
138-
}
139-
140-
return false;
141-
}
142-
143113
}
144114
}
145115
}

src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,45 @@ protected override void AfterMembersCompletedChecks(BindingDiagnosticBag diagnos
19861986
var syntax = (ExtensionBlockDeclarationSyntax)this.GetNonNullSyntaxNode();
19871987
diagnostics.Add(ErrorCode.ERR_BadExtensionContainingType, syntax.Keyword);
19881988
}
1989+
1990+
if (TryGetOrCreateExtensionMarker() is { Parameters: [var extensionParameter] })
1991+
{
1992+
checkUnderspecifiedGenericExtension(extensionParameter, TypeParameters, diagnostics);
1993+
}
1994+
}
1995+
1996+
return;
1997+
1998+
void checkUnderspecifiedGenericExtension(ParameterSymbol parameter, ImmutableArray<TypeParameterSymbol> typeParameters, BindingDiagnosticBag diagnostics)
1999+
{
2000+
if (GetMembers().All((m, a) => m is MethodSymbol { MethodKind: MethodKind.Ordinary }, arg: (object?)null))
2001+
{
2002+
return;
2003+
}
2004+
2005+
var underlyingType = parameter.Type;
2006+
var usedTypeParameters = PooledHashSet<TypeParameterSymbol>.GetInstance();
2007+
underlyingType.VisitType(collectTypeParameters, arg: usedTypeParameters);
2008+
2009+
foreach (var typeParameter in typeParameters)
2010+
{
2011+
if (!usedTypeParameters.Contains(typeParameter))
2012+
{
2013+
diagnostics.Add(ErrorCode.ERR_UnderspecifiedExtension, parameter.GetFirstLocation(), underlyingType, typeParameter);
2014+
}
2015+
}
2016+
2017+
usedTypeParameters.Free();
2018+
}
2019+
2020+
static bool collectTypeParameters(TypeSymbol type, PooledHashSet<TypeParameterSymbol> typeParameters, bool ignored)
2021+
{
2022+
if (type is TypeParameterSymbol typeParameter)
2023+
{
2024+
typeParameters.Add(typeParameter);
2025+
}
2026+
2027+
return false;
19892028
}
19902029
}
19912030
}

src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)