Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/Compiler/Checking/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2640,6 +2640,35 @@ let CheckEntityDefns cenv env tycons =
// check modules
//--------------------------------------------------------------------------

/// Check for duplicate extension member names that would cause IL conflicts.
/// Extension members for types with the same simple name but different fully qualified names
/// will be emitted into the same IL container type, causing a duplicate member error.
let CheckForDuplicateExtensionMemberNames (cenv: cenv) (vals: Val seq) =
if cenv.reportErrors then
// Group extension members by the simple name of the type they extend
let extensionMembers =
vals
|> Seq.filter (fun v -> v.IsExtensionMember && v.IsMember)
|> Seq.toList

if not extensionMembers.IsEmpty then
let groupedBySimpleName =
extensionMembers
|> List.groupBy (fun v -> v.MemberApparentEntity.DisplayNameCore)

for (simpleName, members) in groupedBySimpleName do
// Check if members extend different fully qualified types
let distinctTypes =
members
|> List.map (fun v -> v.MemberApparentEntity)
|> List.distinctBy (fun tcref -> tcref.Stamp)

if distinctTypes.Length > 1 then
// Found extensions for types with same simple name but different fully qualified names
// Report error on the second (and subsequent) extensions
for v in members |> List.skip 1 do
errorR(Error(FSComp.SR.tcDuplicateExtensionMemberNames(simpleName), v.Range))

let rec CheckDefnsInModule cenv env mdefs =
for mdef in mdefs do
CheckDefnInModule cenv env mdef
Expand All @@ -2649,6 +2678,7 @@ and CheckNothingAfterEntryPoint cenv m =
errorR(Error(FSComp.SR.chkEntryPointUsage(), m))

and CheckDefnInModule cenv env mdef =
CheckForDuplicateExtensionMemberNames cenv (allTopLevelValsOfModDef mdef)
match mdef with
| TMDefRec(isRec, _opens, tycons, mspecs, m) ->
CheckNothingAfterEntryPoint cenv 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 @@ -1635,6 +1635,7 @@ featureLowerSimpleMappingsInComprehensionsToFastLoops,"Lowers [for x in xs -> f
3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation."
3355,tcNotAnIndexerNamedIndexingNotYetEnabled,"The value '%s' is not a function and does not support index notation."
3355,tcNotAnIndexerIndexingNotYetEnabled,"This expression is not a function and does not support index notation."
3356,tcDuplicateExtensionMemberNames,"Extension members extending types with the same simple name '%s' but different fully qualified names cannot be defined in the same module. Consider defining these extensions in separate modules."
3360,typrelInterfaceWithConcreteAndVariable,"'%s' cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify."
3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify."
featureInterfacesWithMultipleGenericInstantiation,"interfaces with multiple generic instantiation"
Expand Down
14 changes: 11 additions & 3 deletions src/Compiler/TypedTree/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6445,23 +6445,31 @@ and allEntitiesOfModDef mdef =
yield! allEntitiesOfModDef def
}

and allValsOfModDef mdef =
and allValsOfModDefWithOption processNested mdef =
seq { match mdef with
| TMDefRec(_, _, tycons, mbinds, _) ->
yield! abstractSlotValsOfTycons tycons
for mbind in mbinds do
match mbind with
| ModuleOrNamespaceBinding.Binding bind -> yield bind.Var
| ModuleOrNamespaceBinding.Module(_, def) -> yield! allValsOfModDef def
| ModuleOrNamespaceBinding.Module(_, def) ->
if processNested then
yield! allValsOfModDefWithOption processNested def
| TMDefLet(bind, _) ->
yield bind.Var
| TMDefDo _ -> ()
| TMDefOpens _ -> ()
| TMDefs defs ->
for def in defs do
yield! allValsOfModDef def
yield! allValsOfModDefWithOption processNested def
}

and allValsOfModDef mdef =
allValsOfModDefWithOption true mdef

and allTopLevelValsOfModDef mdef =
allValsOfModDefWithOption false mdef

and copyAndRemapModDef ctxt compgen tmenv mdef =
let tycons = allEntitiesOfModDef mdef |> List.ofSeq
let vs = allValsOfModDef mdef |> List.ofSeq
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2724,6 +2724,8 @@ val (|InnerExprPat|): Expr -> Expr

val allValsOfModDef: ModuleOrNamespaceContents -> seq<Val>

val allTopLevelValsOfModDef: ModuleOrNamespaceContents -> seq<Val>

val BindUnitVars: TcGlobals -> Val list * ArgReprInfo list * Expr -> Val list * Expr

val isThreadOrContextStatic: TcGlobals -> Attrib list -> bool
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.zh-Hant.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading