Skip to content

Commit f57f947

Browse files
committed
squash unsolved variables arising from witness generation
1 parent 4d4402a commit f57f947

25 files changed

+148
-53
lines changed

src/fsharp/CompileOptions.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ let internalFlags (tcConfigB:TcConfigBuilder) =
10551055
[
10561056
CompilerOption
10571057
("stamps", tagNone,
1058-
OptionUnit ignore,
1058+
OptionSet Tastops.DebugPrint.layoutStamps,
10591059
Some(InternalCommandLineOption("--stamps", rangeCmdArgs)), None)
10601060

10611061
CompilerOption

src/fsharp/ConstraintSolver.fs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,8 @@ let NewByRefKindInferenceType (g: TcGlobals) m =
106106

107107
let NewInferenceTypes l = l |> List.map (fun _ -> NewInferenceType ())
108108

109-
// QUERY: should 'rigid' ever really be 'true'? We set this when we know
110-
// we are going to have to generalize a typar, e.g. when implementing a
111-
// abstract generic method slot. But we later check the generalization
112-
// condition anyway, so we could get away with a non-rigid typar. This
113-
// would sort of be cleaner, though give errors later.
114109
let FreshenAndFixupTypars (traitCtxt: ITraitContext option) m rigid fctps tinst tpsorig =
115-
let copy_tyvar (tp: Typar) = NewCompGenTypar (tp.Kind, rigid, tp.StaticReq, (if rigid=TyparRigidity.Rigid then TyparDynamicReq.Yes else TyparDynamicReq.No), false)
110+
let copy_tyvar (tp: Typar) = NewCompGenTypar (tp.Kind, rigid, tp.StaticReq, (if rigid=TyparRigidity.Rigid then TyparDynamicReq.Yes else TyparDynamicReq.No), false)
116111
let tps = tpsorig |> List.map copy_tyvar
117112
let renaming, tinst = FixupNewTypars traitCtxt m fctps tinst tpsorig tps
118113
tps, renaming, tinst
@@ -322,13 +317,13 @@ let rec occursCheck g un ty =
322317
type PermitWeakResolution =
323318

324319
/// Represents the point where we are generalizing inline code
325-
| YesAtInlineGeneralization
320+
| LegacyYesAtInlineGeneralization
326321

327322
/// Represents points where we are choosing a default solution to trait constraints
328323
| YesAtChooseSolution
329324

330-
/// Represents legacy invocations of the constraint solver during codegen
331-
| YesAtCodeGen
325+
/// Represents invocations of the constraint solver during codegen or inlining to determine witnesses
326+
| LegacyYesAtCodeGen
332327

333328
/// No weak resolution allowed
334329
| No
@@ -339,15 +334,15 @@ type PermitWeakResolution =
339334
if g.langVersion.SupportsFeature LanguageFeature.ExtensionConstraintSolutions then
340335
match x with
341336
| YesAtChooseSolution -> true
342-
| YesAtInlineGeneralization
343-
| YesAtCodeGen
337+
| LegacyYesAtCodeGen
338+
| LegacyYesAtInlineGeneralization
344339
| No -> false
345340
else
346341
//legacy
347342
match x with
348-
| YesAtChooseSolution -> true
349-
| YesAtCodeGen -> true
350-
| YesAtInlineGeneralization -> true
343+
| YesAtChooseSolution
344+
| LegacyYesAtCodeGen
345+
| LegacyYesAtInlineGeneralization -> true
351346
| No -> false
352347

353348

@@ -447,7 +442,7 @@ let IsBinaryOpArgTypePair p1 p2 permitWeakResolution minfos g ty1 ty2 =
447442

448443
// During regular canonicalization (weak resolution) we don't do any check on the other type at all - we
449444
// ignore the possibility that method overloads may resolve the constraint
450-
| PermitWeakResolution.YesAtInlineGeneralization
445+
| PermitWeakResolution.LegacyYesAtInlineGeneralization
451446
| PermitWeakResolution.YesAtChooseSolution ->
452447
// weak resolution lets the other type be a variable type
453448
isTyparTy g ty2 ||
@@ -457,7 +452,7 @@ let IsBinaryOpArgTypePair p1 p2 permitWeakResolution minfos g ty1 ty2 =
457452
typeEquivAux EraseMeasures g ty1 ty2
458453

459454
// During codegen we only apply a builtin resolution if both the types are correct
460-
| PermitWeakResolution.YesAtCodeGen ->
455+
| PermitWeakResolution.LegacyYesAtCodeGen ->
461456
p2 ty2 &&
462457
// All built-in rules only apply in cases where left and right operator types are equal (after
463458
// erasing units)
@@ -1853,7 +1848,7 @@ and SolveRelevantMemberConstraintsForTypar (csenv:ConstraintSolverEnv) ndeep (pe
18531848
SolveMemberConstraint csenv true permitWeakResolution (ndeep+1) m2 trace traitInfo)
18541849

18551850
and CanonicalizeRelevantMemberConstraints (csenv: ConstraintSolverEnv) ndeep trace tps isInline =
1856-
let permitWeakResolution = (if isInline then PermitWeakResolution.YesAtInlineGeneralization else PermitWeakResolution.YesAtChooseSolution)
1851+
let permitWeakResolution = (if isInline then PermitWeakResolution.LegacyYesAtInlineGeneralization else PermitWeakResolution.YesAtChooseSolution)
18571852
SolveRelevantMemberConstraints csenv ndeep permitWeakResolution trace tps
18581853

18591854
and AddMemberConstraint (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) traitInfo support (frees: Typar list) =
@@ -3148,17 +3143,6 @@ let CreateCodegenState tcVal g amap =
31483143
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
31493144
InfoReader = new InfoReader(g, amap) }
31503145

