Skip to content
Merged
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
190 changes: 74 additions & 116 deletions src/Compiler/Checking/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,20 +1268,17 @@ module MutRecBindingChecking =
let prelimRecValues = [ for x in defnAs do match x with Phase2AMember bind -> yield bind.RecBindingInfo.Val | _ -> () ]

let tyconOpt =
if cenv.g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired) then
tyconOpt
|> Option.map (fun tycon ->
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envForTycon.eModuleOrNamespaceTypeAccumulator
tycon
)
else
tyconOpt
tyconOpt
|> Option.map (fun tycon ->
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envForTycon.eModuleOrNamespaceTypeAccumulator
tycon
)
let defnAs = MutRecShape.Tycon(TyconBindingsPhase2A(tyconOpt, declKind, prelimRecValues, tcref, copyOfTyconTypars, thisTy, defnAs))
defnAs, (tpenv, recBindIdx, uncheckedBindsRev))

Expand Down Expand Up @@ -1503,22 +1500,17 @@ module MutRecBindingChecking =
Phase2BMember rbind.RecBindingInfo.Index, innerState)

let tyconOpt =
if not(cenv.g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired)) then
tyconOpt
else
// We need to redo this check, which already happened in TcMutRecBindings_Phase2A_CreateRecursiveValuesAndCheckArgumentPatterns
// Because the environment is being reset in the case of recursive modules.
tyconOpt
|> Option.map (fun tycon ->
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envForTycon.eModuleOrNamespaceTypeAccumulator
tycon
)
tyconOpt
|> Option.map (fun tycon ->
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envForTycon.eModuleOrNamespaceTypeAccumulator
tycon
)

let defnBs = MutRecShape.Tycon (TyconBindingsPhase2B(tyconOpt, tcref, defnBs))
let outerState = (tpenv, generalizedRecBinds, preGeneralizationRecBinds, uncheckedRecBindsTable, envNonRec)
Expand Down Expand Up @@ -5039,52 +5031,33 @@ module TcDeclarations =
let withBindings, envFinal = TcMutRecDefns_Phase2 cenv envInitial m scopem mutRecNSInfo envMutRecPrelimWithReprs withEnvs isMutRec

let withBindings =
if cenv.g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired) then
// If any of the types has a member with the System.Runtime.CompilerServices.ExtensionAttribute,
// or a recursive module has a binding with the System.Runtime.CompilerServices.ExtensionAttribute,
// that type/recursive module should also received the ExtensionAttribute if it is not yet present.
// Example:
// open System.Runtime.CompilerServices
//
// type Int32Extensions =
// [<Extension>]
// static member PlusOne (a:int) : int = a + 1
//
// or
//
// module rec Foo
//
// [<System.Runtime.CompilerServices.Extension>]
// let PlusOne (a:int) = a + 1
withBindings
|> List.map (function
| MutRecShape.Tycon (Some tycon, bindings) ->
let tycon =
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envFinal.eModuleOrNamespaceTypeAccumulator
tycon

MutRecShape.Tycon (Some tycon, bindings)
| MutRecShape.Module ((MutRecDefnsPhase2DataForModule(moduleOrNamespaceType, entity), env), shapes) ->
let entity =
tryAddExtensionAttributeIfNotAlreadyPresentForModule
g
(fun tryFindExtensionAttribute ->
moduleOrNamespaceType.Value.AllValsAndMembers
|> Seq.filter(fun v -> v.IsModuleBinding)
|> Seq.tryPick (fun v -> tryFindExtensionAttribute v.Attribs)
)
entity

MutRecShape.Module ((MutRecDefnsPhase2DataForModule(moduleOrNamespaceType, entity), env), shapes)
| shape -> shape)
else
withBindings
withBindings
|> List.map (function
| MutRecShape.Tycon (Some tycon, bindings) ->
let tycon =
tryAddExtensionAttributeIfNotAlreadyPresentForType
g
(fun tryFindExtensionAttribute ->
tycon.MembersOfFSharpTyconSorted
|> Seq.tryPick (fun m -> tryFindExtensionAttribute m.Attribs)
)
envFinal.eModuleOrNamespaceTypeAccumulator
tycon

MutRecShape.Tycon (Some tycon, bindings)
| MutRecShape.Module ((MutRecDefnsPhase2DataForModule(moduleOrNamespaceType, entity), env), shapes) ->
let entity =
tryAddExtensionAttributeIfNotAlreadyPresentForModule
g
(fun tryFindExtensionAttribute ->
moduleOrNamespaceType.Value.AllValsAndMembers
|> Seq.filter(fun v -> v.IsModuleBinding)
|> Seq.tryPick (fun v -> tryFindExtensionAttribute v.Attribs)
)
entity

MutRecShape.Module ((MutRecDefnsPhase2DataForModule(moduleOrNamespaceType, entity), env), shapes)
| shape -> shape)

