Skip to content

Commit b78ad5c

Browse files
authored
Add SynType.Or. (#14058)
* Add SynType.Or for generic constrains in the form (^A or ^B):...
1 parent f64e783 commit b78ad5c

26 files changed

+311
-29
lines changed

src/Compiler/Checking/CheckExpressions.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3953,7 +3953,7 @@ let rec TcTyparConstraint ridx (cenv: cenv) newOk checkConstraints occ (env: TcE
39533953
| SynTypeConstraint.WhereTyparIsDelegate(tp, synTys, m) ->
39543954
TcConstraintWhereTyparIsDelegate cenv env newOk checkConstraints occ tpenv tp synTys m
39553955

3956-
| SynTypeConstraint.WhereTyparSupportsMember(synSupportTys, synMemberSig, m) ->
3956+
| SynTypeConstraint.WhereTyparSupportsMember(TypesForTypar synSupportTys, synMemberSig, m) ->
39573957
TcConstraintWhereTyparSupportsMember cenv env newOk tpenv synSupportTys synMemberSig m
39583958

39593959
| SynTypeConstraint.WhereSelfConstrained(ty, m) ->
@@ -4361,6 +4361,10 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
43614361
| SynType.Paren(innerType, _)
43624362
| SynType.SignatureParameter(usedType = innerType) ->
43634363
TcTypeOrMeasure kindOpt cenv newOk checkConstraints occ iwsam env tpenv innerType
4364+
4365+
| SynType.Or(range = m) ->
4366+
// The inner types are expected to be collected by (|TypesForTypar|) at this point.
4367+
error(Error((FSComp.SR.tcSynTypeOrInvalidInDeclaration()), m))
43644368

43654369
and CheckIWSAM (cenv: cenv) (env: TcEnv) checkConstraints iwsam m tcref =
43664370
let g = cenv.g
@@ -5651,7 +5655,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE
56515655
TcNonControlFlowExpr env <| fun env ->
56525656
TcExprNamedIndexPropertySet cenv overallTy env tpenv (synLongId, synExpr1, synExpr2, mStmt)
56535657

5654-
| SynExpr.TraitCall (tps, synMemberSig, arg, m) ->
5658+
| SynExpr.TraitCall (TypesForTypar tps, synMemberSig, arg, m) ->
56555659
TcNonControlFlowExpr env <| fun env ->
56565660
TcExprTraitCall cenv overallTy env tpenv (tps, synMemberSig, arg, m)
56575661

src/Compiler/FSComp.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,3 +1656,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form"
16561656
3546,parsExpectingPatternInTuple,"Expecting pattern"
16571657
3547,parsExpectedPatternAfterToken,"Expected a pattern after this point"
16581658
3548,matchNotAllowedForUnionCaseWithNoData,"Pattern discard is not allowed for union case that takes no data."
1659+
3549,tcSynTypeOrInvalidInDeclaration,"SynType.Or is not permitted in this declaration"

src/Compiler/Service/ServiceParseTreeWalk.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,8 @@ module SyntaxTraversal =
821821
| SynType.WithGlobalConstraints (ty, _, _)
822822
| SynType.Array (_, ty, _) -> traverseSynType path ty
823823
| SynType.StaticConstantNamed (ty1, ty2, _)
824-
| SynType.MeasureDivide (ty1, ty2, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
824+
| SynType.MeasureDivide (ty1, ty2, _)
825+
| SynType.Or (ty1, ty2, _, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
825826
| SynType.Tuple (path = segments) -> getTypeFromTuplePath segments |> List.tryPick (traverseSynType path)
826827
| SynType.StaticConstantExpr (expr, _) -> traverseSynExpr [] expr
827828
| SynType.Paren (innerType = t)

src/Compiler/Service/ServiceParsedInputOps.fs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ module ParsedInput =
607607
| SynTypeConstraint.WhereTyparIsComparable (t, _) -> walkTypar t
608608
| SynTypeConstraint.WhereTyparIsEquatable (t, _) -> walkTypar t
609609
| SynTypeConstraint.WhereTyparSubtypeOfType (t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty)
610-
| SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) ->
610+
| SynTypeConstraint.WhereTyparSupportsMember (TypesForTypar ts, sign, _) ->
611611
List.tryPick walkType ts |> Option.orElseWith (fun () -> walkMemberSig sign)
612612
| SynTypeConstraint.WhereTyparIsEnum (t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts)
613613
| SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts)
@@ -668,7 +668,8 @@ module ParsedInput =
668668
| SynType.Fun (argType = t1; returnType = t2) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
669669
| SynType.WithGlobalConstraints (t, _, _) -> walkType t
670670
| SynType.HashConstraint (t, _) -> walkType t
671-
| SynType.MeasureDivide (t1, t2, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
671+
| SynType.MeasureDivide (t1, t2, _)
672+
| SynType.Or (t1, t2, _, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
672673
| SynType.MeasurePower (t, _, _) -> walkType t
673674
| SynType.Paren (t, _)
674675
| SynType.SignatureParameter (usedType = t) -> walkType t
@@ -838,7 +839,7 @@ module ParsedInput =
838839

839840
| SynExpr.DoBang (e, _) -> walkExprWithKind parentKind e
840841

841-
| SynExpr.TraitCall (ts, sign, e, _) ->
842+
| SynExpr.TraitCall (TypesForTypar ts, sign, e, _) ->
842843
List.tryPick walkType ts
843844
|> Option.orElseWith (fun () -> walkMemberSig sign)
844845
|> Option.orElseWith (fun () -> walkExprWithKind parentKind e)
@@ -1621,7 +1622,7 @@ module ParsedInput =
16211622
| SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) ->
16221623
walkTypar t
16231624
List.iter walkType ts
1624-
| SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) ->
1625+
| SynTypeConstraint.WhereTyparSupportsMember (TypesForTypar ts, sign, _) ->
16251626
List.iter walkType ts
16261627
walkMemberSig sign
16271628
| SynTypeConstraint.WhereSelfConstrained (ty, _) -> walkType ty
@@ -1673,7 +1674,8 @@ module ParsedInput =
16731674
| SynType.Paren (t, _)
16741675
| SynType.SignatureParameter (usedType = t) -> walkType t
16751676
| SynType.Fun (argType = t1; returnType = t2)
1676-
| SynType.MeasureDivide (t1, t2, _) ->
1677+
| SynType.MeasureDivide (t1, t2, _)
1678+
| SynType.Or (t1, t2, _, _) ->
16771679
walkType t1
16781680
walkType t2
16791681
| SynType.LongIdent ident -> addLongIdentWithDots ident
@@ -1820,7 +1822,7 @@ module ParsedInput =
18201822
walkExpr eAndBang
18211823

18221824
walkExpr e2
1823-
| SynExpr.TraitCall (ts, sign, e, _) ->
1825+
| SynExpr.TraitCall (TypesForTypar ts, sign, e, _) ->
18241826
List.iter walkType ts
18251827
walkMemberSig sign
18261828
walkExpr e

src/Compiler/SyntaxTree/SyntaxTree.fs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ type SynTypeConstraint =
330330

331331
| WhereTyparSubtypeOfType of typar: SynTypar * typeName: SynType * range: range
332332

333-
| WhereTyparSupportsMember of typars: SynType list * memberSig: SynMemberSig * range: range
333+
| WhereTyparSupportsMember of typars: SynType * memberSig: SynMemberSig * range: range
334334

335335
| WhereTyparIsEnum of typar: SynTypar * typeArgs: SynType list * range: range
336336

@@ -441,6 +441,8 @@ type SynType =
441441

442442
| SignatureParameter of attributes: SynAttributes * optional: bool * id: Ident option * usedType: SynType * range: range
443443

444+
| Or of lhsType: SynType * rhsType: SynType * range: range * trivia: SynTypeOrTrivia
445+
444446
member x.Range =
445447
match x with
446448
| SynType.App (range = m)
@@ -459,7 +461,8 @@ type SynType =
459461
| SynType.MeasureDivide (range = m)
460462
| SynType.MeasurePower (range = m)
461463
| SynType.Paren (range = m)
462-
| SynType.SignatureParameter (range = m) -> m
464+
| SynType.SignatureParameter (range = m)
465+
| SynType.Or (range = m) -> m
463466
| SynType.LongIdent lidwd -> lidwd.Range
464467

465468
[<NoEquality; NoComparison; RequireQualifiedAccess>]
@@ -647,7 +650,7 @@ type SynExpr =
647650

648651
| AddressOf of isByref: bool * expr: SynExpr * opRange: range * range: range
649652

650-
| TraitCall of supportTys: SynType list * traitSig: SynMemberSig * argExpr: SynExpr * range: range
653+
| TraitCall of supportTys: SynType * traitSig: SynMemberSig * argExpr: SynExpr * range: range
651654

652655
| JoinIn of lhsExpr: SynExpr * lhsRange: range * rhsExpr: SynExpr * range: range
653656

src/Compiler/SyntaxTree/SyntaxTree.fsi

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ type SynTypeConstraint =
405405
| WhereTyparSubtypeOfType of typar: SynTypar * typeName: SynType * range: range
406406

407407
/// F# syntax is ^T: (static member MemberName: ^T * int -> ^T)
408-
| WhereTyparSupportsMember of typars: SynType list * memberSig: SynMemberSig * range: range
408+
| WhereTyparSupportsMember of typars: SynType * memberSig: SynMemberSig * range: range
409409

410410
/// F# syntax is 'typar: enum<'UnderlyingType>
411411
| WhereTyparIsEnum of typar: SynTypar * typeArgs: SynType list * range: range
@@ -518,6 +518,9 @@ type SynType =
518518
usedType: SynType *
519519
range: range
520520

521+
/// F# syntax: ^a or ^b, used in trait calls
522+
| Or of lhsType: SynType * rhsType: SynType * range: range * trivia: SynTypeOrTrivia
523+
521524
/// Gets the syntax range of this construct
522525
member Range: range
523526

@@ -817,7 +820,7 @@ type SynExpr =
817820
| AddressOf of isByref: bool * expr: SynExpr * opRange: range * range: range
818821

819822
/// F# syntax: ((type1 or ... or typeN): (member-dig) expr)
820-
| TraitCall of supportTys: SynType list * traitSig: SynMemberSig * argExpr: SynExpr * range: range
823+
| TraitCall of supportTys: SynType * traitSig: SynMemberSig * argExpr: SynExpr * range: range
821824

822825
/// F# syntax: ... in ...
823826
/// Computation expressions only, based on JOIN_IN token from lex filter

src/Compiler/SyntaxTree/SyntaxTreeOps.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,3 +1082,12 @@ let (|MultiDimensionArrayType|_|) (t: SynType) =
10821082
else
10831083
None
10841084
| _ -> None
1085+
1086+
let (|TypesForTypar|) (t: SynType) =
1087+
let rec visit continuation t =
1088+
match t with
1089+
| SynType.Paren (innerT, _) -> visit continuation innerT
1090+
| SynType.Or (lhsT, rhsT, _, _) -> visit (fun lhsTs -> [ yield! lhsTs; yield rhsT ] |> continuation) lhsT
1091+
| _ -> continuation [ t ]
1092+
1093+
visit id t

src/Compiler/SyntaxTree/SyntaxTreeOps.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,5 @@ val desugarGetSetMembers: memberDefns: SynMemberDefns -> SynMemberDefns
357357
val getTypeFromTuplePath: path: SynTupleTypeSegment list -> SynType list
358358

359359
val (|MultiDimensionArrayType|_|): t: SynType -> (int * SynType * range) option
360+
361+
val (|TypesForTypar|): t: SynType -> SynType list

src/Compiler/SyntaxTree/SyntaxTrivia.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,6 @@ type SynMemberGetSetTrivia =
265265

266266
[<NoEquality; NoComparison>]
267267
type SynArgPatsNamePatPairsTrivia = { ParenRange: range }
268+
269+
[<NoEquality; NoComparison>]
270+
type SynTypeOrTrivia = { OrKeyword: range }

src/Compiler/SyntaxTree/SyntaxTrivia.fsi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,3 +384,11 @@ type SynArgPatsNamePatPairsTrivia =
384384
/// The syntax range from the beginning of the `(` token till the end of the `)` token.
385385
ParenRange: range
386386
}
387+
388+
/// Represents additional information for SynType.Or
389+
[<NoEquality; NoComparison>]
390+
type SynTypeOrTrivia =
391+
{
392+
/// The syntax range of the `or` keyword
393+
OrKeyword: range
394+
}

0 commit comments

Comments
 (0)