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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
* Stabilized several `preview` language features into F# 11.0 (`--langversion:11.0`, enabled by default with a .NET 11 SDK): `MethodOverloadsCache`, `ErrorOnMissingSignatureAttribute`, `DirectDelegateConstruction`, `AccessProtectedBaseFieldFromClosure`, and `RecordSpreads`. `FromEndSlicing` intentionally remains in `preview`. ([PR #20199](https://github.com/dotnet/fsharp/pull/20199))
* Interpolated string holes (e.g. `$"{x}"`) are now formatted with invariant culture (via the `string` operator) instead of the current thread culture. ([PR #19971](https://github.com/dotnet/fsharp/pull/19971))
* Lines starting with `#:` are now ignored ([Language suggestion 1440](https://github.com/fsharp/fslang-suggestions/issues/1440), [RFC FS-1337](https://github.com/fsharp/fslang-design/pull/830), [PR #20212](https://github.com/dotnet/fsharp/pull/20212))
* Calculate Entity.PublicPath instead of storing ([PR #20285](https://github.com/dotnet/fsharp/pull/20285))

### Breaking Changes
* Add `ExtendedLayoutAttribute` support for future .NET runtime interop. `ILTypeDefLayout` has a new `Extended` case. ([Issue #19190](https://github.com/dotnet/fsharp/issues/19190), [PR #19194](https://github.com/dotnet/fsharp/pull/19194))
Expand Down
6 changes: 3 additions & 3 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,11 +1174,11 @@ let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespac
match modref.TypeReprInfo with
| TProvidedNamespaceRepr(resolutionEnvironment, resolvers) ->
match modref.Deref.PublicPath with
| Some(PubPath path) ->
| ValueSome pubpath ->
resolvers
|> List.choose (fun r-> TryResolveProvidedType(r, m, path, typeName))
|> List.choose (fun r -> TryResolveProvidedType(r, m, pubpath.FullPath, typeName))
|> List.map (fun st -> AddEntityForProvidedType (amap, modref, resolutionEnvironment, st, m))
| None -> []
| ValueNone -> []

// We have a provided type, look up its nested types (populating them on-demand if necessary)
| TProvidedTypeRepr info ->
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Checking/OverloadResolutionRules.fs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ let private compareArg (ctx: OverloadResolutionContext) (calledArg1: CalledArg)
| ValueSome tcref1 when
tcref1.DisplayName = "Func"
&& (match tcref1.PublicPath with
| Some p -> p.EnclosingPath = [| "System" |]
| ValueSome p -> p.EnclosingPath = [| "System" |]
| _ -> false)
&& isDelegateTy g ty1
&& isDelegateTy g ty2
Expand Down
4 changes: 2 additions & 2 deletions src/Compiler/Service/FSharpCheckerResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2741,8 +2741,8 @@ type internal TypeCheckInfo
None
else
match tr.TypeReprInfo, tr.PublicPath with
| TILObjectRepr(TILObjectReprData(ILScopeRef.Assembly assemblyRef, _, _)), Some(PubPath parts) ->
let fullName = parts |> String.concat "."
| TILObjectRepr(TILObjectReprData(ILScopeRef.Assembly assemblyRef, _, _)), ValueSome pubpath ->
let fullName = pubpath.FullPath |> String.concat "."
Some(FindDeclResult.ExternalDecl(assemblyRef.Name, FindDeclExternalSymbol.Type fullName))
| _ -> None
| _ -> None
Expand Down
21 changes: 10 additions & 11 deletions src/Compiler/Service/ServiceDeclarationLists.fs
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,16 @@ module DeclarationListHelpers =
member x.Equals(item1, item2) = nullSafeEquality item1 item2 (fun item1 item2 -> fullDisplayTextOfModRef item1 = fullDisplayTextOfModRef item2)
member x.GetHashCode item = hash item.Stamp }

let OutputFullName displayFullName ppF fnF r =
let OutputFullName displayFullName hasPubPath fnF r =
// Only display full names in quick info, not declaration lists or method lists
if not displayFullName then
match ppF r with
| None -> emptyL
| Some _ -> wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r)
if not displayFullName then
if hasPubPath r then wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r)
else emptyL
else emptyL

let pubpathOfValRef (v: ValRef) = v.PublicPath
let hasPubPathValRef (v: ValRef) = v.PublicPath.IsSome

let pubpathOfTyconRef (x: TyconRef) = x.PublicPath
let hasPubPathTyconRef (x: TyconRef) = x.PublicPath.IsSome

/// Output the quick info information of a language item
let rec FormatItemDescriptionToToolTipElement displayFullName (infoReader: InfoReader) ad m denv (item: ItemWithInst) symbol (width: int option) =
Expand All @@ -169,7 +168,7 @@ module DeclarationListHelpers =

| Item.Value vref | Item.CustomBuilder (_, vref) ->
let prettyTyparInst, resL = layoutQualifiedValOrMember denv infoReader item.TyparInstantiation vref
let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout vref
let remarks = OutputFullName displayFullName hasPubPathValRef fullDisplayTextOfValRefAsLayout vref
let tpsL = FormatTyparMapping denv prettyTyparInst
let typeMapping = List.map toRichText tpsL
let resL = PrintUtilities.squashToWidth width resL
Expand Down Expand Up @@ -212,7 +211,7 @@ module DeclarationListHelpers =
let vTauTy = v.TauType
// REVIEW: use _cxs here
let (prettyTyparInst, prettyTy), _cxs = PrettyTypes.PrettifyInstAndType denv.g (item.TyparInstantiation, vTauTy)
let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout v
let remarks = OutputFullName displayFullName hasPubPathValRef fullDisplayTextOfValRefAsLayout v
let layout =
wordL (tagText (FSComp.SR.typeInfoActiveRecognizer())) ^^
wordL (tagActivePatternCase apref.DisplayName |> mkNav v.DefinitionRange) ^^
Expand All @@ -231,7 +230,7 @@ module DeclarationListHelpers =
| Item.ExnCase ecref ->
let layout = layoutExnDef denv infoReader ecref
let layout = PrintUtilities.squashToWidth width layout
let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfExnRefAsLayout ecref
let remarks = OutputFullName displayFullName hasPubPathTyconRef fullDisplayTextOfExnRefAsLayout ecref
let mainDescription = toRichText layout
let remarks = toRichText remarks
ToolTipElement.Single (mainDescription, xml, remarks=remarks, ?symbol = symbol)
Expand Down Expand Up @@ -388,7 +387,7 @@ module DeclarationListHelpers =
showDocumentation = false }
let layout = layoutTyconDefn denv infoReader ad m (* width *) tcref.Deref
let layout = PrintUtilities.squashToWidth width layout
let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfTyconRefAsLayout tcref
let remarks = OutputFullName displayFullName hasPubPathTyconRef fullDisplayTextOfTyconRefAsLayout tcref
let mainDescription = toRichText layout
let remarks = toRichText remarks
ToolTipElement.Single (mainDescription, xml, remarks=remarks, ?symbol = symbol)
Expand Down
8 changes: 6 additions & 2 deletions src/Compiler/Symbols/Exprs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,11 @@ module FSharpExprConvert =
|> Seq.filter (fun v ->
(v.CompiledName g.CompilerGlobalState) = vName &&
match v.TryDeclaringEntity with
| Parent p -> p.PublicPath = enclosingEntity.PublicPath
| Parent p ->
(match p.PublicPath, enclosingEntity.PublicPath with
| ValueSome pp1, ValueSome pp2 -> pubPathEq pp1 pp2
| ValueNone, ValueNone -> true
| _ -> false)
| _ -> false
) |> List.ofSeq
match findModuleMemberByName with
Expand Down Expand Up @@ -1205,7 +1209,7 @@ module FSharpExprConvert =
let argCount = (List.sumBy List.length argTys) + (if isStatic then 0 else 1)
let key = ValLinkageFullKey({ MemberParentMangledName=memberParentName; MemberIsOverride=false; LogicalName=logicalName; TotalArgCount= argCount }, Some linkageType)

let (PubPath p) = tcref.PublicPath.Value
let p = tcref.PublicPath.Value.FullPath
let enclosingNonLocalRef = mkNonLocalEntityRef tcref.nlr.Ccu p
let vref = mkNonLocalValRef enclosingNonLocalRef key
makeFSExpr isMember vref
Expand Down
68 changes: 36 additions & 32 deletions src/Compiler/TypedTree/TypedTree.fs
Original file line number Diff line number Diff line change
Expand Up @@ -556,15 +556,6 @@ type ModuleOrNamespaceKind =
| ModuleOrType -> 1
| Namespace _ -> 2

/// A public path records where a construct lives within the global namespace
/// of a CCU.
type PublicPath =
| PubPath of string[]
member x.EnclosingPath =
let (PubPath pp) = x
assert (pp.Length >= 1)
pp[0..pp.Length-2]

/// Represents the specified visibility of the accessibility -- used to ensure IL visibility
[<RequireQualifiedAccess>]
type SyntaxAccess =
Expand All @@ -583,9 +574,7 @@ type CompilationPath =

member x.MangledPath = List.map fst x.AccessPath

member x.NestedPublicPath (id: Ident) = PubPath(Array.append (Array.ofList x.MangledPath) [| id.idText |])

member x.ParentCompPath =
member x.ParentCompPath =
let a, _ = List.frontAndBack x.AccessPath
CompPath(x.ILScopeRef, x.SyntaxAccess, a)

Expand All @@ -603,6 +592,31 @@ type CompilationPath =

member x.SyntaxAccess = let (CompPath(_, access, _)) = x in access

[<Struct; NoEquality; NoComparison>]
type PublicPath =
| PubPath of enclosing: CompilationPath * name: string

member x.EnclosingCompilationPath = let (PubPath(cp, _)) = x in cp

member x.Name = let (PubPath(_, nm)) = x in nm

member x.EnclosingPath: string[] = Array.ofList x.EnclosingCompilationPath.MangledPath

member x.FullPath: string[] =
let enclosing = x.EnclosingCompilationPath.MangledPath
let res = Array.zeroCreate (List.length enclosing + 1)
let mutable i = 0

for nm in enclosing do
res[i] <- nm
i <- i + 1

res[i] <- x.Name
res

member x.HasEmptyEnclosingPath = List.isEmpty x.EnclosingCompilationPath.AccessPath


[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
type EntityOptionalData =
{
Expand Down Expand Up @@ -693,12 +707,7 @@ type Entity =
// when compiling fslib to fixup compiler forward references to internal items
mutable entity_modul_type: MaybeLazy<ModuleOrNamespaceType>

/// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2
// REVIEW: it looks like entity_cpath subsumes this
// MUTABILITY: only for unpickle linkage
mutable entity_pubpath: PublicPath option

/// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2
/// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2
// MUTABILITY: only for unpickle linkage
mutable entity_cpath: CompilationPath option

Expand Down Expand Up @@ -960,7 +969,10 @@ type Entity =
| c -> c

/// Get a blob of data indicating how this type is nested in other namespaces, modules or types.
member x.PublicPath = x.entity_pubpath
member x.PublicPath: PublicPath voption =
match x.entity_cpath with
| Some cpath -> ValueSome(PubPath(cpath, x.entity_logical_name))
| None -> ValueNone

/// Get the value representing the accessibility of an F# type definition or module.
member x.Accessibility =
Expand Down Expand Up @@ -1106,7 +1118,6 @@ type Entity =
entity_tycon_repr= Unchecked.defaultof<_>
entity_tycon_tcaug= Unchecked.defaultof<_>
entity_modul_type= Unchecked.defaultof<_>
entity_pubpath = Unchecked.defaultof<_>
entity_cpath = Unchecked.defaultof<_>
entity_il_repr_cache = Unchecked.defaultof<_>
entity_opt_data = Unchecked.defaultof<_>}
Expand All @@ -1125,8 +1136,7 @@ type Entity =
x.entity_tycon_repr <- tg.entity_tycon_repr
x.entity_tycon_tcaug <- tg.entity_tycon_tcaug
x.entity_modul_type <- tg.entity_modul_type
x.entity_pubpath <- tg.entity_pubpath
x.entity_cpath <- tg.entity_cpath
x.entity_cpath <- tg.entity_cpath
x.entity_il_repr_cache <- tg.entity_il_repr_cache
match tg.entity_opt_data with
| Some tg ->
Expand Down Expand Up @@ -3287,9 +3297,9 @@ type Val =
member x.PublicPath =
match x.TryDeclaringEntity with
| Parent eref ->
match eref.PublicPath with
| None -> None
| Some p -> Some(ValPubPath(p, x.GetLinkageFullKey()))
match eref.PublicPath with
| ValueNone -> None
| ValueSome p -> Some(ValPubPath(p, x.GetLinkageFullKey()))
| ParentNone ->
None

Expand Down Expand Up @@ -3946,7 +3956,7 @@ type EntityRef =
member x.CompiledReprCache = x.Deref.CompiledReprCache

/// Get a blob of data indicating how this type is nested in other namespaces, modules or types.
member x.PublicPath: PublicPath option = x.Deref.PublicPath
member x.PublicPath: PublicPath voption = x.Deref.PublicPath

/// Get the value representing the accessibility of an F# type definition or module.
member x.Accessibility = x.Deref.Accessibility
Expand Down Expand Up @@ -6324,7 +6334,6 @@ type Construct() =
static member NewProvidedTycon(resolutionEnvironment, st: Tainted<ProvidedType>, importProvidedType, isSuppressRelocate, m, ?access, ?cpath) =
let stamp = newStamp()
let name = st.PUntaint((fun st -> st.Name), m)
let id = ident (name, m)
let kind =
let isMeasure =
st.PApplyWithProvider((fun (st, provider) ->
Expand All @@ -6344,7 +6353,6 @@ type Construct() =
let enclosingName = GetFSharpPathToProvidedType(st, m)
CompPath(ilScopeRef, SyntaxAccess.Unknown, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace true))
| Some p -> p
let pubpath = cpath.NestedPublicPath id

let repr = Construct.NewProvidedTyconRepr(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m)

Expand All @@ -6359,7 +6367,6 @@ type Construct() =
entity_tycon_tcaug=TyconAugmentation.Create()
entity_modul_type = MaybeLazy.Lazy(InterruptibleLazy(fun _ -> ModuleOrNamespaceType(Namespace true, QueueList.ofList [], QueueList.ofList [])))
// Generated types get internal accessibility
entity_pubpath = Some pubpath
entity_cpath = Some cpath
entity_il_repr_cache = null
entity_opt_data =
Expand All @@ -6383,7 +6390,6 @@ type Construct() =
entity_typars=LazyWithContext.NotLazy []
entity_tycon_repr = TNoRepr
entity_tycon_tcaug=TyconAugmentation.Create()
entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id)
entity_cpath=cpath
entity_attribs=WellKnownEntityAttribs.Create(attribs)
entity_il_repr_cache = null
Expand Down Expand Up @@ -6458,7 +6464,6 @@ type Construct() =
entity_logical_name = id.idText
entity_range = id.idRange
entity_tycon_tcaug = TyconAugmentation.Create()
entity_pubpath = cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id)
entity_modul_type = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType)
entity_cpath = cpath
entity_typars = LazyWithContext.NotLazy []
Expand Down Expand Up @@ -6501,7 +6506,6 @@ type Construct() =
entity_tycon_repr = TNoRepr
entity_tycon_tcaug=TyconAugmentation.Create()
entity_modul_type = mtyp
entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath (mkSynId m nm))
entity_cpath = cpath
entity_il_repr_cache = null
entity_opt_data =
Expand Down
34 changes: 20 additions & 14 deletions src/Compiler/TypedTree/TypedTree.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,6 @@ type ModuleOrNamespaceKind =
/// If false, this namespace was implicitly constructed during type checking.
isExplicit: bool

/// A public path records where a construct lives within the global namespace
/// of a CCU.
type PublicPath =
| PubPath of string[]

member EnclosingPath: string[]

/// Represents the specified visibility of the accessibility -- used to ensure IL visibility
[<RequireQualifiedAccess>]
type SyntaxAccess =
Expand All @@ -364,8 +357,6 @@ type CompilationPath =

member NestedCompPath: n: string -> moduleKind: ModuleOrNamespaceKind -> CompilationPath

member NestedPublicPath: id: Ident -> PublicPath

member AccessPath: (string * ModuleOrNamespaceKind) list

member DemangledPath: string list
Expand All @@ -378,6 +369,24 @@ type CompilationPath =

member SyntaxAccess: SyntaxAccess

/// A public path records where a construct lives within the global namespace of a CCU.
///
/// Comparison goes through pubPathEq: derived equality would also compare the enclosing path's
/// ILScopeRef and SyntaxAccess, besides boxing this struct.
[<Struct; NoEquality; NoComparison>]
type PublicPath =
| PubPath of enclosing: CompilationPath * name: string

member EnclosingCompilationPath: CompilationPath

member Name: string

member EnclosingPath: string[]

member FullPath: string[]

member HasEmptyEnclosingPath: bool

[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
type EntityOptionalData =
{
Expand Down Expand Up @@ -449,9 +458,6 @@ type Entity =
/// This field is used when the 'tycon' is really a module definition. It holds statically nested type definitions type nested modules
mutable entity_modul_type: MaybeLazy<ModuleOrNamespaceType>

/// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2
mutable entity_pubpath: PublicPath option

/// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2
mutable entity_cpath: CompilationPath option

Expand Down Expand Up @@ -768,7 +774,7 @@ type Entity =
member PreEstablishedHasDefaultConstructor: bool

/// Get a blob of data indicating how this type is nested in other namespaces, modules or types.
member PublicPath: PublicPath option
member PublicPath: PublicPath voption

/// The code location where the module, namespace or type is defined.
member Range: range
Expand Down Expand Up @@ -2750,7 +2756,7 @@ type EntityRef =
member PreEstablishedHasDefaultConstructor: bool

/// Get a blob of data indicating how this type is nested in other namespaces, modules or types.
member PublicPath: PublicPath option
member PublicPath: PublicPath voption

/// The code location where the module, namespace or type is defined.
member Range: range
Expand Down
Loading
Loading