Skip to content

Commit ce9be9c

Browse files
authored
[Rust] Fixed derived traits mapping (#3947)
1 parent a60bf5a commit ce9be9c

File tree

3 files changed

+55
-28
lines changed

3 files changed

+55
-28
lines changed

src/Fable.Cli/CHANGELOG.md

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

88
## Unreleased
99

10+
### Fixed
11+
12+
* [Rust] Fixed derived traits mapping (by @ncave)
13+
1014
## 4.23.0 - 2024-10-28
1115

1216
### Added

src/Fable.Transforms/Rust/Fable2Rust.fs

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -437,14 +437,12 @@ module TypeInfo =
437437
// TODO: more unprintable types?
438438
| _ -> hasTypeOfType com isNonPrintableType isNonPrintableEntity entNames typ
439439

440-
let isNonPrintableEntity com entNames (ent: Fable.Entity) = false
441-
// || (hasFieldOfType com isNonPrintableType entNames ent)
440+
let isNonPrintableEntity com entNames (ent: Fable.Entity) =
441+
ent.IsInterface || (hasFieldOfType com isNonPrintableType entNames ent)
442442

443443
let isNonDefaultableType (com: IRustCompiler) entNames typ =
444444
match typ with
445445
// TODO: more undefaultable types?
446-
// | Fable.LambdaType _
447-
// | Fable.DelegateType _ -> true
448446
| _ -> hasTypeOfType com isNonDefaultableType isNonDefaultableEntity entNames typ
449447

450448
let isNonDefaultableEntity com entNames (ent: Fable.Entity) =
@@ -470,7 +468,8 @@ module TypeInfo =
470468
| _ -> hasTypeOfType com isNonCopyableType isNonCopyableEntity entNames typ
471469

472470
let isNonCopyableEntity com entNames (ent: Fable.Entity) =
473-
not ent.IsValueType
471+
ent.IsInterface
472+
|| not ent.IsValueType
474473
|| (hasMutableFields com ent)
475474
|| (hasFieldOfType com isNonCopyableType entNames ent)
476475

@@ -488,8 +487,9 @@ module TypeInfo =
488487
| _ -> hasTypeOfType com isNonEquatableType isNonEquatableEntity entNames typ
489488

490489
let isNonEquatableEntity com entNames (ent: Fable.Entity) =
491-
ent.IsInterface || not (FSharp2Fable.Util.hasStructuralEquality ent)
492-
// || (hasFieldOfType com isNonEquatableType entNames ent)
490+
ent.IsInterface
491+
|| not (FSharp2Fable.Util.hasStructuralEquality ent)
492+
|| (hasFieldOfType com isNonEquatableType entNames ent)
493493

494494
let isNonComparableType (com: IRustCompiler) entNames typ =
495495
match typ with
@@ -3897,15 +3897,24 @@ module Util =
38973897
let defaultTypeBounds =
38983898
[
38993899
mkTypeTraitGenericBound [ rawIdent "Clone" ] None
3900+
// mkTypeTraitGenericBound [ rawIdent "Send" ] None
3901+
// mkTypeTraitGenericBound [ rawIdent "Sync" ] None
39003902
mkLifetimeGenericBound "'static" //TODO: add it only when needed
39013903
]
39023904

3905+
let makeDefaultTypeBounds com ctx =
3906+
// let importName = getLibraryImportName com ctx "Native" "IObject"
3907+
// let objectBound = mkTypeTraitGenericBound [ importName ] None
3908+
// objectBound :: defaultTypeBounds
3909+
defaultTypeBounds
3910+
39033911
let makeGenericParams com ctx (genParams: Fable.GenericParam list) =
39043912
genParams
39053913
|> List.filter (fun p -> not p.IsMeasure)
39063914
|> List.map (fun p ->
39073915
let typeBounds = makeTypeBounds com ctx p.Name p.Constraints
3908-
mkGenericParamFromName [] p.Name (typeBounds @ defaultTypeBounds)
3916+
let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx)
3917+
mkGenericParamFromName [] p.Name typeBounds
39093918
)
39103919

