Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected scoping on type parameter of local function parameter #60110

Open
jcouv opened this issue Mar 11, 2022 · 4 comments
Open

Unexpected scoping on type parameter of local function parameter #60110

jcouv opened this issue Mar 11, 2022 · 4 comments

Comments

@jcouv
Copy link
Member

jcouv commented Mar 11, 2022

        [Fact]
        public void TypeParameterScope_InParameterAttribute()
        {
            var comp = CreateCompilation(@"
class C
{
    void M()
    {
        local<object>(0);

        void local<TParameter>([My(TParameter)] int i) => throw null;
    }

    void M2<TParameter>([My(TParameter)] int i) => throw null;
}

public class MyAttribute : System.Attribute
{
    public MyAttribute(string name1) { }
}
");
            // TParameter unexpectedly was found in local function case
            comp.VerifyDiagnostics(
                // (8,36): error CS0119: 'TParameter' is a type, which is not valid in the given context
                //         void local<TParameter>([My(TParameter)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_BadSKunknown, "TParameter").WithArguments("TParameter", "type").WithLocation(8, 36),
                // (11,29): error CS0103: The name 'TParameter' does not exist in the current context
                //     void M2<TParameter>([My(TParameter)] int i) => throw null;
                Diagnostic(ErrorCode.ERR_NameNotInContext, "TParameter").WithArguments("TParameter").WithLocation(11, 29)
                );
        }

Note: this is a different than #59775
The difference in behavior between the method and the local function is this code in BindIdentifier:

            if (!IsInMethodBody && !IsInsideNameof)
            {
                Debug.Assert((options & LookupOptions.NamespacesOrTypesOnly) == 0);
                options |= LookupOptions.MustNotBeMethodTypeParameter;
            }

Relates to test plan #38801

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Mar 11, 2022
@Youssef1313
Copy link
Member

Is semantic model having the same issue?

if (!binder.IsInMethodBody &&
(options & (LookupOptions.NamespaceAliasesOnly | LookupOptions.NamespacesOrTypesOnly | LookupOptions.LabelsOnly)) == 0)
{
// Method type parameters are not in scope outside a method
// body unless the position is either:
// a) in a type-only context inside an expression, or
// b) inside of an XML name attribute in an XML doc comment.
var parentExpr = token.Parent as ExpressionSyntax;
if (parentExpr != null && !(parentExpr.Parent is XmlNameAttributeSyntax) && !SyntaxFacts.IsInTypeOnlyContext(parentExpr))
{
options |= LookupOptions.MustNotBeMethodTypeParameter;
}
}

Tests for semantic model may include nameof(TParameter) to make sure the behavior matches BindIdentifier. Then, the above comment should include c) inside of a nameof

@Youssef1313
Copy link
Member

There are only 3 usages of IsInMethodBody. Does it make sense to rename it to IsInMethodBodyOrLocalFunction?

The usages are:

if (!IsInMethodBody && !IsInsideNameof)

inLegalPosition = (IsInMethodBody || IsLocalFunctionsScopeBinder) && node.IsLegalCSharp73SpanStackAllocPosition();

@jcouv jcouv removed the untriaged Issues and PRs which have not yet been triaged by a lead label Mar 11, 2022
@jcouv jcouv added this to the Compiler.Next milestone Mar 11, 2022
@RikkiGibson
Copy link
Contributor

It seems like usage of the type parameter outside of nameof() always results in an error here. It's perhaps not urgent to address this unless some new valid way of using the type parameter in an attribute arises.

@jcouv jcouv modified the milestones: Compiler.Next, Backlog Mar 11, 2022
@AlekseyTs
Copy link
Contributor

I think it would be interesting to test with typeof as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants