Skip to content

Commit 9215132

Browse files
committed
[Rust] Updated derived interfaces
1 parent 4612e59 commit 9215132

File tree

8 files changed

+193
-179
lines changed

8 files changed

+193
-179
lines changed

.vscode/launch.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,21 @@
272272
"cwd": "${workspaceRoot}/../fable-test",
273273
"stopAtEntry": false,
274274
"console": "internalConsole"
275+
},
276+
{
277+
"name": "Bench.Cli on ../fable-test",
278+
"type": "coreclr",
279+
"request": "launch",
280+
"program": "${workspaceRoot}/src/fable-standalone/test/bench-compiler/src/bin/Debug/net8.0/bench-compiler.dll",
281+
"args": [
282+
"fable-test.fsproj",
283+
"--outDir", "${workspaceRoot}/../fable-test",
284+
"--fableLib", "${workspaceRoot}/temp/fable-library-rust",
285+
"--lang", "Rust"
286+
],
287+
"cwd": "${workspaceRoot}/../fable-test",
288+
"stopAtEntry": false,
289+
"console": "internalConsole"
275290
}
276291
]
277292
}

src/Fable.Cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
* [Rust] Updated derived interfaces (by @ncave)
1213
* [Rust] Updated string comparisons (by @ncave)
1314
* [Rust] Fixed derived traits mapping (by @ncave)
1415
* [JS/TS] Added missing ICollection helpers (#3914) (by @ncave)

src/Fable.Transforms/Rust/Fable2Rust.fs

Lines changed: 91 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -402,96 +402,95 @@ module TypeInfo =
402402
ent.IsValueType
403403
| _ -> false
404404

405-
let hasTypeOfType (com: IRustCompiler) isTypeOf isEntityOf entNames typ =
405+
let isTypeOfType (com: IRustCompiler) isTypeOf isEntityOf entNames typ =
406406
match typ with
407407
| Fable.Option(genArg, _) -> isTypeOf com entNames genArg
408408
| Fable.Array(genArg, _) -> isTypeOf com entNames genArg
409409
| Fable.List genArg -> isTypeOf com entNames genArg
410-
| Fable.Tuple(genArgs, _) -> List.exists (isTypeOf com entNames) genArgs
411-
| Fable.AnonymousRecordType(_, genArgs, _) -> List.exists (isTypeOf com entNames) genArgs
410+
| Fable.Tuple(genArgs, _) -> List.forall (isTypeOf com entNames) genArgs
411+
| Fable.AnonymousRecordType(_, genArgs, _) -> List.forall (isTypeOf com entNames) genArgs
412412
| Replacements.Util.Builtin(Replacements.Util.FSharpSet genArg) -> isTypeOf com entNames genArg
413413
| Replacements.Util.Builtin(Replacements.Util.FSharpMap(k, v)) ->
414-
isTypeOf com entNames k || isTypeOf com entNames v
414+
isTypeOf com entNames k && isTypeOf com entNames v
415415
| Fable.DeclaredType(entRef, _genArgs) ->
416416
let ent = com.GetEntity(entRef)
417-
isEntityOf com entNames ent //|| hasFieldOfType com isTypeOf entNames ent
418-
| _ -> false
417+
isEntityOf com entNames ent
418+
| _ -> true
419419

420-
let hasFieldOfType (com: IRustCompiler) isTypeOf entNames (ent: Fable.Entity) =
420+
let hasFieldsOfType (com: IRustCompiler) isTypeOf entNames (ent: Fable.Entity) =
421421
if Set.contains ent.FullName entNames then
422-
false // already checked, avoids circular checks
422+
true // already checked, avoids circular checks
423423
else
424424
let entNames = Set.add ent.FullName entNames
425425

426426
if ent.IsFSharpUnion then
427427
ent.UnionCases
428-
|> Seq.exists (fun uci ->
428+
|> Seq.forall (fun uci ->
429429
uci.UnionCaseFields
430-
|> List.exists (fun fi -> isTypeOf com entNames fi.FieldType)
430+
|> List.forall (fun fi -> isTypeOf com entNames fi.FieldType)
431431
)
432432
else
433-
ent.FSharpFields |> Seq.exists (fun fi -> isTypeOf com entNames fi.FieldType)
433+
ent.FSharpFields |> Seq.forall (fun fi -> isTypeOf com entNames fi.FieldType)
434434

435-
let isNonPrintableType (com: IRustCompiler) entNames typ =
436-
match typ with
437-
// TODO: more unprintable types?
438-
| _ -> hasTypeOfType com isNonPrintableType isNonPrintableEntity entNames typ
435+
// let isPrintableType (com: IRustCompiler) entNames typ =
436+
// match typ with
437+
// // TODO: more unprintable types?
438+
// | _ -> isTypeOfType com isPrintableType isPrintableEntity entNames typ
439439

440-
let isNonPrintableEntity com entNames (ent: Fable.Entity) =
441-
ent.IsInterface || (hasFieldOfType com isNonPrintableType entNames ent)
440+
let isPrintableEntity com entNames (ent: Fable.Entity) = (List.isEmpty ent.GenericParameters)
441+
// && (hasFieldsOfType com isPrintableType entNames ent) // commented as it kills performance
442442

443-
let isNonDefaultableType (com: IRustCompiler) entNames typ =
443+
let isDefaultableType (com: IRustCompiler) entNames typ =
444444
match typ with
445445
// TODO: more undefaultable types?
446-
| _ -> hasTypeOfType com isNonDefaultableType isNonDefaultableEntity entNames typ
447-
448-
let isNonDefaultableEntity com entNames (ent: Fable.Entity) =
449-
ent.IsInterface
450-
|| not ent.IsValueType
451-
|| ent.IsFSharpUnion // deriving 'Default' on enums is experimental
452-
|| (hasFieldOfType com isNonDefaultableType entNames ent)
453-
454-
let isNonCopyableType (com: IRustCompiler) entNames typ =
455-
match typ with
456-
// TODO: more uncopyable types?
457-
| Fable.Any
458-
| Fable.Unit
459-
| Fable.Measure _
460-
| Fable.MetaType
461-
| Fable.LambdaType _
462-
| Fable.DelegateType _
463-
| Fable.GenericParam _
464-
| Fable.String
465-
| Fable.Regex -> true
466-
| Fable.Tuple(genArgs, isStruct) when not isStruct -> true
467-
| Fable.AnonymousRecordType(_, genArgs, isStruct) when not isStruct -> true
468-
| _ -> hasTypeOfType com isNonCopyableType isNonCopyableEntity entNames typ
469-
470-
let isNonCopyableEntity com entNames (ent: Fable.Entity) =
471-
ent.IsInterface
472-
|| not ent.IsValueType
473-
|| (hasMutableFields com ent)
474-
|| (hasFieldOfType com isNonCopyableType entNames ent)
475-
476-
let isNonEquatableType (com: IRustCompiler) entNames typ =
446+
| _ -> isTypeOfType com isDefaultableType isDefaultableEntity entNames typ
447+
448+
let isDefaultableEntity com entNames (ent: Fable.Entity) =
449+
ent.IsValueType
450+
&& not ent.IsFSharpUnion // default union cases are quite limited
451+
&& (hasFieldsOfType com isDefaultableType entNames ent)
452+
453+
// let isCopyableType (com: IRustCompiler) entNames typ =
454+
// match typ with
455+
// // TODO: more uncopyable types?
456+
// | Fable.Any
457+
// | Fable.Unit
458+
// | Fable.Measure _
459+
// | Fable.MetaType
460+
// | Fable.LambdaType _
461+
// | Fable.DelegateType _
462+
// | Fable.GenericParam _
463+
// | Fable.String
464+
// | Fable.Regex
465+
// | Fable.List _ -> false
466+
// | Fable.Option(_, isStruct) when not isStruct -> false
467+
// | Fable.Tuple(_, isStruct) when not isStruct -> false
468+
// | Fable.AnonymousRecordType(_, _, isStruct) when not isStruct -> false
469+
// | _ -> isTypeOfType com isCopyableType isCopyableEntity entNames typ
470+
471+
// let isCopyableEntity com entNames (ent: Fable.Entity) =
472+
// ent.IsValueType
473+
// && not (hasMutableFields com ent)
474+
// && (hasFieldsOfType com isCopyableType entNames ent)
475+
476+
let isEquatableType (com: IRustCompiler) entNames typ =
477477
match typ with
478478
// TODO: more unequatable types?
479479
| Fable.Any
480480
| Fable.Unit
481481
| Fable.Measure _
482482
| Fable.MetaType
483483
| Fable.LambdaType _
484-
| Fable.DelegateType _ -> true
484+
| Fable.DelegateType _ -> false
485485
// | Fable.GenericParam(_, _, constraints) ->
486-
// not (constraints |> List.contains Fable.Constraint.HasEquality)
487-
| _ -> hasTypeOfType com isNonEquatableType isNonEquatableEntity entNames typ
486+
// constraints |> List.contains Fable.Constraint.HasEquality
487+
| _ -> isTypeOfType com isEquatableType isEquatableEntity entNames typ
488488

489-
let isNonEquatableEntity com entNames (ent: Fable.Entity) =
490-
ent.IsInterface
491-
|| not (FSharp2Fable.Util.hasStructuralEquality ent)
492-
|| (hasFieldOfType com isNonEquatableType entNames ent)
489+
let isEquatableEntity com entNames (ent: Fable.Entity) =
490+
(FSharp2Fable.Util.hasStructuralEquality ent)
491+
&& (hasFieldsOfType com isEquatableType entNames ent)
493492

494-
let isNonComparableType (com: IRustCompiler) entNames typ =
493+
let isComparableType (com: IRustCompiler) entNames typ =
495494
match typ with
496495
// TODO: more uncomparable types?
497496
| Fable.Any
@@ -500,17 +499,16 @@ module TypeInfo =
500499
| Fable.MetaType
501500
| Fable.LambdaType _
502501
| Fable.DelegateType _
503-
| Fable.Regex -> true
502+
| Fable.Regex -> false
504503
// | Fable.GenericParam(_, _, constraints) ->
505-
// not (constraints |> List.contains Fable.Constraint.HasComparison)
506-
| _ -> hasTypeOfType com isNonComparableType isNonComparableEntity entNames typ
504+
// constraints |> List.contains Fable.Constraint.HasComparison
505+
| _ -> isTypeOfType com isComparableType isComparableEntity entNames typ
507506

508-
let isNonComparableEntity com entNames (ent: Fable.Entity) =
509-
ent.IsInterface
510-
|| not (FSharp2Fable.Util.hasStructuralComparison ent)
511-
|| (hasFieldOfType com isNonComparableType entNames ent)
507+
let isComparableEntity com entNames (ent: Fable.Entity) =
508+
(FSharp2Fable.Util.hasStructuralComparison ent)
509+
&& (hasFieldsOfType com isComparableType entNames ent)
512510

513-
let isNonHashableType com entNames typ =
511+
let isHashableType com entNames typ =
514512
match typ with
515513
// TODO: more unhashable types?
516514
| Fable.Any
@@ -519,13 +517,12 @@ module TypeInfo =
519517
| Fable.MetaType
520518
| Fable.Number((Float32 | Float64), _)
521519
| Fable.LambdaType _
522-
| Fable.DelegateType _ -> true
523-
| _ -> hasTypeOfType com isNonHashableType isNonHashableEntity entNames typ
520+
| Fable.DelegateType _ -> false
521+
| _ -> isTypeOfType com isHashableType isHashableEntity entNames typ
524522

525-
let isNonHashableEntity com entNames (ent: Fable.Entity) =
526-
ent.IsInterface
527-
|| not (FSharp2Fable.Util.hasStructuralEquality ent)
528-
|| (hasFieldOfType com isNonHashableType entNames ent)
523+
let isHashableEntity com entNames (ent: Fable.Entity) =
524+
(FSharp2Fable.Util.hasStructuralEquality ent)
525+
&& (hasFieldsOfType com isHashableType entNames ent)
529526

530527
let isWrappedType com typ =
531528
match typ with
@@ -3894,6 +3891,12 @@ module Util =
38943891

38953892
constraints |> List.distinct |> List.collect makeConstraint
38963893

3894+
let defaultInterfaceTypeBounds =
3895+
[
3896+
mkTypeTraitGenericBound ("core" :: "fmt" :: "Debug" :: []) None
3897+
mkTypeTraitGenericBound ("core" :: "fmt" :: "Display" :: []) None
3898+
]
3899+
38973900
let defaultTypeBounds =
38983901
[
38993902
mkTypeTraitGenericBound [ rawIdent "Clone" ] None
@@ -3902,18 +3905,17 @@ module Util =
39023905
mkLifetimeGenericBound "'static" //TODO: add it only when needed
39033906
]
39043907

3905-
let makeDefaultTypeBounds com ctx =
3906-
// let importName = getLibraryImportName com ctx "Native" "IObject"
3907-
// let objectBound = mkTypeTraitGenericBound [ importName ] None
3908-
// objectBound :: defaultTypeBounds
3909-
defaultTypeBounds
3908+
// let makeDefaultTypeBounds com ctx =
3909+
// let importName = getLibraryImportName com ctx "Native" "IObject"
3910+
// let objectBound = mkTypeTraitGenericBound [ importName ] None
3911+
// objectBound :: defaultTypeBounds
39103912

39113913
let makeGenericParams com ctx (genParams: Fable.GenericParam list) =
39123914
genParams
39133915
|> List.filter (fun p -> not p.IsMeasure)
39143916
|> List.map (fun p ->
39153917
let typeBounds = makeTypeBounds com ctx p.Name p.Constraints
3916-
let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx)
3918+
let typeBounds = typeBounds @ defaultTypeBounds
39173919
mkGenericParamFromName [] p.Name typeBounds
39183920
)
39193921

@@ -3923,7 +3925,7 @@ module Util =
39233925
function
39243926
| Fable.GenericParam(name, isMeasure, constraints) when not isMeasure ->
39253927
let typeBounds = makeTypeBounds com ctx name constraints
3926-
let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx)
3928+
let typeBounds = typeBounds @ defaultTypeBounds
39273929
mkGenericParamFromName [] name typeBounds |> Some
39283930
| _ -> None
39293931
)
@@ -4265,13 +4267,13 @@ module Util =
42654267
fnItem
42664268

