master: Derive the return type of XEPs
stassats via Sbcl-commits <[email protected]> Wed, 06 May 2026 01:37:45 +0000
| Newsgroups | gmane.lisp.steel-bank.cvs |
|---|---|
| Message-ID | <[email protected]> |
The branch "master" has been updated in SBCL:
via 4de59fbb0311928a2a39ff5e554f5b823ebe1f30 (commit)
from 187f57e2244946c0953dcd1c99c3a28553c557ec (commit)
- Log -----------------------------------------------------------------
commit 4de59fbb0311928a2a39ff5e554f5b823ebe1f30
Author: Stas Boukarev <[email protected]>
Date: Wed May 6 04:35:44 2026 +0300
Derive the return type of XEPs
---
src/code/type.lisp | 15 +++++++++++++++
src/cold/exports.lisp | 1 +
src/compiler/ir1opt.lisp | 8 ++++++--
tests/compiler-2.pure.lisp | 9 +++++++++
4 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/src/code/type.lisp b/src/code/type.lisp
index 78f291d34..aa34eb5b0 100644
--- a/src/code/type.lisp
+++ b/src/code/type.lisp
@@ -620,6 +620,21 @@
(new fun-designator-type)
(new fun-type))))))
+(defun fun-type-change-return (type return)
+ (if (fun-type-p type)
+ (make-fun-type
+ :required (fun-type-required type)
+ :optional (fun-type-optional type)
+ :rest (fun-type-rest type)
+ :keyp (fun-type-keyp type)
+ :keywords (fun-type-keywords type)
+ :allowp (fun-type-allowp type)
+ :wild-args (fun-type-wild-args type)
+ :returns return)
+ (make-fun-type
+ :wild-args t
+ :returns return)))
+
;; This seems to be used only by cltl2, and within 'cross-type',
;; where it is never used, which makes sense, since pretty much we
;; never want this object, but instead the classoid FUNCTION
diff --git a/src/cold/exports.lisp b/src/cold/exports.lisp
index 55c93ca5b..fb1213168 100644
--- a/src/cold/exports.lisp
+++ b/src/cold/exports.lisp
@@ -1774,6 +1774,7 @@ is a good idea, but see SB-SYS re. blurring of boundaries.")
"FUN-TYPE-KEYP" "FUN-TYPE-KEYWORDS" "FUN-TYPE-NARGS"
"FUN-TYPE-OPTIONAL" "FUN-TYPE-P" "FUN-TYPE-REQUIRED"
"FUN-TYPE-REST" "FUN-TYPE-RETURNS" "FUN-TYPE-WILD-ARGS"
+ "FUN-TYPE-CHANGE-RETURN"
"GENERALIZED-BOOLEAN"
"GENERIC-ABSTRACT-TYPE-FUNCTION"
"GET-CLOSURE-LENGTH" "GET-HEADER-DATA"
diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp
index a0cba11c1..b500dad9f 100644
--- a/src/compiler/ir1opt.lisp
+++ b/src/compiler/ir1opt.lisp
@@ -809,8 +809,12 @@
(unless (type= (res) (tail-set-type tails))
(setf (tail-set-type tails) (res))
(dolist (fun (tail-set-funs tails))
- (dolist (ref (leaf-refs fun))
- (reoptimize-lvar (node-lvar ref))))))))))
+ (let* ((entry-type (fun-type-change-return (leaf-type fun) (res)))
+ (ref-type (make-single-value-type entry-type)))
+ (setf (leaf-type fun) entry-type)
+ (dolist (ref (leaf-refs fun))
+ (setf (node-derived-type ref) ref-type)
+ (reoptimize-lvar (node-lvar ref)))))))))))
;;;; IF optimization
diff --git a/tests/compiler-2.pure.lisp b/tests/compiler-2.pure.lisp
index ca3ecaf10..1271399be 100644
--- a/tests/compiler-2.pure.lisp
+++ b/tests/compiler-2.pure.lisp
@@ -5143,3 +5143,12 @@
(declare ((simple-array nil (9)) a))
(setf (aref a 0) 1)
a)))
+
+(with-test (:name :xep-type-derivation)
+ (assert-type
+ (lambda (n)
+ (funcall (if n
+ (lambda (a) (+ a 2))
+ (lambda (a) (+ a 1)))
+ 1))
+ number))
-----------------------------------------------------------------------
hooks/post-receive
--
SBCL