Skip to content

Commit

Permalink
Add SynType.Or. (#14058)
Browse files Browse the repository at this point in the history
* Add SynType.Or for generic constrains in the form (^A or ^B):...
  • Loading branch information
nojaf authored Oct 12, 2022
1 parent f64e783 commit b78ad5c
Show file tree
Hide file tree
Showing 26 changed files with 311 additions and 29 deletions.
8 changes: 6 additions & 2 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3953,7 +3953,7 @@ let rec TcTyparConstraint ridx (cenv: cenv) newOk checkConstraints occ (env: TcE
| SynTypeConstraint.WhereTyparIsDelegate(tp, synTys, m) ->
TcConstraintWhereTyparIsDelegate cenv env newOk checkConstraints occ tpenv tp synTys m

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

| SynTypeConstraint.WhereSelfConstrained(ty, m) ->
Expand Down Expand Up @@ -4361,6 +4361,10 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
| SynType.Paren(innerType, _)
| SynType.SignatureParameter(usedType = innerType) ->
TcTypeOrMeasure kindOpt cenv newOk checkConstraints occ iwsam env tpenv innerType

| SynType.Or(range = m) ->
// The inner types are expected to be collected by (|TypesForTypar|) at this point.
error(Error((FSComp.SR.tcSynTypeOrInvalidInDeclaration()), m))

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

| SynExpr.TraitCall (tps, synMemberSig, arg, m) ->
| SynExpr.TraitCall (TypesForTypar tps, synMemberSig, arg, m) ->
TcNonControlFlowExpr env <| fun env ->
TcExprTraitCall cenv overallTy env tpenv (tps, synMemberSig, arg, m)

Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1656,3 +1656,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form"
3546,parsExpectingPatternInTuple,"Expecting pattern"
3547,parsExpectedPatternAfterToken,"Expected a pattern after this point"
3548,matchNotAllowedForUnionCaseWithNoData,"Pattern discard is not allowed for union case that takes no data."
3549,tcSynTypeOrInvalidInDeclaration,"SynType.Or is not permitted in this declaration"
3 changes: 2 additions & 1 deletion src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,8 @@ module SyntaxTraversal =
| SynType.WithGlobalConstraints (ty, _, _)
| SynType.Array (_, ty, _) -> traverseSynType path ty
| SynType.StaticConstantNamed (ty1, ty2, _)
| SynType.MeasureDivide (ty1, ty2, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
| SynType.MeasureDivide (ty1, ty2, _)
| SynType.Or (ty1, ty2, _, _) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
| SynType.Tuple (path = segments) -> getTypeFromTuplePath segments |> List.tryPick (traverseSynType path)
| SynType.StaticConstantExpr (expr, _) -> traverseSynExpr [] expr
| SynType.Paren (innerType = t)
Expand Down
14 changes: 8 additions & 6 deletions src/Compiler/Service/ServiceParsedInputOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsComparable (t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparIsEquatable (t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparSubtypeOfType (t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty)
| SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) ->
| SynTypeConstraint.WhereTyparSupportsMember (TypesForTypar ts, sign, _) ->
List.tryPick walkType ts |> Option.orElseWith (fun () -> walkMemberSig sign)
| SynTypeConstraint.WhereTyparIsEnum (t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts)
| SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) -> walkTypar t |> Option.orElseWith (fun () -> List.tryPick walkType ts)
Expand Down Expand Up @@ -668,7 +668,8 @@ module ParsedInput =
| SynType.Fun (argType = t1; returnType = t2) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.WithGlobalConstraints (t, _, _) -> walkType t
| SynType.HashConstraint (t, _) -> walkType t
| SynType.MeasureDivide (t1, t2, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.MeasureDivide (t1, t2, _)
| SynType.Or (t1, t2, _, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.MeasurePower (t, _, _) -> walkType t
| SynType.Paren (t, _)
| SynType.SignatureParameter (usedType = t) -> walkType t
Expand Down Expand Up @@ -838,7 +839,7 @@ module ParsedInput =

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

| SynExpr.TraitCall (ts, sign, e, _) ->
| SynExpr.TraitCall (TypesForTypar ts, sign, e, _) ->
List.tryPick walkType ts
|> Option.orElseWith (fun () -> walkMemberSig sign)
|> Option.orElseWith (fun () -> walkExprWithKind parentKind e)
Expand Down Expand Up @@ -1621,7 +1622,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsDelegate (t, ts, _) ->
walkTypar t
List.iter walkType ts
| SynTypeConstraint.WhereTyparSupportsMember (ts, sign, _) ->
| SynTypeConstraint.WhereTyparSupportsMember (TypesForTypar ts, sign, _) ->
List.iter walkType ts
walkMemberSig sign
| SynTypeConstraint.WhereSelfConstrained (ty, _) -> walkType ty
Expand Down Expand Up @@ -1673,7 +1674,8 @@ module ParsedInput =
| SynType.Paren (t, _)
| SynType.SignatureParameter (usedType = t) -> walkType t
| SynType.Fun (argType = t1; returnType = t2)
| SynType.MeasureDivide (t1, t2, _) ->
| SynType.MeasureDivide (t1, t2, _)
| SynType.Or (t1, t2, _, _) ->
walkType t1
walkType t2
| SynType.LongIdent ident -> addLongIdentWithDots ident
Expand Down Expand Up @@ -1820,7 +1822,7 @@ module ParsedInput =
walkExpr eAndBang

walkExpr e2
| SynExpr.TraitCall (ts, sign, e, _) ->
| SynExpr.TraitCall (TypesForTypar ts, sign, e, _) ->
List.iter walkType ts
walkMemberSig sign
walkExpr e
Expand Down
9 changes: 6 additions & 3 deletions src/Compiler/SyntaxTree/SyntaxTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ type SynTypeConstraint =

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

| WhereTyparSupportsMember of typars: SynType list * memberSig: SynMemberSig * range: range
| WhereTyparSupportsMember of typars: SynType * memberSig: SynMemberSig * range: range

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

Expand Down Expand Up @@ -441,6 +441,8 @@ type SynType =

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

| Or of lhsType: SynType * rhsType: SynType * range: range * trivia: SynTypeOrTrivia

member x.Range =
match x with
| SynType.App (range = m)
Expand All @@ -459,7 +461,8 @@ type SynType =
| SynType.MeasureDivide (range = m)
| SynType.MeasurePower (range = m)
| SynType.Paren (range = m)
| SynType.SignatureParameter (range = m) -> m
| SynType.SignatureParameter (range = m)
| SynType.Or (range = m) -> m
| SynType.LongIdent lidwd -> lidwd.Range

[<NoEquality; NoComparison; RequireQualifiedAccess>]
Expand Down Expand Up @@ -647,7 +650,7 @@ type SynExpr =

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

| TraitCall of supportTys: SynType list * traitSig: SynMemberSig * argExpr: SynExpr * range: range
| TraitCall of supportTys: SynType * traitSig: SynMemberSig * argExpr: SynExpr * range: range

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

Expand Down
7 changes: 5 additions & 2 deletions src/Compiler/SyntaxTree/SyntaxTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ type SynTypeConstraint =
| WhereTyparSubtypeOfType of typar: SynTypar * typeName: SynType * range: range

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

/// F# syntax is 'typar: enum<'UnderlyingType>
| WhereTyparIsEnum of typar: SynTypar * typeArgs: SynType list * range: range
Expand Down Expand Up @@ -518,6 +518,9 @@ type SynType =
usedType: SynType *
range: range

/// F# syntax: ^a or ^b, used in trait calls
| Or of lhsType: SynType * rhsType: SynType * range: range * trivia: SynTypeOrTrivia

/// Gets the syntax range of this construct
member Range: range

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

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

/// F# syntax: ... in ...
/// Computation expressions only, based on JOIN_IN token from lex filter
Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1082,3 +1082,12 @@ let (|MultiDimensionArrayType|_|) (t: SynType) =
else
None
| _ -> None

let (|TypesForTypar|) (t: SynType) =
let rec visit continuation t =
match t with
| SynType.Paren (innerT, _) -> visit continuation innerT
| SynType.Or (lhsT, rhsT, _, _) -> visit (fun lhsTs -> [ yield! lhsTs; yield rhsT ] |> continuation) lhsT
| _ -> continuation [ t ]

visit id t
2 changes: 2 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,5 @@ val desugarGetSetMembers: memberDefns: SynMemberDefns -> SynMemberDefns
val getTypeFromTuplePath: path: SynTupleTypeSegment list -> SynType list

val (|MultiDimensionArrayType|_|): t: SynType -> (int * SynType * range) option

val (|TypesForTypar|): t: SynType -> SynType list
3 changes: 3 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,6 @@ type SynMemberGetSetTrivia =

[<NoEquality; NoComparison>]
type SynArgPatsNamePatPairsTrivia = { ParenRange: range }

[<NoEquality; NoComparison>]
type SynTypeOrTrivia = { OrKeyword: range }
8 changes: 8 additions & 0 deletions src/Compiler/SyntaxTree/SyntaxTrivia.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -384,3 +384,11 @@ type SynArgPatsNamePatPairsTrivia =
/// The syntax range from the beginning of the `(` token till the end of the `)` token.
ParenRange: range
}

/// Represents additional information for SynType.Or
[<NoEquality; NoComparison>]
type SynTypeOrTrivia =
{
/// The syntax range of the `or` keyword
OrKeyword: range
}
25 changes: 16 additions & 9 deletions src/Compiler/pars.fsy
Original file line number Diff line number Diff line change
Expand Up @@ -2226,10 +2226,12 @@ typeConstraint:

| typar COLON LPAREN classMemberSpfn rparen
{ let tp = $1
SynTypeConstraint.WhereTyparSupportsMember([ SynType.Var(tp, tp.Range) ], $4, lhs parseState) }
SynTypeConstraint.WhereTyparSupportsMember(SynType.Var(tp, tp.Range), $4, lhs parseState) }

| LPAREN typeAlts rparen COLON LPAREN classMemberSpfn rparen
{ SynTypeConstraint.WhereTyparSupportsMember(List.rev($2), $6, lhs parseState) }
{ let mParen = rhs2 parseState 1 3
let t = SynType.Paren($2, mParen)
SynTypeConstraint.WhereTyparSupportsMember(t, $6, lhs parseState) }

| typar COLON DELEGATE typeArgsNoHpaDeprecated
{ let _ltm, _gtm, args, _commas, mWhole = $4
Expand All @@ -2254,10 +2256,12 @@ typeConstraint:

typeAlts:
| typeAlts OR appType
{ $3 :: $1 }
{ let mOr = rhs parseState 2
let m = unionRanges $1.Range $3.Range
SynType.Or($1, $3, m, { OrKeyword = mOr }) }

| appType
{ [$1] }
{ $1 }

/* The core of a union type definition */
unionTypeRepr:
Expand Down Expand Up @@ -4485,17 +4489,20 @@ parenExprBody:

typars:
| typar
{ [SynType.Var($1, rhs parseState 1)] }
{ SynType.Var($1, rhs parseState 1) }

| LPAREN typarAlts rparen
{ List.rev $2 }
| LPAREN typarAlts rparen
{ let m = rhs2 parseState 1 3
SynType.Paren($2, m) }

typarAlts:
| typarAlts OR appType
{$3 :: $1}
{ let mOr = rhs parseState 2
let m = unionRanges $1.Range $3.Range
SynType.Or($1, $3, m, { OrKeyword = mOr }) }

| typar
{ [SynType.Var($1, rhs parseState 1)] }
{ SynType.Var($1, rhs parseState 1) }

braceExpr:
| LBRACE braceExprBody rbrace
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">Tento výraz implicitně převede typ {0} na typ {1}. Přečtěte si téma https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">Dieser Ausdruck konvertiert den Typ "{0}" implizit in den Typ "{1}". Siehe https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">Esta expresión convierte implícitamente el tipo '{0}' al tipo '{1}'. Consulte https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">Cette expression convertit implicitement le type « {0} » en type « {1} ». Voir https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">Questa espressione converte in modo implicito il tipo '{0}' nel tipo '{1}'. Vedere https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">この式は、型 '{0}' を型 '{1}' に暗黙的に変換します。https://aka.ms/fsharp-implicit-convs を参照してください。</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">이 식은 암시적으로 '{0}' 형식을 '{1}' 형식으로 변환 합니다. https://aka.ms/fsharp-implicit-convs 참조</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,11 @@
<target state="translated">To wyrażenie bezwzględnie konwertuje typ "{0}" na typ "{1}". Zobacz https://aka.ms/fsharp-implicit-convs.</target>
<note />
</trans-unit>
<trans-unit id="tcSynTypeOrInvalidInDeclaration">
<source>SynType.Or is not permitted in this declaration</source>
<target state="new">SynType.Or is not permitted in this declaration</target>
<note />
</trans-unit>
<trans-unit id="tcTraitHasMultipleSupportTypes">
<source>The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</source>
<target state="new">The trait '{0}' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance.</target>
Expand Down
Loading

0 comments on commit b78ad5c

Please sign in to comment.