Skip to content

Commit

Permalink
Merge pull request #8254 from dsyme/pre-ext
Browse files Browse the repository at this point in the history
pre-cleanup related to #6805
  • Loading branch information
KevinRansom authored Jan 18, 2020
2 parents 0595fec + c0cc024 commit 27d4652
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 177 deletions.
73 changes: 45 additions & 28 deletions src/fsharp/ConstraintSolver.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,48 @@ val FreshenMethInfo : range -> MethInfo -> TType list
[<RequireQualifiedAccess>]
/// Information about the context of a type equation.
type ContextInfo =
/// No context was given.
| NoContext
/// The type equation comes from an IF expression.
| IfExpression of range
/// The type equation comes from an omitted else branch.
| OmittedElseBranch of range
/// The type equation comes from a type check of the result of an else branch.
| ElseBranchResult of range
/// The type equation comes from the verification of record fields.
| RecordFields
/// The type equation comes from the verification of a tuple in record fields.
| TupleInRecordFields
/// The type equation comes from a list or array constructor
| CollectionElement of bool * range
/// The type equation comes from a return in a computation expression.
| ReturnInComputationExpression
/// The type equation comes from a yield in a computation expression.
| YieldInComputationExpression
/// The type equation comes from a runtime type test.
| RuntimeTypeTest of bool
/// The type equation comes from an downcast where a upcast could be used.
| DowncastUsedInsteadOfUpcast of bool
/// The type equation comes from a return type of a pattern match clause (not the first clause).
| FollowingPatternMatchClause of range
/// The type equation comes from a pattern match guard.
| PatternMatchGuard of range
/// The type equation comes from a sequence expression.
| SequenceExpression of TType

/// No context was given.
| NoContext

/// The type equation comes from an IF expression.
| IfExpression of range

/// The type equation comes from an omitted else branch.
| OmittedElseBranch of range

/// The type equation comes from a type check of the result of an else branch.
| ElseBranchResult of range

/// The type equation comes from the verification of record fields.
| RecordFields

/// The type equation comes from the verification of a tuple in record fields.
| TupleInRecordFields

/// The type equation comes from a list or array constructor
| CollectionElement of bool * range

/// The type equation comes from a return in a computation expression.
| ReturnInComputationExpression

/// The type equation comes from a yield in a computation expression.
| YieldInComputationExpression

/// The type equation comes from a runtime type test.
| RuntimeTypeTest of bool

/// The type equation comes from an downcast where a upcast could be used.
| DowncastUsedInsteadOfUpcast of bool

/// The type equation comes from a return type of a pattern match clause (not the first clause).
| FollowingPatternMatchClause of range

/// The type equation comes from a pattern match guard.
| PatternMatchGuard of range

/// The type equation comes from a sequence expression.
| SequenceExpression of TType

exception ConstraintSolverTupleDiffLengths of displayEnv: DisplayEnv * TType list * TType list * range * range
exception ConstraintSolverInfiniteTypes of displayEnv: DisplayEnv * contextInfo: ContextInfo * TType * TType * range * range
Expand Down Expand Up @@ -116,7 +130,10 @@ type OptionalTrace =
val SimplifyMeasuresInTypeScheme : TcGlobals -> bool -> Typars -> TType -> TyparConstraint list -> Typars
val SolveTyparEqualsType : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult<unit>
val SolveTypeEqualsTypeKeepAbbrevs : ConstraintSolverEnv -> int -> range -> OptionalTrace -> TType -> TType -> OperationResult<unit>

/// Canonicalize constraints prior to generalization
val CanonicalizeRelevantMemberConstraints : ConstraintSolverEnv -> int -> OptionalTrace -> Typars -> OperationResult<unit>

val ResolveOverloading : ConstraintSolverEnv -> OptionalTrace -> string -> ndeep: int -> TraitConstraintInfo option -> int * int -> AccessorDomain -> CalledMeth<Expr> list -> bool -> TType option -> CalledMeth<Expr> option * OperationResult<unit>
val UnifyUniqueOverloading : ConstraintSolverEnv -> int * int -> string -> AccessorDomain -> CalledMeth<SynExpr> list -> TType -> OperationResult<bool>
val EliminateConstraintsForGeneralizedTypars : ConstraintSolverEnv -> OptionalTrace -> Typars -> unit
Expand Down
10 changes: 5 additions & 5 deletions src/fsharp/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5273,7 +5273,7 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) s
// Workaround for .NET and Visual Studio restriction w.r.t debugger type proxys
// Mark internal constructors in internal classes as public.
let access =
if access = ILMemberAccess.Assembly && vspec.IsConstructor && IsHiddenTycon g eenv.sigToImplRemapInfo vspec.MemberApparentEntity.Deref then
if access = ILMemberAccess.Assembly && vspec.IsConstructor && IsHiddenTycon eenv.sigToImplRemapInfo vspec.MemberApparentEntity.Deref then
ILMemberAccess.Public
else
access
Expand Down Expand Up @@ -6488,7 +6488,7 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la
GenLetRecBindings cenv cgbuf eenv ([bind], m)

