Repository navigation
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
| | _ -> None) | ||
| | _ -> None) | ||
|
|
||
| let GetTraitConstraintForCodegen (g: TcGlobals) (traitInfo: TraitConstraintInfo) = |
There was a problem hiding this comment.
This replaces the source-position replay from #19602 with witnesses in each call's existing constraint cells. RFC FS-1043 remains supported.
| let css = CreateCodegenState tcVal g amap | ||
| let csenv = MakeConstraintSolverEnv ContextInfo.NoContext css m (DisplayEnv.Empty g) | ||
| // Failed probes must not persist provisional solutions in generic inline bodies. | ||
| NoTrace.CollectThenUndoOrCommit |
There was a problem hiding this comment.
Failed codegen probes now undo provisional solutions. Generic forwarding keeps its witness arguments without optimization.
| minfo.IsExtensionMember || | ||
| // The fallback must not expose explicit interface implementations as ordinary operators. | ||
| not (IsTraitMethodOnSupportType g traitInfo minfo)) | ||
| CreateTraitContext selectExtensionMethods nenv AccessibleFromEverywhere |
There was a problem hiding this comment.
Normal extension lookup replaces the manual fallback from #19602. Earlier files supply signature values, which code generation can bind.
| and OptimizeTraitCall cenv env (traitInfo, args, m) = | ||
|
|
||
| let g = cenv.g | ||
| let traitInfo = ConstraintSolver.GetTraitConstraintForCodegen g traitInfo |
There was a problem hiding this comment.
This removes the replay recovery from #19602. The optimizer uses the retained witness before fallback lookup.
| OptimizeExpr cenv env specLambda |> fst | ||
|
|
||
| // Equal types do not imply equal consumer-selected extension witnesses. | ||
| let canCacheSpecialization = |
There was a problem hiding this comment.
When imported traits lack a captured scope, equal types can select different extension witnesses. These specializations skip cache reuse, not recursion protection.
| // The outer ConditionalWeakTable partitions the record by the CCU being compiled so nothing leaks or | ||
| // cross-contaminates when a single shared (framework) TcGlobals serves many projects under FCS. | ||
| // Not serialized (consistent with traitCtxt): purely intra-compilation. | ||
| let extensionOperatorSolutions = |
There was a problem hiding this comment.
This removes the replay table from #19602 and its FSI reset hooks. Each call's constraint cells now retain the witness.
|
|
||
| member _.AccessRights = ad | ||
|
|
||
| member _.Remap(remapType, remapValRef, remapStamp) = |
There was a problem hiding this comment.
The captured scope from #19602 now follows normal identity remapping through signatures and inline copies. NameResolution stays unchanged.
Keep exception-safe rollback. Refresh the exact neg45 baseline and run the existing case on every runtime and in Debug. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
/azp run fsharp-ci |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
| let canCacheSpecialization = | ||
| allTyargsAreConcrete && | ||
| (not (g.langVersion.SupportsFeature LanguageFeature.ExtensionConstraintSolutions) || | ||
| traits |> List.forall (fun traitInfo -> traitInfo.TraitContext.IsSome)) |
There was a problem hiding this comment.
🤖🕵️ Silent wrong-code under --langversion:preview --optimize-: a captured context still allows a specialization with B's witness to be reused for an independent A call.
module A =
type System.String with
static member (*) (x: string, y: string) = x + y
let inline combine x y = x * y
module B =
type System.String with
static member (*) (x: string, y: string) = y + x
let inline combineTwice x y =
let first = x * y
first, A.combine x y
[<EntryPoint>]
let main _ =
printfn "B=%A" (B.combineTwice "a" "b")
printfn "A=%s" (A.combine "a" "b")
0--optimize-: B=("ba", "ba"), A=ba. --optimize+, or removing the preceding B call: A=ab. Reproduced with both realsig modes. The base compiler rejects the unoptimized case; this PR newly accepts it with the wrong result. Cache eligibility needs to account for the effective selected witnesses, not just the presence of TraitContext.
Keep intrinsic candidates separate from scope-provided operators. Prefer applicable primitive built-ins while preserving heterogeneous extension solutions and witness transport. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use a struct tuple instead of an anonymous struct record for the internal lookup result. Preserve candidate origin, order and built-in arbitration without adding generated public types or changing the API baseline. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Description
Fixes #20683
Fixes #20684
Fixes #20685
Inline calls keep their extension constraints and selected witnesses. Generic extension forwarding also compiles without optimization.
Checklist
Test cases added
Performance benchmarks added in case of performance changes
Release notes entry updated: