Skip to content
This repository was archived by the owner on Dec 23, 2024. It is now read-only.

Commit 430d201

Browse files
dsymenosami
authored andcommitted
cleanup and pre-prep for dotnet#6810 (dotnet#8503)
1 parent a17b6ff commit 430d201

File tree

8 files changed

+219
-192
lines changed

8 files changed

+219
-192
lines changed

src/fsharp/ConstraintSolver.fs

Lines changed: 10 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,130 +3024,22 @@ let ApplyTyparDefaultAtPriority denv css priority (tp: Typar) =
30243024
|> RaiseOperationResult
30253025
| _ -> ())
30263026

3027+
let CreateCodegenState tcVal g amap =
3028+
{ g = g
3029+
amap = amap
3030+
TcVal = tcVal
3031+
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
3032+
InfoReader = new InfoReader(g, amap) }
3033+
30273034
let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors {
3028-
let css =
3029-
{ g = g
3030-
amap = amap
3031-
TcVal = tcVal
3032-
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
3033-
InfoReader = new InfoReader(g, amap) }
3035+
let css = CreateCodegenState tcVal g amap
30343036

30353037
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
30363038

30373039
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo
30383040

3039-
let sln =
3040-
match traitInfo.Solution with
3041-
| None -> Choice5Of5()
3042-
| Some sln ->
3043-
3044-
// Given the solution information, reconstruct the MethInfo for the solution
3045-
match sln with
3046-
| ILMethSln(origTy, extOpt, mref, minst) ->
3047-
let metadataTy = convertToTypeWithMetadataIfPossible g origTy
3048-
let tcref = tcrefOfAppTy g metadataTy
3049-
let mdef = IL.resolveILMethodRef tcref.ILTyconRawMetadata mref
3050-
let ilMethInfo =
3051-
match extOpt with
3052-
| None -> MethInfo.CreateILMeth(amap, m, origTy, mdef)
3053-
| Some ilActualTypeRef ->
3054-
let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef
3055-
MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef)
3056-
Choice1Of5 (ilMethInfo, minst)
3057-
3058-
| FSMethSln(ty, vref, minst) ->
3059-
Choice1Of5 (FSMeth(g, ty, vref, None), minst)
3060-
3061-
| FSRecdFieldSln(tinst, rfref, isSetProp) ->
3062-
Choice2Of5 (tinst, rfref, isSetProp)
3063-
3064-
| FSAnonRecdFieldSln(anonInfo, tinst, i) ->
3065-
Choice3Of5 (anonInfo, tinst, i)
3066-
3067-
| BuiltInSln ->
3068-
Choice5Of5 ()
3069-
3070-
| ClosedExprSln expr ->
3071-
Choice4Of5 expr
3072-
return!
3073-
match sln with
3074-
| Choice1Of5(minfo, methArgTys) ->
3075-
let argExprs =
3076-
// FIX for #421894 - typechecker assumes that coercion can be applied for the trait calls arguments but codegen doesn't emit coercion operations
3077-
// result - generation of non-verifiable code
3078-
// fix - apply coercion for the arguments (excluding 'receiver' argument in instance calls)
3079-
3080-
// flatten list of argument types (looks like trait calls with curried arguments are not supported so we can just convert argument list in straightforward way)
3081-
let argTypes =
3082-
minfo.GetParamTypes(amap, m, methArgTys)
3083-
|> List.concat
3084-
// do not apply coercion to the 'receiver' argument
3085-
let receiverArgOpt, argExprs =
3086-
if minfo.IsInstance then
3087-
match argExprs with
3088-
| h :: t -> Some h, t
3089-
| argExprs -> None, argExprs
3090-
else None, argExprs
3091-
let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr)
3092-
match receiverArgOpt with
3093-
| Some r -> r :: convertedArgs
3094-
| None -> convertedArgs
3095-
3096-
// Fix bug 1281: If we resolve to an instance method on a struct and we haven't yet taken
3097-
// the address of the object then go do that
3098-
if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then
3099-
let h, t = List.headAndTail argExprs
3100-
let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false PossiblyMutates h None m
3101-
ResultD (Some (wrap (Expr.Op (TOp.TraitCall (traitInfo), [], (h' :: t), m))))
3102-
else
3103-
ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs ))
3104-
3105-
| Choice2Of5 (tinst, rfref, isSet) ->
3106-
let res =
3107-
match isSet, rfref.RecdField.IsStatic, argExprs.Length with
3108-
3109-
// static setter
3110-
| true, true, 1 ->
3111-
Some (mkStaticRecdFieldSet (rfref, tinst, argExprs.[0], m))
3112-
3113-
// instance setter
3114-
| true, false, 2 ->
3115-
// If we resolve to an instance field on a struct and we haven't yet taken
3116-
// the address of the object then go do that
3117-
if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then
3118-
let h = List.head argExprs
3119-
let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m
3120-
Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m)))
3121-
else
3122-
Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m))
3123-
3124-
// static getter
3125-
| false, true, 0 ->
3126-
Some (mkStaticRecdFieldGet (rfref, tinst, m))
3127-
3128-
// instance getter
3129-
| false, false, 1 ->
3130-
if rfref.Tycon.IsStructOrEnumTycon && isByrefTy g (tyOfExpr g argExprs.[0]) then
3131-
Some (mkRecdFieldGetViaExprAddr (argExprs.[0], rfref, tinst, m))
3132-
else
3133-
Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m))
3134-
| _ -> None
3135-
ResultD res
3136-
3137-
| Choice3Of5 (anonInfo, tinst, i) ->
3138-
let res =
3139-
let tupInfo = anonInfo.TupInfo
3140-
if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then
3141-
Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m))
3142-
else
3143-
Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m))
3144-
ResultD res
3145-
3146-
| Choice4Of5 expr ->
3147-
ResultD (Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m)))
3148-
3149-
| Choice5Of5 () ->
3150-
ResultD None
3041+
let sln = GenWitnessExpr amap g m traitInfo argExprs
3042+
return sln
31513043
}
31523044