42674269
let makeDerivedFrom com (ent: Fable.Entity) =
4268-
let isCopyable = false //not (ent |> isNonCopyableEntity com Set.empty)
4269-
let isCloneable = true //not (ent |> isNonCloneableEntity com Set.empty)
4270-
let isPrintable = not (ent |> isNonPrintableEntity com Set.empty)
4271-
let isDefaultable = not (ent |> isNonDefaultableEntity com Set.empty)
4272-
let isHashable = not (ent |> isNonHashableEntity com Set.empty)
4273-
let isEquatable = not (ent |> isNonEquatableEntity com Set.empty)
4274-
let isComparable = not (ent |> isNonComparableEntity com Set.empty)
4270+
let isCopyable = false //ent |> isCopyableEntity com Set.empty
4271+
let isCloneable = true //ent |> isCloneableEntity com Set.empty
4272+
let isPrintable = ent |> isPrintableEntity com Set.empty
4273+
let isDefaultable = ent |> isDefaultableEntity com Set.empty
4274+
let isHashable = ent |> isHashableEntity com Set.empty
4275+
let isEquatable = ent |> isEquatableEntity com Set.empty
4276+
let isComparable = ent |> isComparableEntity com Set.empty
42754277

42764278
let derivedFrom =
42774279
[
@@ -4528,7 +4530,7 @@ module Util =
45284530
let traitItem =
45294531
let assocItems = makeInterfaceItems com ctx false typeName ent
45304532
let generics = makeGenerics com ctx genArgs
4531-
let traitBounds = [] // (makeDefaultTypeBounds com ctx)
4533+
let traitBounds = defaultInterfaceTypeBounds
45324534
let attrs = transformAttributes com ctx ent.Attributes decl.XmlDoc
45334535
mkTraitItem attrs entName assocItems traitBounds generics
45344536

@@ -4537,7 +4539,7 @@ module Util =
45374539
let memberItems = makeInterfaceItems com ctx true typeName ent
45384540
let genArgsOpt = transformGenArgs com ctx genArgs
45394541
let traitBound = mkTypeTraitGenericBound [ entName ] genArgsOpt
4540-
let typeBounds = traitBound :: (makeDefaultTypeBounds com ctx)
4542+
let typeBounds = traitBound :: defaultInterfaceTypeBounds
45414543
let typeParam = mkGenericParamFromName [] typeName typeBounds
45424544
let genParams = makeGenericParamsFromArgs com ctx genArgs
45434545
let generics = typeParam :: genParams |> mkGenerics
@@ -4875,7 +4877,8 @@ module Util =
48754877
let hasToString =
48764878
nonInterfaceMembers |> List.exists (fun (d, m) -> m.CompiledName = "ToString")
48774879

4878-
makeDisplayTraitImpls com ctx entName genParams hasToString false
4880+
let hasDebug = not (List.isEmpty ent.GenericParameters)
4881+
makeDisplayTraitImpls com ctx entName genParams hasToString hasDebug
48794882

48804883
let operatorTraitImpls =
48814884
nonInterfaceMembers |> makeOpTraitImpls com ctx ent entName genArgs

src/fable-library-rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ default = ["bigint", "datetime", "decimal", "enum_func", "enum_string", "guid",
2222
chrono = { version = "0.4", optional = true }
2323
futures = { version = "0.3", features = ["executor", "thread-pool"], default-features = false, optional = true }
2424
futures-timer = { version = "3.0", optional = true }
25-
hashbrown = { version = "0.14", optional = true }
25+
hashbrown = { version = "0.15", optional = true }
2626
num-bigint = { version = "0.4", optional = true }
2727
num-integer = { version = "0.1", optional = true }
2828
num-traits = { version = "0.2", optional = true }

src/fable-library-rust/src/LrcPtr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl<T: ?Sized> LrcPtr<T> {
3030
}
3131
}
3232

33-
// impl<T> Default for LrcPtr<T> {
33+
// impl<T: ?Sized> Default for LrcPtr<T> {
3434
// fn default() -> Self {
3535
// Self::null()
3636
// }
@@ -59,27 +59,27 @@ impl<T: ?Sized> Deref for LrcPtr<T> {
5959
}
6060
}
6161

