Skip to content

Commit c61dbf4

Browse files
Wrap in union
1 parent 5f8ff64 commit c61dbf4

File tree

7 files changed

+112
-97
lines changed

7 files changed

+112
-97
lines changed

src/Compiler/Checking/CheckPatterns.fs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,11 @@ and TcPatArrayOrList warnOnUpper cenv env vFlags patEnv ty isArray args m =
458458

459459
and TcRecordPat warnOnUpper (cenv: cenv) env vFlags patEnv ty fieldPats m =
460460
let fieldPats =
461-
// This will obviously need to change if we support spreads in record patterns.
462-
let isFromSpread = false
463461
fieldPats
464462
|> List.map (fun (NamePatPairField(fieldName = fieldLid; pat = pat)) ->
465463
match fieldLid.LongIdent with
466-
| [id] -> isFromSpread, ([], id), pat
467-
| lid -> isFromSpread, List.frontAndBack lid, pat)
464+
| [id] -> ExplicitOrSpread.Explicit (([], id), pat)
465+
| lid -> ExplicitOrSpread.Explicit (List.frontAndBack lid, pat))
468466

469467
match BuildFieldMap cenv env false ty fieldPats m with
470468
| None -> (fun _ -> TPat_error m), patEnv
@@ -481,13 +479,14 @@ and TcRecordPat warnOnUpper (cenv: cenv) env vFlags patEnv ty fieldPats m =
481479
let fieldPats, patEnvR =
482480
(patEnv, ftys) ||> List.mapFold (fun s (ty, fsp) ->
483481
match fldsmap.TryGetValue fsp.rfield_id.idText with
484-
| true, v ->
482+
| true, ExplicitOrSpread.Explicit v ->
485483
let warnOnUpper =
486484
if cenv.g.langVersion.SupportsFeature(LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns) then
487485
AllIdsOK
488486
else
489487
warnOnUpper
490488
TcPat warnOnUpper cenv env None vFlags s ty v
489+
| true, ExplicitOrSpread.Spread _ -> (* Unreachable. *) error (InternalError ("Spreads in patterns are not supported.", m))
491490
| _ -> (fun _ -> TPat_wild m), s)
492491

493492
let phase2 values =

src/Compiler/Checking/CheckRecordSyntaxHelpers.fs

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ open FSharp.Compiler.TypedTree
1414
open FSharp.Compiler.Xml
1515
open FSharp.Compiler.SyntaxTrivia
1616

