diff --git a/.vscode/launch.json b/.vscode/launch.json index dde10cbb32..344170be2c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -272,6 +272,21 @@ "cwd": "${workspaceRoot}/../fable-test", "stopAtEntry": false, "console": "internalConsole" + }, + { + "name": "Bench.Cli on ../fable-test", + "type": "coreclr", + "request": "launch", + "program": "${workspaceRoot}/src/fable-standalone/test/bench-compiler/src/bin/Debug/net8.0/bench-compiler.dll", + "args": [ + "fable-test.fsproj", + "--outDir", "${workspaceRoot}/../fable-test", + "--fableLib", "${workspaceRoot}/temp/fable-library-rust", + "--lang", "Rust" + ], + "cwd": "${workspaceRoot}/../fable-test", + "stopAtEntry": false, + "console": "internalConsole" } ] } \ No newline at end of file diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 08dd4af4aa..06f7870d68 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* [Rust] Updated derived interfaces (by @ncave) * [Rust] Updated string comparisons (by @ncave) * [Rust] Fixed derived traits mapping (by @ncave) * [JS/TS] Added missing ICollection helpers (#3914) (by @ncave) diff --git a/src/Fable.Transforms/Rust/Fable2Rust.fs b/src/Fable.Transforms/Rust/Fable2Rust.fs index 802a006249..1e0a252d2a 100644 --- a/src/Fable.Transforms/Rust/Fable2Rust.fs +++ b/src/Fable.Transforms/Rust/Fable2Rust.fs @@ -402,78 +402,78 @@ module TypeInfo = ent.IsValueType | _ -> false - let hasTypeOfType (com: IRustCompiler) isTypeOf isEntityOf entNames typ = + let isTypeOfType (com: IRustCompiler) isTypeOf isEntityOf entNames typ = match typ with | Fable.Option(genArg, _) -> isTypeOf com entNames genArg | Fable.Array(genArg, _) -> isTypeOf com entNames genArg | Fable.List genArg -> isTypeOf com entNames genArg - | Fable.Tuple(genArgs, _) -> List.exists (isTypeOf com entNames) genArgs - | Fable.AnonymousRecordType(_, genArgs, _) -> List.exists (isTypeOf com entNames) genArgs + | Fable.Tuple(genArgs, _) -> List.forall (isTypeOf com entNames) genArgs + | Fable.AnonymousRecordType(_, genArgs, _) -> List.forall (isTypeOf com entNames) genArgs | Replacements.Util.Builtin(Replacements.Util.FSharpSet genArg) -> isTypeOf com entNames genArg | Replacements.Util.Builtin(Replacements.Util.FSharpMap(k, v)) -> - isTypeOf com entNames k || isTypeOf com entNames v + isTypeOf com entNames k && isTypeOf com entNames v | Fable.DeclaredType(entRef, _genArgs) -> let ent = com.GetEntity(entRef) - isEntityOf com entNames ent //|| hasFieldOfType com isTypeOf entNames ent - | _ -> false + isEntityOf com entNames ent + | _ -> true - let hasFieldOfType (com: IRustCompiler) isTypeOf entNames (ent: Fable.Entity) = + let hasFieldsOfType (com: IRustCompiler) isTypeOf entNames (ent: Fable.Entity) = if Set.contains ent.FullName entNames then - false // already checked, avoids circular checks + true // already checked, avoids circular checks else let entNames = Set.add ent.FullName entNames if ent.IsFSharpUnion then ent.UnionCases - |> Seq.exists (fun uci -> + |> Seq.forall (fun uci -> uci.UnionCaseFields - |> List.exists (fun fi -> isTypeOf com entNames fi.FieldType) + |> List.forall (fun fi -> isTypeOf com entNames fi.FieldType) ) else - ent.FSharpFields |> Seq.exists (fun fi -> isTypeOf com entNames fi.FieldType) + ent.FSharpFields |> Seq.forall (fun fi -> isTypeOf com entNames fi.FieldType) - let isNonPrintableType (com: IRustCompiler) entNames typ = - match typ with - // TODO: more unprintable types? - | _ -> hasTypeOfType com isNonPrintableType isNonPrintableEntity entNames typ + // let isPrintableType (com: IRustCompiler) entNames typ = + // match typ with + // // TODO: more unprintable types? + // | _ -> isTypeOfType com isPrintableType isPrintableEntity entNames typ - let isNonPrintableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface || (hasFieldOfType com isNonPrintableType entNames ent) + let isPrintableEntity com entNames (ent: Fable.Entity) = (List.isEmpty ent.GenericParameters) + // && (hasFieldsOfType com isPrintableType entNames ent) // commented as it kills performance - let isNonDefaultableType (com: IRustCompiler) entNames typ = + let isDefaultableType (com: IRustCompiler) entNames typ = match typ with // TODO: more undefaultable types? - | _ -> hasTypeOfType com isNonDefaultableType isNonDefaultableEntity entNames typ - - let isNonDefaultableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface - || not ent.IsValueType - || ent.IsFSharpUnion // deriving 'Default' on enums is experimental - || (hasFieldOfType com isNonDefaultableType entNames ent) - - let isNonCopyableType (com: IRustCompiler) entNames typ = - match typ with - // TODO: more uncopyable types? - | Fable.Any - | Fable.Unit - | Fable.Measure _ - | Fable.MetaType - | Fable.LambdaType _ - | Fable.DelegateType _ - | Fable.GenericParam _ - | Fable.String - | Fable.Regex -> true - | Fable.Tuple(genArgs, isStruct) when not isStruct -> true - | Fable.AnonymousRecordType(_, genArgs, isStruct) when not isStruct -> true - | _ -> hasTypeOfType com isNonCopyableType isNonCopyableEntity entNames typ - - let isNonCopyableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface - || not ent.IsValueType - || (hasMutableFields com ent) - || (hasFieldOfType com isNonCopyableType entNames ent) - - let isNonEquatableType (com: IRustCompiler) entNames typ = + | _ -> isTypeOfType com isDefaultableType isDefaultableEntity entNames typ + + let isDefaultableEntity com entNames (ent: Fable.Entity) = + ent.IsValueType + && not ent.IsFSharpUnion // default union cases are quite limited + && (hasFieldsOfType com isDefaultableType entNames ent) + + // let isCopyableType (com: IRustCompiler) entNames typ = + // match typ with + // // TODO: more uncopyable types? + // | Fable.Any + // | Fable.Unit + // | Fable.Measure _ + // | Fable.MetaType + // | Fable.LambdaType _ + // | Fable.DelegateType _ + // | Fable.GenericParam _ + // | Fable.String + // | Fable.Regex + // | Fable.List _ -> false + // | Fable.Option(_, isStruct) when not isStruct -> false + // | Fable.Tuple(_, isStruct) when not isStruct -> false + // | Fable.AnonymousRecordType(_, _, isStruct) when not isStruct -> false + // | _ -> isTypeOfType com isCopyableType isCopyableEntity entNames typ + + // let isCopyableEntity com entNames (ent: Fable.Entity) = + // ent.IsValueType + // && not (hasMutableFields com ent) + // && (hasFieldsOfType com isCopyableType entNames ent) + + let isEquatableType (com: IRustCompiler) entNames typ = match typ with // TODO: more unequatable types? | Fable.Any @@ -481,17 +481,16 @@ module TypeInfo = | Fable.Measure _ | Fable.MetaType | Fable.LambdaType _ - | Fable.DelegateType _ -> true + | Fable.DelegateType _ -> false // | Fable.GenericParam(_, _, constraints) -> - // not (constraints |> List.contains Fable.Constraint.HasEquality) - | _ -> hasTypeOfType com isNonEquatableType isNonEquatableEntity entNames typ + // constraints |> List.contains Fable.Constraint.HasEquality + | _ -> isTypeOfType com isEquatableType isEquatableEntity entNames typ - let isNonEquatableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface - || not (FSharp2Fable.Util.hasStructuralEquality ent) - || (hasFieldOfType com isNonEquatableType entNames ent) + let isEquatableEntity com entNames (ent: Fable.Entity) = + (FSharp2Fable.Util.hasStructuralEquality ent) + && (hasFieldsOfType com isEquatableType entNames ent) - let isNonComparableType (com: IRustCompiler) entNames typ = + let isComparableType (com: IRustCompiler) entNames typ = match typ with // TODO: more uncomparable types? | Fable.Any @@ -500,17 +499,16 @@ module TypeInfo = | Fable.MetaType | Fable.LambdaType _ | Fable.DelegateType _ - | Fable.Regex -> true + | Fable.Regex -> false // | Fable.GenericParam(_, _, constraints) -> - // not (constraints |> List.contains Fable.Constraint.HasComparison) - | _ -> hasTypeOfType com isNonComparableType isNonComparableEntity entNames typ + // constraints |> List.contains Fable.Constraint.HasComparison + | _ -> isTypeOfType com isComparableType isComparableEntity entNames typ - let isNonComparableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface - || not (FSharp2Fable.Util.hasStructuralComparison ent) - || (hasFieldOfType com isNonComparableType entNames ent) + let isComparableEntity com entNames (ent: Fable.Entity) = + (FSharp2Fable.Util.hasStructuralComparison ent) + && (hasFieldsOfType com isComparableType entNames ent) - let isNonHashableType com entNames typ = + let isHashableType com entNames typ = match typ with // TODO: more unhashable types? | Fable.Any @@ -519,13 +517,12 @@ module TypeInfo = | Fable.MetaType | Fable.Number((Float32 | Float64), _) | Fable.LambdaType _ - | Fable.DelegateType _ -> true - | _ -> hasTypeOfType com isNonHashableType isNonHashableEntity entNames typ + | Fable.DelegateType _ -> false + | _ -> isTypeOfType com isHashableType isHashableEntity entNames typ - let isNonHashableEntity com entNames (ent: Fable.Entity) = - ent.IsInterface - || not (FSharp2Fable.Util.hasStructuralEquality ent) - || (hasFieldOfType com isNonHashableType entNames ent) + let isHashableEntity com entNames (ent: Fable.Entity) = + (FSharp2Fable.Util.hasStructuralEquality ent) + && (hasFieldsOfType com isHashableType entNames ent) let isWrappedType com typ = match typ with @@ -3894,6 +3891,12 @@ module Util = constraints |> List.distinct |> List.collect makeConstraint + let defaultInterfaceTypeBounds = + [ + mkTypeTraitGenericBound ("core" :: "fmt" :: "Debug" :: []) None + mkTypeTraitGenericBound ("core" :: "fmt" :: "Display" :: []) None + ] + let defaultTypeBounds = [ mkTypeTraitGenericBound [ rawIdent "Clone" ] None @@ -3902,18 +3905,17 @@ module Util = mkLifetimeGenericBound "'static" //TODO: add it only when needed ] - let makeDefaultTypeBounds com ctx = - // let importName = getLibraryImportName com ctx "Native" "IObject" - // let objectBound = mkTypeTraitGenericBound [ importName ] None - // objectBound :: defaultTypeBounds - defaultTypeBounds + // let makeDefaultTypeBounds com ctx = + // let importName = getLibraryImportName com ctx "Native" "IObject" + // let objectBound = mkTypeTraitGenericBound [ importName ] None + // objectBound :: defaultTypeBounds let makeGenericParams com ctx (genParams: Fable.GenericParam list) = genParams |> List.filter (fun p -> not p.IsMeasure) |> List.map (fun p -> let typeBounds = makeTypeBounds com ctx p.Name p.Constraints - let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx) + let typeBounds = typeBounds @ defaultTypeBounds mkGenericParamFromName [] p.Name typeBounds ) @@ -3923,7 +3925,7 @@ module Util = function | Fable.GenericParam(name, isMeasure, constraints) when not isMeasure -> let typeBounds = makeTypeBounds com ctx name constraints - let typeBounds = typeBounds @ (makeDefaultTypeBounds com ctx) + let typeBounds = typeBounds @ defaultTypeBounds mkGenericParamFromName [] name typeBounds |> Some | _ -> None ) @@ -4265,13 +4267,13 @@ module Util = fnItem let makeDerivedFrom com (ent: Fable.Entity) = - let isCopyable = false //not (ent |> isNonCopyableEntity com Set.empty) - let isCloneable = true //not (ent |> isNonCloneableEntity com Set.empty) - let isPrintable = not (ent |> isNonPrintableEntity com Set.empty) - let isDefaultable = not (ent |> isNonDefaultableEntity com Set.empty) - let isHashable = not (ent |> isNonHashableEntity com Set.empty) - let isEquatable = not (ent |> isNonEquatableEntity com Set.empty) - let isComparable = not (ent |> isNonComparableEntity com Set.empty) + let isCopyable = false //ent |> isCopyableEntity com Set.empty + let isCloneable = true //ent |> isCloneableEntity com Set.empty + let isPrintable = ent |> isPrintableEntity com Set.empty + let isDefaultable = ent |> isDefaultableEntity com Set.empty + let isHashable = ent |> isHashableEntity com Set.empty + let isEquatable = ent |> isEquatableEntity com Set.empty + let isComparable = ent |> isComparableEntity com Set.empty let derivedFrom = [ @@ -4528,7 +4530,7 @@ module Util = let traitItem = let assocItems = makeInterfaceItems com ctx false typeName ent let generics = makeGenerics com ctx genArgs - let traitBounds = [] // (makeDefaultTypeBounds com ctx) + let traitBounds = defaultInterfaceTypeBounds let attrs = transformAttributes com ctx ent.Attributes decl.XmlDoc mkTraitItem attrs entName assocItems traitBounds generics @@ -4537,7 +4539,7 @@ module Util = let memberItems = makeInterfaceItems com ctx true typeName ent let genArgsOpt = transformGenArgs com ctx genArgs let traitBound = mkTypeTraitGenericBound [ entName ] genArgsOpt - let typeBounds = traitBound :: (makeDefaultTypeBounds com ctx) + let typeBounds = traitBound :: defaultInterfaceTypeBounds let typeParam = mkGenericParamFromName [] typeName typeBounds let genParams = makeGenericParamsFromArgs com ctx genArgs let generics = typeParam :: genParams |> mkGenerics @@ -4875,7 +4877,8 @@ module Util = let hasToString = nonInterfaceMembers |> List.exists (fun (d, m) -> m.CompiledName = "ToString") - makeDisplayTraitImpls com ctx entName genParams hasToString false + let hasDebug = not (List.isEmpty ent.GenericParameters) + makeDisplayTraitImpls com ctx entName genParams hasToString hasDebug let operatorTraitImpls = nonInterfaceMembers |> makeOpTraitImpls com ctx ent entName genArgs diff --git a/src/Fable.Transforms/Rust/Replacements.fs b/src/Fable.Transforms/Rust/Replacements.fs index 158ae5453e..bc957b9ed0 100644 --- a/src/Fable.Transforms/Rust/Replacements.fs +++ b/src/Fable.Transforms/Rust/Replacements.fs @@ -2367,8 +2367,8 @@ let collections (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr let exceptions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) = match i.CompiledName, thisArg with | ".ctor", None -> bclType com ctx r t i thisArg args - | "get_Message", Some callee -> makeInstanceCall r t i callee i.CompiledName args |> Some - // | "get_StackTrace", Some e -> getFieldWith r t e "stack" |> Some + | "get_Message", Some ex -> makeInstanceCall r t i ex i.CompiledName args |> Some + | "get_StackTrace", Some ex -> makeInstanceCall r t i ex i.CompiledName args |> Some | _ -> None let objects (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) = diff --git a/src/fable-library-rust/src/LrcPtr.rs b/src/fable-library-rust/src/LrcPtr.rs index 337399204c..9540413e12 100644 --- a/src/fable-library-rust/src/LrcPtr.rs +++ b/src/fable-library-rust/src/LrcPtr.rs @@ -30,7 +30,7 @@ impl LrcPtr { } } -// impl Default for LrcPtr { +// impl Default for LrcPtr { // fn default() -> Self { // Self::null() // } @@ -59,27 +59,27 @@ impl Deref for LrcPtr { } } -impl core::fmt::Debug for LrcPtr { +impl core::fmt::Debug for LrcPtr { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{:?}", self.deref()) } } -impl core::fmt::Display for LrcPtr { +impl core::fmt::Display for LrcPtr { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}", self.deref()) } } // // Custom code within the destructor. -// impl Drop for LrcPtr { +// impl Drop for LrcPtr { // fn drop(&mut self) { // self.0.drop(); // } // } // Used for indexing operations (container[index]) -impl, Idx> Index for LrcPtr { +impl, Idx> Index for LrcPtr { type Output = T::Output; fn index(&self, idx: Idx) -> &Self::Output { diff --git a/src/fable-library-rust/src/RegExp.rs b/src/fable-library-rust/src/RegExp.rs index 3b234836cc..a58378d3fb 100644 --- a/src/fable-library-rust/src/RegExp.rs +++ b/src/fable-library-rust/src/RegExp.rs @@ -472,6 +472,12 @@ pub mod RegExp_ { } } + impl core::fmt::Display for CaptureCollection { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", core::any::type_name::()) + } + } + impl GroupCollection { pub fn count(&self) -> i32 { self.0.len() as i32 @@ -519,6 +525,12 @@ pub mod RegExp_ { } } + impl core::fmt::Display for GroupCollection { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", core::any::type_name::()) + } + } + impl MatchCollection { pub fn count(&self) -> i32 { self.0.len() as i32 @@ -534,4 +546,10 @@ pub mod RegExp_ { ofArray(self.0.clone()).GetEnumerator() } } + + impl core::fmt::Display for MatchCollection { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "{}", core::any::type_name::()) + } + } } diff --git a/src/fable-library-rust/src/System.fs b/src/fable-library-rust/src/System.fs index 1983735a3d..29c7dcb42d 100644 --- a/src/fable-library-rust/src/System.fs +++ b/src/fable-library-rust/src/System.fs @@ -17,6 +17,8 @@ type Exception(message: string) = else message + member _.StackTrace = "" + interface System.Collections.IStructuralEquatable with member x.Equals(y, comparer) = false member x.GetHashCode(comparer) = 0 diff --git a/src/fcs-fable/System.Collections.fs b/src/fcs-fable/System.Collections.fs index fb953ff3b3..5da3b027d9 100644 --- a/src/fcs-fable/System.Collections.fs +++ b/src/fcs-fable/System.Collections.fs @@ -4,29 +4,6 @@ namespace System.Collections -module Generic = - - type Queue<'T>() = - let xs = ResizeArray<'T>() - - member _.Clear () = xs.Clear() - - member _.Enqueue (item: 'T) = - xs.Add(item) - - member _.Dequeue () = - let item = xs.Item(0) - xs.RemoveAt(0) - item - - interface System.Collections.IEnumerable with - member _.GetEnumerator() = - (xs.GetEnumerator() :> System.Collections.IEnumerator) - - interface System.Collections.Generic.IEnumerable<'T> with - member _.GetEnumerator() = - xs.GetEnumerator() - module Immutable = open System.Collections.Generic @@ -35,7 +12,7 @@ module Immutable = static member CreateBuilder() = ResizeArray<'T>() [] - type ImmutableHashSet<'T>(values: 'T seq) = + type ImmutableHashSet<'T when 'T: equality>(values: 'T seq) = let xs = HashSet<'T>(values) static member Create<'T>(values) = ImmutableHashSet<'T>(values) @@ -48,61 +25,63 @@ module Immutable = member _.Union (values: seq<'T>) = let copy = HashSet<'T>(xs) - copy.UnionWith(values) + // copy.UnionWith(values) + for value in values do + copy.Add(value) |> ignore ImmutableHashSet<'T>(copy) member _.Overlaps (values: seq<'T>) = // xs.Overlaps(values) values |> Seq.exists (fun x -> xs.Contains(x)) - interface System.Collections.IEnumerable with - member _.GetEnumerator() = - (xs.GetEnumerator() :> System.Collections.IEnumerator) - interface IEnumerable<'T> with member _.GetEnumerator() = xs.GetEnumerator() + interface System.Collections.IEnumerable with + member _.GetEnumerator() = + (xs.GetEnumerator() :> System.Collections.IEnumerator) + [] - type ImmutableDictionary<'Key, 'Value when 'Key: equality>(xs: Dictionary<'Key, 'Value>) = - static member Create(comparer: IEqualityComparer<'Key>) = - ImmutableDictionary<'Key, 'Value>(Dictionary(comparer)) + type ImmutableDictionary<'K, 'V when 'K: equality>(xs: Dictionary<'K, 'V>) = + static member Create(comparer: IEqualityComparer<'K>) = + ImmutableDictionary<'K, 'V>(Dictionary(comparer)) - static member CreateRange(items: IEnumerable>) = - let xs = Dictionary<'Key, 'Value>() + static member CreateRange(items: IEnumerable>) = + let xs = Dictionary<'K, 'V>() for pair in items do xs.Add(pair.Key, pair.Value) - ImmutableDictionary<'Key, 'Value>(xs) + ImmutableDictionary<'K, 'V>(xs) static member Empty = - ImmutableDictionary<'Key, 'Value>(Dictionary()) + ImmutableDictionary<'K, 'V>(Dictionary()) member _.IsEmpty = xs.Count = 0 - member _.Item with get (key: 'Key): 'Value = xs[key] - member _.ContainsKey (key: 'Key) = xs.ContainsKey(key) + member _.Item with get (key: 'K): 'V = xs[key] + member _.ContainsKey (key: 'K) = xs.ContainsKey(key) - member _.Add (key: 'Key, value: 'Value) = - let copy = Dictionary<'Key, 'Value>(xs) + member _.Add (key: 'K, value: 'V) = + let copy = Dictionary<'K, 'V>(xs) copy.Add(key, value) - ImmutableDictionary<'Key, 'Value>(copy) + ImmutableDictionary<'K, 'V>(copy) - member _.SetItem (key: 'Key, value: 'Value) = - let copy = Dictionary<'Key, 'Value>(xs) + member _.SetItem (key: 'K, value: 'V) = + let copy = Dictionary<'K, 'V>(xs) copy[key] <- value - ImmutableDictionary<'Key, 'Value>(copy) + ImmutableDictionary<'K, 'V>(copy) - member _.TryGetValue (key: 'Key): bool * 'Value = + member _.TryGetValue (key: 'K): bool * 'V = match xs.TryGetValue(key) with | true, v -> (true, v) | false, v -> (false, v) - interface System.Collections.IEnumerable with + interface IEnumerable> with member _.GetEnumerator() = - (xs.GetEnumerator() :> System.Collections.IEnumerator) + xs.GetEnumerator() - interface IEnumerable> with + interface System.Collections.IEnumerable with member _.GetEnumerator() = - xs.GetEnumerator() + (xs.GetEnumerator() :> System.Collections.IEnumerator) module Concurrent = open System.Collections.Generic @@ -116,92 +95,95 @@ module Concurrent = member _.Clear () = xs.Clear() member _.ToArray () = xs.ToArray() - interface System.Collections.IEnumerable with - member _.GetEnumerator() = - (xs.GetEnumerator() :> System.Collections.IEnumerator) - interface IEnumerable<'T> with member _.GetEnumerator() = xs.GetEnumerator() + interface System.Collections.IEnumerable with + member _.GetEnumerator() = + (xs.GetEnumerator() :> System.Collections.IEnumerator) + // not thread safe, just a Dictionary // TODO: threaded implementation [] - type ConcurrentDictionary<'Key, 'Value>(comparer: IEqualityComparer<'Key>) = + type ConcurrentDictionary<'K, 'V>(comparer: IEqualityComparer<'K>) = let xs = Dictionary(comparer) new () = - ConcurrentDictionary<'Key, 'Value>(EqualityComparer.Default) + ConcurrentDictionary<'K, 'V>(EqualityComparer.Default) new (_concurrencyLevel: int, _capacity: int) = - ConcurrentDictionary<'Key, 'Value>() - new (_concurrencyLevel: int, comparer: IEqualityComparer<'Key>) = - ConcurrentDictionary<'Key, 'Value>(comparer) - new (_concurrencyLevel: int, _capacity: int, comparer: IEqualityComparer<'Key>) = - ConcurrentDictionary<'Key, 'Value>(comparer) + ConcurrentDictionary<'K, 'V>() + new (_concurrencyLevel: int, comparer: IEqualityComparer<'K>) = + ConcurrentDictionary<'K, 'V>(comparer) + new (_concurrencyLevel: int, _capacity: int, comparer: IEqualityComparer<'K>) = + ConcurrentDictionary<'K, 'V>(comparer) + member _.Comparer = comparer member _.Keys = xs.Keys member _.Values = xs.Values member _.Item - with get (key: 'Key): 'Value = xs[key] - and set (key: 'Key) (value: 'Value) = xs[key] <- value + with get (key: 'K): 'V = xs[key] + and set (key: 'K) (value: 'V) = xs[key] <- value member _.Clear () = xs.Clear() - member _.ContainsKey (key: 'Key) = xs.ContainsKey(key) + member _.ContainsKey (key: 'K) = xs.ContainsKey(key) - member _.TryGetValue (key: 'Key): bool * 'Value = + member _.TryGetValue (key: 'K): bool * 'V = match xs.TryGetValue(key) with | true, v -> (true, v) | false, v -> (false, v) - member _.TryAdd (key: 'Key, value: 'Value): bool = + member _.TryAdd (key: 'K, value: 'V): bool = if xs.ContainsKey(key) then false else xs.Add(key, value); true - member _.TryRemove (key: 'Key): bool * 'Value = + member _.TryRemove (key: 'K): bool * 'V = match xs.TryGetValue(key) with | true, v -> (xs.Remove(key), v) | _ as res -> res - member _.GetOrAdd (key: 'Key, value: 'Value): 'Value = + member _.GetOrAdd (key: 'K, value: 'V): 'V = match xs.TryGetValue(key) with | true, v -> v | _ -> let v = value in xs.Add(key, v); v - member _.GetOrAdd (key: 'Key, valueFactory: System.Func<'Key, 'Value>): 'Value = + member _.GetOrAdd (key: 'K, valueFactory: System.Func<'K, 'V>): 'V = match xs.TryGetValue(key) with | true, v -> v | _ -> let v = valueFactory.Invoke(key) in xs.Add(key, v); v - // member _.GetOrAdd<'Arg> (key: 'Key, valueFactory: 'Key * 'Arg -> 'Value, arg: 'Arg): 'Value = + // member _.GetOrAdd<'Arg> (key: 'K, valueFactory: 'K * 'Arg -> 'V, arg: 'Arg): 'V = // match xs.TryGetValue(key) with // | true, v -> v // | _ -> let v = valueFactory(key, arg) in xs.Add(key, v); v - member _.TryUpdate (key: 'Key, value: 'Value, comparisonValue: 'Value): bool = - match xs.TryGetValue(key) with - | true, v when Unchecked.equals v comparisonValue -> xs[key] <- value; true - | _ -> false + member _.TryUpdate (key: 'K, value: 'V, comparisonValue: 'V): bool = + // match xs.TryGetValue(key) with + // | true, v when Unchecked.equals v comparisonValue -> xs[key] <- value; true + // | _ -> false + xs[key] <- value + true - member _.AddOrUpdate (key: 'Key, value: 'Value, updateFactory: System.Func<'Key, 'Value, 'Value>): 'Value = + member _.AddOrUpdate (key: 'K, value: 'V, updateFactory: System.Func<'K, 'V, 'V>): 'V = match xs.TryGetValue(key) with | true, v -> let v = updateFactory.Invoke(key, v) in xs[key] <- v; v | _ -> let v = value in xs.Add(key, v); v - // member _.AddOrUpdate (key: 'Key, valueFactory: 'Key -> 'Value, updateFactory: 'Key * 'Value -> 'Value): 'Value = + // member _.AddOrUpdate (key: 'K, valueFactory: 'K -> 'V, updateFactory: 'K * 'V -> 'V): 'V = // match xs.TryGetValue(key) with // | true, v -> let v = updateFactory(key, v) in xs[key] <- v; v // | _ -> let v = valueFactory(key) in xs.Add(key, v); v - // member _.AddOrUpdate (key: 'Key, valueFactory: 'Key * 'Arg -> 'Value, updateFactory: 'Key * 'Arg * 'Value -> 'Value, arg: 'Arg): 'Value = + // member _.AddOrUpdate (key: 'K, valueFactory: 'K * 'Arg -> 'V, updateFactory: 'K * 'Arg * 'V -> 'V, arg: 'Arg): 'V = // match xs.TryGetValue(key) with // | true, v -> let v = updateFactory(key, arg, v) in xs[key] <- v; v // | _ -> let v = valueFactory(key, arg) in xs.Add(key, v); v - interface System.Collections.IEnumerable with + interface IEnumerable> with member _.GetEnumerator() = - (xs.GetEnumerator() :> System.Collections.IEnumerator) + xs.GetEnumerator() - interface IEnumerable> with + interface System.Collections.IEnumerable with member _.GetEnumerator() = - xs.GetEnumerator() + (xs.GetEnumerator() :> System.Collections.IEnumerator) diff --git a/src/fcs-fable/src/Compiler/Symbols/Exprs.fs b/src/fcs-fable/src/Compiler/Symbols/Exprs.fs index daae21431e..24d9118a69 100644 --- a/src/fcs-fable/src/Compiler/Symbols/Exprs.fs +++ b/src/fcs-fable/src/Compiler/Symbols/Exprs.fs @@ -1251,13 +1251,8 @@ module FSharpExprConvert = | Const.UInt32 i -> E.Const(box i, tyR) | Const.Int64 i -> E.Const(box i, tyR) | Const.UInt64 i -> E.Const(box i, tyR) -#if FABLE_COMPILER - | Const.IntPtr i -> E.Const(box i, tyR) - | Const.UIntPtr i -> E.Const(box i, tyR) -#else | Const.IntPtr i -> E.Const(box (nativeint i), tyR) | Const.UIntPtr i -> E.Const(box (unativeint i), tyR) -#endif | Const.Decimal i -> E.Const(box i, tyR) | Const.Double i -> E.Const(box i, tyR) | Const.Single i -> E.Const(box i, tyR)