Skip to content
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
8 changes: 8 additions & 0 deletions src/Fable.Transforms/Python/Fable2Python.Transforms.fs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,14 @@ let transformCast (com: IPythonCompiler) (ctx: Context) t e : Expression * State
let value, stmts = com.TransformAsExpr(ctx, e)
libCall com ctx None "core" "int32" [ value ], stmts
| _ -> com.TransformAsExpr(ctx, e)
// The other integer widths are wrapper classes too, so `uint32 (x: byte)` needs the same explicit constructor call
| Fable.Number((Int8 | UInt8 | Int16 | UInt16 | UInt32) as kind, _), _ ->
match e.Type with
| Fable.Number(sourceKind, _) when sourceKind = kind -> com.TransformAsExpr(ctx, e)
| Fable.Number _ ->
let value, stmts = com.TransformAsExpr(ctx, e)
libCall com ctx None "core" (Py.Replacements.getIntTypeName kind) [ value ], stmts
| _ -> com.TransformAsExpr(ctx, e)
// Float64 is a plain Python `float`, and the same reasoning applies:
// `Replacements.toFloat` emits a bare `TypeCast` for every numeric source that is
// not bigint/decimal/int64, so `float (x: float32)` would otherwise stay a
Expand Down
20 changes: 20 additions & 0 deletions tests/Python/TestConvert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,26 @@ let private toIntFromInt16 (x: int16) = int x
let private toFloatFromSingle (x: float32) = float x
let private toFloatFromByte (x: byte) = float x
let private toFloatFromInt (x: int) = float x
let private toInt16FromSByte (x: sbyte) = int16 x
let private toUInt16FromByte (x: byte) = uint16 x
let private toUInt32FromByte (x: byte) = uint32 x
let private toUInt32FromUInt16 (x: uint16) = uint32 x

[<Fact>]
let ``test Widening between integer wrappers uses the target width`` () =
// Compare as int so wrapper equality cannot truncate the expected value to the source width.
toInt16FromSByte 100y <<< 1 |> int |> equal 200
toInt16FromSByte -100y <<< 1 |> int |> equal -200
toUInt16FromByte 200uy <<< 1 |> int |> equal 400
toUInt32FromByte 200uy <<< 1 |> int |> equal 400
toUInt32FromUInt16 60000us <<< 1 |> int |> equal 120000

[<Fact>]
let ``test Widening between integer wrappers has the target runtime type`` () =
box (toInt16FromSByte 5y) :? int16 |> equal true
box (toUInt16FromByte 5uy) :? uint16 |> equal true
box (toUInt32FromByte 5uy) :? uint32 |> equal true
box (toUInt32FromUInt16 5us) :? uint32 |> equal true

[<Fact>]
let ``test Widening to int does not keep the source width`` () =
Expand Down
Loading