Skip to content

Commit 1c22fe3

Browse files
authored
Merge pull request #1319 from dsyme/fix-126
[RFC FS-1019] Fix 126 - Make "Module" suffix implicit if type being defined with the same name
2 parents c9847c1 + c146209 commit 1c22fe3

File tree

2 files changed

+267
-26
lines changed

2 files changed

+267
-26
lines changed

src/fsharp/TypeChecker.fs

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,7 +3463,7 @@ module MutRecShapes =
34633463
| MutRecShape.Tycon a -> MutRecShape.Tycon (f2 parent a)
34643464
| MutRecShape.Lets b -> MutRecShape.Lets (f3 parent b)
34653465
| MutRecShape.Module (c,d) ->
3466-
let c2, parent2 = f1 parent c
3466+
let c2, parent2 = f1 parent c d
34673467
MutRecShape.Module (c2, mapWithParent parent2 f1 f2 f3 d))
34683468

34693469
let rec computeEnvs f1 f2 (env: 'Env) xs =
@@ -14111,19 +14111,28 @@ module EstablishTypeDefinitionCores =
1411114111
| _ ->
1411214112
() ]
1411314113

14114-
let ComputeModuleOrNamespaceKind g isModule attribs =
14114+
let ComputeModuleOrNamespaceKind g isModule typeNames attribs nm =
1411514115
if not isModule then Namespace
14116-
elif ModuleNameIsMangled g attribs then FSharpModuleWithSuffix
14116+
elif ModuleNameIsMangled g attribs || Set.contains nm typeNames then FSharpModuleWithSuffix
1411714117
else ModuleOrType
1411814118

1411914119
let AdjustModuleName modKind nm = (match modKind with FSharpModuleWithSuffix -> nm+FSharpModuleSuffix | _ -> nm)
1412014120

1412114121

14122-
let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent compInfo =
14122+
let TypeNamesInMutRecDecls (compDecls: MutRecShapes<MutRecDefnsPhase1DataForTycon * 'MemberInfo, 'LetInfo, SynComponentInfo, _, _>) =
14123+
[ for d in compDecls do
14124+
match d with
14125+
| MutRecShape.Tycon (MutRecDefnsPhase1DataForTycon(ComponentInfo(_,_,_,ids,_,_,_,_),_,_,_,_,isAtOriginalTyconDefn),_) ->
14126+
if isAtOriginalTyconDefn then
14127+
yield (List.last ids).idText
14128+
| _ -> () ]
14129+
|> set
14130+
14131+
let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo compDecls =
1412314132
let (ComponentInfo(attribs,_parms, _constraints,longPath,xml,_,vis,im)) = compInfo
1412414133
let id = ComputeModuleName longPath
1412514134
let modAttrs = TcAttributes cenv envInitial AttributeTargets.ModuleDecl attribs
14126-
let modKind = ComputeModuleOrNamespaceKind cenv.g true modAttrs
14135+
let modKind = ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText
1412714136
let modName = AdjustModuleName modKind id.idText
1412814137

1412914138
let vis,_ = ComputeAccessAndCompPath envInitial None id.idRange vis parent
@@ -14136,7 +14145,8 @@ module EstablishTypeDefinitionCores =
1413614145
let envForDecls, mtypeAcc = MakeInnerEnv envInitial id modKind
1413714146
let mspec = NewModuleOrNamespace (Some envInitial.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (notlazy (NewEmptyModuleOrNamespaceType modKind))
1413814147
let innerParent = Parent (mkLocalModRef mspec)
14139-
MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, envForDecls)
14148+
let typeNames = TypeNamesInMutRecDecls compDecls
14149+
MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, typeNames, envForDecls)
1414014150

1414114151
/// Establish 'type <vis1> C < T1... TN > = <vis2> ...' including
1414214152
/// - computing the mangled name for C
@@ -14154,7 +14164,6 @@ module EstablishTypeDefinitionCores =
1415414164

1415514165
// Augmentations of type definitions are allowed within the same file as long as no new type representation or abbreviation is given
1415614166
CheckForDuplicateConcreteType env id.idText id.idRange
14157-
CheckForDuplicateModule env id.idText id.idRange
1415814167
let vis,cpath = ComputeAccessAndCompPath env None id.idRange synVis parent
1415914168

1416014169
// Establish the visibility of the representation, e.g.
@@ -15202,20 +15211,20 @@ module EstablishTypeDefinitionCores =
1520215211
| _ -> ())
1520315212

1520415213

15205-
let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent inSig tpenv m scopem mutRecNSInfo (typeDefCores:MutRecShapes<MutRecDefnsPhase1DataForTycon * 'MemberInfo, 'LetInfo, SynComponentInfo, _, _>) =
15214+
let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent inSig tpenv m scopem mutRecNSInfo (mutRecDefns:MutRecShapes<MutRecDefnsPhase1DataForTycon * 'MemberInfo, 'LetInfo, SynComponentInfo, _, _>) =
1520615215