| ModuleOrNamespaceBinding.Module (mspec, mdef) ->
let hidden = IsHiddenTycon cenv.g eenv.sigToImplRemapInfo mspec
let hidden = IsHiddenTycon eenv.sigToImplRemapInfo mspec

let eenvinner =
if mspec.IsNamespace then eenv else
Expand Down Expand Up @@ -6827,8 +6827,8 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) =
let ilIntfTys = tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.map (GenType cenv.amap m eenvinner.tyenv)
let ilTypeName = tref.Name

let hidden = IsHiddenTycon g eenv.sigToImplRemapInfo tycon
let hiddenRepr = hidden || IsHiddenTyconRepr g eenv.sigToImplRemapInfo tycon
let hidden = IsHiddenTycon eenv.sigToImplRemapInfo tycon
let hiddenRepr = hidden || IsHiddenTyconRepr eenv.sigToImplRemapInfo tycon
let access = ComputeTypeAccess tref hidden

// The implicit augmentation doesn't actually create CompareTo(object) or Object.Equals
Expand Down Expand Up @@ -7411,7 +7411,7 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
| TExnFresh _ ->
let ilThisTy = GenExnType cenv.amap m eenv.tyenv exncref
let tref = ilThisTy.TypeRef
let isHidden = IsHiddenTycon g eenv.sigToImplRemapInfo exnc
let isHidden = IsHiddenTycon eenv.sigToImplRemapInfo exnc
let access = ComputeTypeAccess tref isHidden
let reprAccess = ComputeMemberAccess isHidden
let fspecs = exnc.TrueInstanceFieldsAsList
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/InfoReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ open FSharp.Compiler.Tastops
open FSharp.Compiler.TcGlobals

/// Use the given function to select some of the member values from the members of an F# type
let private SelectImmediateMemberVals g optFilter f (tcref: TyconRef) =
let SelectImmediateMemberVals g optFilter f (tcref: TyconRef) =
let chooser (vref: ValRef) =
match vref.MemberInfo with
// The 'when' condition is a workaround for the fact that values providing
Expand Down
7 changes: 7 additions & 0 deletions src/fsharp/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ type CalledMeth<'T>

member x.TotalNumAssignedNamedArgs = x.ArgSets |> List.sumBy (fun x -> x.NumAssignedNamedArgs)

override x.ToString() = "call to " + minfo.ToString()

let NamesOfCalledArgs (calledArgs: CalledArg list) =
calledArgs |> List.choose (fun x -> x.NameOpt)

Expand Down Expand Up @@ -1050,15 +1052,20 @@ let BuildFSharpMethodCall g m (ty, vref: ValRef) valUseFlags minst args =
/// calls to the type-directed solutions to member constraints.
let MakeMethInfoCall amap m minfo minst args =
let valUseFlags = NormalValUse // correct unless if we allow wild trait constraints like "T has a ctor and can be used as a parent class"

match minfo with

| ILMeth(g, ilminfo, _) ->
let direct = not minfo.IsVirtual
let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant
BuildILMethInfoCall g amap m isProp ilminfo valUseFlags minst direct args |> fst

| FSMeth(g, ty, vref, _) ->
BuildFSharpMethodCall g m (ty, vref) valUseFlags minst args |> fst

| DefaultStructCtor(_, ty) ->
mkDefault (m, ty)

#if !NO_EXTENSIONTYPING
| ProvidedMeth(amap, mi, _, m) ->
let isProp = false // not necessarily correct, but this is only used post-creflect where this flag is irrelevant
Expand Down
37 changes: 21 additions & 16 deletions src/fsharp/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -550,15 +550,30 @@ let AllPropInfosOfTypeInScope collectionSettings infoReader nenv optFilter ad fi
@ ExtensionPropInfosOfTypeInScope collectionSettings infoReader nenv optFilter ad m ty

/// Get the available methods of a type (both declared and inherited)
let IntrinsicMethInfosOfType (infoReader:InfoReader) optFilter ad allowMultiIntfInst findFlag m ty =
let IntrinsicMethInfosOfType (infoReader: InfoReader) optFilter ad allowMultiIntfInst findFlag m ty =
let g = infoReader.g
let amap = infoReader.amap
let minfos = GetIntrinsicMethInfoSetsOfType infoReader optFilter ad allowMultiIntfInst findFlag m ty
let minfos = minfos |> ExcludeHiddenOfMethInfos g amap m
minfos

