Skip to content

Commit

Permalink
[Rust] Updated module let bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave committed Feb 10, 2024
1 parent 6705b20 commit 9905d52
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 96 deletions.
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
72 changes: 28 additions & 44 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 @@ -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)

// 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
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
63 changes: 50 additions & 13 deletions src/fable-library-rust/src/Lazy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
/// Lazy values and one-time initialization.

use core::fmt::Debug;
// Lazy values and one-time initialization.
use crate::Native_::MutCell;
use core::fmt::Debug;

#[cfg(feature = "threaded")]
pub type OnceInit<T> = std::sync::OnceLock<T>;

#[cfg(not(feature = "threaded"))]
#[repr(transparent)]
pub struct OnceInit<T> {
value: MutCell<Option<T>>,
}

#[cfg(not(feature = "threaded"))]
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>>,
Expand All @@ -10,28 +42,33 @@ pub struct Lazy<T, F = fn() -> T> {

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()
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)) }
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 {
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
let val = match self.init.take() {
Some(f) => f(),
None => panic!("`Lazy` instance has already been initialized"),
};
self.cell.set(Some(val));
self.cell.get().as_ref().unwrap()
}
}
}
Expand Down
Loading

0 comments on commit 9905d52

Please sign in to comment.