39113920
let makeGenericParamsFromArgs com ctx (genArgs: Fable.Type list) =
@@ -3914,7 +3923,8 @@ module Util =
39143923
function
39153924
| Fable.GenericParam(name, isMeasure, constraints) when not isMeasure ->
39163925
let typeBounds = makeTypeBounds com ctx name constraints
3917-
mkGenericParamFromName [] name (typeBounds @ defaultTypeBounds) |> Some
3926+
let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx)
3927+
mkGenericParamFromName [] name typeBounds |> Some
39183928
| _ -> None
39193929
)
39203930

@@ -4052,7 +4062,8 @@ module Util =
40524062
// | Fable.DeclaredType(entRef, genArgs) :: _ ->
40534063
// let entName = getEntityFullName com ctx entRef
40544064
// let memberItem = makeMemberItem com ctx true (decl, memb)
4055-
// [ memberItem ] |> makeTraitImpls com ctx entName genArgs None
4065+
// let implItem = [ memberItem ] |> makeTraitImpl com ctx entName genArgs None
4066+
// [ implItem ]
40564067
// | _ -> []
40574068

40584069
let transformModuleFunction (com: IRustCompiler) ctx (memb: Fable.MemberFunctionOrValue) (decl: Fable.MemberDecl) =
@@ -4254,7 +4265,8 @@ module Util =
42544265
fnItem
42554266

42564267
let makeDerivedFrom com (ent: Fable.Entity) =
4257-
// let isCopyable = not (ent |> isNonCopyableEntity com Set.empty)
4268+
let isCopyable = false //not (ent |> isNonCopyableEntity com Set.empty)
4269+
let isCloneable = true //not (ent |> isNonCloneableEntity com Set.empty)
42584270
let isPrintable = not (ent |> isNonPrintableEntity com Set.empty)
42594271
let isDefaultable = not (ent |> isNonDefaultableEntity com Set.empty)
42604272
let isHashable = not (ent |> isNonHashableEntity com Set.empty)
@@ -4263,9 +4275,10 @@ module Util =
42634275