31533045
let ChooseTyparSolutionAndSolve css denv tp =

src/fsharp/IlxGen.fs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,9 +3789,9 @@ and GenQuotation cenv cgbuf eenv (ast, conv, m, ety) sequel =
37893789
| None ->
37903790
try
37913791
let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No)
3792-
let astSpec = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast
3793-
let referencedTypeDefs, spliceTypes, spliceArgExprs = qscope.Close()
3794-
referencedTypeDefs, List.map fst spliceTypes, List.map fst spliceArgExprs, astSpec
3792+
let astSpec = QuotationTranslator.ConvExprPublic qscope ast
3793+
let referencedTypeDefs, typeSplices, exprSplices = qscope.Close()
3794+
referencedTypeDefs, List.map fst typeSplices, List.map fst exprSplices, astSpec
37953795
with
37963796
QuotationTranslator.InvalidQuotedTerm e -> error e
37973797

@@ -7579,14 +7579,7 @@ let GenerateCode (cenv, anonTypeTable, eenv, TypedAssemblyAfterOptimization file
75797579
let defns =
75807580
reflectedDefinitions |> List.choose (fun ((methName, v), e) ->
75817581
try
7582-
let ety = tyOfExpr g e
7583-
let tps, taue, _ =
7584-
match e with
7585-
| Expr.TyLambda (_, tps, b, _, _) -> tps, b, applyForallTy g ety (List.map mkTyparTy tps)
7586-
| _ -> [], e, ety
7587-
let env = QuotationTranslator.QuotationTranslationEnv.Empty.BindTypars tps
7588-
let astExpr = QuotationTranslator.ConvExprPublic qscope env taue
7589-
let mbaseR = QuotationTranslator.ConvMethodBase qscope env (methName, v)
7582+
let mbaseR, astExpr = QuotationTranslator.ConvReflectedDefinition qscope methName v e
75907583

75917584
Some(mbaseR, astExpr)
75927585
with

src/fsharp/MethodCalls.fs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,3 +1782,126 @@ let CheckRecdFieldMutation m denv (rfinfo: RecdFieldInfo) =
17821782
if not rfinfo.RecdField.IsMutable then
17831783
errorR (FieldNotMutable (denv, rfinfo.RecdFieldRef, m))
17841784

1785+
1786+
/// Generate a witness for the given (solved) constraint. Five possiblilities are taken
1787+
/// into account.
1788+
/// 1. The constraint is solved by a .NET-declared method or an F#-declared method
1789+
/// 2. The constraint is solved by an F# record field
1790+
/// 3. The constraint is solved by an F# anonymous record field
1791+
/// 4. The constraint is considered solved by a "built in" solution
1792+
/// 5. The constraint is solved by a closed expression given by a provided method from a type provider
1793+
///
1794+
/// In each case an expression is returned where the method is applied to the given arguments, or the
1795+
/// field is dereferenced.
1796+
///
1797+
/// None is returned in the cases where the trait has not been solved (e.g. is part of generic code)
1798+
/// or there is an unexpected mismatch of some kind.
1799+
let GenWitnessExpr amap g m (traitInfo: TraitConstraintInfo) argExprs =
1800+
1801+
let sln =
1802+
match traitInfo.Solution with
1803+
| None -> Choice5Of5()
1804+
| Some sln ->
1805+
1806+
// Given the solution information, reconstruct the MethInfo for the solution
1807+
match sln with
1808+
| ILMethSln(origTy, extOpt, mref, minst) ->
1809+
let metadataTy = convertToTypeWithMetadataIfPossible g origTy
1810+
let tcref = tcrefOfAppTy g metadataTy
1811+
let mdef = resolveILMethodRef tcref.ILTyconRawMetadata mref
1812+
let ilMethInfo =
1813+
match extOpt with
1814+
| None -> MethInfo.CreateILMeth(amap, m, origTy, mdef)
1815+
| Some ilActualTypeRef ->
1816+
let actualTyconRef = Import.ImportILTypeRef amap m ilActualTypeRef
1817+
MethInfo.CreateILExtensionMeth(amap, m, origTy, actualTyconRef, None, mdef)
1818+
Choice1Of5 (ilMethInfo, minst)
1819+
1820+
| FSMethSln(ty, vref, minst) ->
1821+
Choice1Of5 (FSMeth(g, ty, vref, None), minst)
1822+
1823+
| FSRecdFieldSln(tinst, rfref, isSetProp) ->
1824+
Choice2Of5 (tinst, rfref, isSetProp)
1825+
1826+
| FSAnonRecdFieldSln(anonInfo, tinst, i) ->
1827+
Choice3Of5 (anonInfo, tinst, i)
1828+
1829+
| BuiltInSln ->
1830+
Choice5Of5 ()
1831+
1832+
| ClosedExprSln expr ->
1833+
Choice4Of5 expr
1834+
match sln with
1835+
| Choice1Of5(minfo, methArgTys) ->
1836+
let argExprs =
1837+
// FIX for #421894 - typechecker assumes that coercion can be applied for the trait calls arguments but codegen doesn't emit coercion operations
1838+
// result - generation of non-verifiable code
1839+
// fix - apply coercion for the arguments (excluding 'receiver' argument in instance calls)
1840+
1841+
// flatten list of argument types (looks like trait calls with curried arguments are not supported so we can just convert argument list in straightforward way)
1842+
let argTypes =
1843+
minfo.GetParamTypes(amap, m, methArgTys)
1844+
|> List.concat
1845+
// do not apply coercion to the 'receiver' argument
1846+
let receiverArgOpt, argExprs =
1847+
if minfo.IsInstance then
1848+
match argExprs with
1849+
| h :: t -> Some h, t
1850+
| argExprs -> None, argExprs
1851+
else None, argExprs
1852+
let convertedArgs = (argExprs, argTypes) ||> List.map2 (fun expr expectedTy -> mkCoerceIfNeeded g expectedTy (tyOfExpr g expr) expr)
1853+
match receiverArgOpt with
1854+
| Some r -> r :: convertedArgs
1855+
| None -> convertedArgs
1856+
1857+
// Fix bug 1281: If we resolve to an instance method on a struct and we haven't yet taken
1858+
// the address of the object then go do that
1859+
if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then
1860+
let h, t = List.headAndTail argExprs
1861+
let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false PossiblyMutates h None m
1862+
Some (wrap (Expr.Op (TOp.TraitCall (traitInfo), [], (h' :: t), m)))
1863+
else
1864+
Some (MakeMethInfoCall amap m minfo methArgTys argExprs )
1865+
1866+
| Choice2Of5 (tinst, rfref, isSet) ->
1867+
match isSet, rfref.RecdField.IsStatic, argExprs.Length with
1868+
1869+
// static setter
1870+
| true, true, 1 ->
1871+
Some (mkStaticRecdFieldSet (rfref, tinst, argExprs.[0], m))
1872+
1873+
// instance setter
1874+
| true, false, 2 ->
1875+
// If we resolve to an instance field on a struct and we haven't yet taken
1876+
// the address of the object then go do that
1877+
if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then
1878+
let h = List.head argExprs
1879+
let wrap, h', _readonly, _writeonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m
1880+
Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m)))
1881+
else
1882+
Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m))
1883+
1884+
// static getter
1885+
| false, true, 0 ->
1886+
Some (mkStaticRecdFieldGet (rfref, tinst, m))
1887+
1888+
// instance getter
1889+
| false, false, 1 ->
1890+
if rfref.Tycon.IsStructOrEnumTycon && isByrefTy g (tyOfExpr g argExprs.[0]) then
1891+
Some (mkRecdFieldGetViaExprAddr (argExprs.[0], rfref, tinst, m))
1892+
else
1893+
Some (mkRecdFieldGet g (argExprs.[0], rfref, tinst, m))
1894+
| _ -> None
1895+
1896+
| Choice3Of5 (anonInfo, tinst, i) ->
1897+
let tupInfo = anonInfo.TupInfo
1898+
if evalTupInfoIsStruct tupInfo && isByrefTy g (tyOfExpr g argExprs.[0]) then
1899+
Some (mkAnonRecdFieldGetViaExprAddr (anonInfo, argExprs.[0], tinst, i, m))
1900+
else
1901+
Some (mkAnonRecdFieldGet g (anonInfo, argExprs.[0], tinst, i, m))
1902+
1903+
| Choice4Of5 expr ->
1904+
Some (MakeApplicationAndBetaReduce g (expr, tyOfExpr g expr, [], argExprs, m))
1905+
1906+
| Choice5Of5 () ->
1907+
None

src/fsharp/PostInferenceChecks.fs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ and CheckExpr (cenv: cenv) (env: env) origExpr (context: PermitByRefExpr) : Limi
973973
// Translate to quotation data
974974
try
975975
let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No)
976-
let qdata = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast
976+
let qdata = QuotationTranslator.ConvExprPublic qscope ast
977977
let typeDefs, spliceTypes, spliceExprs = qscope.Close()
978978
match savedConv.Value with
979979
| None -> savedConv:= Some (typeDefs, List.map fst spliceTypes, List.map fst spliceExprs, qdata)
@@ -1752,18 +1752,13 @@ and CheckBinding cenv env alwaysCheckNoReraise context (TBind(v, bindRhs, _) as
17521752
// no real need for that except that it helps us to bundle all reflected definitions up into
17531753
// one blob for pickling to the binary format
17541754
try
1755-
let ety = tyOfExpr g bindRhs
1756-
let tps, taue, _ =
1757-
match bindRhs with
1758-
| Expr.TyLambda (_, tps, b, _, _) -> tps, b, applyForallTy g ety (List.map mkTyparTy tps)
1759-
| _ -> [], bindRhs, ety
1760-
let env = QuotationTranslator.QuotationTranslationEnv.Empty.BindTypars tps
17611755
let qscope = QuotationTranslator.QuotationGenerationScope.Create (g, cenv.amap, cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes)
1762-
QuotationTranslator.ConvExprPublic qscope env taue |> ignore
1763-
let _, _, argExprs = qscope.Close()
1764-
if not (isNil argExprs) then
1756+
let methName = v.CompiledName g.CompilerGlobalState
1757+
QuotationTranslator.ConvReflectedDefinition qscope methName v bindRhs |> ignore
1758+
1759+
let _, _, exprSplices = qscope.Close()
1760+
if not (isNil exprSplices) then
17651761
errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), v.Range))
1766-
QuotationTranslator.ConvMethodBase qscope env (v.CompiledName g.CompilerGlobalState, v) |> ignore
17671762
with
17681763
| QuotationTranslator.InvalidQuotedTerm e ->
17691764
errorR e

