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

Allow _.Property / _.MethodCall() / _.IndexerAccess[idx] shorthand for accessor functions #13907

Merged
merged 55 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
69fb04e
Add test
tboby Aug 20, 2022
9b1a18a
Initial extra type
tboby Aug 20, 2022
4b07e0a
WIP
tboby Aug 20, 2022
ffde018
Workaround
tboby Sep 2, 2022
5217eb5
WIP underscore
tboby Sep 10, 2022
ae44f72
Some progress, swap to properly wrapping the whole thing
tboby Sep 10, 2022
e8e01f7
Working by walking the whole dotlambda and inserting the ident
tboby Sep 10, 2022
669c365
Temp remove tests
tboby Sep 15, 2022
2c1b6b1
Fix hpa?
tboby Sep 21, 2022
8970bc5
Add indexed get handling
tboby Sep 21, 2022
5448563
Catch all case
tboby Sep 21, 2022
f373a84
Formatting
tboby Sep 21, 2022
1cde708
Fixup tests
tboby Sep 21, 2022
44abcb2
Fix area
tboby Sep 21, 2022
e25f16f
Tidy a little
tboby Sep 22, 2022
6dbd749
Add a simple test
tboby Sep 22, 2022
ad0743b
Add trivia and service test
tboby Sep 22, 2022
605d228
Update and add test
tboby Sep 23, 2022
e6087a0
Add a warning for wildcard conflicts
tboby Sep 23, 2022
7b39768
Format
tboby Sep 23, 2022
927df17
Update tests
tboby Sep 23, 2022
deab1b6
Try and add lang feature
tboby Sep 24, 2022
f1e627e
Fix tests and improve diagnostic range
tboby Sep 24, 2022
36c5afe
Merge branch 'main' into pr/13907
T-Gro Jun 22, 2023
799ba5d
Initial revival commit
T-Gro Jun 22, 2023
bec03ed
revive with failing tests
T-Gro Jun 22, 2023
d5be20b
ambigous discard - 3570 error
T-Gro Jun 22, 2023
5c3b26e
getting tests in shape
T-Gro Jun 22, 2023
3148d74
tests
T-Gro Jun 22, 2023
46f9ab3
Merge branch 'main' into pr/13907
T-Gro Jun 22, 2023
acd09b2
tests
T-Gro Jun 22, 2023
9d48de4
Merge branch 'main' into prop_expression_2
T-Gro Jun 22, 2023
90c1ee8
Test migrated
T-Gro Jun 26, 2023
8de8386
Merge branch 'main' into pr/13907
T-Gro Jun 26, 2023
74eb227
Merge branch 'main' into pr/13907
T-Gro Jun 28, 2023
06a6335
tests
T-Gro Jun 28, 2023
6da867f
Service operations + range adjustment
T-Gro Jun 29, 2023
74a63ba
Nested _. usages should fail, as it makes the "I_" character ambigous
T-Gro Jun 29, 2023
7e8cdb6
Merge branch 'main' into pr/13907
T-Gro Jun 29, 2023
26fcaba
fix
T-Gro Jun 29, 2023
71e83be
pars.fsy rename
T-Gro Jun 29, 2023
5230bd6
clean
T-Gro Jun 29, 2023
335349f
completion tests
T-Gro Jun 29, 2023
3dcf334
Merge branch 'main' into prop_expression_2
T-Gro Jun 29, 2023
33aeee8
Merge branch 'main' into prop_expression_2
T-Gro Jul 4, 2023
a088e4e
Merge branch 'main' into pr/13907
T-Gro Jul 7, 2023
8cb5d60
sigdata roundtrip tests, parse tree tests
T-Gro Jul 7, 2023
21a6457
Negative tests for incorrect feature usage - also shows what the OOB …
T-Gro Jul 7, 2023
7da2b4c
Merge branch 'main' into prop_expression_2
T-Gro Jul 13, 2023
7bb40ea
Merge branch 'main' into prop_expression_2
T-Gro Jul 17, 2023
952e1e4
message rename to make it more explicit
T-Gro Jul 17, 2023
01a8f96
Diagnostics for nonatomic expressions, recovery when not using _. on …
T-Gro Jul 17, 2023
0f59ea9
syntax tree baseline updated
T-Gro Jul 17, 2023
6c49846
Merge branch 'main' into prop_expression_2
T-Gro Jul 19, 2023
53d6d63
Merge branch 'main' into prop_expression_2
T-Gro Jul 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5524,7 +5524,15 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
TcNonControlFlowExpr env <| fun env ->
CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights)
TcConstExpr cenv overallTy env m tpenv synConst