// Generate the hash/compare/equality bindings for all tycons.
//
Expand Down Expand Up @@ -5198,25 +5171,20 @@ module TcDeclarations =
let envForTycon = MakeInnerEnvForTyconRef envForTycon tcref (declKind = ExtrinsicExtensionBinding)

let vals, env = TcTyconMemberSpecs cenv envForTycon (TyconContainerInfo(innerParent, tcref, declaredTyconTypars, NoSafeInitInfo)) declKind tpenv members
if not(cenv.g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired)) then
vals, env
else
// Check if any of the vals has the `[<Extension>]` attribute
// If this is the case, add it to the type in the env.
let extensionAttributeOnVals =
vals
|> List.tryPick (fun v -> tryFindExtensionAttribute g v.Attribs)

let typeEntity =
envForTycon.eModuleOrNamespaceTypeAccumulator.Value.AllEntitiesByLogicalMangledName.TryFind(tcref.LogicalName)

match extensionAttributeOnVals, typeEntity with
| Some extensionAttribute, Some typeEntity ->
if Option.isNone (tryFindExtensionAttribute g typeEntity.Attribs) then
typeEntity.entity_attribs <- typeEntity.EntityAttribs.Add(extensionAttribute, WellKnownEntityAttributes.ExtensionAttribute)
| _ -> ()
let extensionAttributeOnVals =
vals
|> List.tryPick (fun v -> tryFindExtensionAttribute g v.Attribs)

let typeEntity =
envForTycon.eModuleOrNamespaceTypeAccumulator.Value.AllEntitiesByLogicalMangledName.TryFind(tcref.LogicalName)

vals, env
match extensionAttributeOnVals, typeEntity with
| Some extensionAttribute, Some typeEntity ->
if Option.isNone (tryFindExtensionAttribute g typeEntity.Attribs) then
typeEntity.entity_attribs <- typeEntity.EntityAttribs.Add(extensionAttribute, WellKnownEntityAttributes.ExtensionAttribute)
| _ -> ()

vals, env

)
// Do this for each 'val' declaration in a module
Expand Down Expand Up @@ -5850,28 +5818,18 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
moduleEntity.entity_modul_type <- MaybeLazy.Strict moduleTyAcc.Value

let moduleEntity =
if cenv.g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired) then
// If any of the let bindings inside the module has the System.Runtime.CompilerServices.ExtensionAttribute,
// that module should also received the ExtensionAttribute if it is not yet present.
// Example:
// module Foo
//
//[<System.Runtime.CompilerServices.Extension>]
//let PlusOne (a:int) = a + 1
tryAddExtensionAttributeIfNotAlreadyPresentForModule
g
(fun tryFindExtensionAttribute ->
match moduleContents with
| ModuleOrNamespaceContents.TMDefs(defs) ->
defs
|> Seq.tryPick (function
| ModuleOrNamespaceContents.TMDefLet (Binding.TBind(var = v),_) ->
tryFindExtensionAttribute v.Attribs
| _ -> None)
| _ -> None
)
moduleEntity
else
tryAddExtensionAttributeIfNotAlreadyPresentForModule
g
(fun tryFindExtensionAttribute ->
match moduleContents with
| ModuleOrNamespaceContents.TMDefs(defs) ->
defs
|> Seq.tryPick (function
| ModuleOrNamespaceContents.TMDefLet (Binding.TBind(var = v),_) ->
tryFindExtensionAttribute v.Attribs
| _ -> None)
| _ -> None
)
moduleEntity