src/fsharp/QuotationPickler.fs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ type VarData =
4545
vType: TypeData
4646
vMutable: bool }
4747

48-
type FieldData = NamedTypeData * string
49-
type RecdFieldData = NamedTypeData * string
5048
type PropInfoData = NamedTypeData * string * TypeData * TypeData list
5149

5250
type CombOp =
@@ -145,15 +143,15 @@ let mkLetRec (ves, body) =
145143

146144
let mkRecdMk (n, tys, args) = CombExpr(RecdMkOp n, tys, args)
147145

148-
let mkRecdGet ((d1, d2), tyargs, args) = CombExpr(RecdGetOp(d1, d2), tyargs, args)
146+
let mkRecdGet (d1, d2, tyargs, args) = CombExpr(RecdGetOp(d1, d2), tyargs, args)
149147

150-
let mkRecdSet ((d1, d2), tyargs, args) = CombExpr(RecdSetOp(d1, d2), tyargs, args)
148+
let mkRecdSet (d1, d2, tyargs, args) = CombExpr(RecdSetOp(d1, d2), tyargs, args)
151149

152-
let mkUnion ((d1, d2), tyargs, args) = CombExpr(SumMkOp(d1, d2), tyargs, args)
150+
let mkUnion (d1, d2, tyargs, args) = CombExpr(SumMkOp(d1, d2), tyargs, args)
153151