let TrySelectExtensionMethInfoOfILExtMem m amap apparentTy (actualParent, minfo, pri) =
match minfo with
| ILMeth(_,ilminfo,_) ->
MethInfo.CreateILExtensionMeth (amap, m, apparentTy, actualParent, Some pri, ilminfo.RawMetadata) |> Some
// F#-defined IL-style extension methods are not seen as extension methods in F# code
| FSMeth(g,_,vref,_) ->
FSMeth(g, apparentTy, vref, Some pri) |> Some
#if !NO_EXTENSIONTYPING
// // Provided extension methods are not yet supported
| ProvidedMeth(amap,providedMeth,_,m) ->
ProvidedMeth(amap, providedMeth, Some pri,m) |> Some
#endif
| DefaultStructCtor _ ->
None

/// Select from a list of extension methods
let SelectMethInfosFromExtMembers (infoReader:InfoReader) optFilter apparentTy m extMemInfos =
let SelectMethInfosFromExtMembers (infoReader: InfoReader) optFilter apparentTy m extMemInfos =
let g = infoReader.g
// NOTE: multiple "open"'s push multiple duplicate values into eIndexedExtensionMembers
let seen = HashSet(ExtensionMember.Comparer g)
Expand All @@ -575,24 +590,14 @@ let SelectMethInfosFromExtMembers (infoReader:InfoReader) optFilter apparentTy m
| _ -> ()
| ILExtMem (actualParent, minfo, pri) when (match optFilter with None -> true | Some nm -> nm = minfo.LogicalName) ->
// Make a reference to the type containing the extension members
match minfo with
| ILMeth(_, ilminfo, _) ->
yield (MethInfo.CreateILExtensionMeth (infoReader.amap, m, apparentTy, actualParent, Some pri, ilminfo.RawMetadata))
// F#-defined IL-style extension methods are not seen as extension methods in F# code
| FSMeth(g, _, vref, _) ->
yield (FSMeth(g, apparentTy, vref, Some pri))
#if !NO_EXTENSIONTYPING
// // Provided extension methods are not yet supported
| ProvidedMeth(amap, providedMeth, _, m) ->
yield (ProvidedMeth(amap, providedMeth, Some pri, m))
#endif
| DefaultStructCtor _ ->
()
match TrySelectExtensionMethInfoOfILExtMem m infoReader.amap apparentTy (actualParent, minfo, pri) with
| Some minfo -> yield minfo
| None -> ()
| _ -> ()
]

/// Query the available extension properties of a methods (including extension methods for inherited types)
let ExtensionMethInfosOfTypeInScope (collectionSettings:ResultCollectionSettings) (infoReader:InfoReader) (nenv: NameResolutionEnv) optFilter m ty =
let ExtensionMethInfosOfTypeInScope (collectionSettings: ResultCollectionSettings) (infoReader: InfoReader) (nenv: NameResolutionEnv) optFilter m ty =
let extMemsDangling = SelectMethInfosFromExtMembers infoReader optFilter ty m nenv.eUnindexedExtensionMembers
if collectionSettings = ResultCollectionSettings.AtMostOneResult && not (isNil extMemsDangling) then
extMemsDangling
Expand Down
76 changes: 61 additions & 15 deletions src/fsharp/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -141,25 +141,68 @@ val ItemWithNoInst : Item -> ItemWithInst
type FieldResolution = FieldResolution of RecdFieldRef * bool

/// Information about an extension member held in the name resolution environment
[<Sealed>]
type ExtensionMember
type ExtensionMember =
/// F#-style Extrinsic extension member, defined in F# code
| FSExtMem of ValRef * ExtensionMethodPriority

/// ILExtMem(declaringTyconRef, ilMetadata, pri)
///
/// IL-style extension member, backed by some kind of method with an [<Extension>] attribute
| ILExtMem of TyconRef * MethInfo * ExtensionMethodPriority

/// Describes the sequence order of the introduction of an extension method. Extension methods that are introduced
/// later through 'open' get priority in overload resolution.
member Priority : ExtensionMethodPriority

