-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Closed
Labels
Area-CompilersTestTest failures in roslyn-CITest failures in roslyn-CITest-GapDescribes a specific feature or scenario that does not have test coverageDescribes a specific feature or scenario that does not have test coverage
Milestone
Description
Feature
This feature allows for the following changes to local functions:
- Allow
staticmodifier to be applied to local function declarations. Such a function will not be allowed to capture
any state from the enclosing functions: locals, parameters orthis. Additionally the function is guaranteed to be
emitted asstaticin the binary. - Allow locals and parameters in a local function,
staticor not, to shadow identifiers in the enclosing scope.
- Specification for static local functions checked in to
csharplang. - Specification for name shadowing in nested functions checked in to
csharplang.
Code Examples
Static enforcement
int field;
void M() {
int x = 42;
M(x);
static int M(int p) {
Console.WriteLine(x); // Error: Can't capture local
Console.WriteLine(field); // Error: Can't capture this
return p;
}
}Shadowing
void G(DiagnosticBag diagnostics) {
void M(DiagnosticsBag diagnostics) {
DiagnosticsBag diagnostics; // Error: can't shadow in same scope
}
}Compiler Scenarios
- Ensure all features tied to the C# 8.0 feature flag
- Can't shadow
- Can't annotate a local function with
static
-
staticlocal function- Can't capture
this, local or parameter (function or lambda) - Can't call instance methods
- Can't use instance fields
- Can access
privatedata from enclosing scope as long as it'sstatic - Parsing
- Fails for
static static - Fails for
<return type> static
- Fails for
- Definition is emitted as
staticin the binarystaticLocal Functions are not being emitted as static #38143 - Can't declare an extension method
- Semantic API correctly implements the is static check for local functions
- Can't capture
- Shadowing
- Can't shadow within a scope
- Can shadow in non-
staticlocal functions - Test semantic model (
LookupSymbols,GetSymbolInfo,GetOperationin particular) - Can shadow local, parameter, lambda parameter, local function parameter
- Can shadow in nested scenarios
- Can shadow with different type
- Can shadow in
- LINQ query
from - LINQ query
group by - Pattern expression
-
outvariable declaration - Type parameter
- LINQ query
-
Can't shadow in lambda expressions (not part of this implementation) -
nameofon identifiers that shadow (variables and type parameter)- On shadowed variables
- On variables in enclosing scope
- Ensure self referencing initializers that shadow use final identifier
void M() { int x = 13; void G() { int x = (x = 0) + 42; Console.WriteLine(x); // Prints 42 } G(); Console.WriteLine(x); // Prints 13 }
- IOperation can produce nodes for identifiers that shadow
- CFG can represent control flow of shadowed identifiers properly
- Confirm shadowing expectations for static and non-static local functions with LDM
- Design principal: removing
staticfrom a local function in a valid program should not change the meaning of the program - Emit as static method with same signature. If the containing method is generic, the method emitted for the local function should be generic, even if the local function does not reference the type parameters.
EmittedAsStatic_03 - Can reference type parameters from enclosing scope.
StaticWithTypeParameterReferences - Allow shadowing type parameter in containing method with local, parameter, type parameter, range variable in local function. Shadowing a type parameter with a type parameter should be a warning.
ShadowNames_TypeParameter - Allow shadowing local, parameter, type parameter, range variable in containing method with type parameter in local function.
- Allow using local function name for local, parameter, type parameter, range variable in same local function:
void Local(object Local) { }.ShadowNames_ThisLocalFunction - No new diagnostics for existing scenarios
- Non-static local function inside static local function can capture variables from static local function but not variables outside the static local function
StaticWithLocalFunctionVariableReference_01,_02 -
nameof(identifier)should bind to shadowing symbol -
typeof(T)should bind to type parameterTeven ifTis shadowed by a variable -
sizeof(T)should bind to type parameterTeven ifTis shadowed by a variable -
_should bind to_symbol in outer scope even in static local function.UnderscoreInOuterScope -
varshould bind tovarsymbol in outer scope even in static local function.VarInOuterScope -
awaitshould be contextual keyword in the same way regardless of whether local function is static.AwaitWithinAsyncOuterScope_02 - Test overloading with mix of static and non-static
- Test IOperation and CFG to ensure IDE does not crash
- EE: should be easier to allow invoking static local functions than non-static local functions
- Intellisense should only include one identifier for shadowed symbol
- Intellisense should only include shadowing local function, not shadowed
- Invoking a static local function in an expression tree should be an error.
ExpressionTreeLocalFunctionUsage_02 - Emit
callrather thancallvirtfor local functions regardless of whether local function is static.EmitCallInstruction - ISymbol.IsStatic should return false for non-static local function (not blocking)
IDE Scenarios
- UpgradeProject should prompt on
staticmodifier for local function - EE
- Evaluate locals / params that shadow other local / params
- Evaluate local function marked
static
- ENC
- Ensure adding a shadowing identifier is processed correctly
- Intellisense
- Recommend
staticwhen typing out a local function declaration (issue Auto-complete does not includestaticfor local function #32174, PR Recommend keyword static for static local functions #32187) - Do not recommend
this(filed issuethiskeyword should not be recommended within a static local function #35644) - Only recommends final identifier (shadowed identifiers are not included)
- Recommend
- Analyzer to flag local functions that could be made static
Reactions are currently unavailable
Metadata
Metadata
Labels
Area-CompilersTestTest failures in roslyn-CITest failures in roslyn-CITest-GapDescribes a specific feature or scenario that does not have test coverageDescribes a specific feature or scenario that does not have test coverage