Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rust] Updated module let bindings #3747

Merged
merged 2 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Fable.Build/Test/Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ let handle (args: string list) =

let cargoTestArgs =
if noStd then
"cargo test --features no_std"
"cargo test --features no_std -- --test-threads=1"
elif threaded then
"cargo test --features threaded"
else
"cargo test"
"cargo test -- --test-threads=1"

let fableArgs =
CmdLine.concat
Expand Down
5 changes: 1 addition & 4 deletions src/Fable.Transforms/Python/Fable2Python.fs
Original file line number Diff line number Diff line change
Expand Up @@ -579,17 +579,14 @@ module Helpers =
| Fable.Any -> true
| _ -> false

let index = (Seq.initInfinite id).GetEnumerator()

let removeNamespace (fullName: string) =
fullName.Split('.')
|> Array.last
|> (fun name -> name.Replace("`", "_"))
|> Helpers.clean

let getUniqueIdentifier (name: string) : Identifier =
do index.MoveNext() |> ignore
let idx = index.Current.ToString()
let idx = Naming.getUniqueIndex ()

let deliminator =
if Char.IsLower name[0] then
Expand Down
6 changes: 6 additions & 0 deletions src/Fable.Transforms/Python/Prelude.fs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ module Naming =

let reflectionSuffix = "_reflection"

let mutable uniqueIndex = 0

let getUniqueIndex () =
let idx = uniqueIndex
uniqueIndex <- uniqueIndex + 1
idx

let preventConflicts conflicts originalName =
let rec check originalName n =
Expand Down
2 changes: 2 additions & 0 deletions src/Fable.Transforms/Rust/AST/Rust.AST.Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,8 @@ module Types =

let mkInferTy () : Ty = TyKind.Infer |> mkTy

let mkNeverTy () : Ty = TyKind.Never |> mkTy

let mkImplSelfTy () : Ty = TyKind.ImplicitSelf |> mkTy

let mkTraitTy bounds : Ty =
Expand Down
79 changes: 33 additions & 46 deletions src/Fable.Transforms/Rust/Fable2Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,9 @@ module TypeInfo =
let makeBoxTy com ctx (ty: Rust.Ty) : Rust.Ty =
[ ty ] |> makeImportType com ctx "Native" "Box"

// TODO: emit Lazy or SyncLazy depending on threading.
let makeLazyTy com ctx (ty: Rust.Ty) : Rust.Ty =
[ ty ] |> makeImportType com ctx "Native" "Lazy"
// // TODO: emit Lazy or SyncLazy depending on threading.
// let makeLazyTy com ctx (ty: Rust.Ty) : Rust.Ty =
// [ ty ] |> makeImportType com ctx "Native" "Lazy"

// TODO: emit MutCell or AtomicCell depending on threading.
let makeMutTy com ctx (ty: Rust.Ty) : Rust.Ty =
Expand Down Expand Up @@ -1011,7 +1011,7 @@ module TypeInfo =

let transformGenericParamType com ctx name isMeasure : Rust.Ty =
if isInferredGenericParam com ctx name isMeasure then
mkInferTy () // makeAnyTy com ctx
mkInferTy () // mnNeverTy com ctx
else
primitiveType name

Expand Down Expand Up @@ -1494,14 +1494,7 @@ module Util =
makeLibCall com ctx None "Seq" "ofArray" [ ar ]

// casts to generic param
| _, Fable.GenericParam(name, _isMeasure, _constraints) ->
makeCall
[
name
"from"
]
None
[ expr ] // e.g. T::from(value)
| _, Fable.GenericParam(name, _isMeasure, _constraints) -> makeCall (name :: "from" :: []) None [ expr ] // e.g. T::from(value)
ncave marked this conversation as resolved.
Show resolved Hide resolved

// casts to IDictionary, for now does nothing // TODO: fix it
| Replacements.Util.IsEntity (Types.dictionary) _, Replacements.Util.IsEntity (Types.idictionary) _ -> expr
Expand Down Expand Up @@ -1533,41 +1526,37 @@ module Util =
let callee = mkGenericPathExpr pathNames genArgs
mkCallExpr callee args

let makeNew com ctx moduleName typeName (value: Rust.Expr) =
let makeNew com ctx moduleName typeName (values: Rust.Expr list) =
let importName = getLibraryImportName com ctx moduleName typeName

makeCall
[
importName
"new"
]
None
[ value ]
makeCall (importName :: "new" :: []) None values

// let makeFrom com ctx moduleName typeName (value: Rust.Expr) =
// let importName = getLibraryImportName com ctx moduleName typeName
// makeCall [importName; "from"] None [value]

let makeFluentValue com ctx (value: Rust.Expr) =
makeLibCall com ctx None "Native" "fromFluent" [ value ]
[ value ] |> makeLibCall com ctx None "Native" "fromFluent"

let makeLrcPtrValue com ctx (value: Rust.Expr) =
value |> makeNew com ctx "Native" "LrcPtr"
[ value ] |> makeNew com ctx "Native" "LrcPtr"

// let makeLrcValue com ctx (value: Rust.Expr) =
// value |> makeNew com ctx "Native" "Lrc"
// [ value ] |> makeNew com ctx "Native" "Lrc"