| SynExpr.DotLambda (synExpr, m, trivia) ->
if env.NameEnv.eUnqualifiedItems |> Map.exists(fun _ itemValue -> itemValue |> function |Item.Value _ when itemValue.DisplayNameCore.StartsWith("_") -> true |_ -> false)
then
warning(Error(FSComp.SR.tcAmbiguousDiscardDotLambda(), trivia.UnderscoreRange))
let unaryArg = mkSynId trivia.UnderscoreRange (cenv.synArgNameGenerator.New())
let svar = mkSynCompGenSimplePatVar unaryArg
let pushedExpr = pushUnaryArg synExpr unaryArg
let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ],[], svar.Range), pushedExpr, None, m, SynExprLambdaTrivia.Zero)
TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda
| SynExpr.Lambda _ ->
TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr

Expand Down Expand Up @@ -8721,6 +8729,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed =
| SynExpr.Const _
| SynExpr.Typar _
| SynExpr.LongIdent _
| SynExpr.DotLambda _
| SynExpr.Dynamic _ -> true

| SynExpr.Tuple (_, synExprs, _, _)
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Checking/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ let InferLambdaArgsForLambdaPropagation origRhsExpr =
match e with
| SynExpr.Lambda (body = rest) -> 1 + loop rest
| SynExpr.MatchLambda _ -> 1
| SynExpr.DotLambda _ -> 1
| _ -> 0
loop origRhsExpr

Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Driver/GraphChecking/FileContentMapping.fs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list =
| SynExpr.IndexFromEnd (expr, _) -> visit expr continuation
| SynExpr.ComputationExpr (expr = expr) -> visit expr continuation
| SynExpr.Lambda (args = args; body = body) -> visit body (fun bodyNodes -> visitSynSimplePats args @ bodyNodes |> continuation)
| SynExpr.DotLambda (expr = expr) -> visit expr continuation
| SynExpr.MatchLambda (matchClauses = clauses) -> List.collect visitSynMatchClause clauses |> continuation
| SynExpr.Match (expr = expr; clauses = clauses) ->
visit expr (fun exprNodes ->
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1699,4 +1699,6 @@ featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj infer
3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements."
3567,parsMissingMemberBody,"Expecting member body"
3568,parsMissingKeyword,"Missing keyword '%s'"
3570,tcAmbiguousDiscardDotLambda,"Discard is ambiguous"
featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function"
3577,tcOverrideUsesMultipleArgumentsInsteadOfTuple,"This override takes a tuple instead of multiple arguments. Try to add an additional layer of parentheses at the method definition (e.g. 'member _.Foo((x, y))'), or remove parentheses at the abstract method declaration (e.g. 'abstract member Foo: 'a * 'b -> 'c')."
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type LanguageFeature =
| LowercaseDUWhenRequireQualifiedAccess
| InterfacesWithAbstractStaticMembers
| SelfTypeConstraints
| AccessorFunctionShorthand
| MatchNotAllowedForUnionCaseWithNoData
| CSharpExtensionAttributeNotRequired
| ErrorForNonVirtualMembersOverrides
Expand Down Expand Up @@ -148,6 +149,7 @@ type LanguageVersion(versionText) =

// F# preview
LanguageFeature.FromEndSlicing, previewVersion
LanguageFeature.AccessorFunctionShorthand, previewVersion
LanguageFeature.MatchNotAllowedForUnionCaseWithNoData, previewVersion
LanguageFeature.CSharpExtensionAttributeNotRequired, previewVersion
LanguageFeature.ErrorForNonVirtualMembersOverrides, previewVersion
Expand Down Expand Up @@ -272,6 +274,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.LowercaseDUWhenRequireQualifiedAccess -> FSComp.SR.featureLowercaseDUWhenRequireQualifiedAccess ()
| LanguageFeature.InterfacesWithAbstractStaticMembers -> FSComp.SR.featureInterfacesWithAbstractStaticMembers ()
| LanguageFeature.SelfTypeConstraints -> FSComp.SR.featureSelfTypeConstraints ()
| LanguageFeature.AccessorFunctionShorthand -> FSComp.SR.featureAccessorFunctionShorthand ()
| LanguageFeature.MatchNotAllowedForUnionCaseWithNoData -> FSComp.SR.featureMatchNotAllowedForUnionCaseWithNoData ()
| LanguageFeature.CSharpExtensionAttributeNotRequired -> FSComp.SR.featureCSharpExtensionAttributeNotRequired ()
| LanguageFeature.ErrorForNonVirtualMembersOverrides -> FSComp.SR.featureErrorForNonVirtualMembersOverrides ()
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type LanguageFeature =
| LowercaseDUWhenRequireQualifiedAccess
| InterfacesWithAbstractStaticMembers
| SelfTypeConstraints
| AccessorFunctionShorthand
| MatchNotAllowedForUnionCaseWithNoData
| CSharpExtensionAttributeNotRequired
| ErrorForNonVirtualMembersOverrides
Expand Down
7 changes: 7 additions & 0 deletions src/Compiler/Service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
// Capture the body of a lambda, often nested in a call to a collection function
| SynExpr.Lambda (body = body) when rangeContainsPos body.Range pos -> getIdentRangeForFuncExprInApp traverseSynExpr body pos

| SynExpr.DotLambda (expr = body) when rangeContainsPos body.Range pos -> getIdentRangeForFuncExprInApp traverseSynExpr body pos

| SynExpr.Do (expr, range) when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos

| SynExpr.Assert (expr, range) when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos
Expand Down Expand Up @@ -410,6 +412,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
override _.VisitBinding(_path, defaultTraverse, binding) =
match binding with
| SynBinding(expr = SynExpr.Lambda _) when skipLambdas -> defaultTraverse binding
| SynBinding(expr = SynExpr.DotLambda _) when skipLambdas -> defaultTraverse binding

// Skip manually type-annotated bindings
| SynBinding(returnInfo = Some (SynBindingReturnInfo _)) -> defaultTraverse binding
Expand Down Expand Up @@ -500,6 +503,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
| SynBinding.SynBinding (expr = expr; range = range) when Position.posEq range.Start pos ->
match expr with
| SynExpr.Lambda _ -> Some range
| SynExpr.DotLambda _ -> Some range
| _ -> None
| _ -> defaultTraverse binding
}
Expand Down Expand Up @@ -634,6 +638,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
match expr with
| SynExpr.ArbitraryAfterError _
| SynExpr.LongIdent _
| SynExpr.DotLambda _
| SynExpr.LibraryOnlyILAssembly _
| SynExpr.LibraryOnlyStaticOptimization _
| SynExpr.Null _
Expand Down Expand Up @@ -795,6 +800,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,

