Skip to content

Commit b3c38ab

Browse files
committed
Add more right-shift tests
1 parent ce7eba9 commit b3c38ab

5 files changed

Lines changed: 68 additions & 5 deletions

File tree

src/Fable.Transforms/Rust/Fable2Rust.fs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5360,14 +5360,15 @@ module Compiler =
53605360
|> Seq.toList
53615361

53625362
member _.ClearAllImports(ctx) =
5363-
for import in imports do
5363+
let importsList = imports |> Seq.toList
5364+
5365+
for import in importsList do
53645366
import.Value.Depths <-
53655367
// remove all import depths at this module level or deeper
53665368
import.Value.Depths |> List.filter (fun d -> d < ctx.ModuleDepth)
53675369

53685370
if import.Value.Depths.Length = 0 then
53695371
imports.Remove(import.Key) |> ignore
5370-
53715372
ctx.UsedNames.RootScope.Remove(import.Value.LocalIdent) |> ignore
53725373

53735374
member _.GetAllModules() = importModules.Keys |> Seq.toList

tests/Beam/ArithmeticTests.fs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,23 @@ let ``test Bitwise XOR on large unsigned integer works`` () =
703703
let ``test Zero fill shift right for unsigned`` () =
704704
0x80000000 >>> 1 |> equal -1073741824
705705
0x80000000u >>> 1 |> equal 1073741824u
706-
0x80000000UL>>> 1 |> equal 1073741824UL
706+
0x80000000UL >>> 1 |> equal 1073741824UL
707+
708+
[<Fact>]
709+
let ``Zero fill right shift is logical for unsigned integer types`` () =
710+
// For unsigned types, >>> is zero-fill (logical) - the high bit is NOT sign-extended
711+
0xFFuy >>> 1 |> equal 127uy // uint8: 0x7F
712+
0xFFFFus >>> 1 |> equal 32767us // uint16: 0x7FFF
713+
0xFFFFFFFFu >>> 1 |> equal 2147483647u // uint32: 0x7FFFFFFF
714+
0xFFFFFFFFFFFFFFFFUL >>> 1 |> equal 9223372036854775807UL // uint64: 0x7FFFFFFFFFFFFFFF
715+
716+
[<Fact>]
717+
let ``Arithmetic right shift preserves sign for signed integer types`` () =
718+
// For signed types, >>> is arithmetic (sign-propagating) - the sign bit IS extended
719+
-2y >>> 1 |> equal -1y // int8: 0xFF = -1
720+
-2s >>> 1 |> equal -1s // int16: 0xFFFF = -1
721+
-2 >>> 1 |> equal -1 // int32: 0xFFFFFFFF = -1
722+
-2L >>> 1 |> equal -1L // int64: 0xFFFFFFFFFFFFFFFF = -1
707723

708724
// TODO: ~~~ on unsigned integers uses LogicalNotDynamic which is not supported by Fable
709725
// [<Fact>]

tests/Js/Main/ArithmeticTests.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@ let tests =
127127
0x80000000u >>> 1 |> equal 1073741824u
128128
0x80000000UL >>> 1 |> equal 1073741824UL
129129

130+
testCase "Zero fill right shift is logical for unsigned integer types" <| fun () ->
131+
// For unsigned types, >>> is zero-fill (logical) - the high bit is NOT sign-extended
132+
0xFFuy >>> 1 |> equal 127uy // uint8: 0x7F
133+
0xFFFFus >>> 1 |> equal 32767us // uint16: 0x7FFF
134+
0xFFFFFFFFu >>> 1 |> equal 2147483647u // uint32: 0x7FFFFFFF
135+
0xFFFFFFFFFFFFFFFFUL >>> 1 |> equal 9223372036854775807UL // uint64: 0x7FFFFFFFFFFFFFFF
136+
137+
testCase "Arithmetic right shift preserves sign for signed integer types" <| fun () ->
138+
// For signed types, >>> is arithmetic (sign-propagating) - the sign bit IS extended
139+
-2y >>> 1 |> equal -1y // int8: 0xFF = -1
140+
-2s >>> 1 |> equal -1s // int16: 0xFFFF = -1
141+
-2 >>> 1 |> equal -1 // int32: 0xFFFFFFFF = -1
142+
-2L >>> 1 |> equal -1L // int64: 0xFFFFFFFFFFFFFFFF = -1
143+
130144
testCase "UInt64 multiplication with 0 returns uint" <| fun () -> // See #1480
131145
0x0UL * 0x1UL |> equal 0x0UL
132146