1520715216
// Phase1A - build Entity for type definitions, exception definitions and module definitions.
1520815217
// Also for abbreviations of any of these. Augmentations are skipped in this phase.
1520915218
let withEntities =
15210-
typeDefCores
15219+
mutRecDefns
1521115220
|> MutRecShapes.mapWithParent
15212-
(parent, envInitial)
15221+
(parent, TypeNamesInMutRecDecls mutRecDefns, envInitial)
1521315222
// Build the initial entity for each module definition
15214-
(fun (innerParent, envForDecls) compInfo ->
15215-
TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent compInfo)
15223+
(fun (innerParent, typeNames, envForDecls) compInfo decls ->
15224+
TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent typeNames compInfo decls)
1521615225

1521715226
// Build the initial Tycon for each type definition
15218-
(fun (innerParent, envForDecls) (typeDefCore,tyconMemberInfo) ->
15227+
(fun (innerParent, _, envForDecls) (typeDefCore,tyconMemberInfo) ->
1521915228
let (MutRecDefnsPhase1DataForTycon(_,_,_,_,_,isAtOriginalTyconDefn)) = typeDefCore
1522015229
let tyconOpt =
1522115230
if isAtOriginalTyconDefn then
@@ -15225,7 +15234,7 @@ module EstablishTypeDefinitionCores =
1522515234
(typeDefCore, tyconMemberInfo, innerParent), tyconOpt)
1522615235

1522715236
// Bundle up the data for each 'val', 'member' or 'let' definition (just package up the data, no processing yet)
15228-
(fun (innerParent,_) synBinds ->
15237+
(fun (innerParent, _, _) synBinds ->
1522915238
let containerInfo = ModuleOrNamespaceContainerInfo(match innerParent with Parent p -> p | _ -> failwith "unreachable")
1523015239
mkLetInfo containerInfo synBinds)
1523115240

@@ -15246,7 +15255,6 @@ module EstablishTypeDefinitionCores =
1524615255
tyconOpt |> Option.iter (fun tycon ->
1524715256
// recheck these in case type is a duplicate in a mutually recursive set
1524815257
CheckForDuplicateConcreteType envAbove tycon.LogicalName tycon.Range
15249-
CheckForDuplicateModule envAbove tycon.LogicalName tycon.Range
1525015258
PublishTypeDefn cenv envAbove tycon))
1525115259

1525215260
// Updates the types of the modules to contain the contents so far
@@ -15657,7 +15665,7 @@ module TcDeclarations =
1565715665

1565815666
| SynTypeDefnRepr.Simple(repr,_) ->
1565915667
let members = []
15660-
let isAtOriginalTyconDefn = not (isAugmentationTyconDefnRepr repr)
15668+
let isAtOriginalTyconDefn = true
1566115669
let core = MutRecDefnsPhase1DataForTycon(synTyconInfo, repr, implements1, false, false, isAtOriginalTyconDefn)
1566215670
core, members @ extraMembers
1566315671

@@ -15738,8 +15746,10 @@ module TcDeclarations =
1573815746

1573915747
/// Separates the signature declaration into core (shape) and body.
1574015748
let rec private SplitTyconSignature (TypeDefnSig(synTyconInfo,trepr,extraMembers,_)) =
15749+
1574115750
let implements1 =
1574215751
extraMembers |> List.choose (function SynMemberSig.Interface (f,m) -> Some(f,m) | _ -> None)
15752+
1574315753
match trepr with
1574415754
| SynTypeDefnSigRepr.ObjectModel(kind,cspec,m) ->
1574515755
let fields = cspec |> List.choose (function SynMemberSig.ValField (f,_) -> Some(f) | _ -> None)
@@ -15847,7 +15857,7 @@ module TcDeclarations =
1584715857
// Bind module types
1584815858
//-------------------------------------------------------------------------
1584915859

15850-
let rec TcSignatureElementNonMutRec cenv parent endm (env: TcEnv) synSigDecl : Eventually<TcEnv> =
15860+
let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synSigDecl : Eventually<TcEnv> =
1585115861
eventually {
1585215862
try
1585315863
match synSigDecl with
@@ -15888,10 +15898,9 @@ let rec TcSignatureElementNonMutRec cenv parent endm (env: TcEnv) synSigDecl : E
1588815898
let vis,_ = ComputeAccessAndCompPath env None im vis parent
1588915899
let attribs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs
1589015900
CheckNamespaceModuleOrTypeName cenv.g id
15891-
let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true attribs
15901+
let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames attribs id.idText
1589215902
let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText
1589315903
CheckForDuplicateConcreteType env modName id.idRange
15894-
CheckForDuplicateModule env id.idText id.idRange
1589515904

1589615905
// Now typecheck the signature, accumulating and then recording the submodule description.
1589715906
let id = ident (modName, id.idRange)
@@ -15999,7 +16008,19 @@ and TcSignatureElements cenv parent endm env xml mutRecNSInfo defs =
1599916008

1600016009
and TcSignatureElementsNonMutRec cenv parent endm env defs =
1600116010
eventually {
16002-
return! Eventually.fold (TcSignatureElementNonMutRec cenv parent endm ) env defs
16011+
// Collect the type names so we can implicitly add the compilation suffix to module names
16012+
let typeNames =
16013+
[ for def in defs do
16014+
match def with
16015+
| SynModuleSigDecl.Types (typeSpecs,_) ->
16016+
for (TypeDefnSig(ComponentInfo(_,_,_,ids,_,_,_,_),trepr,extraMembers,_)) in typeSpecs do
16017+
match trepr with
16018+
| SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when nonNil extraMembers -> ()
16019+
| _ -> yield (List.last ids).idText
16020+
| _ -> () ]
16021+
|> set
16022+
16023+
return! Eventually.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs
1600316024
}
1600416025

1600516026
and TcSignatureElementsMutRec cenv parent endm mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
@@ -16116,7 +16137,7 @@ let CheckLetOrDoInNamespace binds m =
1611616137
error(NumberedError(FSComp.SR.tcNamespaceCannotContainValues(),binds.Head.RangeOfHeadPat))
1611716138

1611816139
/// The non-mutually recursive case for a declaration
16119-
let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDecl =
16140+
let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem env synDecl =
1612016141
eventually {
1612116142
cenv.synArgNameGenerator.Reset()
1612216143
let tpenv = emptyUnscopedTyparEnv
@@ -16188,7 +16209,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDec
1618816209
let id = ComputeModuleName longPath
1618916210

1619016211
let modAttrs = TcAttributes cenv env AttributeTargets.ModuleDecl attribs
16191-
let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true modAttrs
16212+
let modKind = EstablishTypeDefinitionCores.ComputeModuleOrNamespaceKind cenv.g true typeNames modAttrs id.idText
1619216213
let modName = EstablishTypeDefinitionCores.AdjustModuleName modKind id.idText
1619316214
CheckForDuplicateConcreteType env modName im
1619416215
CheckForDuplicateModule env id.idText id.idRange
@@ -16292,7 +16313,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent scopem env synDec
1629216313
}
1629316314

1629416315
/// The non-mutually recursive case for a sequence of declarations
16295-
and TcModuleOrNamespaceElementsNonMutRec cenv parent endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) =
16316+
and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar, env, envAtEnd) (moreDefs: SynModuleDecl list) =
1629616317
eventually {
1629716318
match moreDefs with
1629816319
| (firstDef :: otherDefs) ->
@@ -16304,9 +16325,9 @@ and TcModuleOrNamespaceElementsNonMutRec cenv parent endm (defsSoFar, env, envAt
1630416325
// Possibly better:
1630516326
//let scopem = unionRanges h1.Range.EndRange endm
1630616327

16307-
let! firstDef',env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent scopem env firstDef
16328+
let! firstDef',env', envAtEnd' = TcModuleOrNamespaceElementNonMutRec cenv parent typeNames scopem env firstDef
1630816329
// tail recursive
16309-
return! TcModuleOrNamespaceElementsNonMutRec cenv parent endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs
16330+
return! TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ( (firstDef' :: defsSoFar), env', envAtEnd') otherDefs
1631016331
| [] ->
1631116332
return List.rev defsSoFar, envAtEnd
1631216333
}
@@ -16416,7 +16437,19 @@ and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo defs =
1641616437
return (mexpr, topAttrsNew, envAtEnd)
1641716438

1641816439
| None ->
16419-
let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent endm ([], env, env) defs
16440+
// Collect the type names so we can implicitly add the compilation suffix to module names
16441+
let typeNames =
16442+
[ for def in defs do
16443+
match def with
16444+
| SynModuleDecl.Types (typeSpecs,_) ->
16445+
for (TypeDefn(ComponentInfo(_,_,_,ids,_,_,_,_),trepr,_,_)) in typeSpecs do
16446+
match trepr with
16447+
| SynTypeDefnRepr.ObjectModel(TyconAugmentation,_,_) -> ()
16448+
| _ -> yield (List.last ids).idText
16449+
| _ -> () ]
16450+
|> set
16451+
16452+
let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) defs
1642016453

1642116454
// Apply the functions for each declaration to build the overall expression-builder
1642216455
let mexpr = TMDefs(List.foldBack (fun (f,_) x -> f x) compiledDefs [])

0 commit comments

Comments
 (0)