| SynExpr.Lambda (body = bodyExpr) -> yield! walkExpr true bodyExpr

| SynExpr.DotLambda (expr = bodyExpr) -> yield! walkExpr true bodyExpr

| SynExpr.Match (matchDebugPoint = spBind; expr = inpExpr; clauses = cl) ->
yield! walkBindSeqPt spBind
yield! walkExpr false inpExpr
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Service/ServiceInterfaceStubGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -880,6 +880,8 @@ module InterfaceStubGenerator =

| SynExpr.Lambda (body = synExpr) -> walkExpr synExpr

| SynExpr.DotLambda (expr = synExpr) -> walkExpr synExpr

| SynExpr.MatchLambda (_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) ->
synMatchClauseList
|> List.tryPick (fun (SynMatchClause (resultExpr = e)) -> walkExpr e)
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ module SyntaxTraversal =
| None -> traverseSynExpr synExpr
| x -> x

| SynExpr.DotLambda (expr = e) -> traverseSynExpr e

| SynExpr.MatchLambda (_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) ->
synMatchClauseList
|> List.map (fun x -> dive x x.Range (traverseSynMatchClause path))
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,8 @@ module ParsedInput =

| SynExpr.Lambda (body = e) -> walkExprWithKind parentKind e

| SynExpr.DotLambda (expr = e) -> walkExprWithKind parentKind e

| SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> List.tryPick walkClause synMatchClauseList

| SynExpr.Match (expr = e; clauses = synMatchClauseList) ->
Expand Down Expand Up @@ -1733,6 +1735,7 @@ module ParsedInput =
| SynExpr.Lambda (args = pats; body = e) ->
walkSimplePats pats
walkExpr e
| SynExpr.DotLambda (expr = e) -> walkExpr e
| SynExpr.New (_, t, e, _)
| SynExpr.TypeTest (e, t, _)
| SynExpr.Upcast (e, t, _)
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ type SynExpr =

| DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range

| DotLambda of expr: SynExpr * range: range * trivia: SynExprDotLambdaTrivia

| DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range

| Set of targetExpr: SynExpr * rhsExpr: SynExpr * range: range
Expand Down Expand Up @@ -755,6 +757,7 @@ type SynExpr =
| SynExpr.DotIndexedGet (range = m)
| SynExpr.DotIndexedSet (range = m)
| SynExpr.DotGet (range = m)
| SynExpr.DotLambda (range = m)
| SynExpr.DotSet (range = m)
| SynExpr.Set (range = m)
| SynExpr.DotNamedIndexedPropertySet (range = m)
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,9 @@ type SynExpr =
/// F# syntax: expr.ident.ident
| DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range

/// F# syntax: _.ident.ident
| DotLambda of expr: SynExpr * range: range * trivia: SynExprDotLambdaTrivia

/// F# syntax: expr.ident...ident <- expr
| DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range