3151-
let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors {
3152-
let css = CreateCodegenState tcVal g amap
3153-
3154-
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
3155-
3156-
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.YesAtCodeGen 0 m NoTrace traitInfo
3157-
3158-
let sln = GenWitnessExpr amap g m traitInfo argExprs
3159-
return sln
3160-
}
3161-
31623146
let ChooseTyparSolutionAndSolve css denv tp =
31633147
let g = css.g
31643148
let amap = css.amap
@@ -3169,6 +3153,25 @@ let ChooseTyparSolutionAndSolve css denv tp =
31693153
(fun err -> ErrorD(ErrorFromApplyingDefault(g, denv, tp, max, err, m)))
31703154
|> RaiseOperationResult
31713155

3156+
let CodegenWitnessThatTypeSupportsTraitConstraint tcVal g amap m (traitInfo: TraitConstraintInfo) argExprs = trackErrors {
3157+
let css = CreateCodegenState tcVal g amap
3158+
let denv = DisplayEnv.Empty g
3159+
3160+
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv
3161+
3162+
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.LegacyYesAtCodeGen 0 m NoTrace traitInfo
3163+
let sln = GenWitnessExpr amap g m traitInfo argExprs
3164+
3165+
sln |> Option.iter (fun slnExpr ->
3166+
let unsolved = FSharp.Compiler.FindUnsolved.UnsolvedTyparsOfExpr g amap denv slnExpr
3167+
3168+
unsolved |> List.iter (fun tp ->
3169+
if (tp.Rigidity <> TyparRigidity.Rigid) && not tp.IsSolved then
3170+
ChooseTyparSolutionAndSolve css denv tp))
3171+
3172+
return sln
3173+
}
3174+
31723175
let CheckDeclaredTypars denv css m typars1 typars2 =
31733176
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m denv
31743177
TryD_IgnoreAbortForFailedOverloadResolution

src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,12 @@
446446
<Compile Include="..\PatternMatchCompilation.fs">
447447
<Link>Logic\PatternMatchCompilation.fs</Link>
448448
</Compile>
449+
<Compile Include="..\FindUnsolved.fsi">
450+
<Link>Logic\FindUnsolved.fsi</Link>
451+
</Compile>
452+
<Compile Include="..\FindUnsolved.fs">
453+
<Link>Logic\FindUnsolved.fs</Link>
454+
</Compile>
449455
<Compile Include="..\ConstraintSolver.fsi">
450456
<Link>Logic\ConstraintSolver.fsi</Link>
451457
</Compile>
@@ -458,12 +464,6 @@
458464
<Compile Include="..\CheckFormatStrings.fs">
459465
<Link>Logic\CheckFormatStrings.fs</Link>
460466
</Compile>
461-
<Compile Include="..\FindUnsolved.fsi">
462-
<Link>Logic\FindUnsolved.fsi</Link>
463-
</Compile>
464-
<Compile Include="..\FindUnsolved.fs">
465-
<Link>Logic\FindUnsolved.fs</Link>
466-
</Compile>
467467
<Compile Include="..\QuotationTranslator.fsi">
468468
<Link>Logic\QuotationTranslator.fsi</Link>
469469
</Compile>

src/fsharp/FindUnsolved.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,4 +276,13 @@ let UnsolvedTyparsOfModuleDef g amap denv (mdef, extraAttribs) =
276276
accAttribs cenv Nix extraAttribs
277277
List.rev cenv.unsolved
278278

279+
let UnsolvedTyparsOfExpr g amap denv expr =
280+
let cenv =
281+
{ g =g
282+
amap=amap
283+
denv=denv
284+
unsolved = [] }
285+
accExpr cenv Nix expr
286+
List.rev cenv.unsolved
287+
279288

