Skip to content
Closed
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
27 changes: 18 additions & 9 deletions src/fsharp/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ type ConstraintSolverState =
/// Indicates if the constraint solver is being run after type checking is complete,
/// e.g. during codegen to determine solutions and witnesses for trait constraints.
/// Suppresses the generation of certain errors such as missing constraint warnings.
afterTypeCheck: bool

/// Indicates if the constraint solver is being run at very last stage (ilxgen)
/// Allows constraints to be added to type parameters to produce a witness.
/// There is no really good reason this should be allowed nor should it be needed,
/// but it was in the codebase and remains active for legacy compat reasons.
codegen: bool

/// This table stores all unsolved, ungeneralized trait constraints, indexed by free type variable.
Expand All @@ -262,6 +268,7 @@ type ConstraintSolverState =
amap = amap
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
InfoReader = infoReader
afterTypeCheck = false
codegen = false
TcVal = tcVal }

Expand Down Expand Up @@ -1952,7 +1959,7 @@ and AddConstraint (csenv: ConstraintSolverEnv) ndeep m2 trace tp newConstraint
// will-be-made-rigid type variable. This is because the existence of these warnings
// is relevant to the overload resolution rules (see 'candidateWarnCount' in the overload resolution
// implementation).
if tp.Rigidity.WarnIfMissingConstraint && not csenv.SolverState.codegen then
if tp.Rigidity.WarnIfMissingConstraint && not csenv.SolverState.afterTypeCheck then
do! WarnD (ConstraintSolverMissingConstraint(denv, tp, newConstraint, m, m2))

let newConstraints =
Expand Down Expand Up @@ -3060,26 +3067,27 @@ let ApplyTyparDefaultAtPriority denv css priority (tp: Typar) =
|> RaiseOperationResult
| _ -> ())

let CreateCodegenState tcVal g amap =
let CreateCodegenState tcVal g amap codegen =
{ g = g
amap = amap
TcVal = tcVal
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
InfoReader = new InfoReader(g, amap)
codegen = true }
codegen = codegen
afterTypeCheck = true }

