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
2 changes: 1 addition & 1 deletion src/Init/Data/FloatArray/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ instance : EmptyCollection FloatArray where
def push : FloatArray → Float → FloatArray
| ⟨ds⟩, b => ⟨ds.push b⟩

@[extern "lean_float_array_size"]
@[extern "lean_float_array_size", tagged_return]
def size : (@& FloatArray) → Nat
| ⟨ds⟩ => ds.size

Expand Down
4 changes: 2 additions & 2 deletions src/Init/Data/SInt/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Converts an 8-bit signed integer to an arbitrary-precision integer that denotes

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_int8_to_int"]
@[extern "lean_int8_to_int", tagged_return]
def Int8.toInt (i : Int8) : Int := i.toBitVec.toInt
/--
Converts an 8-bit signed integer to a natural number, mapping all negative numbers to `0`.
Expand Down Expand Up @@ -503,7 +503,7 @@ Converts a 16-bit signed integer to an arbitrary-precision integer that denotes

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_int16_to_int"]
@[extern "lean_int16_to_int", tagged_return]
def Int16.toInt (i : Int16) : Int := i.toBitVec.toInt
/--
Converts a 16-bit signed integer to a natural number, mapping all negative numbers to `0`.
Expand Down
6 changes: 3 additions & 3 deletions src/Init/Data/String/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Examples:
* `"abc".length = 3`
* `"L∃∀N".length = 4`
-/
@[extern "lean_string_length", expose]
@[extern "lean_string_length", expose, tagged_return]
def String.length (b : @& String) : Nat :=
b.toList.length

Expand Down Expand Up @@ -1652,7 +1652,7 @@ def Slice.pos! (s : Slice) (off : String.Pos.Raw) : s.Pos :=

/-- Advances a valid position on a string to the next valid position, given a proof that the
position is not the past-the-end position, which guarantees that such a position exists. -/
@[expose, extern "lean_string_utf8_next_fast"]
@[expose, extern "lean_string_utf8_next_fast", tagged_return]
def Pos.next {s : @& String} (pos : @& s.Pos) (h : pos ≠ s.endPos) : s.Pos :=
ofToSlice (Slice.Pos.next pos.toSlice (ne_of_apply_ne Pos.ofToSlice (by simpa)))

Expand Down Expand Up @@ -2656,7 +2656,7 @@ This is a legacy function. The recommended alternative is `String.Pos.next`, com
Example:
* `let abc := "abc"; abc.get (abc.next' 0 (by decide)) = 'b'`
-/
@[extern "lean_string_utf8_next_fast", expose]
@[extern "lean_string_utf8_next_fast", expose, tagged_return]
def Pos.Raw.next' (s : @& String) (p : @& Pos.Raw) (h : ¬ p.atEnd s) : Pos.Raw :=
let c := p.get s
p + c
Expand Down
4 changes: 2 additions & 2 deletions src/Init/Data/UInt/BasicAux.lean
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Converts an 8-bit unsigned integer to an arbitrary-precision natural number.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint8_to_nat"]
@[extern "lean_uint8_to_nat", tagged_return]
def UInt8.toNat (n : UInt8) : Nat := n.toBitVec.toNat

instance UInt8.instOfNat : OfNat UInt8 n := ⟨UInt8.ofNat n⟩
Expand Down Expand Up @@ -108,7 +108,7 @@ Converts a 16-bit unsigned integer to an arbitrary-precision natural number.

This function is overridden at runtime with an efficient implementation.
-/
@[extern "lean_uint16_to_nat"]
@[extern "lean_uint16_to_nat", tagged_return]
def UInt16.toNat (n : UInt16) : Nat := n.toBitVec.toNat
/--
Converts 16-bit unsigned integers to 8-bit unsigned integers. Wraps around on overflow.
Expand Down
6 changes: 3 additions & 3 deletions src/Init/Prelude.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3185,7 +3185,7 @@ This is a cached value, so it is `O(1)` to access. The space allocated for an ar
its _capacity_, is at least as large as its size, but may be larger. The capacity of an array is an
internal detail that's not observable by Lean code.
-/
@[extern "lean_array_get_size"]
@[extern "lean_array_get_size", tagged_return]
def Array.size {α : Type u} (a : @& Array α) : Nat :=
a.toList.length

Expand Down Expand Up @@ -3393,7 +3393,7 @@ Returns the number of bytes in the byte array.
This is the number of bytes actually in the array, as distinct from its capacity, which is the
amount of memory presently allocated for the array.
-/
@[extern "lean_byte_array_size"]
@[extern "lean_byte_array_size", tagged_return]
def ByteArray.size : (@& ByteArray) → Nat
| ⟨bs⟩ => bs.size