let makeRcValue com ctx (value: Rust.Expr) = value |> makeNew com ctx "Native" "Rc"
let makeRcValue com ctx (value: Rust.Expr) =
[ value ] |> makeNew com ctx "Native" "Rc"

let makeArcValue com ctx (value: Rust.Expr) = value |> makeNew com ctx "Native" "Arc"
let makeArcValue com ctx (value: Rust.Expr) =
[ value ] |> makeNew com ctx "Native" "Arc"

let makeBoxValue com ctx (value: Rust.Expr) = value |> makeNew com ctx "Native" "Box"
let makeBoxValue com ctx (value: Rust.Expr) =
[ value ] |> makeNew com ctx "Native" "Box"

let makeMutValue com ctx (value: Rust.Expr) =
value |> makeNew com ctx "Native" "MutCell"
[ value ] |> makeNew com ctx "Native" "MutCell"

let makeLazyValue com ctx (value: Rust.Expr) =
value |> makeNew com ctx "Native" "Lazy"
// let makeLazyValue com ctx (value: Rust.Expr) =
// [ value ] |> makeNew com ctx "Native" "Lazy"

let makeFuncValue com ctx (ident: Fable.Ident) =
let argTypes =
Expand All @@ -1585,13 +1574,7 @@ module Util =
let funcWrap = getLibraryImportName com ctx "Native" ("Func" + argCount)
let expr = transformIdent com ctx None ident

makeCall
[
funcWrap
"from"
]
None
[ expr ]
makeCall (funcWrap :: "from" :: []) None [ expr ]

let maybeWrapSmartPtr com ctx ent expr =
match ent with
Expand Down Expand Up @@ -2432,7 +2415,8 @@ module Util =
let callee = transformCallee com ctx calleeExpr
mkCallExpr callee args

let mutableGet expr = mkMethodCallExpr "get" None expr []
let mutableGet expr =
mkMethodCallExpr "get" None expr [] |> makeClone

let mutableGetMut expr = mkMethodCallExpr "get_mut" None expr []

Expand Down Expand Up @@ -3978,14 +3962,13 @@ module Util =
let transformModuleLetValue (com: IRustCompiler) ctx (memb: Fable.MemberFunctionOrValue) (decl: Fable.MemberDecl) =
// expected output:
// pub fn value() -> T {
// static value: MutCell<Option<T>> = MutCell::new(None);
// value.get_or_init(|| initValue)
// static value: OnceInit<T> = OnceInit::new();
// value.get_or_init(|| initValue).clone()
// }
let name = splitLast decl.Name
let typ = decl.Body.Type

let initNone = mkGenericPathExpr [ rawIdent "None" ] None |> makeMutValue com ctx

let initNone = makeNew com ctx "Native" "OnceInit" []
let value = transformLeaveContext com ctx None decl.Body

let value =
Expand All @@ -4002,8 +3985,7 @@ module Util =
else
ty

let staticTy = ty |> makeOptionTy |> makeMutTy com ctx

let staticTy = [ ty ] |> makeImportType com ctx "Native" "OnceInit"
let staticStmt = mkStaticItem [] name staticTy (Some initNone) |> mkItemStmt

let callee = com.TransformExpr(ctx, makeIdentExpr name)
Expand All @@ -4013,7 +3995,9 @@ module Util =
mkClosureExpr false fnDecl value

let valueStmt =
mkMethodCallExpr "get_or_init" None callee [ closureExpr ] |> mkExprStmt
mkMethodCallExpr "get_or_init" None callee [ closureExpr ]
|> makeClone
|> mkExprStmt

let attrs = transformAttributes com ctx memb.Attributes

Expand Down Expand Up @@ -4372,7 +4356,10 @@ module Util =
let traitItem =
let assocItems = makeInterfaceItems com ctx false ent
let generics = makeGenerics com ctx genArgs
mkTraitItem [] entName assocItems [] generics
// let sendBound = mkTypeTraitGenericBound [ rawIdent "Send" ] None
// let syncBound = mkTypeTraitGenericBound [ rawIdent "Sync" ] None
let traitBounds = [] // [ sendBound; syncBound ]
mkTraitItem [] entName assocItems traitBounds generics

let implItem =
let memberItems = makeInterfaceItems com ctx true ent
Expand Down
5 changes: 4 additions & 1 deletion src/Fable.Transforms/Rust/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,11 @@ let makeDecimal com r t (x: decimal) =
let makeRef (value: Expr) =
Operation(Unary(UnaryAddressOf, value), Tags.empty, value.Type, None)

let makeClone com r t (expr: Expr) =
Helper.InstanceCall(expr, "clone", t, [], ?loc = r)

let getRefCell com r t (expr: Expr) =
Helper.InstanceCall(expr, "get", t, [], ?loc = r)
Helper.InstanceCall(expr, "get", t, [], ?loc = r) |> makeClone com r t