src/fsharp/FindUnsolved.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ open FSharp.Compiler.Import
1010

1111
/// Find all unsolved inference variables after type inference for an entire file
1212
val UnsolvedTyparsOfModuleDef: g: TcGlobals -> amap: ImportMap -> denv: DisplayEnv -> mdef : ModuleOrNamespaceExpr * extraAttribs: Attrib list -> Typar list
13+
14+
/// Find all unsolved inference variables after adhoc generation of witness
15+
val UnsolvedTyparsOfExpr: g: TcGlobals -> amap: ImportMap -> denv: DisplayEnv -> expr: Expr -> Typar list

src/fsharp/IlxGen.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ let ComputeTypeAccess (tref: ILTypeRef) hidden =
389389
type TypeReprEnv(reprs: Map<Stamp, uint16>, count: int) =
390390

391391
/// Lookup a type parameter
392-
member __.Item (tp: Typar, m: range) =
392+
member __.LookupTyparRepr (tp: Typar, m: range) =
393393
try reprs.[tp.Stamp]
394394
with :? KeyNotFoundException ->
395395
errorR(InternalError("Undefined or unsolved type variable: " + showL(typarL tp), m))
@@ -540,7 +540,7 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
540540
if tps.IsEmpty then GenTypeAux amap m tyenv VoidNotOK ptrsOK tau
541541
else EraseClosures.mkILTyFuncTy g.ilxPubCloEnv
542542

543-
| TType_var tp -> mkILTyvarTy tyenv.[tp, m]
543+
| TType_var tp -> mkILTyvarTy (tyenv.LookupTyparRepr(tp, m))
544544

545545
| TType_measure _ -> g.ilg.typ_Int32
546546

@@ -4361,7 +4361,7 @@ and GenGenericParams cenv eenv tps =
43614361
tps |> DropErasedTypars |> List.map (GenGenericParam cenv eenv)
43624362

43634363
and GenGenericArgs m (tyenv: TypeReprEnv) tps =
4364-
tps |> DropErasedTypars |> List.map (fun c -> (mkILTyvarTy tyenv.[c, m]))
4364+
tps |> DropErasedTypars |> List.map (fun c -> mkILTyvarTy (tyenv.LookupTyparRepr(c, m)))
43654365

43664366
/// Generate the closure class for a function
43674367
and GenLambdaClosure cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc selfv expr =

src/fsharp/TastOps.fs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,7 +2743,7 @@ type DisplayEnv =
27432743
maxMembers = None
27442744
showObsoleteMembers = false
27452745
showHiddenMembers = false
2746-
showTyparBinding = false
2746+
showTyparBinding = true
27472747
showImperativeTyparAnnotations = false
27482748
suppressInlineKeyword = false
27492749
suppressMutableKeyword = false
@@ -3383,8 +3383,9 @@ module DebugPrint =
33833383
else stat
33843384
stat
33853385

3386-
let stampL _n w =
3387-
w
3386+
let layoutStamps = ref false
3387+
let stampL (n: int64) w =
3388+
if layoutStamps.Value then w ++ (wordL (tagText ("#" + string n))) else w
33883389