/// The environment of information used to resolve names
[<NoEquality; NoComparison>]
type NameResolutionEnv =
{eDisplayEnv: DisplayEnv
eUnqualifiedItems: LayeredMap<string,Item>
ePatItems: NameMap<Item>
eModulesAndNamespaces: NameMultiMap<ModuleOrNamespaceRef>
eFullyQualifiedModulesAndNamespaces: NameMultiMap<ModuleOrNamespaceRef>
eFieldLabels: NameMultiMap<RecdFieldRef>
eTyconsByAccessNames: LayeredMultiMap<string,TyconRef>
eFullyQualifiedTyconsByAccessNames: LayeredMultiMap<string,TyconRef>
eTyconsByDemangledNameAndArity: LayeredMap<NameArityPair,TyconRef>
eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap<NameArityPair,TyconRef>
eIndexedExtensionMembers: TyconRefMultiMap<ExtensionMember>
eUnindexedExtensionMembers: ExtensionMember list
eTypars: NameMap<Typar> }
{ /// Display environment information for output
eDisplayEnv: DisplayEnv

/// Values and Data Tags available by unqualified name
eUnqualifiedItems: LayeredMap<string,Item>

/// Data Tags and Active Pattern Tags available by unqualified name
ePatItems: NameMap<Item>

/// Modules accessible via "." notation. Note this is a multi-map.
/// Adding a module abbreviation adds it a local entry to this List.map.
/// Likewise adding a ccu or opening a path adds entries to this List.map.
eModulesAndNamespaces: NameMultiMap<Tast.ModuleOrNamespaceRef>

/// Fully qualified modules and namespaces. 'open' does not change this.
eFullyQualifiedModulesAndNamespaces: NameMultiMap<Tast.ModuleOrNamespaceRef>

/// RecdField labels in scope. RecdField labels are those where type are inferred
/// by label rather than by known type annotation.
/// Bools indicate if from a record, where no warning is given on indeterminate lookup
eFieldLabels: NameMultiMap<Tast.RecdFieldRef>

/// Tycons indexed by the various names that may be used to access them, e.g.
/// "List" --> multiple TyconRef's for the various tycons accessible by this name.
/// "List`1" --> TyconRef
eTyconsByAccessNames: LayeredMultiMap<string,TyconRef>

eFullyQualifiedTyconsByAccessNames: LayeredMultiMap<string,TyconRef>

/// Tycons available by unqualified, demangled names (i.e. (List,1) --> TyconRef)
eTyconsByDemangledNameAndArity: LayeredMap<NameArityPair,TyconRef>

/// Tycons available by unqualified, demangled names (i.e. (List,1) --> TyconRef)
eFullyQualifiedTyconsByDemangledNameAndArity: LayeredMap<NameArityPair,TyconRef>

/// Extension members by type and name
eIndexedExtensionMembers: TyconRefMultiMap<ExtensionMember>

/// Other extension members unindexed by type
eUnindexedExtensionMembers: ExtensionMember list

/// Typars (always available by unqualified names). Further typars can be
/// in the tpenv, a structure folded through each top-level definition.
eTypars: NameMap<Typar>

}
static member Empty : g:TcGlobals -> NameResolutionEnv
member DisplayEnv : DisplayEnv
member FindUnqualifiedItem : string -> Item
Expand Down Expand Up @@ -545,3 +588,6 @@ val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> Resolv
val GetVisibleNamespacesAndModulesAtPoint : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> ModuleOrNamespaceRef list

val IsItemResolvable : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> Item -> bool

val TrySelectExtensionMethInfoOfILExtMem : range -> ImportMap -> TType -> TyconRef * MethInfo * ExtensionMethodPriority -> MethInfo option
6 changes: 3 additions & 3 deletions src/fsharp/PostInferenceChecks.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1926,8 +1926,8 @@ let CheckRecdField isUnion cenv env (tycon: Tycon) (rfield: RecdField) =
let m = rfield.Range
let fieldTy = stripTyEqns cenv.g rfield.FormalType
let isHidden =
IsHiddenTycon cenv.g env.sigToImplRemapInfo tycon ||
IsHiddenTyconRepr cenv.g env.sigToImplRemapInfo tycon ||
IsHiddenTycon env.sigToImplRemapInfo tycon ||
IsHiddenTyconRepr env.sigToImplRemapInfo tycon ||
(not isUnion && IsHiddenRecdField env.sigToImplRemapInfo (tcref.MakeNestedRecdFieldRef rfield))
let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility
CheckTypeForAccess cenv env (fun () -> rfield.Name) access m fieldTy
Expand Down Expand Up @@ -2189,7 +2189,7 @@ let CheckEntityDefn cenv env (tycon: Entity) =
uc.RecdFieldsArray |> Array.iter (CheckRecdField true cenv env tycon))

// Access checks
let access = AdjustAccess (IsHiddenTycon g env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility
let access = AdjustAccess (IsHiddenTycon env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility
let visitType ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty

abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType)
Expand Down
Loading

0 comments on commit 27d4652

Please sign in to comment.