X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fctype.lisp;h=babda466e4cb8667615491a708687da49ff66bb9;hb=80f222325e1f677e5cf8de01c6990906fa47f65d;hp=64dce3b13203acb710af90bcb9b46948cadd0257;hpb=57e21c4b62e8c1a1ee7ef59ed2abb0c864fb06bc;p=sbcl.git diff --git a/src/compiler/ctype.lisp b/src/compiler/ctype.lisp index 64dce3b..babda46 100644 --- a/src/compiler/ctype.lisp +++ b/src/compiler/ctype.lisp @@ -93,10 +93,8 @@ ;;; matches the specified result. ;;; ;;; Unlike the argument test, the result test may be called on values -;;; or function types. If STRICT-RESULT is true and SAFETY is -;;; non-zero, then the NODE-DERIVED-TYPE is always used. Otherwise, if -;;; CONT's TYPE-CHECK is true, then the NODE-DERIVED-TYPE is -;;; intersected with the CONT's ASSERTED-TYPE. +;;; or function types. NODE-DERIVED-TYPE is intersected with the +;;; trusted asserted type. ;;; ;;; The error and warning functions are functions that are called to ;;; explain the result. We bind *COMPILER-ERROR-CONTEXT* to the @@ -107,7 +105,7 @@ (result-test #'values-subtypep) ((:lossage-fun *lossage-fun*)) ((:unwinnage-fun *unwinnage-fun*))) - (declare (type function result-test) (type combination call) + (declare (type (or function null) result-test) (type combination call) ;; FIXME: Could TYPE here actually be something like ;; (AND GENERIC-FUNCTION (FUNCTION (T) T))? How ;; horrible... -- CSR, 2003-05-03 @@ -153,17 +151,26 @@ (when keyp (check-key-args args max-args type)))) - (let* ((dtype (node-derived-type call)) - (return-type (fun-type-returns type)) - (out-type dtype)) - (multiple-value-bind (int win) (funcall result-test out-type return-type) - (cond ((not win) - (note-unwinnage "can't tell whether the result is a ~S" - (type-specifier return-type))) - ((not int) - (note-lossage "The result is a ~S, not a ~S." - (type-specifier out-type) - (type-specifier return-type))))))) + (when result-test + (let* ((dtype (node-derived-type call)) + (out-type (or + (binding* ((lvar (node-lvar call) :exit-if-null) + (dest (lvar-dest lvar))) + (when (and (cast-p dest) + (eq (cast-type-to-check dest) *wild-type*) + (immediately-used-p lvar call)) + (values-type-intersection + dtype (cast-asserted-type dest)))) + dtype)) + (return-type (fun-type-returns type))) + (multiple-value-bind (int win) (funcall result-test out-type return-type) + (cond ((not win) + (note-unwinnage "can't tell whether the result is a ~S" + (type-specifier return-type))) + ((not int) + (note-lossage "The result is a ~S, not a ~S." + (type-specifier out-type) + (type-specifier return-type)))))))) (loop for arg in args and i from 1 do (check-arg-type arg *wild-type* i))) @@ -843,7 +850,8 @@ (let ((atype (lvar-value atype)) (dtype (lvar-value dtype))) (unless (eq atype nil) - (compiler-warn - "~@" - atype dtype)))) + (warn 'type-warning + :format-control + "~@" + :format-arguments (list atype dtype))))) (ir2-convert-full-call node block)))