Expand Down
37 changes: 37 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,42 @@ let mkSynSimplePatVar isOpt id =
let mkSynCompGenSimplePatVar id =
SynSimplePat.Id(id, None, true, false, false, id.idRange)

let rec pushUnaryArg expr arg =
match expr with
| SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.Ident ident, x1, m1) ->
SynExpr.App(
ExprAtomicFlag.Atomic,
infix,
SynExpr.LongIdent(false, SynLongIdent(arg :: ident :: [], [ ident.idRange ], [ None ]), None, ident.idRange),
x1,
m1
)
| SynExpr.App (ExprAtomicFlag.Atomic,
infix,
SynExpr.LongIdent (isOptional, SynLongIdent (id, dotRanges, trivia), altNameRefCell, range),
x1,
m1) ->
SynExpr.App(
ExprAtomicFlag.Atomic,
infix,
SynExpr.LongIdent(isOptional, SynLongIdent(arg :: id, dotRanges, trivia), altNameRefCell, range),
x1,
m1
)
| SynExpr.App (ExprAtomicFlag.Atomic, infix, (SynExpr.App (_) as innerApp), x1, m1) ->
SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnaryArg innerApp arg), x1, m1)
| SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range), x1, m1) ->
SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnaryArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1)
| SynExpr.App (ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) ->
SynExpr.App(ExprAtomicFlag.Atomic, infix, pushUnaryArg innerExpr arg, x1, m1)
| SynExpr.Ident ident -> SynExpr.LongIdent(false, SynLongIdent(arg :: ident :: [], [ ident.idRange ], [ None ]), None, ident.idRange)
| SynExpr.LongIdent (isOptional, SynLongIdent (id, dotRanges, trivia), altNameRefCell, range) ->
SynExpr.LongIdent(isOptional, SynLongIdent(arg :: id, dotRanges, trivia), altNameRefCell, range)
| SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range) -> SynExpr.DotGet(pushUnaryArg synExpr arg, rangeOfDot, synLongIdent, range)
| SynExpr.DotIndexedGet (objectExpr, indexArgs, dotRange, range) ->
SynExpr.DotIndexedGet(pushUnaryArg objectExpr arg, indexArgs, dotRange, range)
| _ -> expr

let (|SynSingleIdent|_|) x =
match x with
| SynLongIdent ([ id ], _, _) -> Some id
Expand Down Expand Up @@ -792,6 +828,7 @@ let rec synExprContainsError inpExpr =
| SynExpr.ArbitraryAfterError _ -> true

| SynExpr.LongIdent _
| SynExpr.DotLambda _
| SynExpr.Quote _
| SynExpr.LibraryOnlyILAssembly _
| SynExpr.LibraryOnlyStaticOptimization _
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ val mkSynSimplePatVar: isOpt: bool -> id: Ident -> SynSimplePat

val mkSynCompGenSimplePatVar: id: Ident -> SynSimplePat

val pushUnaryArg: expr: SynExpr -> arg: Ident -> SynExpr

/// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree.
val (|LongOrSingleIdent|_|):
inp: SynExpr -> (bool * SynLongIdent * SynSimplePatAlternativeIdInfo ref option * range) option
Expand Down
7 changes: 7 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ type SynExprLambdaTrivia =

static member Zero: SynExprLambdaTrivia = { ArrowRange = None }

[<NoEquality; NoComparison>]
type SynExprDotLambdaTrivia =
{
UnderscoreRange: range
DotRange: range
}

[<NoEquality; NoComparison>]
type SynExprLetOrUseTrivia = { InKeyword: range option }

Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ type SynExprLambdaTrivia =

static member Zero: SynExprLambdaTrivia

/// Represents additional information for SynExpr.DotLambda
[<NoEquality; NoComparison>]
type SynExprDotLambdaTrivia =
{ UnderscoreRange: range
DotRange: range }

/// Represents additional information for SynExpr.LetOrUse
[<NoEquality; NoComparison>]
type SynExprLetOrUseTrivia =
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) ->
%left pat_app
%left pat_args
%left PREFIX_OP
%right dot_lambda
%left DOT QMARK
%left HIGH_PRECEDENCE_BRACK_APP
%left HIGH_PRECEDENCE_PAREN_APP
Expand Down Expand Up @@ -4795,6 +4796,14 @@ argExpr:
arg }

atomicExpr:
| UNDERSCORE DOT atomicExpr %prec dot_lambda
{ let mUnderscore = rhs parseState 1
let mDot = rhs parseState 2
parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (unionRanges mUnderscore mDot )
let expr, hpa = $3
let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = mUnderscore ; DotRange = mDot }
SynExpr.DotLambda(expr, unionRanges mUnderscore expr.Range, trivia), false }

| atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr
{ let arg1, _ = $1
let arg2, hpa = $3
Expand Down
10 changes: 10 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading