@@ -131,12 +131,11 @@ module UsageTracking =
131
131
let isBoxScoped ctx name =
132
132
ctx.ScopedSymbols |> Map.tryFind name |> Option.map ( fun s -> s.IsBox) |> Option.defaultValue false
133
133
134
- let usageCount name usages =
134
+ let usageCount name usages =
135
135
Map.tryFind name usages |> Option.defaultValue 0
136
136
137
137
let hasMultipleUses ( name : string ) =
138
138
Map.tryFind name >> Option.map ( fun x -> x > 1 ) >> Option.defaultValue true
139
- //fun _ -> true
140
139
141
140
module TypeInfo =
142
141
@@ -230,6 +229,14 @@ module TypeInfo =
230
229
not ( ent |> hasStructuralEquality)
231
230
| _ -> false
232
231
232
+ let hasMutableFields ( com : IRustCompiler ) ( ent : Fable.Entity ) =
233
+ if ent.IsFSharpUnion then
234
+ ent.UnionCases |> Seq.exists ( fun uci ->
235
+ uci.UnionCaseFields |> List.exists ( fun fi -> fi.IsMutable)
236
+ )
237
+ else
238
+ ent.FSharpFields |> Seq.exists ( fun fi -> fi.IsMutable)
239
+
233
240
let isEntityOfType ( com : IRustCompiler ) isTypeOf entNames ( ent : Fable.Entity ) =
234
241
if Set.contains ent.FullName entNames then
235
242
true // already checked, avoids circular checks
@@ -330,6 +337,7 @@ module TypeInfo =
330
337
let isCopyableEntity com entNames ( ent : Fable.Entity ) =
331
338
not ( ent.IsInterface)
332
339
&& ent.IsValueType
340
+ && not ( hasMutableFields com ent)
333
341
&& ( isEntityOfType com isCopyableType entNames ent)
334
342
335
343
let isEquatableType ( com : IRustCompiler ) entNames typ =
@@ -448,6 +456,7 @@ module TypeInfo =
448
456
| Fable.DelegateType _
449
457
| Fable.Option _
450
458
| Fable.List _
459
+ | Fable.Array _
451
460
-> true
452
461
453
462
| Fable.AnonymousRecordType _ -> true
@@ -463,10 +472,13 @@ module TypeInfo =
463
472
| Fable.UnionField _
464
473
| Fable.FieldGet _
465
474
| Fable.ListHead _
466
- | Fable.ListTail _ -> true
475
+ | Fable.ListTail _
476
+ -> true
477
+
467
478
| Fable.TupleIndex _
468
479
| Fable.ExprGet _
469
- | Fable.UnionTag _ -> false
480
+ | Fable.UnionTag _
481
+ -> false
470
482
// TODO: Add isForced flag to distinguish between value accessed in pattern matching or not
471
483
| Fable.IdentExpr _
472
484
-> true
@@ -1292,7 +1304,7 @@ module Util =
1292
1304
if shouldBeRefCountWrapped com ctx typ |> Option.isSome
1293
1305
then makeAsRef expr
1294
1306
else
1295
- if isRefScoped ctx name
1307
+ if isRefScoped ctx name || ( isInRefType com typ )
1296
1308
then expr
1297
1309
else expr |> mkAddrOfExpr
1298
1310
@@ -1620,8 +1632,8 @@ module Util =
1620
1632
expr |> mkAddrOfExpr
1621
1633
elif Option.exists ( isByRefType com) t && not varAttrs.IsRef then //implicit syntax
1622
1634
expr |> mkAddrOfExpr
1623
- elif shouldBeRefCountWrapped com ctx e.Type |> Option.isSome && not isOnlyReference then
1624
- expr |> makeClone
1635
+ // elif shouldBeRefCountWrapped com ctx e.Type |> Option.isSome && not isOnlyReference then
1636
+ // expr |> makeClone
1625
1637
elif isCloneableType com e.Type && not isOnlyReference then
1626
1638
expr |> makeClone // TODO: can this clone be removed somehow?
1627
1639
elif varAttrs.IsRef then
0 commit comments