Expand Down Expand Up @@ -3540,7 +3540,7 @@ The number of bytes used by the string's UTF-8 encoding.

At runtime, this function takes constant time because the byte length of strings is cached.
-/
@[extern "lean_string_utf8_byte_size"]
@[extern "lean_string_utf8_byte_size", tagged_return]
def String.utf8ByteSize (s : @& String) : Nat :=
s.toByteArray.size

Expand Down
161 changes: 161 additions & 0 deletions tests/lean/run/tagged_return_2.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/-! This test asserts that the built-in symbols marked with tagged_return compile correctly -/

/--
trace: [Compiler.IR] [result]
def test1 (x_1 : @& obj) : tobj :=
let x_2 : tagged := FloatArray.size x_1;
ret x_2
def test1._boxed (x_1 : obj) : tobj :=
let x_2 : tobj := test1 x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test1 (a : FloatArray) := a.size

/--
trace: [Compiler.IR] [result]
def test2 (x_1 : @& obj) : tobj :=
let x_2 : tagged := ByteArray.size x_1;
ret x_2
def test2._boxed (x_1 : obj) : tobj :=
let x_2 : tobj := test2 x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test2 (a : ByteArray) := a.size

/--
trace: [Compiler.IR] [result]
def test3 (x_1 : @& obj) : tobj :=
let x_2 : tagged := Array.size ◾ x_1;
ret x_2
def test3._boxed (x_1 : obj) : tobj :=
let x_2 : tobj := test3 x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test3 (a : Array Nat) := a.size

/--
trace: [Compiler.IR] [result]
def test4 (x_1 : @& obj) : tobj :=
let x_2 : tagged := String.length x_1;
ret x_2
def test4._boxed (x_1 : obj) : tobj :=
let x_2 : tobj := test4 x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test4 (a : String) := a.length

/--
trace: [Compiler.IR] [result]
def test5 (x_1 : @& obj) : tobj :=
let x_2 : tagged := String.utf8ByteSize x_1;
ret x_2
def test5._boxed (x_1 : obj) : tobj :=
let x_2 : tobj := test5 x_1;
dec x_1;
ret x_2
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test5 (a : String) := a.utf8ByteSize

/--
warning: declaration uses 'sorry'
---
trace: [Compiler.IR] [result]
def test6 (x_1 : @& obj) (x_2 : @& tobj) : tobj :=
let x_3 : tagged := String.Pos.next x_1 x_2 ◾;
ret x_3
def test6._boxed (x_1 : obj) (x_2 : tobj) : tobj :=
let x_3 : tobj := test6 x_1 x_2;
dec x_2;
dec x_1;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test6 (a : String) (p : a.Pos) := p.next sorry

/--
trace: [Compiler.IR] [result]
def test8 (x_1 : u8) : tobj :=
let x_2 : tagged := UInt8.toNat x_1;
ret x_2
def test8._boxed (x_1 : tagged) : tobj :=
let x_2 : u8 := unbox x_1;
let x_3 : tobj := test8 x_2;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test8 (a : UInt8) := a.toNat

/--
trace: [Compiler.IR] [result]
def test9 (x_1 : u16) : tobj :=
let x_2 : tagged := UInt16.toNat x_1;
ret x_2
def test9._boxed (x_1 : tagged) : tobj :=
let x_2 : u16 := unbox x_1;
let x_3 : tobj := test9 x_2;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test9 (a : UInt16) := a.toNat

/--
trace: [Compiler.IR] [result]
def test10 (x_1 : u8) : tobj :=
let x_2 : tagged := Int8.toInt x_1;
ret x_2
def test10._boxed (x_1 : tagged) : tobj :=
let x_2 : u8 := unbox x_1;
let x_3 : tobj := test10 x_2;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test10 (a : Int8) := a.toInt

/--
trace: [Compiler.IR] [result]
def test11 (x_1 : u16) : tobj :=
let x_2 : tagged := Int16.toInt x_1;
ret x_2
def test11._boxed (x_1 : tagged) : tobj :=
let x_2 : u16 := unbox x_1;
let x_3 : tobj := test11 x_2;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test11 (a : Int16) := a.toInt

/--
warning: declaration uses 'sorry'
---
trace: [Compiler.IR] [result]
def test12 (x_1 : @& obj) (x_2 : @& tobj) : tobj :=
let x_3 : tagged := String.Pos.Raw.next' x_1 x_2 ◾;
ret x_3
def test12._boxed (x_1 : obj) (x_2 : tobj) : tobj :=
let x_3 : tobj := test12 x_1 x_2;
dec x_2;
dec x_1;
ret x_3
-/
#guard_msgs in
set_option trace.compiler.ir.result true in
def test12 (a : String) (p : String.Pos.Raw) := p.next' a sorry
Loading