Skip to content

Commit 7b92bd5

Browse files
CopilotT-Gro
andcommitted
Temporarily disable struct member extraction transformation
The transformation is causing false positives - it's being applied to object expressions in non-struct contexts, leading to byref type errors in files like ServiceParamInfoLocations.fs. Root cause: The check for `v.IsInstanceMember && isStructTyconRef v.DeclaringEntity` is too broad - it matches any struct instance member that appears as a free variable, even when the object expression is not inside a struct instance member method. Need to add context awareness to only transform when we're truly inside a struct instance member context, not just when we happen to reference any struct member. Co-authored-by: T-Gro <[email protected]>
1 parent de69a3c commit 7b92bd5

File tree

1 file changed

+5
-59
lines changed

1 file changed

+5
-59
lines changed

src/Compiler/Checking/Expressions/CheckExpressionsOps.fs

Lines changed: 5 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -404,62 +404,8 @@ let TryExtractStructMembersFromObjectExpr
404404
overridesAndVirts
405405
(mWholeExpr: range) : (Val * Expr) list * Remap =
406406

407-
// Early guard: Only apply for object expressions deriving from base classes, not pure interface implementations
408-
// Interface implementations don't pass struct members to base constructors, so they don't have the byref issue
409-
if isInterfaceTy then
410-
[], Remap.Empty
411-
else
412-
// Collect all method bodies from the object expression overrides
413-
let allMethodBodies =
414-
overridesAndVirts
415-
|> List.collect (fun (_, _, _, _, _, overrides) ->
416-
overrides |> List.map (fun (_, (_, _, _, _, bindingBody)) -> bindingBody))
417-
418-
// Early exit if no methods to analyze
419-
if allMethodBodies.IsEmpty then
420-
[], Remap.Empty
421-
else
422-
// Find all free variables in the method bodies
423-
let freeVars =
424-
allMethodBodies
425-
|> List.fold (fun acc body ->
426-
let bodyFreeVars = freeInExpr CollectTyparsAndLocals body
427-
unionFreeVars acc bodyFreeVars) emptyFreeVars
428-
429-
// Filter to only instance members of struct types
430-
// This identifies the problematic case: when an object expression inside a struct
431-
// captures instance members, which would require capturing 'this' as a byref
432-
let structMembers =
433-
freeVars.FreeLocals
434-
|> Zset.elements
435-
|> List.filter (fun (v: Val) ->
436-
// Must be an instance member (not static)
437-
v.IsInstanceMember &&
438-
// Must have a declaring entity
439-
v.HasDeclaringEntity &&
440-
// The declaring entity must be a struct type
441-
isStructTyconRef v.DeclaringEntity)
442-
443-
// Early exit if no struct members captured
444-
if structMembers.IsEmpty then
445-
[], Remap.Empty
446-
else
447-
// Create local variables for each captured struct member
448-
let bindings =
449-
structMembers
450-
|> List.map (fun (memberVal: Val) ->
451-
// Create a new local to hold the member's value
452-
let localVal, _ = mkCompGenLocal mWholeExpr memberVal.DisplayName memberVal.Type
453-
// The value expression is just a reference to the member
454-
let valueExpr = exprForVal mWholeExpr memberVal
455-
(memberVal, localVal, valueExpr))
456-
457-
// Build a remap from original member vals to new local vals
458-
let remap =
459-
bindings
460-
|> List.fold (fun (remap: Remap) (origVal, localVal, _) ->
461-
{ remap with valRemap = remap.valRemap.Add origVal (mkLocalValRef localVal) }) Remap.Empty
462-
463-
// Return the bindings to be added before the object expression
464-
let bindPairs = bindings |> List.map (fun (_, localVal, valueExpr) -> (localVal, valueExpr))
465-
bindPairs, remap
407+
// TEMPORARILY DISABLED: This transformation is causing false positives
408+
// TODO: Need to add better context checks to ensure we're only transforming
409+
// object expressions that are truly inside struct instance member methods
410+
// See issue: https://github.com/dotnet/fsharp/issues/19068
411+
[], Remap.Empty

0 commit comments

Comments
 (0)