X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Flate-type.lisp;h=63431b9f85aad4fc6d7bda8e1eb0e0a8e1a1f8ee;hb=a6a12ed609d5467ec43b411283e5b3568fee81df;hp=16b605d7dc8b4e174ad849a0daa20fb938475bd5;hpb=49319a8c7f3527b0d452b8f07bdabe02283e8ff7;p=sbcl.git diff --git a/src/code/late-type.lisp b/src/code/late-type.lisp index 16b605d..63431b9 100644 --- a/src/code/late-type.lisp +++ b/src/code/late-type.lisp @@ -432,8 +432,9 @@ 1 (values-type-max-value-count type))) +;;; VALUES type with a single value. (defun type-single-value-p (type) - (and (values-type-p type) + (and (%values-type-p type) (not (values-type-rest type)) (null (values-type-optional type)) (singleton-p (values-type-required type)))) @@ -1731,7 +1732,7 @@ (eql low high) (eql (numeric-type-complexp type) :real) (member (numeric-type-class type) '(integer rational - #!-sb-xc-host float))) + #-sb-xc-host float))) (values t (numeric-type-low type)) (values nil nil)))) @@ -1883,10 +1884,12 @@ ;;; Return a numeric type that is a supertype for both TYPE1 and TYPE2. ;;; -;;; Old comment, probably no longer applicable: -;;; -;;; ### Note: we give up early to keep from dropping lots of -;;; information on the floor by returning overly general types. +;;; Binding *APPROXIMATE-NUMERIC-UNIONS* to T allows merging non-adjacent +;;; numeric types, eg (OR (INTEGER 0 12) (INTEGER 20 128)) => (INTEGER 0 128), +;;; the compiler does this occasionally during type-derivation to avoid +;;; creating absurdly complex unions of numeric types. +(defvar *approximate-numeric-unions* nil) + (!define-type-method (number :simple-union2) (type1 type2) (declare (type numeric-type type1 type2)) (cond ((csubtypep type1 type2) type2) @@ -1902,7 +1905,8 @@ ((and (eq class1 class2) (eq format1 format2) (eq complexp1 complexp2) - (or (numeric-types-intersect type1 type2) + (or *approximate-numeric-unions* + (numeric-types-intersect type1 type2) (numeric-types-adjacent type1 type2) (numeric-types-adjacent type2 type1))) (make-numeric-type @@ -1924,7 +1928,8 @@ (integerp (numeric-type-low type2)) (integerp (numeric-type-high type2)) (= (numeric-type-low type2) (numeric-type-high type2)) - (or (numeric-types-adjacent type1 type2) + (or *approximate-numeric-unions* + (numeric-types-adjacent type1 type2) (numeric-types-adjacent type2 type1))) (make-numeric-type :class 'rational @@ -1943,7 +1948,8 @@ (integerp (numeric-type-low type1)) (integerp (numeric-type-high type1)) (= (numeric-type-low type1) (numeric-type-high type1)) - (or (numeric-types-adjacent type1 type2) + (or *approximate-numeric-unions* + (numeric-types-adjacent type1 type2) (numeric-types-adjacent type2 type1))) (make-numeric-type :class 'rational @@ -2398,14 +2404,8 @@ used for a COMPLEX component.~:@>" (values nil t)) ((or (unknown-type-p (array-type-element-type type1)) (unknown-type-p (array-type-element-type type2))) - (multiple-value-bind (equalp certainp) - (type= (array-type-element-type type1) - (array-type-element-type type2)) - ;; By its nature, the call to TYPE= should never return - ;; NIL, T, as we don't know what the UNKNOWN-TYPE will grow - ;; up to be. -- CSR, 2002-08-19 - (aver (not (and (not equalp) certainp))) - (values equalp certainp))) + (type= (array-type-element-type type1) + (array-type-element-type type2))) (t (values (type= (array-type-specialized-element-type type1) (array-type-specialized-element-type type2)) @@ -2904,11 +2904,12 @@ used for a COMPLEX component.~:@>" :high (if (null (numeric-type-high type1)) nil (list (1+ (numeric-type-high type1))))))) - (type-union type1 - (apply #'type-intersection - (remove (specifier-type '(not integer)) - (intersection-type-types type2) - :test #'type=)))) + (let* ((intersected (intersection-type-types type2)) + (remaining (remove (specifier-type '(not integer)) + intersected + :test #'type=))) + (and (not (equal intersected remaining)) + (type-union type1 (apply #'type-intersection remaining))))) (t (let ((accumulator *universal-type*)) (do ((t2s (intersection-type-types type2) (cdr t2s))) @@ -3296,10 +3297,20 @@ used for a COMPLEX component.~:@>" ((type= type (specifier-type 'base-char)) 'base-char) ((type= type (specifier-type 'extended-char)) 'extended-char) ((type= type (specifier-type 'standard-char)) 'standard-char) - (t (let ((pairs (character-set-type-pairs type))) - `(member ,@(loop for (low . high) in pairs + (t + ;; Unparse into either MEMBER or CHARACTER-SET. We use MEMBER if there + ;; are at most as many characters than there are character code ranges. + (let* ((pairs (character-set-type-pairs type)) + (count (length pairs)) + (chars (loop named outer + for (low . high) in pairs nconc (loop for code from low upto high - collect (sb!xc:code-char code)))))))) + collect (sb!xc:code-char code) + when (minusp (decf count)) + do (return-from outer t))))) + (if (eq chars t) + `(character-set ,pairs) + `(member ,@chars)))))) (!define-type-method (character-set :singleton-p) (type) (let* ((pairs (character-set-type-pairs type))