154-
let mkUnionFieldGet ((d1, d2, d3), tyargs, arg) = CombExpr(SumFieldGetOp(d1, d2, d3), tyargs, [arg])
152+
let mkUnionFieldGet (d1, d2, d3, tyargs, arg) = CombExpr(SumFieldGetOp(d1, d2, d3), tyargs, [arg])
155153

156-
let mkUnionCaseTagTest ((d1, d2), tyargs, arg) = CombExpr(SumTagTestOp(d1, d2), tyargs, [arg])
154+
let mkUnionCaseTagTest (d1, d2, tyargs, arg) = CombExpr(SumTagTestOp(d1, d2), tyargs, [arg])
157155

158156
let mkTupleGet (ty, n, e) = CombExpr(TupleGetOp n, [ty], [e])
159157

@@ -215,9 +213,9 @@ let mkPropGet (d, tyargs, args) = CombExpr(PropGetOp(d), tyargs, args)
215213

216214
let mkPropSet (d, tyargs, args) = CombExpr(PropSetOp(d), tyargs, args)
217215

218-
let mkFieldGet ((d1, d2), tyargs, args) = CombExpr(FieldGetOp(d1, d2), tyargs, args)
216+
let mkFieldGet (d1, d2, tyargs, args) = CombExpr(FieldGetOp(d1, d2), tyargs, args)
219217

220-
let mkFieldSet ((d1, d2), tyargs, args) = CombExpr(FieldSetOp(d1, d2), tyargs, args)
218+
let mkFieldSet (d1, d2, tyargs, args) = CombExpr(FieldSetOp(d1, d2), tyargs, args)
221219

222220
let mkCtorCall (d, tyargs, args) = CombExpr(CtorCallOp(d), tyargs, args)
223221

@@ -409,7 +407,11 @@ let p_PropInfoData a st =
409407
let p_CombOp x st =
410408
match x with
411409
| CondOp -> p_byte 0 st
412-
| ModuleValueOp (x, y, z) -> p_byte 1 st; p_tup3 p_NamedType p_string p_bool (x, y, z) st
410+
| ModuleValueOp (x, y, z) ->
411+
p_byte 1 st
412+
p_NamedType x st
413+
p_string y st
414+
p_bool z st
413415
| LetRecOp -> p_byte 2 st
414416
| RecdMkOp a -> p_byte 3 st; p_NamedType a st
415417
| RecdGetOp (x, y) -> p_byte 4 st; p_recdFieldSpec (x, y) st

0 commit comments

Comments
 (0)