提交 a29abe34 编写于 作者: D Don Syme 提交者: Kevin Ransom (msft)

Fix 1720 - Implicit module suffix is not added to rec modules (#3249)

* Fix 1720 - Implicit module suffix is not added to rec modules

* Fix 1720 - Implicit module suffix is not added to rec modules

* adjust fix
上级 3b4f17e7
......@@ -14444,7 +14444,32 @@ module EstablishTypeDefinitionCores =
| _ -> () ]
|> set
let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo compDecls =
let TypeNamesInNonMutRecDecls defs =
[ for def in defs do
match def with
| SynModuleDecl.Types (typeSpecs,_) ->
for (TypeDefn(ComponentInfo(_,typars,_,ids,_,_,_,_),trepr,_,_)) in typeSpecs do
if isNil typars then
match trepr with
| SynTypeDefnRepr.ObjectModel(TyconAugmentation,_,_) -> ()
| _ -> yield (List.last ids).idText
| _ -> () ]
|> set
// Collect the type names so we can implicitly add the compilation suffix to module names
let TypeNamesInNonMutRecSigDecls defs =
[ for def in defs do
match def with
| SynModuleSigDecl.Types (typeSpecs,_) ->
for (TypeDefnSig(ComponentInfo(_,typars,_,ids,_,_,_,_),trepr,extraMembers,_)) in typeSpecs do
if isNil typars then
match trepr with
| SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when not (isNil extraMembers) -> ()
| _ -> yield (List.last ids).idText
| _ -> () ]
|> set
let TcTyconDefnCore_Phase1A_BuildInitialModule cenv envInitial parent typeNames compInfo decls =
let (ComponentInfo(attribs,_parms, _constraints,longPath,xml,_,vis,im)) = compInfo
let id = ComputeModuleName longPath
let modAttrs = TcAttributes cenv envInitial AttributeTargets.ModuleDecl attribs
......@@ -14461,8 +14486,8 @@ module EstablishTypeDefinitionCores =
let envForDecls, mtypeAcc = MakeInnerEnv envInitial id modKind
let mspec = NewModuleOrNamespace (Some envInitial.eCompPath) vis id (xml.ToXmlDoc()) modAttrs (MaybeLazy.Strict (NewEmptyModuleOrNamespaceType modKind))
let innerParent = Parent (mkLocalModRef mspec)
let typeNames = TypeNamesInMutRecDecls compDecls
MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, typeNames, envForDecls)
let innerTypeNames = TypeNamesInMutRecDecls decls
MutRecDefnsPhase2DataForModule (mtypeAcc, mspec), (innerParent, innerTypeNames, envForDecls)
/// Establish 'type <vis1> C < T1... TN > = <vis2> ...' including
/// - computing the mangled name for C
......@@ -15528,14 +15553,14 @@ module EstablishTypeDefinitionCores =
| _ -> ())
let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent inSig tpenv m scopem mutRecNSInfo (mutRecDefns:MutRecShapes<MutRecDefnsPhase1DataForTycon * 'MemberInfo, 'LetInfo, SynComponentInfo, _, _>) =
let TcMutRecDefns_Phase1 mkLetInfo cenv envInitial parent typeNames inSig tpenv m scopem mutRecNSInfo (mutRecDefns:MutRecShapes<MutRecDefnsPhase1DataForTycon * 'MemberInfo, 'LetInfo, SynComponentInfo, _, _>) =
// Phase1A - build Entity for type definitions, exception definitions and module definitions.
// Also for abbreviations of any of these. Augmentations are skipped in this phase.
let withEntities =
mutRecDefns
|> MutRecShapes.mapWithParent
(parent, TypeNamesInMutRecDecls mutRecDefns, envInitial)
(parent, typeNames, envInitial)
// Build the initial entity for each module definition
(fun (innerParent, typeNames, envForDecls) compInfo decls ->
TcTyconDefnCore_Phase1A_BuildInitialModule cenv envForDecls innerParent typeNames compInfo decls)
......@@ -16000,7 +16025,7 @@ module TcDeclarations =
//-------------------------------------------------------------------------
/// Bind a collection of mutually recursive definitions in an implementation file
let TcMutRecDefinitions cenv envInitial parent tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) =
let TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecDefns: MutRecDefnsInitialData) =
// Split the definitions into "core representations" and "members". The code to process core representations
// is shared between processing of signature files and implementation files.
......@@ -16010,7 +16035,7 @@ module TcDeclarations =
let tycons, envMutRecPrelim, mutRecDefnsAfterCore =
EstablishTypeDefinitionCores.TcMutRecDefns_Phase1
(fun containerInfo synBinds -> [ for synBind in synBinds -> RecDefnBindingInfo(containerInfo,NoNewSlots,ModuleOrMemberBinding,synBind) ])
cenv envInitial parent false tpenv m scopem mutRecNSInfo mutRecDefnsAfterSplit
cenv envInitial parent typeNames false tpenv m scopem mutRecNSInfo mutRecDefnsAfterSplit
// Package up the phase two information for processing members.
let mutRecDefnsAfterPrep =
......@@ -16151,9 +16176,9 @@ module TcDeclarations =
/// Bind a collection of mutually recursive declarations in a signature file
let TcMutRecSignatureDecls cenv envInitial parent tpenv m scopem mutRecNSInfo (mutRecSigs:MutRecSigsInitialData) =
let TcMutRecSignatureDecls cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo (mutRecSigs:MutRecSigsInitialData) =
let mutRecSigsAfterSplit = mutRecSigs |> MutRecShapes.mapTycons SplitTyconSignature
let _tycons, envMutRec, mutRecDefnsAfterCore = EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 (fun containerInfo valDecl -> (containerInfo, valDecl)) cenv envInitial parent true tpenv m scopem mutRecNSInfo mutRecSigsAfterSplit
let _tycons, envMutRec, mutRecDefnsAfterCore = EstablishTypeDefinitionCores.TcMutRecDefns_Phase1 (fun containerInfo valDecl -> (containerInfo, valDecl)) cenv envInitial parent typeNames true tpenv m scopem mutRecNSInfo mutRecSigsAfterSplit
// Updates the types of the modules to contain the contents so far, which now includes values and members
MutRecBindingChecking.TcMutRecDefns_UpdateModuleContents mutRecNSInfo mutRecDefnsAfterCore
......@@ -16192,7 +16217,7 @@ let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synS
| SynModuleSigDecl.Types (typeSpecs,m) ->
let scopem = unionRanges m endm
let mutRecDefns = typeSpecs |> List.map MutRecShape.Tycon
let env = TcDeclarations.TcMutRecSignatureDecls cenv env parent emptyUnscopedTyparEnv m scopem None mutRecDefns
let env = TcDeclarations.TcMutRecSignatureDecls cenv env parent typeNames emptyUnscopedTyparEnv m scopem None mutRecDefns
return env
| SynModuleSigDecl.Open (mp,m) ->
......@@ -16215,7 +16240,8 @@ let rec TcSignatureElementNonMutRec cenv parent typeNames endm (env: TcEnv) synS
if isRec then
// Treat 'module rec M = ...' as a single mutually recursive definition group 'module M = ...'
let modDecl = SynModuleSigDecl.NestedModule(compInfo,false,mdefs,m)
return! TcSignatureElementsMutRec cenv parent endm None env [modDecl]
return! TcSignatureElementsMutRec cenv parent typeNames endm None env [modDecl]
else
let id = ComputeModuleName longPath
let vis,_ = ComputeAccessAndCompPath env None im vis None parent
......@@ -16325,32 +16351,21 @@ and TcSignatureElements cenv parent endm env xml mutRecNSInfo defs =
if cenv.compilingCanonicalFslibModuleType then
ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath (xml.ToXmlDoc())
let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecSigDecls defs
match mutRecNSInfo with
| Some _ ->
return! TcSignatureElementsMutRec cenv parent endm mutRecNSInfo env defs
return! TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo env defs
| None ->
return! TcSignatureElementsNonMutRec cenv parent endm env defs
return! TcSignatureElementsNonMutRec cenv parent typeNames endm env defs
}
and TcSignatureElementsNonMutRec cenv parent endm env defs =
and TcSignatureElementsNonMutRec cenv parent typeNames endm env defs =
eventually {
// Collect the type names so we can implicitly add the compilation suffix to module names
let typeNames =
[ for def in defs do
match def with
| SynModuleSigDecl.Types (typeSpecs,_) ->
for (TypeDefnSig(ComponentInfo(_,typars,_,ids,_,_,_,_),trepr,extraMembers,_)) in typeSpecs do
if isNil typars then
match trepr with
| SynTypeDefnSigRepr.Simple((SynTypeDefnSimpleRepr.None _),_) when not (isNil extraMembers) -> ()
| _ -> yield (List.last ids).idText
| _ -> () ]
|> set
return! Eventually.fold (TcSignatureElementNonMutRec cenv parent typeNames endm) env defs
}
and TcSignatureElementsMutRec cenv parent endm mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
and TcSignatureElementsMutRec cenv parent typeNames endm mutRecNSInfo envInitial (defs: SynModuleSigDecl list) =
eventually {
let m = match defs with [] -> endm | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
let scopem = (defs, endm) ||> List.foldBack (fun h m -> unionRanges h.Range m)
......@@ -16398,7 +16413,7 @@ and TcSignatureElementsMutRec cenv parent endm mutRecNSInfo envInitial (defs: Sy
|> fst
loop (match parent with ParentNone -> true | Parent _ -> false) defs
return TcDeclarations.TcMutRecSignatureDecls cenv envInitial parent emptyUnscopedTyparEnv m scopem mutRecNSInfo mutRecDefns
return TcDeclarations.TcMutRecSignatureDecls cenv envInitial parent typeNames emptyUnscopedTyparEnv m scopem mutRecNSInfo mutRecDefns
}
......@@ -16484,7 +16499,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem
| SynModuleDecl.Types (typeDefs,m) ->
let scopem = unionRanges m scopem
let mutRecDefns = typeDefs |> List.map MutRecShape.Tycon
let mutRecDefnsChecked,envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent tpenv m scopem None mutRecDefns
let mutRecDefnsChecked,envAfter = TcDeclarations.TcMutRecDefinitions cenv env parent typeNames tpenv m scopem None mutRecDefns
// Check the non-escaping condition as we build the expression on the way back up
let exprfWithEscapeCheck e =
TcMutRecDefnsEscapeCheck mutRecDefnsChecked env
......@@ -16530,7 +16545,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv:cenv) parent typeNames scopem
if isRec then
assert (not isContinuingModule)
let modDecl = SynModuleDecl.NestedModule(compInfo, false, mdefs, isContinuingModule, m)
return! TcModuleOrNamespaceElementsMutRec cenv parent m env None [modDecl]
return! TcModuleOrNamespaceElementsMutRec cenv parent typeNames m env None [modDecl]
else
let (ComponentInfo(attribs,_parms, _constraints,longPath,xml,_,vis,im)) = compInfo
let id = ComputeModuleName longPath
......@@ -16657,7 +16672,7 @@ and TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm (defsSoFar,
}
/// The mutually recursive case for a sequence of declarations (and nested modules)
and TcModuleOrNamespaceElementsMutRec cenv parent endm envInitial mutRecNSInfo (defs: SynModuleDecl list) =
and TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm envInitial mutRecNSInfo (defs: SynModuleDecl list) =
eventually {
let m = match defs with [] -> endm | _ -> defs |> List.map (fun d -> d.Range) |> List.reduce unionRanges
......@@ -16716,7 +16731,7 @@ and TcModuleOrNamespaceElementsMutRec cenv parent endm envInitial mutRecNSInfo (
loop (match parent with ParentNone -> true | Parent _ -> false) [] defs
let tpenv = emptyUnscopedTyparEnv
let mutRecDefnsChecked,envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent tpenv m scopem mutRecNSInfo mutRecDefns
let mutRecDefnsChecked,envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns
// Check the assembly attributes
let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs
......@@ -16753,26 +16768,17 @@ and TcModuleOrNamespaceElements cenv parent endm env xml mutRecNSInfo defs =
if cenv.compilingCanonicalFslibModuleType then
ensureCcuHasModuleOrNamespaceAtPath cenv.topCcu env.ePath env.eCompPath (xml.ToXmlDoc())
// Collect the type names so we can implicitly add the compilation suffix to module names
let typeNames = EstablishTypeDefinitionCores.TypeNamesInNonMutRecDecls defs
match mutRecNSInfo with
| Some _ ->
let! (exprf, topAttrsNew), _, envAtEnd = TcModuleOrNamespaceElementsMutRec cenv parent endm env mutRecNSInfo defs
let! (exprf, topAttrsNew), _, envAtEnd = TcModuleOrNamespaceElementsMutRec cenv parent typeNames endm env mutRecNSInfo defs
// Apply the functions for each declaration to build the overall expression-builder
let mexpr = TMDefs(exprf [])
return (mexpr, topAttrsNew, envAtEnd)
| None ->
// Collect the type names so we can implicitly add the compilation suffix to module names
let typeNames =
[ for def in defs do
match def with
| SynModuleDecl.Types (typeSpecs,_) ->
for (TypeDefn(ComponentInfo(_,typars,_,ids,_,_,_,_),trepr,_,_)) in typeSpecs do
if isNil typars then
match trepr with
| SynTypeDefnRepr.ObjectModel(TyconAugmentation,_,_) -> ()
| _ -> yield (List.last ids).idText
| _ -> () ]
|> set
let! compiledDefs, envAtEnd = TcModuleOrNamespaceElementsNonMutRec cenv parent typeNames endm ([], env, env) defs
......
......@@ -1671,6 +1671,18 @@ module TypecheckTests =
#endif
#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS
[<Test>]
let ``sigs pos26`` () =
let cfg = testConfig "typecheck/sigs"
fsc cfg "%s --target:exe -o:pos26.exe" cfg.fsc_flags ["pos26.fsi"; "pos26.fs"]
peverify cfg "pos26.exe"
[<Test>]
let ``sigs pos25`` () =
let cfg = testConfig "typecheck/sigs"
fsc cfg "%s --target:exe -o:pos25.exe" cfg.fsc_flags ["pos25.fs"]
peverify cfg "pos25.exe"
[<Test>]
let ``sigs pos24`` () =
let cfg = testConfig "typecheck/sigs"
......
module Pos25
type R = R
module rec R = begin end
\ No newline at end of file
namespace Pos26
type R = R
module rec R = begin end
\ No newline at end of file
namespace Pos26
type R = R
module R = begin end
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册