tests/Python/TestArithmetic.fs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,23 @@ let ``test Bitwise shift right can be generated`` () = // See #1530
139139
let ``test Zero fill shift right for unsigned`` () = // See #646
140140
0x80000000 >>> 1 |> equal -1073741824
141141
0x80000000u >>> 1 |> equal 1073741824u
142-
0x80000000UL>>> 1 |> equal 1073741824UL
142+
0x80000000UL >>> 1 |> equal 1073741824UL
143+
144+
[<Fact>]
145+
let ``test Zero fill right shift is logical for unsigned integer types`` () =
146+
// For unsigned types, >>> is zero-fill (logical) - the high bit is NOT sign-extended
147+
0xFFuy >>> 1 |> equal 127uy // uint8: 0x7F
148+
0xFFFFus >>> 1 |> equal 32767us // uint16: 0x7FFF
149+
0xFFFFFFFFu >>> 1 |> equal 2147483647u // uint32: 0x7FFFFFFF
150+
0xFFFFFFFFFFFFFFFFUL >>> 1 |> equal 9223372036854775807UL // uint64: 0x7FFFFFFFFFFFFFFF
151+
152+
[<Fact>]
153+
let ``test Arithmetic right shift preserves sign for signed integer types`` () =
154+
// For signed types, >>> is arithmetic (sign-propagating) - the sign bit IS extended
155+
-2y >>> 1 |> equal -1y // int8: 0xFF = -1
156+
-2s >>> 1 |> equal -1s // int16: 0xFFFF = -1
157+
-2 >>> 1 |> equal -1 // int32: 0xFFFFFFFF = -1
158+
-2L >>> 1 |> equal -1L // int64: 0xFFFFFFFFFFFFFFFF = -1
143159

144160
[<Fact>]
145161
let ``test UInt64 multiplication with 0 returns uint`` () = // See #1480

tests/Rust/tests/src/ArithmeticTests.fs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,23 @@ let ``Bitwise shift right can be generated`` () = // See #1530
136136
let ``Zero fill shift right for unsigned`` () = // See #646
137137
0x80000000 >>> 1 |> equal -1073741824
138138
0x80000000u >>> 1 |> equal 1073741824u
139-
0x80000000UL>>> 1 |> equal 1073741824UL
139+
0x80000000UL >>> 1 |> equal 1073741824UL
140+
141+
[<Fact>]
142+
let ``Zero fill right shift is logical for unsigned integer types`` () =
143+
// For unsigned types, >>> is zero-fill (logical) - the high bit is NOT sign-extended
144+
0xFFuy >>> 1 |> equal 127uy // uint8: 0x7F
145+
0xFFFFus >>> 1 |> equal 32767us // uint16: 0x7FFF
146+
0xFFFFFFFFu >>> 1 |> equal 2147483647u // uint32: 0x7FFFFFFF
147+
0xFFFFFFFFFFFFFFFFUL >>> 1 |> equal 9223372036854775807UL // uint64: 0x7FFFFFFFFFFFFFFF
148+
149+
[<Fact>]
150+
let ``Arithmetic right shift preserves sign for signed integer types`` () =
151+
// For signed types, >>> is arithmetic (sign-propagating) - the sign bit IS extended
152+
-2y >>> 1 |> equal -1y // int8: 0xFF = -1
153+
-2s >>> 1 |> equal -1s // int16: 0xFFFF = -1
154+
-2 >>> 1 |> equal -1 // int32: 0xFFFFFFFF = -1
155+
-2L >>> 1 |> equal -1L // int64: 0xFFFFFFFFFFFFFFFF = -1
140156

141157
[<Fact>]
142158
let ``UInt64 multiplication with 0 returns uint`` () = // See #1480

0 commit comments

Comments
 (0)