Skip to content

Test plan for lambda improvements #52192

@cston

Description

@cston

Proposal: lambda-improvements.md
Branch: features/lambdas

Championed issue (explicit return type, attributes): dotnet/csharplang#4934
Championed issue (direct invocation): dotnet/csharplang#4748

Remaining work items

Attributes

Parsing

  • static lambdas
  • async lambdas
  • With parameter types
  • Without parameter types
  • With parameter ref specifiers
  • Without parameter ref specifiers
  • Nonparenthesized parameter list (should be a binding error)
  • Conditional array accesses
  • Object/collection initializers
  • After ternaries
  • Switch expression arms
  • Operator precedence
  • Disallow on lambda converted to expression tree

Semantics

  • Nullability enforcements on lambda returns when there is an explicit return type and/or attributes (PR Enforce nullability contract in lambda body #56590)
    • DisallowNull
    • NotNull/NotNullWhen
    • AllowNull
    • MaybeNull/MaybeNullWhen
    • MemberNotNull/MemberNotNullWhen
    • DoesNotReturn/DoesNotReturnIf
  • Special attributes
    • UnmanagedCallersOnlyAttribute
    • ObsoleteAttribute/ExperimentalAttribute/DeprecatedAttribute
    • SkipLocalsInitAttribute
    • ExcludeFromCodeCoverageAttribute
    • Security attributes
    • CallerFilePathAttribute
    • CallerLineNumberAttribute
    • CallerMemberNameAttribute
    • ConditionalAttribute
    • MethodImplAttribute
    • PreserveSigAttribute
    • MarshalAsAttribute
    • DllImportAttribute (error)
    • EnumeratorCancellationAttribute
  • GetTypeInfo (see LambdaTests.LambdaAttributes_AttributeSemanticModel())
  • GetSymbolInfo
  • SyntaxNormalizer

IDE/Public API

  • Attribute type completion inside brackets
  • Automatic close bracket insertion
  • Smart complete statement
  • Speculation inside attribute brackets
    • New attributes
    • Argument positions
  • Debugging: DebuggerStepThroughAttribute
  • DebuggerDisplay
  • Find all refs on attribute types
  • IDE syntax formatter
  • EnC
  • Convert to local function/method refactorings

Explicit return type

Syntax

  • async async(async async) => async
  • async MyMethod() => null; on the top level parses as a local function statement with a return type of async
  • Other async contexts
  • static lambdas
  • void return type
  • disallow var return type (reserved)
  • ref/ref readonly return
    • Errors on void return
  • Nested lambdas
  • After is
  • switch expression arms
  • Ternary arms
  • Operator precedence
  • Type-tuple patterns in switch expression arms continue to be parsed as type-tuple patterns
  • Before and after range operators
  • Everywhere a method can be used

Semantics

  • Mismatched return statement types and declared return type
    • Nullable-only
    • Inconvertible types
  • Target-typing for contained return statements
  • Type inference
    • LDM: Should the explicit return type contribute to type inference? (Yes) (see TypeInference_ExplicitReturnType_01, ...)
  • Pathological inference case short-circuiting (see OverloadResolutionPerfTests.NestedLambdas_WithParameterAndReturnTypes())
  • GetTypeInfo (see LambdaTests.LambdaReturnType_SemanticModel())
  • GetSymbolInfo (see LambdaTests.LambdaReturnType_SemanticModel())
  • SyntaxNormalizer (issue SyntaxNormalizer does not include space between lambda expression return type and parenthesized parameter list #59653)

IDE/Public API

  • FindAllRefs finds return type
  • Convert to local function/method
  • Intellisense shows types (including after things like static or async)
  • IDE formatter

Inferred (natural) delegate type

Syntax

  • None

Semantics

  • revert conditional binding patch from 16.11 (ie. revert Infer delegate types with -langversion:preview only #53241)
  • Implicit and explicit conversions of lambda expression to:
    • System.MulticastDelegate and base types and interfaces
    • System.Linq.Expressions.Expression<TDelegate>
    • System.Linq.Expressions.Expression, System.Linq.Expressions.LambdaExpression
  • Implicit and explicit conversions of method group to
    • System.MulticastDelegate and base types and interfaces
  • Directly invoke lambda expressions
  • Breaking change tests
  • Type inference based on lambdas
  • var
    • direct lambda/method group assignment
    • variant assignment through ternaries
  • dicard: _ = () => {}; (disallowed)
  • Method group with multiple candidates
    • instance and static methods with same/different signature invoked with implicit/explicit receiver or explicit type qualifier
    • instance and extension methods with same/different signature invoked with implicit/explicit receiver
    • overridden method
    • hidden method
    • accessible and inaccessible overloads
    • overloads that differ by parameter types/ref or return type/ref
    • overloads that differ by object/dynamic, tuple element names, nullability, etc.
    • overloads with different arity, invoked with implicit/explicit type arguments
    • overloads with different type parameter constraints
  • Missing Action or Func types
  • Missing System.Delegate type
  • modopt and modreq do not affect delegate type
  • Delegate parameter types or return type that cannot be used as type arguments
  • Delegate type includes inferred nullability
  • Synthesized types are shared
  • Handling of parameter names (see VB)
  • Delegate type is only synthesized when required (not when converting to explicit type)
  • ErrorCode.ERR_CannotInferDelegateType only reported when delegate type is required
  • Pattern-based language constructs
    • Query expression on lambda expression/method group with extension Select on delegate type
    • Extension GetAwaiter
    • Extension GetEnumerator
    • Extension GetAsyncEnumerator
    • Extension deconstruct
  • Address of on single-method method groups correctly infers function pointer type
  • Interaction with discard parameters
  • Lambdas that just throw
  • GetTypeInfo on lambdas and method groups (issue GetTypeInfo() should return the inferred delegate type for method groups #52874)
    • Does .Type return null or the Action/Func/synthesized delegate type? How does ASP.NET source generator obtain the lambda signature? (see here)
  • GetSymbolInfo on lambdas and method groups (issue GetSymbolInfo() should return the resolved method from a method group with inferred delegate type #52870)
  • IOperation nodes adjusted to give natural types
  • ClassifyConversion (see DelegateTypeTests.ClassifyConversionFromExpression())
  • ToDisplayString on synthesized delegate types

IDE/Public API

Open issues

Metadata

Metadata

Type

No type

Projects

Status

Language/design

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions