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

Test plan for lambda improvements #52192

Closed
cston opened this issue Mar 27, 2021 · 4 comments
Closed

Test plan for lambda improvements #52192

cston opened this issue Mar 27, 2021 · 4 comments

Comments

@cston
Copy link
Member

cston commented Mar 27, 2021

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

@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 27, 2021
@jaredpar jaredpar added Feature Request Feature - Lambda Improvements and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Mar 29, 2021
@jaredpar jaredpar modified the milestones: 16.10, C# 10 Mar 29, 2021
@333fred
Copy link
Member

333fred commented Apr 17, 2021

Updated with initial test plan for Monday.

@Youssef1313
Copy link
Member

SyntaxGenerator.WithType and also SyntaxGenerator.GetType may need to be updated to handle explicit return type:

SyntaxKind.DelegateDeclaration => ((DelegateDeclarationSyntax)declaration).WithReturnType((TypeSyntax)type),
SyntaxKind.MethodDeclaration => ((MethodDeclarationSyntax)declaration).WithReturnType((TypeSyntax)type),
SyntaxKind.FieldDeclaration => ((FieldDeclarationSyntax)declaration).WithDeclaration(((FieldDeclarationSyntax)declaration).Declaration.WithType((TypeSyntax)type)),
SyntaxKind.PropertyDeclaration => ((PropertyDeclarationSyntax)declaration).WithType((TypeSyntax)type),
SyntaxKind.IndexerDeclaration => ((IndexerDeclarationSyntax)declaration).WithType((TypeSyntax)type),
SyntaxKind.EventFieldDeclaration => ((EventFieldDeclarationSyntax)declaration).WithDeclaration(((EventFieldDeclarationSyntax)declaration).Declaration.WithType((TypeSyntax)type)),
SyntaxKind.EventDeclaration => ((EventDeclarationSyntax)declaration).WithType((TypeSyntax)type),
SyntaxKind.Parameter => ((ParameterSyntax)declaration).WithType((TypeSyntax)type),
SyntaxKind.LocalDeclarationStatement => ((LocalDeclarationStatementSyntax)declaration).WithDeclaration(((LocalDeclarationStatementSyntax)declaration).Declaration.WithType((TypeSyntax)type)),
SyntaxKind.VariableDeclaration => ((VariableDeclarationSyntax)declaration).WithType((TypeSyntax)type),
_ => declaration,

case SyntaxKind.DelegateDeclaration:
return NotVoid(((DelegateDeclarationSyntax)declaration).ReturnType);
case SyntaxKind.MethodDeclaration:
return NotVoid(((MethodDeclarationSyntax)declaration).ReturnType);
case SyntaxKind.FieldDeclaration:
return ((FieldDeclarationSyntax)declaration).Declaration.Type;
case SyntaxKind.PropertyDeclaration:
return ((PropertyDeclarationSyntax)declaration).Type;
case SyntaxKind.IndexerDeclaration:
return ((IndexerDeclarationSyntax)declaration).Type;
case SyntaxKind.EventFieldDeclaration:
return ((EventFieldDeclarationSyntax)declaration).Declaration.Type;
case SyntaxKind.EventDeclaration:
return ((EventDeclarationSyntax)declaration).Type;
case SyntaxKind.Parameter:
return ((ParameterSyntax)declaration).Type;
case SyntaxKind.LocalDeclarationStatement:
return ((LocalDeclarationStatementSyntax)declaration).Declaration.Type;
case SyntaxKind.VariableDeclaration:
return ((VariableDeclarationSyntax)declaration).Type;
case SyntaxKind.VariableDeclarator:
if (declaration.Parent != null)
{
return this.GetType(declaration.Parent);
}
break;

@jaredpar jaredpar removed this from the C# 10 milestone Jul 13, 2021
@jcouv jcouv modified the milestones: 17.0, 17.1 Oct 5, 2021
@CyrusNajmabadi
Copy link
Member

So far we haven't heard about any issues on the IDE side. We consider things to be good there, and we'll instead do work here if triggered from user reported issues where 'improved lambdas' aren't working properly for them.

@jcouv
Copy link
Member

jcouv commented Feb 21, 2022

Thanks for adding the remaining tests @cston. Closing the test plan.

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

No branches or pull requests

6 participants