/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code
let CodegenWitnessForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs = trackErrors {
let css = CreateCodegenState tcVal g amap
let CodegenWitnessForTraitConstraint tcVal g amap m (traitInfo:TraitConstraintInfo) argExprs codegen = trackErrors {
let css = CreateCodegenState tcVal g amap codegen
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo
let sln = GenWitnessExpr amap g m traitInfo argExprs
return sln
}

/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors {
let css = CreateCodegenState tcVal g amap
let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs codegen = trackErrors {
let css = CreateCodegenState tcVal g amap codegen
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
let ftps, _renaming, tinst = FreshenTypeInst m typars
let traitInfos = GetTraitConstraintInfosOfTypars g ftps
Expand All @@ -3088,8 +3096,8 @@ let CodegenWitnessesForTyparInst tcVal g amap m typars tyargs = trackErrors {
}

/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
let CodegenWitnessesForTraitWitness tcVal g amap m traitInfo = trackErrors {
let css = CreateCodegenState tcVal g amap
let CodegenWitnessesForTraitWitness tcVal g amap m traitInfo codegen = trackErrors {
let css = CreateCodegenState tcVal g amap codegen
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
let! _res = SolveMemberConstraint csenv true PermitWeakResolution.Yes 0 m NoTrace traitInfo
return MethodCalls.GenWitnessExprLambda amap g m traitInfo
Expand Down Expand Up @@ -3140,6 +3148,7 @@ let IsApplicableMethApprox g amap m (minfo: MethInfo) availObjTy =
amap = amap
TcVal = (fun _ -> failwith "should not be called")
ExtraCxs = HashMultiMap(10, HashIdentity.Structural)
afterTypeCheck = false
codegen = false
InfoReader = new InfoReader(g, amap) }
let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g)
Expand Down
6 changes: 3 additions & 3 deletions src/fsharp/ConstraintSolver.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,13 @@ val SolveTypeAsError: DisplayEnv -> ConstraintSolverState -> range -> TType -> u
val ApplyTyparDefaultAtPriority: DisplayEnv -> ConstraintSolverState -> priority: int -> Typar -> unit

/// Generate a witness expression if none is otherwise available, e.g. in legacy non-witness-passing code
val CodegenWitnessForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> OperationResult<Expr option>
val CodegenWitnessForTraitConstraint : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> Expr list -> bool -> OperationResult<Expr option>

/// Generate the arguments passed when using a generic construct that accepts traits witnesses
val CodegenWitnessesForTyparInst : TcValF -> TcGlobals -> ImportMap -> range -> Typars -> TType list -> OperationResult<Choice<TraitConstraintInfo, Expr> list>
val CodegenWitnessesForTyparInst : TcValF -> TcGlobals -> ImportMap -> range -> Typars -> TType list -> bool -> OperationResult<Choice<TraitConstraintInfo, Expr> list>

/// Generate the lambda argument passed for a use of a generic construct that accepts trait witnesses
val CodegenWitnessesForTraitWitness : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> OperationResult<Choice<TraitConstraintInfo, Expr>>
val CodegenWitnessesForTraitWitness : TcValF -> TcGlobals -> ImportMap -> range -> TraitConstraintInfo -> bool -> OperationResult<Choice<TraitConstraintInfo, Expr>>

/// For some code like "let f() = ([] = [])", a free choice is made for a type parameter
/// for an interior type variable. This chooses a solution for a type parameter subject
Expand Down
6 changes: 3 additions & 3 deletions src/fsharp/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3114,7 +3114,7 @@ and GenWitnessArgFromTraitInfo cenv cgbuf eenv m traitInfo =
match storage with
| None ->
let witnessExpr =
ConstraintSolver.CodegenWitnessesForTraitWitness cenv.tcVal g cenv.amap m traitInfo
ConstraintSolver.CodegenWitnessesForTraitWitness cenv.tcVal g cenv.amap m traitInfo true
|> CommitOperationResult
match witnessExpr with
| Choice1Of2 _traitInfo ->
Expand Down Expand Up @@ -3152,7 +3152,7 @@ and GenWitnessArgs cenv cgbuf eenv m tps tyargs =
// Witness arguments are only generated in emitted 'inline' code where witness parameters are available.
if generateWitnesses then
let mwitnesses =
ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs
ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs true
|> CommitOperationResult

for witnessArg in mwitnesses do
Expand Down Expand Up @@ -4084,7 +4084,7 @@ and GenTraitCall (cenv: cenv) cgbuf eenv (traitInfo: TraitConstraintInfo, argExp
// If witnesses are available, we should now always find trait witnesses in scope
assert not generateWitnesses

let minfoOpt = CommitOperationResult (ConstraintSolver.CodegenWitnessForTraitConstraint cenv.tcVal g cenv.amap m traitInfo argExprs)
let minfoOpt = CommitOperationResult (ConstraintSolver.CodegenWitnessForTraitConstraint cenv.tcVal g cenv.amap m traitInfo argExprs true)
match minfoOpt with
| None ->
let exnArg = mkString g m (FSComp.SR.ilDynamicInvocationNotSupported(traitInfo.MemberName))
Expand Down
8 changes: 4 additions & 4 deletions src/fsharp/Optimizer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,9 @@ let BindInternalLocalVal cenv (v: Val) vval env =
env

let BindExternalLocalVal cenv (v: Val) vval env =
#if CHECKED
CheckInlineValueIsComplete v vval
#endif
//#if CHECKED
CheckInlineValueIsComplete v vval.ValExprInfo
//#endif

let vval = if v.IsMutable then {vval with ValExprInfo=UnknownValue } else vval
let env =
Expand Down Expand Up @@ -2451,7 +2451,7 @@ and OptimizeWhileLoop cenv env (spWhile, marker, e1, e2, m) =
and OptimizeTraitCall cenv env (traitInfo, args, m) =

// Resolve the static overloading early (during the compulsory rewrite phase) so we can inline.
match ConstraintSolver.CodegenWitnessForTraitConstraint cenv.TcVal cenv.g cenv.amap m traitInfo args with
match ConstraintSolver.CodegenWitnessForTraitConstraint cenv.TcVal cenv.g cenv.amap m traitInfo args false with

| OkResult (_, Some expr) -> OptimizeExpr cenv env expr

Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/QuotationTranslator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ and GetWitnessArgs cenv (env : QuotationTranslationEnv) m tps tyargs =
let g = cenv.g
if g.generateWitnesses && not env.suppressWitnesses then
let witnessExprs =
ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs
ConstraintSolver.CodegenWitnessesForTyparInst cenv.tcVal g cenv.amap m tps tyargs false
|> CommitOperationResult
let env = { env with suppressWitnesses = true }
witnessExprs |> List.map (fun arg ->
Expand Down Expand Up @@ -737,7 +737,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.

let minfoOpt =
if g.generateWitnesses then
ConstraintSolver.CodegenWitnessForTraitConstraint cenv.tcVal g cenv.amap m traitInfo args |> CommitOperationResult
ConstraintSolver.CodegenWitnessForTraitConstraint cenv.tcVal g cenv.amap m traitInfo args false |> CommitOperationResult
else
None
match minfoOpt with
Expand Down