(ok-lvar-lambda-var (first args) constraints)
(if (ctype-p val)
val
- (specifier-type val))
+ (let ((*compiler-error-context* use))
+ (specifier-type val)))
nil)))))
((eq eql)
(let* ((arg1 (first args))
(var2
(add 'eql var1 var2 nil))
((constant-lvar-p arg2)
- (add 'eql var1 (ref-leaf (principal-lvar-use arg2))
+ (add 'eql var1
+ (let ((use (principal-lvar-use arg2)))
+ (if (ref-p use)
+ (ref-leaf use)
+ (find-constant (lvar-value arg2))))
nil))
(t
(add-test-constraint 'typep var1 (lvar-type arg2)
(modified-numeric-type x :low new-bound)
(modified-numeric-type x :high new-bound)))))
+;;; Return true if LEAF is "visible" from NODE.
+(defun leaf-visible-from-node-p (leaf node)
+ (cond
+ ((lambda-var-p leaf)
+ ;; A LAMBDA-VAR is visible iif it is homed in a CLAMBDA that is an
+ ;; ancestor for NODE.
+ (let ((leaf-lambda (lambda-var-home leaf)))
+ (loop for lambda = (node-home-lambda node)
+ then (lambda-parent lambda)
+ while lambda
+ when (eq lambda leaf-lambda)
+ return t)))
+ ;; FIXME: Check on FUNCTIONALs (CLAMBDAs and OPTIONAL-DISPATCHes),
+ ;; not just LAMBDA-VARs.
+ (t
+ ;; Assume everything else is globally visible.
+ t)))
+
;;; Given the set of CONSTRAINTS for a variable and the current set of
;;; restrictions from flow analysis IN, set the type for REF
;;; accordingly.
(and (leaf-refs other) ; protect from
; deleted vars
(csubtypep other-type leaf-type)
- (not (type= other-type leaf-type))))
+ (not (type= other-type leaf-type))
+ ;; Don't change to a LEAF not visible here.
+ (leaf-visible-from-node-p other ref)))
(change-ref-leaf ref other)
(when (constant-p other) (return)))
(t
for var in (lambda-vars fun)
and val in (combination-args call)
when (and val (lambda-var-constraints var))
- do (let* ((type (lvar-type val))
- (con (find-or-create-constraint 'typep var type
- nil)))
- (conset-adjoin con gen))
- (maybe-add-eql-var-var-constraint var val gen)))))
+ do (let ((type (lvar-type val)))
+ (unless (eq type *universal-type*)
+ (let ((con (find-or-create-constraint 'typep var type nil)))
+ (conset-adjoin con gen))))
+ (maybe-add-eql-var-var-constraint var val gen)))))
(ref
(when (ok-ref-lambda-var node)
(maybe-add-eql-var-lvar-constraint node gen)
(let ((var (ok-lvar-lambda-var lvar gen)))
(when var
(let ((atype (single-value-type (cast-derived-type node)))) ;FIXME
- (do-eql-vars (var (var gen))
- (let ((con (find-or-create-constraint 'typep var atype nil)))
- (conset-adjoin con gen))))))))
+ (unless (eq atype *universal-type*)
+ (do-eql-vars (var (var gen))
+ (let ((con (find-or-create-constraint 'typep var atype nil)))
+ (conset-adjoin con gen)))))))))
(cset
(binding* ((var (set-var node))
(nil (lambda-var-p var) :exit-if-null)
(cons (lambda-var-constraints var) :exit-if-null))
(conset-difference gen cons)
- (let* ((type (single-value-type (node-derived-type node)))
- (con (find-or-create-constraint 'typep var type nil)))
- (conset-adjoin con gen))
+ (let ((type (single-value-type (node-derived-type node))))
+ (unless (eq type *universal-type*)
+ (let ((con (find-or-create-constraint 'typep var type nil)))
+ (conset-adjoin con gen))))
(maybe-add-eql-var-var-constraint var (set-value node) gen)))))
gen)