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
2 changes: 1 addition & 1 deletion src/fsharp/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2604,7 +2604,7 @@ let CodegenWitnessThatTypSupportsTraitConstraint tcVal g amap m (traitInfo:Trait
| Some sln ->
match sln with
| ILMethSln(origTy, extOpt, mref, minst) ->
let metadataTy = helpEnsureTypeHasMetadata g origTy
let metadataTy = convertToTypeWithMetadataIfPossible g origTy
let tcref, _tinst = destAppTy g metadataTy
let mdef = IL.resolveILMethodRef tcref.ILTyconRawMetadata mref
let ilMethInfo =
Expand Down
8 changes: 4 additions & 4 deletions src/fsharp/InfoReader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ let rec GetImmediateIntrinsicMethInfosOfTypeAux (optFilter,ad) g amap m origTy m
// Tuple types also support the methods get_Item1-8, get_Rest from the compiled tuple type.
// In this case convert to the .NET Tuple type that carries metadata and try again
if isAnyTupleTy g metadataTy then
let betterMetadataTy = helpEnsureTypeHasMetadata g metadataTy
let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
GetImmediateIntrinsicMethInfosOfTypeAux (optFilter,ad) g amap m origTy betterMetadataTy
// Function types support methods FSharpFunc<_,_>.FromConverter and friends from .NET metadata,
// but not instance methods (you can't write "f.Invoke(x)", you have to write "f x")
elif isFunTy g metadataTy then
let betterMetadataTy = helpEnsureTypeHasMetadata g metadataTy
let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
GetImmediateIntrinsicMethInfosOfTypeAux (optFilter,ad) g amap m origTy betterMetadataTy
|> List.filter (fun minfo -> not minfo.IsInstance)
else
Expand Down Expand Up @@ -165,7 +165,7 @@ let rec GetImmediateIntrinsicPropInfosOfTypeAux (optFilter,ad) g amap m origTy m
// Tuple types also support the properties Item1-8, Rest from the compiled tuple type
// In this case convert to the .NET Tuple type that carries metadata and try again
if isAnyTupleTy g metadataTy || isFunTy g metadataTy then
let betterMetadataTy = helpEnsureTypeHasMetadata g metadataTy
let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
GetImmediateIntrinsicPropInfosOfTypeAux (optFilter,ad) g amap m origTy betterMetadataTy
else
match tryDestAppTy g metadataTy with
Expand Down Expand Up @@ -465,7 +465,7 @@ let rec GetIntrinsicConstructorInfosOfTypeAux (infoReader:InfoReader) m origTy m
// Tuple types also support constructors. In this case convert to the .NET Tuple type that carries metadata and try again
// Function types also support constructors. In this case convert to the FSharpFunc type that carries metadata and try again
if isAnyTupleTy g metadataTy || isFunTy g metadataTy then
let betterMetadataTy = helpEnsureTypeHasMetadata g metadataTy
let betterMetadataTy = convertToTypeWithMetadataIfPossible g metadataTy
GetIntrinsicConstructorInfosOfTypeAux infoReader m origTy betterMetadataTy
else
match tryDestAppTy g metadataTy with
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1889,7 +1889,7 @@ let private ResolveObjectConstructorPrim (ncenv:NameResolver) edenv resInfo m ad
raze (Error(FSComp.SR.nrNoConstructorsAvailableForType(NicePrint.minimalStringOfType edenv typ),m))
else
let ctorInfos = ctorInfos |> List.filter (IsMethInfoAccessible amap m ad)
let metadataTy = helpEnsureTypeHasMetadata g typ
let metadataTy = convertToTypeWithMetadataIfPossible g typ
success (resInfo,Item.MakeCtorGroup ((tcrefOfAppTy g metadataTy).LogicalName, (defaultStructCtorInfo@ctorInfos)))

/// Perform name resolution for an identifier which must resolve to be an object constructor.
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/TastOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ let mkInstForAppTy g typ =
let domainOfFunTy g ty = fst (destFunTy g ty)
let rangeOfFunTy g ty = snd (destFunTy g ty)

let helpEnsureTypeHasMetadata g ty =
let convertToTypeWithMetadataIfPossible g ty =
if isAnyTupleTy g ty then
let (tupInfo, tupElemTys) = destAnyTupleTy g ty
mkOuterCompiledTupleTy g (evalTupInfoIsStruct tupInfo) tupElemTys
Expand Down
2 changes: 1 addition & 1 deletion src/fsharp/TastOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ val mkGetTupleItemN : TcGlobals -> range -> int -> ILType -> bool -> Expr -> TTy
val evalTupInfoIsStruct : TupInfo -> bool

/// If it is a tuple type, ensure it's outermost type is a .NET tuple type, otherwise leave unchanged
val helpEnsureTypeHasMetadata : TcGlobals -> TType -> TType
val convertToTypeWithMetadataIfPossible : TcGlobals -> TType -> TType


//-------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/TypeChecker.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4923,7 +4923,7 @@ and TcTypeAndRecover cenv newOk checkCxs occ env tpenv ty =
TcTypeOrMeasureAndRecover (Some TyparKind.Type) cenv newOk checkCxs occ env tpenv ty

and TcNestedTypeApplication cenv newOk checkCxs occ env tpenv mWholeTypeApp typ tyargs =
let typ = helpEnsureTypeHasMetadata cenv.g typ
let typ = convertToTypeWithMetadataIfPossible cenv.g typ
if not (isAppTy cenv.g typ) then error(Error(FSComp.SR.tcTypeHasNoNestedTypes(), mWholeTypeApp))
match typ with
| TType_app(tcref, tinst) ->
Expand Down Expand Up @@ -13226,7 +13226,7 @@ module MutRecBindingChecking =
// Phase2B: typecheck the argument to an 'inherits' call and build the new object expr for the inherit-call
| Phase2AInherit (synBaseTy, arg, baseValOpt, m) ->
let baseTy, tpenv = TcType cenv NoNewTypars CheckCxs ItemOccurence.Use envInstance tpenv synBaseTy
let baseTy = baseTy |> helpEnsureTypeHasMetadata cenv.g
let baseTy = baseTy |> convertToTypeWithMetadataIfPossible cenv.g
let inheritsExpr, tpenv = TcNewExpr cenv envInstance tpenv baseTy (Some synBaseTy.Range) true arg m
let envInstance = match baseValOpt with Some baseVal -> AddLocalVal cenv.tcSink scopem baseVal envInstance | None -> envInstance
let envNonRec = match baseValOpt with Some baseVal -> AddLocalVal cenv.tcSink scopem baseVal envNonRec | None -> envNonRec
Expand Down
32 changes: 18 additions & 14 deletions src/fsharp/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ type ILTypeInfo =
member x.ToType = let (ILTypeInfo(_,ty,_,_)) = x in ty

/// Get the compiled nominal type. In the case of tuple types, this is a .NET tuple type
member x.ToAppType = helpEnsureTypeHasMetadata x.TcGlobals x.ToType
member x.ToAppType = convertToTypeWithMetadataIfPossible x.TcGlobals x.ToType

member x.TyconRefOfRawMetadata = tcrefOfAppTy x.TcGlobals x.ToAppType

Expand All @@ -690,7 +690,7 @@ type ILTypeInfo =
if isAnyTupleTy g ty then
// When getting .NET metadata for the properties and methods
// of an F# tuple type, use the compiled nominal type, which is a .NET tuple type
let metadataTy = helpEnsureTypeHasMetadata g ty
let metadataTy = convertToTypeWithMetadataIfPossible g ty
assert (isILAppTy g metadataTy)
let metadataTyconRef = tcrefOfAppTy g metadataTy
let (TILObjectReprData(scoref, enc, tdef)) = metadataTyconRef.ILTyconInfo
Expand Down Expand Up @@ -727,7 +727,7 @@ type ILMethInfo =
member x.ApparentEnclosingType = match x with ILMethInfo(_,ty,_,_,_) -> ty

/// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type
member x.ApparentEnclosingAppType = helpEnsureTypeHasMetadata x.TcGlobals x.ApparentEnclosingType
member x.ApparentEnclosingAppType = convertToTypeWithMetadataIfPossible x.TcGlobals x.ApparentEnclosingType

/// Get the declaring type associated with an extension member, if any.
member x.ILExtensionMethodDeclaringTyconRef = match x with ILMethInfo(_,_,tcrefOpt,_,_) -> tcrefOpt
Expand Down Expand Up @@ -897,9 +897,7 @@ type MethInfo =

/// Get the enclosing type of the method info, using a nominal type for tuple types
member x.ApparentEnclosingAppType =
match x with
| ILMeth(_,ilminfo,_) -> ilminfo.ApparentEnclosingAppType
| _ -> x.ApparentEnclosingType
convertToTypeWithMetadataIfPossible x.TcGlobals x.ApparentEnclosingType

member x.ApparentEnclosingTyconRef =
tcrefOfAppTy x.TcGlobals x.ApparentEnclosingAppType
Expand Down Expand Up @@ -1005,7 +1003,8 @@ type MethInfo =
member x.FormalMethodTypars =
match x with
| ILMeth(_,ilmeth,_) -> ilmeth.FormalMethodTypars
| FSMeth(g,typ,vref,_) ->
| FSMeth(g,_,vref,_) ->
let typ = x.ApparentEnclosingAppType
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, yes. However there are a few other paths to AnalyzeTypeOfMemberVal, which is assuming that typ is an AppTy, e.g. via GetCompiledReturnTy and GetParamTypes which I think will also fail. I'm surprised we're not hitting those

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dsyme, yes I was going to look through those today. The trick is figuring out the repro, as you say, with all this code base none hit it.

let _,memberMethodTypars,_,_ = AnalyzeTypeOfMemberVal x.IsCSharpStyleExtensionMember g (typ,vref)
memberMethodTypars
| DefaultStructCtor _ -> []
Expand Down Expand Up @@ -1283,7 +1282,8 @@ type MethInfo =
match x with
| ILMeth(_g,ilminfo,_) ->
ilminfo.GetCompiledReturnTy(amap, m, minst)
| FSMeth(g,typ,vref,_) ->
| FSMeth(g,_,vref,_) ->
let typ = x.ApparentEnclosingAppType
let inst = GetInstantiationForMemberVal g x.IsCSharpStyleExtensionMember (typ,vref,minst)
let _,_,retTy,_ = AnalyzeTypeOfMemberVal x.IsCSharpStyleExtensionMember g (typ,vref)
retTy |> Option.map (instType inst)
Expand Down Expand Up @@ -1320,8 +1320,9 @@ type MethInfo =
member x.GetObjArgTypes (amap, m, minst) =
match x with
| ILMeth(_,ilminfo,_) -> ilminfo.GetObjArgTypes(amap, m, minst)
| FSMeth(g,typ,vref,_) ->
| FSMeth(g,_,vref,_) ->
if x.IsInstance then
let typ = x.ApparentEnclosingAppType
// The 'this' pointer of an extension member can depend on the minst
if x.IsExtensionMember then
let inst = GetInstantiationForMemberVal g x.IsCSharpStyleExtensionMember (typ,vref,minst)
Expand Down Expand Up @@ -1521,7 +1522,8 @@ type MethInfo =
match x with
| ILMeth(_g,ilminfo,_) ->
[ ilminfo.GetParamNamesAndTypes(amap,m,minst) ]
| FSMeth(g,typ,vref,_) ->
| FSMeth(g,_,vref,_) ->
let typ = x.ApparentEnclosingAppType
let items = ParamNameAndType.FromMember x.IsCSharpStyleExtensionMember g vref
let inst = GetInstantiationForMemberVal g x.IsCSharpStyleExtensionMember (typ,vref,minst)
items |> ParamNameAndType.InstantiateCurried inst
Expand Down Expand Up @@ -1561,7 +1563,8 @@ type MethInfo =
if x.IsExtensionMember then []
else
match x with
| FSMeth(g,typ,vref,_) ->
| FSMeth(g,_,vref,_) ->
let typ = x.ApparentEnclosingAppType
let memberParentTypars,_,_,_ = AnalyzeTypeOfMemberVal false g (typ,vref)
memberParentTypars
| _ ->
Expand Down Expand Up @@ -1790,7 +1793,7 @@ type ILPropInfo =
member x.ApparentEnclosingType = match x with ILPropInfo(tinfo,_) -> tinfo.ToType

/// Like ApparentEnclosingType but use the compiled nominal type if this is a method on a tuple type
member x.ApparentEnclosingAppType = helpEnsureTypeHasMetadata x.TcGlobals x.ApparentEnclosingType
member x.ApparentEnclosingAppType = convertToTypeWithMetadataIfPossible x.TcGlobals x.ApparentEnclosingType

/// Get the raw Abstract IL metadata for the IL property
member x.RawMetadata = match x with ILPropInfo(_,pd) -> pd
Expand Down Expand Up @@ -2096,8 +2099,9 @@ type PropInfo =
member x.GetPropertyType (amap,m) =
match x with
| ILProp ilpinfo -> ilpinfo.GetPropertyType (amap,m)
| FSProp (g,typ,Some vref,_)
| FSProp (g,typ,_,Some vref) ->
| FSProp (g,_,Some vref,_)
| FSProp (g,_,_,Some vref) ->
let typ = x.ApparentEnclosingAppType
let inst = GetInstantiationForPropertyVal g (typ,vref)
ReturnTypeOfPropertyVal g vref.Deref |> instType inst

Expand Down