17-
[<RequireQualifiedAccess; NoEquality; NoComparison>]
18-
type SynExprOrSpreadValue =
19-
| SynExpr of SynExpr
20-
| SpreadValue of TType * Expr
21-
2217
/// Merges updates to nested record fields on the same level in record copy-and-update.
2318
///
2419
/// `TransformAstForNestedUpdates` expands `{ x with A.B = 10; A.C = "" }`
@@ -33,29 +28,29 @@ type SynExprOrSpreadValue =
3328
/// which we here convert to
3429
///
3530
/// { x with A = { x.A with B = 10; C = "" } }
36-
let GroupUpdatesToNestedFields (fields: ((Ident list * Ident) * SynExprOrSpreadValue option) list) =
31+
let GroupUpdatesToNestedFields (fields: (ExplicitOrSpread<(Ident list * Ident) * SynExpr option, (Ident list * Ident) * 'Spread>) list) =
3732
let rec groupIfNested res xs =
3833
match xs with
3934
| [] -> res
4035
| [ x ] -> x :: res
4136
| x :: y :: ys ->
4237
match x, y with
43-
| (lidwid, Some(SynExprOrSpreadValue.SynExpr(SynExpr.Record(baseInfo, copyInfo, fields1, m)))),
44-
(_, Some(SynExprOrSpreadValue.SynExpr(SynExpr.Record(recordFields = fields2)))) ->
38+
| ExplicitOrSpread.Explicit(lidwid, Some(SynExpr.Record(baseInfo, copyInfo, fields1, m))),
39+
ExplicitOrSpread.Explicit(_, Some(SynExpr.Record(recordFields = fields2))) ->
4540
let reducedRecd =
46-
(lidwid, Some(SynExprOrSpreadValue.SynExpr(SynExpr.Record(baseInfo, copyInfo, fields1 @ fields2, m))))
41+
ExplicitOrSpread.Explicit(lidwid, Some(SynExpr.Record(baseInfo, copyInfo, fields1 @ fields2, m)))
4742

4843
groupIfNested res (reducedRecd :: ys)
49-
| (lidwid, Some(SynExprOrSpreadValue.SynExpr(SynExpr.AnonRecd(isStruct, copyInfo, fields1, m, trivia)))),
50-
(_, Some(SynExprOrSpreadValue.SynExpr(SynExpr.AnonRecd(recordFields = fields2)))) ->
44+
| ExplicitOrSpread.Explicit(lidwid, Some(SynExpr.AnonRecd(isStruct, copyInfo, fields1, m, trivia))),
45+
ExplicitOrSpread.Explicit(_, Some(SynExpr.AnonRecd(recordFields = fields2))) ->
5146
let reducedRecd =
52-
(lidwid, Some(SynExprOrSpreadValue.SynExpr(SynExpr.AnonRecd(isStruct, copyInfo, fields1 @ fields2, m, trivia))))
47+
ExplicitOrSpread.Explicit(lidwid, Some(SynExpr.AnonRecd(isStruct, copyInfo, fields1 @ fields2, m, trivia)))
5348

5449
groupIfNested res (reducedRecd :: ys)
5550
| _ -> groupIfNested (x :: res) (y :: ys)
5651

5752
fields
58-
|> List.groupBy (fun ((_, field), _) -> field.idText)
53+
|> List.groupBy (fun (ExplicitOrSpread.Explicit((_, field), _) | ExplicitOrSpread.Spread((_, field), _)) -> field.idText)
5954
|> List.collect (fun (_, fields) ->
6055
if fields.Length < 2 then
6156
fields
@@ -156,23 +151,25 @@ let TransformAstForNestedUpdates (cenv: TcFileState) (env: TcEnv) overallTy (lid
156151

157152
match access, fields with
158153
| _, [] -> failwith "unreachable"
159-
| accessIds, [ (fieldId, _) ] -> (accessIds, fieldId), Some exprBeingAssigned
154+
| accessIds, [ (fieldId, _) ] ->
155+
match exprBeingAssigned with
156+
| ExplicitOrSpread.Explicit exprBeingAssigned -> ExplicitOrSpread.Explicit((accessIds, fieldId), Some exprBeingAssigned)
157+
| ExplicitOrSpread.Spread exprBeingAssigned -> ExplicitOrSpread.Spread((accessIds, fieldId), Some exprBeingAssigned)
158+
160159
| accessIds, (outerFieldId, item) :: rest ->
161160
checkLanguageFeatureAndRecover cenv.g.langVersion LanguageFeature.NestedCopyAndUpdate (rangeOfLid lid)
162161

163162
CallNameResolutionSink cenv.tcSink (outerFieldId.idRange, env.NameEnv, item, [], ItemOccurrence.Use, env.AccessRights)
164163

165164
let outerFieldId = ident (outerFieldId.idText, outerFieldId.idRange.MakeSynthetic())
166165

167-
let recdExpr =
168-
match exprBeingAssigned with
169-
| SynExprOrSpreadValue.SynExpr synExpr ->
170-
Some(
171-
SynExprOrSpreadValue.SynExpr(synExprRecd (recdExprCopyInfo (fields |> List.map fst) withExpr) outerFieldId rest synExpr)
172-
)
173-
| SynExprOrSpreadValue.SpreadValue _ -> Some exprBeingAssigned
174-
175-
(accessIds, outerFieldId), recdExpr
166+
match exprBeingAssigned with
167+
| ExplicitOrSpread.Explicit synExpr ->
168+
ExplicitOrSpread.Explicit(
169+
(accessIds, outerFieldId),
170+
Some(synExprRecd (recdExprCopyInfo (fields |> List.map fst) withExpr) outerFieldId rest synExpr)
171+
)
172+
| ExplicitOrSpread.Spread exprBeingAssigned -> ExplicitOrSpread.Spread((accessIds, outerFieldId), Some exprBeingAssigned)
176173

177174
/// When the original expression in copy-and-update is more complex than `{ x with ... }`, like `{ f () with ... }`,
178175
/// we bind it first, so that it's not evaluated multiple times during a nested update

src/Compiler/Checking/CheckRecordSyntaxHelpers.fsi

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,23 @@
33
module internal FSharp.Compiler.CheckRecordSyntaxHelpers
44

55
open FSharp.Compiler.CheckBasics
6+
open FSharp.Compiler.NameResolution
67
open FSharp.Compiler.Syntax
78
open FSharp.Compiler.Text
89
open FSharp.Compiler.TypedTree
910

10-
[<RequireQualifiedAccess; NoEquality; NoComparison>]
11-
type SynExprOrSpreadValue =
12-
/// A syntactic expression being assigned to a record field.
13-
| SynExpr of SynExpr
14-
15-
/// A typechecked record field `get` from a spread expression.
16-
| SpreadValue of TType * Expr
17-
1811
val GroupUpdatesToNestedFields:
19-
fields: ((Ident list * Ident) * SynExprOrSpreadValue option) list ->
20-
((Ident list * Ident) * SynExprOrSpreadValue option) list
12+
fields: (ExplicitOrSpread<(Ident list * Ident) * SynExpr option, (Ident list * Ident) * 'Spread>) list ->
13+
(ExplicitOrSpread<(Ident list * Ident) * SynExpr option, (Ident list * Ident) * 'Spread>) list
2114

2215
val TransformAstForNestedUpdates:
2316
cenv: TcFileState ->
2417
env: TcEnv ->
2518
overallTy: TType ->
2619
lid: LongIdent ->
27-
exprBeingAssigned: SynExprOrSpreadValue ->
20+
exprBeingAssigned: ExplicitOrSpread<SynExpr, 'Spread> ->
2821
withExpr: SynExpr * BlockSeparator ->
29-
(Ident list * Ident) * SynExprOrSpreadValue option
22+
ExplicitOrSpread<(Ident list * Ident) * SynExpr option, (Ident list * Ident) * 'Spread option>
3023

3124
val BindOriginalRecdExpr:
3225
withExpr: SynExpr * BlockSeparator -> mkRecdExpr: ((SynExpr * BlockSeparator) option -> SynExpr) -> SynExpr

0 commit comments

Comments
 (0)