62-
impl<T: core::fmt::Debug> core::fmt::Debug for LrcPtr<T> {
62+
impl<T: ?Sized + core::fmt::Debug> core::fmt::Debug for LrcPtr<T> {
6363
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
6464
write!(f, "{:?}", self.deref())
6565
}
6666
}
6767

68-
impl<T: core::fmt::Display> core::fmt::Display for LrcPtr<T> {
68+
impl<T: ?Sized + core::fmt::Display> core::fmt::Display for LrcPtr<T> {
6969
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
7070
write!(f, "{}", self.deref())
7171
}
7272
}
7373

7474
// // Custom code within the destructor.
75-
// impl<T: Drop> Drop for LrcPtr<T> {
75+
// impl<T: ?Sized + Drop> Drop for LrcPtr<T> {
7676
// fn drop(&mut self) {
7777
// self.0.drop();
7878
// }
7979
// }
8080

8181
// Used for indexing operations (container[index])
82-
impl<T: Index<Idx>, Idx> Index<Idx> for LrcPtr<T> {
82+
impl<T: ?Sized + Index<Idx>, Idx> Index<Idx> for LrcPtr<T> {
8383
type Output = T::Output;
8484

8585
fn index(&self, idx: Idx) -> &Self::Output {

0 commit comments

Comments
 (0)