Skip to content

Commit

Permalink
FIX: Use of the return: keyword in a function specification
Browse files Browse the repository at this point in the history
  • Loading branch information
Oldes committed Oct 31, 2024
1 parent 38f47f5 commit 25a05f4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/core/c-function.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,14 @@
if (!return_defined && VAL_WORD_SYM(blk) == SYM_RETURN && IS_BLOCK(blk+1)) {
return_defined = TRUE;
blk++; // skips the return's specification
continue;
Remove_Series(words, n+1, 1);
break;
}
// fall thru...
default:
Trap1(RE_BAD_FUNC_DEF, blk);
// Report full invalid function spec block in the error.
Set_Block(DS_RETURN, block);
Trap1(RE_BAD_FUNC_DEF, DS_RETURN);
}
}

Expand Down
51 changes: 51 additions & 0 deletions src/tests/units/func-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,57 @@ Rebol [
===end-group===


===start-group=== "function construction"

--test-- "return: keyword"
;@@ https://github.com/Oldes/Rebol-issues/issues/2602
;; because unit tests are guearded by `wrap`, the return value would be unset:/
return: :lib/return ;; so use the original function
;; maybe it would be good not to use return as a set-word in this case at all!

fun: func[a [integer!] return: [integer!]][ return 2 * a 'foo]
--assert 2 == fun 1

foreach spec [
[return: []]
[return: [] "Foo"]
[a return: []]
[return: [] a]
[return: [integer!]]
[a [integer!] return: [integer!]]
[/foo return: [integer!]]
["test" return: []]
["test" return: [] "Foo"]
["test" a return: []]
["test" return: [] a]
["test" return: [integer!]]
["test" a [integer!] return: [integer!]]
["test" /foo return: [integer!]]
][
--assert all [
function? fun: try [ func :spec [true] ]
spec == spec-of :fun
]
]
foreach spec [
[return:]
[return: ""]
][
--assert all [
error? e: try [ func :spec [] ]
e/id = 'bad-func-def
e/arg1 == spec
]
]
--assert all [
error? e: try [ func [return: [] a return: []][] ]
e/id = 'dup-vars
e/arg1 = 'return
]

===end-group===


===start-group=== "Apply"

--test-- "apply :do [:func]"
Expand Down

0 comments on commit 25a05f4

Please sign in to comment.