33893390
let layoutTyconRef (tc: TyconRef) =
33903391
wordL (tagText tc.DisplayNameWithStaticParameters) |> stampL tc.Stamp
@@ -3901,7 +3902,7 @@ module DebugPrint =
39013902
wordL(tagText "bytes++")
39023903
| Expr.Op (TOp.UInt16s _, _, _, _) -> wordL(tagText "uint16++")
39033904
| Expr.Op (TOp.RefAddrGet _, _tyargs, _args, _) -> wordL(tagText "GetRefLVal...")
3904-
| Expr.Op (TOp.TraitCall _, _tyargs, _args, _) -> wordL(tagText "traitcall...")
3905+
| Expr.Op (TOp.TraitCall traitInfo, _tyargs, _args, _) -> wordL(tagText "traitcall") ^^ auxTraitL SimplifyTypes.typeSimplificationInfo0 traitInfo
39053906
| Expr.Op (TOp.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...")
39063907
| Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...")
39073908
| Expr.Op (TOp.TryFinally _, _tyargs, _args, _) -> wordL(tagText "TOp.TryFinally...")
@@ -7499,7 +7500,7 @@ let AdjustPossibleSubsumptionExpr g (expr: Expr) (suppliedArgs: Expr list) : (Ex
74997500

75007501
let curriedInputTys, _ = stripFunTy g inputTy
75017502

7502-
assert (curriedActualArgTys.Length = curriedInputTys.Length)
7503+
if curriedActualArgTys.Length <> curriedInputTys.Length then None else
75037504

75047505
let argTys = (curriedInputTys, curriedActualArgTys) ||> List.mapi2 (fun i x y -> (i, x, y))
75057506

src/fsharp/TastOps.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,9 @@ module DebugPrint =
13031303
/// A global flag indicating whether debug output should include ranges
13041304
val layoutRanges : bool ref
13051305

1306+
/// A global flag indicating whether debug output should include stamps
1307+
val layoutStamps : bool ref
1308+
13061309
/// Convert a type to a string for debugging purposes
13071310
val showType : TType -> string
13081311

src/fsharp/TypeChecker.fs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11481,7 +11481,7 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBinds
1148111481
let (ExplicitTyparInfo(_, declaredTypars, canInferTypars)) = flex
1148211482
let allDeclaredTypars = enclosingDeclaredTypars @ declaredTypars
1148311483
let generalizedTypars, prelimValSchemes2 =
11484-
let canInferTypars = GeneralizationHelpers. ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, canInferTypars, None)
11484+
let canInferTypars = GeneralizationHelpers.ComputeCanInferExtraGeneralizableTypars (containerInfo.ParentRef, canInferTypars, None)
1148511485

1148611486
let maxInferredTypars = freeInTypeLeftToRight cenv.g false tauTy
1148711487

@@ -11494,6 +11494,10 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBinds
1149411494
GeneralizationHelpers.ComputeAndGeneralizeGenericTypars
1149511495
(cenv, denv, m, freeInEnv, canInferTypars, canConstrain, inlineFlag, Some rhsExpr, allDeclaredTypars, maxInferredTypars, tauTy, false)
1149611496

11497+
//printfn "Generalizing 'let' at %A" m
11498+
//printfn " generalizedTypars = %s" (Layout.showL (DebugPrint.typarsL generalizedTypars))
11499+
//printfn " rhsExpr = %s" (Layout.showL (DebugPrint.exprL cenv.g rhsExpr))
11500+
1149711501
let prelimValSchemes2 = GeneralizeVals cenv denv enclosingDeclaredTypars generalizedTypars nameToPrelimValSchemeMap
1149811502

1149911503
generalizedTypars, prelimValSchemes2
@@ -12394,6 +12398,10 @@ and TcLetrecComputeAndGeneralizeGenericTyparsForBinding cenv denv freeInEnv (pgr
1239412398

1239512399
let canGeneralizeConstrained = GeneralizationHelpers.CanGeneralizeConstrainedTyparsForDecl rbinfo.DeclKind
1239612400
let generalizedTypars = GeneralizationHelpers.ComputeAndGeneralizeGenericTypars (cenv, denv, m, freeInEnv, canInferTypars, canGeneralizeConstrained, inlineFlag, Some expr, allDeclaredTypars, maxInferredTypars, tau, isCtor)
12401+
12402+
printfn "Generalizing 'member/let-rec' at %A" m
12403+
printfn " generalizedTypars = %s" (Layout.showL (DebugPrint.typarsL generalizedTypars))
12404+
printfn " rhsExpr = %s" (Layout.showL (DebugPrint.exprL cenv.g expr))
1239712405
generalizedTypars
1239812406

1239912407
/// Compute the type variables which may have member constraints that need to be canonicalized prior to generalization

src/fsharp/tast.fs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5714,17 +5714,20 @@ let MakeRecdFieldsTable ucs: TyconRecdFields =
57145714
{ FieldsByIndex = Array.ofList ucs
57155715
FieldsByName = ucs |> NameMap.ofKeyedList (fun rfld -> rfld.Name) }
57165716

5717-
57185717
let MakeUnionCases ucs: TyconUnionData =
57195718
{ CasesTable=MakeUnionCasesTable ucs
57205719
CompiledRepresentation=newCache() }
57215720

57225721
let MakeUnionRepr ucs = TUnionRepr (MakeUnionCases ucs)
57235722

57245723
let NewTypar (kind, rigid, Typar(id, staticReq, isCompGen), isFromError, dynamicReq, attribs, eqDep, compDep) =
5724+
let stamp = newStamp()
5725+
//printfn "stamp = %d" stamp
5726+
//if stamp = 16193L then
5727+
// assert false
57255728
Typar.New
57265729
{ typar_id = id
5727-
typar_stamp = newStamp()
5730+
typar_stamp = stamp
57285731
typar_flags= TyparFlags(kind, rigid, isFromError, isCompGen, staticReq, dynamicReq, eqDep, compDep)
57295732
typar_solution = None
57305733
typar_astype = Unchecked.defaultof<_>

0 commit comments

Comments
 (0)