let setRefCell com r (expr: Expr) (value: Expr) =
Set(expr, ValueSet, value.Type, value, r)
Expand Down
13 changes: 8 additions & 5 deletions src/fable-library-rust/src/Encoding.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pub mod Encoding_ {
use crate::NativeArray_::{array_from, Array};
use crate::Native_::{Lrc, LrcPtr, MutCell, String, Vec};
use crate::Native_::{Lrc, LrcPtr, OnceInit, String, Vec};
use crate::String_::{fromChars2, fromSlice, fromString, string, substring2_safe};

pub trait Encoding {
pub trait Encoding: Send + Sync {
fn getBytes(&self, s: string) -> Array<u8>;
fn getBytes2(&self, s: string, index: i32, count: i32) -> Array<u8>;
fn getBytesFromChars(&self, chars: Array<char>) -> Array<u8>;
Expand Down Expand Up @@ -35,8 +35,10 @@ pub mod Encoding_ {
pub struct UTF16LE {}

pub fn get_Unicode() -> LrcPtr<dyn Encoding> {
static utf16le: MutCell<Option<LrcPtr<dyn Encoding>>> = MutCell::new(None);
utf16le.get_or_init(move || LrcPtr::from(Lrc::from(UTF16LE {}) as Lrc<dyn Encoding>))
static utf16le: OnceInit<LrcPtr<dyn Encoding>> = OnceInit::new();
utf16le
.get_or_init(move || LrcPtr::from(Lrc::from(UTF16LE {}) as Lrc<dyn Encoding>))
.clone()
}

impl UTF16LE {
Expand Down Expand Up @@ -134,8 +136,9 @@ pub mod Encoding_ {
pub struct UTF8 {}

pub fn get_UTF8() -> LrcPtr<dyn Encoding> {
static utf8: MutCell<Option<LrcPtr<dyn Encoding>>> = MutCell::new(None);
static utf8: OnceInit<LrcPtr<dyn Encoding>> = OnceInit::new();
utf8.get_or_init(move || LrcPtr::from(Lrc::from(UTF8 {}) as Lrc<dyn Encoding>))
.clone()
}

impl UTF8 {
Expand Down
99 changes: 70 additions & 29 deletions src/fable-library-rust/src/Lazy.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,86 @@
/// Lazy values and one-time initialization.
// Lazy values and one-time initialization.

use core::fmt::Debug;
use crate::Native_::MutCell;
#[cfg(feature = "threaded")]
pub type OnceInit<T> = std::sync::OnceLock<T>;
#[cfg(not(feature = "threaded"))]
pub type OnceInit<T> = NonSyncLazy::OnceInit<T>;

pub struct Lazy<T, F = fn() -> T> {
cell: MutCell<Option<T>>,
init: MutCell<Option<F>>,
}
#[cfg(not(feature = "threaded"))]
mod NonSyncLazy {
use crate::Native_::MutCell;
use core::fmt::Debug;

impl<T: Clone + Debug, F> Debug for Lazy<T, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
#[repr(transparent)]
pub struct OnceInit<T> {
value: MutCell<Option<T>>,
}
}

impl<T, F> Lazy<T, F> {
pub const fn new(init: F) -> Lazy<T, F> {
Lazy { cell: MutCell::new(None), init: MutCell::new(Some(init)) }
impl<T> OnceInit<T> {
#[inline]
pub const fn new() -> OnceInit<T> {
OnceInit {
value: MutCell::new(None),
}
}

#[inline]
pub fn get_or_init<F>(&self, f: F) -> &T
where
F: FnOnce() -> T,
{
match self.value.get() {
Some(v) => v,
None => {
self.value.set(Some(f()));
self.value.get().as_ref().unwrap()
}
}
}
}

pub struct Lazy<T, F = fn() -> T> {
cell: MutCell<Option<T>>,
init: MutCell<Option<F>>,
}
}

impl<T: Clone, F: Fn() -> T> Lazy<T, F> {
pub fn force(self: &Lazy<T, F>) -> T {
match self.cell.get() {
Some(val) => val,
None => {
let val =
match self.init.take() {
impl<T: Clone + Debug, F> Debug for Lazy<T, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Lazy")
.field("cell", &self.cell)
.field("init", &"..")
.finish()
}
}

impl<T, F> Lazy<T, F> {
pub const fn new(init: F) -> Lazy<T, F> {
Lazy {
cell: MutCell::new(None),
init: MutCell::new(Some(init)),
}
}
}

impl<T: Clone, F: Fn() -> T> Lazy<T, F> {
pub fn force(self: &Lazy<T, F>) -> &T {
match self.cell.get() {
Some(val) => val,
None => {
let val = match self.init.take() {
Some(f) => f(),
None => panic!("`Lazy` instance has already been initialized"),
};
self.cell.set(Some(val.clone()));
val
self.cell.set(Some(val));
self.cell.get().as_ref().unwrap()
}
}
}
}
}

impl<T: Default> Default for Lazy<T> {
/// Creates a new lazy value using `Default` as the initializing function.
fn default() -> Lazy<T> {
Lazy::new(T::default)
impl<T: Default> Default for Lazy<T> {
/// Creates a new lazy value using `Default` as the initializing function.
fn default() -> Lazy<T> {
Lazy::new(T::default)
}
}
}
Loading
Loading