let moduleDef = TMDefRec(false, [], [], [ModuleOrNamespaceBinding.Module(moduleEntity, moduleContents)], m)
Expand Down
2 changes: 0 additions & 2 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,6 @@ let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap: Import.Impor

let isApplicable =
IsTyconRefUsedForCSharpStyleExtensionMembers g tcrefOfStaticClass ||

g.langVersion.SupportsFeature(LanguageFeature.CSharpExtensionAttributeNotRequired) &&
tcrefOfStaticClass.IsLocalRef &&
not tcrefOfStaticClass.IsTypeAbbrev

Expand Down
1 change: 0 additions & 1 deletion src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1554,7 +1554,6 @@ featureFromEndSlicing,"from-end slicing"
featureNullnessChecking,"nullness checking"
featureRuntimeAsync,"runtime async"
featureWitnessPassing,"witness passing for trait constraints in F# quotations"
featureCSharpExtensionAttributeNotRequired,"Allow implicit Extension attribute on declaring types, modules"
featurePreferExtensionMethodOverPlainProperty,"prefer extension method over plain property"
featureWarningIndexedPropertiesGetSetSameType,"Indexed properties getter and setter must have the same type"
featureChkTailCallAttrOnNonRec,"Raises warnings if the 'TailCall' attribute is used on non-recursive functions."
Expand Down
5 changes: 0 additions & 5 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ type LanguageFeature =
| WitnessPassing
| NullnessChecking
| UnionIsPropertiesVisible
| CSharpExtensionAttributeNotRequired
| UnmanagedConstraintCsharpInterop
| ReuseSameFieldsInStructUnions
| PreferExtensionMethodOverPlainProperty
Expand Down Expand Up @@ -110,9 +109,6 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array)
// F# 5.0
LanguageFeature.WitnessPassing, languageVersion50

// F# 8.0
LanguageFeature.CSharpExtensionAttributeNotRequired, languageVersion80

// F# 9.0
LanguageFeature.NullnessChecking, languageVersion90
LanguageFeature.ReuseSameFieldsInStructUnions, languageVersion90
Expand Down Expand Up @@ -267,7 +263,6 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array)
| LanguageFeature.RuntimeAsync -> FSComp.SR.featureRuntimeAsync ()
| LanguageFeature.WitnessPassing -> FSComp.SR.featureWitnessPassing ()
| LanguageFeature.UnionIsPropertiesVisible -> FSComp.SR.featureUnionIsPropertiesVisible ()
| LanguageFeature.CSharpExtensionAttributeNotRequired -> FSComp.SR.featureCSharpExtensionAttributeNotRequired ()
| LanguageFeature.UnmanagedConstraintCsharpInterop -> FSComp.SR.featureUnmanagedConstraintCsharpInterop ()
| LanguageFeature.ReuseSameFieldsInStructUnions -> FSComp.SR.featureReuseSameFieldsInStructUnions ()
| LanguageFeature.PreferExtensionMethodOverPlainProperty -> FSComp.SR.featurePreferExtensionMethodOverPlainProperty ()
Expand Down
1 change: 0 additions & 1 deletion src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type LanguageFeature =
| WitnessPassing
| NullnessChecking
| UnionIsPropertiesVisible
| CSharpExtensionAttributeNotRequired
| UnmanagedConstraintCsharpInterop
| ReuseSameFieldsInStructUnions
/// RFC-1137
Expand Down
5 changes: 0 additions & 5 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: 0 additions & 5 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: 0 additions & 5 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: 0 additions & 5 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: 0 additions & 5 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.

Loading
Loading