42644276
let derivedFrom =
42654277
[
4266-
rawIdent "Clone"
4267-
// if isCopyable then
4268-
// rawIdent "Copy"
4278+
if isCopyable then
4279+
rawIdent "Copy"
4280+
if isCloneable then
4281+
rawIdent "Clone"
42694282
if isPrintable then
42704283
rawIdent "Debug"
42714284
if isDefaultable then
@@ -4515,9 +4528,7 @@ module Util =
45154528
let traitItem =
45164529
let assocItems = makeInterfaceItems com ctx false typeName ent
45174530
let generics = makeGenerics com ctx genArgs
4518-
// let sendBound = mkTypeTraitGenericBound [ rawIdent "Send" ] None
4519-
// let syncBound = mkTypeTraitGenericBound [ rawIdent "Sync" ] None
4520-
let traitBounds = [] // [ sendBound; syncBound ]
4531+
let traitBounds = [] // (makeDefaultTypeBounds com ctx)
45214532
let attrs = transformAttributes com ctx ent.Attributes decl.XmlDoc
45224533
mkTraitItem attrs entName assocItems traitBounds generics
45234534

@@ -4526,7 +4537,7 @@ module Util =
45264537
let memberItems = makeInterfaceItems com ctx true typeName ent
45274538
let genArgsOpt = transformGenArgs com ctx genArgs
45284539
let traitBound = mkTypeTraitGenericBound [ entName ] genArgsOpt
4529-
let typeBounds = traitBound :: defaultTypeBounds
4540+
let typeBounds = traitBound :: (makeDefaultTypeBounds com ctx)
45304541
let typeParam = mkGenericParamFromName [] typeName typeBounds
45314542
let genParams = makeGenericParamsFromArgs com ctx genArgs
45324543
let generics = typeParam :: genParams |> mkGenerics
@@ -4614,10 +4625,11 @@ module Util =
46144625
let ofTrait = mkTraitRef path |> Some
46154626
let assocItems = [ tyItem; fnItem ]
46164627

4617-
assocItems |> makeTraitImpls com ctx entName genArgs ofTrait
4628+
let implItem = assocItems |> makeTraitImpl com ctx entName genArgs ofTrait
4629+
[ implItem ]
46184630
| _ -> []
46194631

4620-
let makeDisplayTraitImpls com ctx entName genArgs hasToString =
4632+
let makeDisplayTraitImpls com ctx entName genArgs hasToString hasDebug =
46214633
// expected output:
46224634
// impl core::fmt::Display for {self_ty} {
46234635
// fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
@@ -4649,10 +4661,16 @@ module Util =
46494661
let fnKind = mkFnKind DEFAULT_FN_HEADER fnDecl NO_GENERICS fnBody
46504662
let fnItem = mkFnAssocItem [] "fmt" fnKind
46514663

4652-
let path = mkGenericPath ("core" :: "fmt" :: "Display" :: []) None
4653-
let ofTrait = mkTraitRef path |> Some
4664+
let makeItem fmtTrait =
4665+
let path = mkGenericPath ("core" :: "fmt" :: fmtTrait :: []) None
4666+
let ofTrait = mkTraitRef path |> Some
4667+
let implItem = [ fnItem ] |> makeTraitImpl com ctx entName genArgs ofTrait
4668+
implItem
46544669

4655-
[ fnItem ] |> makeTraitImpls com ctx entName genArgs ofTrait
4670+
if hasDebug then
4671+
[ makeItem "Debug"; makeItem "Display" ]
4672+
else
4673+
[ makeItem "Display" ]
46564674

46574675
let op_impl_map =
46584676
Map
@@ -4757,21 +4775,22 @@ module Util =
47574775

47584776
[ ctorItem ]
47594777

4760-
let makeTraitImpls (com: IRustCompiler) ctx entName genArgs ofTrait memberItems =
4778+
let makeTraitImpl (com: IRustCompiler) ctx entName genArgs ofTrait memberItems =
47614779
let nameParts = entName |> splitNameParts
47624780
let genArgsOpt = transformGenArgs com ctx genArgs
47634781
let traitBound = mkTypeTraitGenericBound nameParts genArgsOpt
47644782
let self_ty = mkTraitTy [ traitBound ]
47654783
let generics = makeGenerics com ctx genArgs
47664784
let implItem = mkImplItem [] "" self_ty generics memberItems ofTrait
4767-
[ implItem ]
4785+
implItem
47684786

47694787
let makeInterfaceTraitImpls (com: IRustCompiler) ctx entName genArgs ifcEntRef ifcGenArgs memberItems =
47704788
let ifcFullName = getEntityFullName com ctx ifcEntRef
47714789
let ifcGenArgsOpt = transformGenArgs com ctx ifcGenArgs
47724790
let path = makeFullNamePath ifcFullName ifcGenArgsOpt
47734791
let ofTrait = mkTraitRef path |> Some
4774-
memberItems |> makeTraitImpls com ctx entName genArgs ofTrait
4792+
let implItem = memberItems |> makeTraitImpl com ctx entName genArgs ofTrait
4793+
[ implItem ]
47754794

47764795
// let objectMemberNames =
47774796
// set
@@ -4838,7 +4857,8 @@ module Util =
48384857
if List.isEmpty memberItems then
48394858
[]
48404859
else
4841-
memberItems |> makeTraitImpls com ctx entName genArgs None
4860+
let implItem = memberItems |> makeTraitImpl com ctx entName genArgs None
4861+
[ implItem ]
48424862

48434863
let baseTypeOpt =
48444864
if isObjectExpr then
@@ -4855,7 +4875,7 @@ module Util =
48554875
let hasToString =
48564876
nonInterfaceMembers |> List.exists (fun (d, m) -> m.CompiledName = "ToString")
48574877

4858-
makeDisplayTraitImpls com ctx entName genParams hasToString
4878+
makeDisplayTraitImpls com ctx entName genParams hasToString false
48594879

48604880
let operatorTraitImpls =
48614881
nonInterfaceMembers |> makeOpTraitImpls com ctx ent entName genArgs

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub mod Native_ {
6868
use core::fmt::{Debug, Display, Formatter, Result};
6969
use core::hash::{BuildHasher, Hash, Hasher};
7070

71+
// default object trait
72+
// pub trait IObject: Clone + Debug + 'static {}
73+
7174
// -----------------------------------------------------------
7275
// Helpers
7376
// -----------------------------------------------------------

0 commit comments

Comments
 (0)