1 ;;;; This file contains the definition of non-CLASS types (e.g.
2 ;;;; subtypes of interesting BUILT-IN-CLASSes) and the interfaces to
3 ;;;; the type system. Common Lisp type specifiers are parsed into a
4 ;;;; somewhat canonical internal type representation that supports
5 ;;;; type union, intersection, etc.
7 ;;;; This software is part of the SBCL system. See the README file for
10 ;;;; This software is derived from the CMU CL system, which was
11 ;;;; written at Carnegie Mellon University and released into the
12 ;;;; public domain. The software is in the public domain and is
13 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
14 ;;;; files for more information.
16 (in-package "SB-KERNEL")
18 (!begin-collecting-cold-init-forms
)
20 ;;; ### Remaining incorrectnesses:
22 ;;; There are all sorts of nasty problems with open bounds on FLOAT
23 ;;; types (and probably FLOAT types in general.)
25 ;;; This condition is signalled whenever we make a UNKNOWN-TYPE so that
26 ;;; compiler warnings can be emitted as appropriate.
27 (define-condition parse-unknown-type
(condition)
28 ((specifier :reader parse-unknown-type-specifier
:initarg
:specifier
))
30 :specifier
(missing-arg)))
32 ;;; This condition is signalled whenever we encounter a type (DEFTYPE,
33 ;;; structure, condition, class) that has been marked as deprecated.
34 (define-condition parse-deprecated-type
(condition)
35 ((specifier :reader parse-deprecated-type-specifier
:initarg
:specifier
))
37 :specifier
(missing-arg)))
39 ;;; For-effect-only variant of CHECK-DEPRECATED-THING for
40 ;;; type-specifiers that descends into compound type-specifiers.
41 (defun sb-impl::%check-deprecated-type
(type-specifier)
43 ;; KLUDGE: we have to use SPECIFIER-TYPE to sanely traverse
44 ;; TYPE-SPECIFIER and detect references to deprecated types. But
45 ;; then we may have to drop its cache to get the
46 ;; PARSE-DEPRECATED-TYPE condition when TYPE-SPECIFIER is parsed
49 ;; Proper fix would be a
51 ;; walk-type function type-specifier
53 ;; mechanism that could drive VALUES-SPECIFIER-TYPE but also
54 ;; things like this function.
57 ((parse-deprecated-type
59 (let ((type-specifier (parse-deprecated-type-specifier condition
)))
60 (aver (symbolp type-specifier
))
61 (unless (memq type-specifier seen
)
62 (push type-specifier seen
)
63 (check-deprecated-thing 'type type-specifier
)))))
64 ((or error parse-unknown-type
)
66 (declare (ignore condition
))
68 (specifier-type type-specifier
)))))
70 (defun check-slot-type-specifier (specifier slot-name context
)
71 ;; This signals an error for malformed type specifiers and
72 ;; deprecation warnings for deprecated types but does nothing for
74 (with-current-source-form (specifier)
76 (and (let ((ctype (specifier-type specifier
)))
77 (when (eq ctype
*empty-type
*)
78 (style-warn "The type of the slot ~s is the empty type NIL" slot-name
))
80 (sb-impl::%check-deprecated-type specifier
))
81 (parse-unknown-type (c)
82 (when (typep specifier
'(cons (eql quote
)))
85 (destructuring-bind (operator . class-name
) context
86 (sb-c:compiler-warn
"Invalid :TYPE for slot ~S in ~S ~S: ~A."
87 slot-name operator class-name condition
))))))
89 (defun maybe-reparse-specifier (type)
90 (when (unknown-type-p type
)
91 (let* ((spec (unknown-type-specifier type
))
92 (name (if (consp spec
)
95 (when (info :type
:kind name
)
96 (let ((new-type (specifier-type spec
)))
97 (unless (unknown-type-p new-type
)
101 (defmacro maybe-reparse-specifier
! (type)
102 (aver (symbolp type
))
103 (with-unique-names (new-type)
104 `(let ((,new-type
(maybe-reparse-specifier ,type
)))
106 (setf ,type
,new-type
)
109 ;;; These functions are used as method for types which need a complex
110 ;;; subtypep method to handle some superclasses, but cover a subtree
111 ;;; of the type graph (i.e. there is no simple way for any other type
112 ;;; class to be a subtype.) There are always still complex ways,
113 ;;; namely UNION and MEMBER types, so we must give TYPE1's method a
114 ;;; chance to run, instead of immediately returning NIL, T.
115 (defun delegate-complex-subtypep-arg2 (type1 type2
)
117 (type-class-complex-subtypep-arg1 (type-class type1
))))
119 (funcall subtypep-arg1 type1 type2
)
121 (defun delegate-complex-intersection2 (type1 type2
)
122 (let ((method (type-class-complex-intersection2 (type-class type1
))))
123 (if (and method
(not (eq method
#'delegate-complex-intersection2
)))
124 (funcall method type2 type1
)
125 (hierarchical-intersection2 type1 type2
))))
127 (defun map-type (function ctype
)
128 (declare (type (or ctype null
) ctype
)
129 (dynamic-extent function
))
130 (named-let %map
((type ctype
))
131 (funcall function type
)
134 (mapc #'%map
(compound-type-types type
)))
135 (negation-type (%map
(negation-type-type type
)))
137 (%map
(cons-type-car-type type
))
138 (%map
(cons-type-cdr-type type
)))
140 (%map
(array-type-element-type type
)))
142 (%map
(constant-type-type type
)))
144 (mapc #'%map
(args-type-required type
))
145 (mapc #'%map
(args-type-optional type
))
146 (when (args-type-rest type
)
147 (%map
(args-type-rest type
)))
148 (mapc (lambda (x) (%map
(key-info-type x
)))
149 (args-type-keywords type
))
150 (when (fun-type-p type
)
151 (%map
(fun-type-returns type
))))))
154 (defun replace-hairy-type (type)
155 (if (contains-hairy-type-p type
)
157 (hairy-type *universal-type
*)
158 (intersection-type (%type-intersection
159 (mapcar #'replace-hairy-type
(intersection-type-types type
))))
160 (union-type (%type-union
161 (mapcar #'replace-hairy-type
(union-type-types type
))))
163 (let ((new (replace-hairy-type (negation-type-type type
))))
164 (if (eq new
*universal-type
*)
166 (type-negation new
))))
171 ;; Similar to (NOT CONTAINS-UNKNOWN-TYPE-P), but report that (SATISFIES F)
172 ;; is not a testable type unless F is currently bound.
173 (defun testable-type-p (ctype)
174 (unless (contains-hairy-type-p ctype
)
175 (return-from testable-type-p t
))
180 (return-from testable-type-p nil
)) ; must precede HAIRY because an unknown is HAIRY
182 (let ((spec (hairy-type-specifier ctype
)))
183 ;; Anything other than (SATISFIES ...) is testable
184 ;; because there's no reason to suppose that it isn't.
185 (unless (or (neq (car spec
) 'satisfies
) (fboundp (cadr spec
)))
186 (return-from testable-type-p nil
))))))
190 ;;; This is used by !DEFINE-SUPERCLASSES to define the SUBTYPE-ARG1
191 ;;; method. INFO is a list of conses
192 ;;; (SUPERCLASS-CLASS . {GUARD-TYPE-SPECIFIER | NIL}).
193 (defun has-superclasses-complex-subtypep-arg1 (type1 type2 info
)
194 ;; If TYPE2 might be concealing something related to our class
196 (cond ((type-might-contain-other-types-p type2
)
197 ;; too confusing, gotta punt
199 ((fun-designator-type-p type1
)
202 ;; ordinary case expected by old CMU CL code, where the taxonomy
203 ;; of TYPE2's representation accurately reflects the taxonomy of
204 ;; the underlying set
206 ;; FIXME: This old CMU CL code probably deserves a comment
207 ;; explaining to us mere mortals how it works...
208 (and (sb-xc:typep type2
'classoid
)
210 (let ((guard (cdr x
)))
211 (when (or (not guard
)
212 (csubtypep type1
(if (%instancep guard
)
215 (specifier-type guard
)))))
217 (or (eq type2
(car x
))
218 (let ((inherits (layout-inherits
219 (classoid-layout (car x
)))))
220 (dotimes (i (length inherits
) nil
)
221 (when (eq type2
(layout-classoid (svref inherits i
)))
225 ;;; This function takes a list of specs, each of the form
226 ;;; (SUPERCLASS-NAME &OPTIONAL GUARD).
227 ;;; Consider one spec (with no guard): any instance of the named
228 ;;; TYPE-CLASS is also a subtype of the named superclass and of any of
229 ;;; its superclasses. If there are multiple specs, then some will have
230 ;;; guards. We choose the first spec whose guard is a supertype of
231 ;;; TYPE1 and use its superclass. In effect, a sequence of guards
234 ;;; G0,(and G1 (not G0)), (and G2 (not (or G0 G1))).
236 ;;; WHEN controls when the forms are executed.
237 (defmacro !define-superclasses
(type-class-name specs progn-oid
)
238 (let ((defun-name (symbolicate type-class-name
"-COMPLEX-SUBTYPEP-ARG1")))
240 (defun ,defun-name
(type1 type2
)
241 (has-superclasses-complex-subtypep-arg1
244 (list ,@(mapcar (lambda (spec)
245 (destructuring-bind (super &optional guard
) spec
246 `(cons (find-classoid ',super
) ',guard
)))
247 specs
)) #-sb-xc-host t
)))
249 (let ((type-class (!type-class-or-lose
',type-class-name
)))
250 (setf (type-class-complex-subtypep-arg1 type-class
) #',defun-name
)
251 (setf (type-class-complex-subtypep-arg2 type-class
)
252 #'delegate-complex-subtypep-arg2
)
253 (setf (type-class-complex-intersection2 type-class
)
254 #'delegate-complex-intersection2
))))))
256 ;;;; FUNCTION and VALUES types
258 ;;;; Pretty much all of the general type operations are illegal on
259 ;;;; VALUES types, since we can't discriminate using them, do
260 ;;;; SUBTYPEP, etc. FUNCTION types are acceptable to the normal type
261 ;;;; operations, but are generally considered to be equivalent to
262 ;;;; FUNCTION. These really aren't true types in any type theoretic
263 ;;;; sense, but we still parse them into CTYPE structures for two
266 ;;;; -- Parsing and unparsing work the same way, and indeed we can't
267 ;;;; tell whether a type is a function or values type without
269 ;;;; -- Many of the places that can be annotated with real types can
270 ;;;; also be annotated with function or values types.
272 (define-type-class values
:enumerable nil
:might-contain-other-types nil
)
274 (defun make-values-type (required &optional optional rest
)
275 (multiple-value-bind (required optional rest
)
276 (canonicalize-args-type-args required optional rest
)
277 (cond ((and (null required
) (null optional
) (eq rest
*universal-type
*))
279 ((memq *empty-type
* required
)
282 (let ((required (intern-ctype-list required
))
283 (optional (intern-ctype-list optional
)))
284 (new-ctype values-type
286 (logior (type-list-flags (args-type-required x
))
287 (type-list-flags (args-type-optional x
))
288 (acond ((args-type-rest x
) (type-flags it
))
290 required optional rest
))))))
292 (define-type-method (values :simple-subtypep
:complex-subtypep-arg1
)
294 (declare (ignore type2
))
295 ;; FIXME: should be TYPE-ERROR, here and in next method
296 (error "SUBTYPEP is illegal on this type:~% ~S" (type-specifier type1
)))
298 (define-type-method (values :complex-subtypep-arg2
)
300 (declare (ignore type1
))
301 (error "SUBTYPEP is illegal on this type:~% ~S" (type-specifier type2
)))
303 (define-type-method (values :negate
) (type)
304 (error "NOT VALUES too confusing on ~S" (type-specifier type
)))
306 (defun type-unparse (flags thing
)
308 (mapcar (lambda (x) (funcall (type-class-unparse (type-class x
)) flags x
))
310 (funcall (type-class-unparse (type-class thing
)) flags thing
)))
312 ;;; Return the lambda-list-like type specification corresponding
314 (defun unparse-args-types (flags type
)
316 (when (args-type-optional type
)
318 (dolist (arg (args-type-optional type
))
319 (result (type-unparse flags arg
))))
321 (when (args-type-rest type
)
323 (result (type-unparse flags
(args-type-rest type
))))
325 (when (args-type-keyp type
)
327 (dolist (key (args-type-keywords type
))
328 (result (list (key-info-name key
)
329 (type-unparse flags
(key-info-type key
))))))
331 (when (args-type-allowp type
)
332 (result '&allow-other-keys
))
334 (nconc (type-unparse flags
(args-type-required type
))
337 (define-type-method (values :unparse
) (flags type
)
339 (let ((unparsed (unparse-args-types flags type
)))
340 (if (or (values-type-optional type
)
341 (values-type-rest type
))
343 (nconc unparsed
'(&optional
))))))
345 ;;; Hmm, according to the comments at DEFUN-CACHED, it may be inefficient
346 ;;; to proclaim the type of a cached function, because it forces checks to
347 ;;; be inserted on every return from the function, even though we would only
348 ;;; need to check when inserting to the cache.
350 (declaim (ftype (sfunction (ctype ctype
) (values t t
)) type
=))
352 ;;; Return true if LIST1 and LIST2 have the same elements in the same
353 ;;; positions according to TYPE=. We return NIL, NIL if there is an
354 ;;; uncertain comparison.
355 (defun type=-list
(list1 list2
)
356 (declare (list list1 list2
))
357 (do ((types1 list1
(cdr types1
))
358 (types2 list2
(cdr types2
)))
359 ((or (null types1
) (null types2
))
360 (if (or types1 types2
)
363 (multiple-value-bind (val win
)
364 (type= (first types1
) (first types2
))
366 (return (values nil nil
)))
368 (return (values nil t
))))))
370 (define-type-method (values :simple-
=) (type1 type2
)
371 (type=-args type1 type2
))
373 (define-type-class function
:enumerable nil
:might-contain-other-types nil
)
375 (define-type-method (function :negate
) (type) (make-negation-type type
))
377 (define-type-method (function :unparse
) (flags type
)
378 (let ((name (if (fun-designator-type-p type
)
381 (cond ((logtest flags
+unparse-fun-type-simplify
+)
385 (if (fun-type-wild-args type
)
387 (unparse-args-types flags type
))
388 (type-unparse flags
(fun-type-returns type
)))))))
390 ;;; The meaning of this is a little confused. On the one hand, all
391 ;;; function objects are represented the same way regardless of the
392 ;;; arglists and return values, and apps don't get to ask things like
393 ;;; (TYPEP #'FOO (FUNCTION (FIXNUM) *)) in any meaningful way. On the
394 ;;; other hand, Python wants to reason about function types. So...
395 (define-type-method (function :simple-subtypep
) (type1 type2
)
396 (cond ((and (fun-designator-type-p type1
)
397 (not (fun-designator-type-p type2
)))
400 ;; Since the following doesn't handle &rest or &key at least
401 ;; pick out equal types.
404 (flet ((fun-type-simple-p (type)
405 (not (or (fun-type-rest type
)
406 (fun-type-keyp type
))))
407 (every-csubtypep (types1 types2
)
411 do
(multiple-value-bind (res sure-p
)
413 (unless res
(return (values res sure-p
))))
414 finally
(return (values t t
)))))
415 (and/type
(values-subtypep (fun-type-returns type1
)
416 (fun-type-returns type2
))
417 (cond ((fun-type-wild-args type2
) (values t t
))
418 ((fun-type-wild-args type1
)
419 (cond ((fun-type-keyp type2
) (values nil nil
))
420 ((not (fun-type-rest type2
)) (values nil t
))
421 ((not (null (fun-type-required type2
)))
423 (t (and/type
(type= *universal-type
*
424 (fun-type-rest type2
))
429 ((not (and (fun-type-simple-p type1
)
430 (fun-type-simple-p type2
)))
432 (t (multiple-value-bind (min1 max1
) (fun-type-nargs type1
)
433 (multiple-value-bind (min2 max2
) (fun-type-nargs type2
)
434 (cond ((or (> max1 max2
) (< min1 min2
))
436 ((and (= min1 min2
) (= max1 max2
))
437 (and/type
(every-csubtypep
438 (fun-type-required type1
)
439 (fun-type-required type2
))
441 (fun-type-optional type1
)
442 (fun-type-optional type2
))))
445 (fun-type-required type1
)
446 (fun-type-optional type1
))
448 (fun-type-required type2
)
449 (fun-type-optional type2
))))))))))))))
451 (!define-superclasses function
((function)) !cold-init-forms
)
453 ;;; The union or intersection of two FUNCTION types is FUNCTION.
454 (define-type-method (function :simple-union2
) (type1 type2
)
455 (let ((designator (or (fun-designator-type-p type1
)
456 (fun-designator-type-p type2
)))
457 (ftype (specifier-type 'function
)))
458 (if (or (eq type1 ftype
)
461 (specifier-type 'function-designator
)
462 (specifier-type 'function
))
463 (let ((rtype (values-type-union (fun-type-returns type1
)
464 (fun-type-returns type2
))))
466 ((fun-type-wild-args type1
)
467 (make-fun-type :wild-args t
469 :designator designator
))
470 ((fun-type-wild-args type2
)
471 (make-fun-type :wild-args t
473 :designator designator
))
475 (multiple-value-bind (req opt rest
)
476 (args-type-op type1 type2
#'type-union
#'min
)
477 (let* ((keyp (or (fun-type-keyp type1
)
478 (fun-type-keyp type2
)))
479 (actually-keyp (and keyp
480 (= (sb-c::fun-type-positional-count type1
)
481 (sb-c::fun-type-positional-count type2
))))
488 (subseq opt
0 (- (min (sb-c::fun-type-positional-count type1
)
489 (sb-c::fun-type-positional-count type2
))
492 (keys (when actually-keyp
494 (loop for key1 in
(fun-type-keywords type1
)
495 for key2
= (find (key-info-name key1
)
496 (fun-type-keywords type2
)
497 :key
#'key-info-name
)
499 (push (make-key-info (key-info-name key1
)
500 (type-union (key-info-type key1
)
501 (key-info-type key2
)))
504 (loop for key2 in
(fun-type-keywords type2
)
505 do
(pushnew key2 keys
:key
#'key-info-name
))
507 (make-fun-type :required req
510 :allowp
(or (fun-type-allowp type1
)
511 (fun-type-allowp type2
))
514 :keywords
(intern-key-infos keys
)
515 :designator designator
)))))))))
517 (define-type-method (function :simple-intersection2
) (type1 type2
)
518 (let ((ftype (specifier-type 'function
)))
519 (cond ((eq type1 ftype
) type2
)
520 ((eq type2 ftype
) type1
)
521 (t (let ((rtype (values-type-intersection (fun-type-returns type1
)
522 (fun-type-returns type2
)))
524 (and (fun-designator-type-p type1
)
525 (fun-designator-type-p type2
))))
526 (flet ((change-returns (ftype rtype
)
527 (declare (type fun-type ftype
) (type ctype rtype
))
528 (make-fun-type :required
(fun-type-required ftype
)
529 :optional
(fun-type-optional ftype
)
530 :keyp
(fun-type-keyp ftype
)
531 :rest
(fun-type-rest ftype
)
532 :keywords
(fun-type-keywords ftype
)
533 :allowp
(fun-type-allowp ftype
)
535 :designator designator
)))
537 ((fun-type-wild-args type1
)
538 (if (fun-type-wild-args type2
)
539 (make-fun-type :wild-args t
541 :designator designator
)
542 (change-returns type2 rtype
)))
543 ((fun-type-wild-args type2
)
544 (change-returns type1 rtype
))
545 (t (multiple-value-bind (req opt rest
)
546 (args-type-op type1 type2
#'type-intersection
#'max
)
547 (let ((keyp (and (fun-type-keyp type1
)
548 (fun-type-keyp type2
))))
549 (make-fun-type :required req
556 (loop for key1 in
(fun-type-keywords type1
)
557 for key2
= (find (key-info-name key1
)
558 (fun-type-keywords type2
)
559 :key
#'key-info-name
)
561 (push (make-key-info (key-info-name key1
)
562 (type-intersection (key-info-type key1
)
563 (key-info-type key2
)))
565 (intern-key-infos keys
)))
566 :allowp
(and (fun-type-allowp type1
)
567 (fun-type-allowp type2
))
569 :designator designator
)))))))))))
571 ;;; The union or intersection of a subclass of FUNCTION with a
572 ;;; FUNCTION type is somewhat complicated.
573 (define-type-method (function :complex-intersection2
) (type1 type2
)
575 ((and (fun-designator-type-p type2
)
576 (or (csubtypep type1
(specifier-type 'symbol
))
577 (csubtypep type1
(specifier-type 'function
))))
579 ((type= type1
(specifier-type 'function
)) type2
)
580 ((csubtypep type1
(specifier-type 'function
)) nil
)
581 (t :call-other-method
)))
582 (define-type-method (function :complex-union2
) (type1 type2
)
583 (declare (ignore type2
))
584 ;; TYPE2 is a FUNCTION type. If TYPE1 is a classoid type naming
585 ;; FUNCTION, then it is the union of the two; otherwise, there is no
588 ((type= type1
(specifier-type 'function
)) type1
)
591 (define-type-method (function :simple-
=) (type1 type2
)
592 (if (or (and (fun-designator-type-p type1
)
593 (not (fun-designator-type-p type2
)))
594 (and (not (fun-designator-type-p type1
))
595 (fun-designator-type-p type2
)))
597 (macrolet ((compare (comparator field
)
598 (let ((reader (symbolicate '#:fun-type- field
)))
599 `(,comparator
(,reader type1
) (,reader type2
)))))
600 (and/type
(compare type
= returns
)
601 (cond ((neq (fun-type-wild-args type1
) (fun-type-wild-args type2
))
603 ((eq (fun-type-wild-args type1
) t
)
605 (t (type=-args type1 type2
)))))))
607 (defun make-fun-type (&key required optional rest
611 (let ((rest (if (eq rest
*empty-type
*) nil rest
))
612 (required (intern-ctype-list required
))
613 (optional (intern-ctype-list optional
)))
614 (flet ((fun-type-flags (x)
615 (logior (type-list-flags (fun-type-required x
))
616 (type-list-flags (fun-type-optional x
))
617 (acond ((fun-type-rest x
) (type-flags it
))
619 (key-info-list-flags (fun-type-keywords x
))
620 (type-flags (fun-type-returns x
)))))
621 (macrolet ((new (metatype)
622 `(new-ctype ,metatype
#'fun-type-flags
623 required optional rest keyp keywords
624 allowp wild-args returns
)))
626 (new fun-designator-type
)
629 ;; This seems to be used only by cltl2, and within 'cross-type',
630 ;; where it is never used, which makes sense, since pretty much we
631 ;; never want this object, but instead the classoid FUNCTION
632 ;; if we know nothing about a function's signature.
633 ;; Maybe this should not exist unless cltl2 is loaded???
634 (define-load-time-global *universal-fun-type
*
635 (make-fun-type :wild-args t
:returns
*wild-type
*))
637 (define-type-class constant
:inherits values
)
639 (define-type-method (constant :negate
) (type)
640 (error "NOT CONSTANT too confusing on ~S" (type-specifier type
)))
642 (define-type-method (constant :unparse
) (flags type
)
643 `(constant-arg ,(type-unparse flags
(constant-type-type type
))))
645 (define-type-method (constant :simple-
=) (type1 type2
)
646 (type= (constant-type-type type1
) (constant-type-type type2
)))
648 (def-type-translator constant-arg
((:context context
) type
)
649 (let ((parse (single-value-specifier-type type context
)))
650 (new-ctype constant-type
(type-flags parse
) parse
)))
652 (defun canonicalize-args-type-args (required optional rest
&optional keyp
)
653 (when (eq rest
*empty-type
*)
656 (loop with last-not-rest
= nil
659 do
(cond ((eq opt
*empty-type
*)
660 (return (values required
(subseq optional
0 i
) rest
)))
661 ((and (not keyp
) (neq opt rest
))
662 (setq last-not-rest i
)))
663 finally
(return (values required
667 (subseq optional
0 (1+ last-not-rest
))))
670 ;;; CONTEXT is the cookie passed down from the outermost surrounding call
671 ;;; of BASIC-PARSE-TYPE. INNER-CONTEXT-KIND is an indicator of whether
672 ;;; we are currently parsing a FUNCTION or a VALUES compound type specifier.
673 ;;; If the entire LAMBDA-LISTY-THING is *, we do not call this function at all.
674 ;;; If an element of it is *, that constitutes an error, as is clear
675 ;;; for VALUES: "The symbol * may not be among the value-types."
676 ;;; http://www.lispworks.com/documentation/HyperSpec/Body/t_values.htm
677 ;;; and the FUNCTION compound type, for which the grammar is:
678 ;;; function [arg-typespec [value-typespec]]
679 ;;; arg-typespec::= (typespec* [&optional typespec*] [&rest typespec];[&key (keyword typespec)*])
680 ;;; typespec --- a type specifier.
681 ;;; where the glossary says: "type specifier: n. an expression that denotes a type."
682 ;;; which of course * does not denote, and is made all the more clear by the fact
683 ;;; that the AND, OR, and NOT combinators explicitly preclude * as an element.
684 (defun parse-args-types (context lambda-listy-thing inner-context-kind
)
685 (multiple-value-bind (llks required optional rest keys
)
688 :context inner-context-kind
689 :accept
(ecase inner-context-kind
690 (:values-type
(lambda-list-keyword-mask '(&optional
&rest
)))
691 (:function-type
(lambda-list-keyword-mask
692 '(&optional
&rest
&key
&allow-other-keys
))))
694 (labels ((parse-list (list) (mapcar #'parse-one list
))
696 (specifier-type x context
697 (case inner-context-kind
698 (:function-type
'function
)
700 (let ((required (parse-list required
))
701 (optional (parse-list optional
))
702 (rest (when rest
(parse-one (car rest
))))
704 (collect ((key-info))
706 (unless (proper-list-of-length-p key
2)
707 (error "Keyword type description is not a two-list: ~S." key
))
708 (let ((kwd (first key
)))
709 (when (find kwd
(key-info) :key
#'key-info-name
)
710 (error (sb-format:tokens
711 "~@<repeated keyword ~S in lambda list: ~2I~_~
712 ~/sb-impl:print-lambda-list/~:>")
713 kwd lambda-listy-thing
))
716 ;; MAKE-KEY-INFO will complain if KWD is not a symbol.
717 ;; That's good enough - we don't need an extra check here.
719 (single-value-specifier-type (second key
) context
)))))
720 (intern-key-infos (key-info)))))
721 (multiple-value-bind (required optional rest
)
722 (canonicalize-args-type-args required optional rest
724 (values llks required optional rest keywords
))))))
726 (defun translate-fun-type (context args result
728 (let ((result (coerce-to-values (basic-parse-typespec result context
))))
730 (multiple-value-bind (llks required optional rest keywords
)
731 (parse-args-types context args
:function-type
)
732 (if (and (null required
)
734 (eq rest
*universal-type
*)
735 (not (ll-kwds-keyp llks
)))
736 (if (eq result
*wild-type
*)
737 (specifier-type 'function
)
738 (make-fun-type :wild-args t
:returns result
739 :designator designator
))
740 (make-fun-type :required required
743 :keyp
(ll-kwds-keyp llks
)
745 :allowp
(ll-kwds-allowp llks
)
747 :designator designator
))))
748 ((eq result
*wild-type
*)
750 ;; Do not put 'FUNCTION-DESIGNATOR here!
751 ;; (Since this is the parser for FUNCTION-DESIGNATOR)
752 (specifier-type '(or function symbol
))
753 (specifier-type 'function
)))
755 (make-fun-type :wild-args t
:returns result
756 :designator designator
)))))
758 (def-type-translator function
((:context context
)
759 &optional
(args '*) (result '*))
760 (translate-fun-type context args result
))
762 (def-type-translator function-designator
((:context context
)
763 &optional
(args '*) (result '*))
764 (translate-fun-type context args result
:designator t
))
766 (def-type-translator values
:list
((:context context
) &rest values
)
767 ;; comment from CMUCL:
768 ;; "Signal an error if the spec has &KEY or &ALLOW-OTHER-KEYS.
769 ;; Actually, CLHS lists &ALLOW-OTHER-KEYS without listing &KEYS,
770 ;; but keys clearly don't make any sense."
771 (multiple-value-bind (llks required optional rest
)
772 (parse-args-types context values
:values-type
)
774 (make-values-type required optional rest
)
775 (make-short-values-type required
))))
777 ;;;; VALUES types interfaces
779 ;;;; We provide a few special operations that can be meaningfully used
780 ;;;; on VALUES types (as well as on any other type).
782 ;;; Return the minimum number of values possibly matching VALUES type
784 (defun values-type-min-value-count (type)
787 (ecase (named-type-name type
)
791 (length (values-type-required type
)))))
793 ;;; Return the maximum number of values possibly matching VALUES type
795 (defun values-type-max-value-count (type)
798 (ecase (named-type-name type
)
799 ((t *) call-arguments-limit
)
802 (if (values-type-rest type
)
804 (+ (length (values-type-optional type
))
805 (length (values-type-required type
)))))))
807 (defun values-type-may-be-single-value-p (type)
808 (<= (values-type-min-value-count type
)
810 (values-type-max-value-count type
)))
812 ;;; VALUES type with a single value.
813 (defun type-single-value-p (type)
814 (and (values-type-p type
)
815 (not (values-type-rest type
))
816 (null (values-type-optional type
))
817 (singleton-p (values-type-required type
))))
819 ;;; Return the type of the first value indicated by TYPE. This is used
820 ;;; by people who don't want to have to deal with VALUES types.
821 (defun single-value-type (type)
822 (declare (type ctype type
))
823 (cond ((eq type
*wild-type
*)
825 ((eq type
*empty-type
*)
827 ((not (values-type-p type
))
829 ((car (args-type-required type
)))
830 (t (type-union (specifier-type 'null
)
831 (or (car (args-type-optional type
))
832 (args-type-rest type
)
833 (specifier-type 'null
))))))
835 ;;; Return the minimum number of arguments that a function can be
836 ;;; called with, and the maximum number or NIL. If not a function
837 ;;; type, return NIL, NIL.
838 (defun fun-type-nargs (type)
839 (declare (type ctype type
))
840 (if (and (fun-type-p type
) (not (fun-type-wild-args type
)))
841 (let ((fixed (length (args-type-required type
))))
842 (if (or (args-type-rest type
)
843 (args-type-keyp type
)
844 (args-type-allowp type
))
846 (values fixed
(+ fixed
(length (args-type-optional type
))))))
849 ;;; Determine whether TYPE corresponds to a definite number of values.
850 ;;; The first value is a list of the types for each value, and the
851 ;;; second value is the number of values. If the number of values is
852 ;;; not fixed, then return NIL and :UNKNOWN.
853 (defun values-types (type)
854 (declare (type ctype type
))
855 (cond ((or (eq type
*wild-type
*) (eq type
*empty-type
*))
856 (values nil
:unknown
))
857 ((or (args-type-optional type
)
858 (args-type-rest type
))
859 (values nil
:unknown
))
861 (let ((req (args-type-required type
)))
862 (values req
(length req
))))))
864 ;;; Return two values:
865 ;;; 1. A list of all the positional (fixed and optional) types.
866 ;;; 2. The &REST type (if any). If no &REST, then the DEFAULT-TYPE.
867 (defun values-type-types (type &optional
(default-type *empty-type
*))
868 (declare (type ctype type
))
869 (if (eq type
*wild-type
*)
870 (values nil
*universal-type
*)
871 (values (append (args-type-required type
)
872 (args-type-optional type
))
873 (or (args-type-rest type
)
876 ;;; types of values in (the <type> (values o_1 ... o_n))
877 (defun values-type-out (type count
)
878 (declare (type ctype type
) (type unsigned-byte count
))
879 (if (eq type
*wild-type
*)
880 (make-list count
:initial-element
*universal-type
*)
882 (flet ((process-types (types)
883 (loop for type in types
887 (process-types (values-type-required type
))
888 (process-types (values-type-optional type
))
889 (let ((rest (values-type-rest type
)))
895 ;;; types of variable in (m-v-bind (v_1 ... v_n) (the <type> ...
896 (defun values-type-in (type count
)
897 (declare (type ctype type
) (type unsigned-byte count
))
898 (if (eq type
*wild-type
*)
899 (make-list count
:initial-element
*universal-type
*)
901 (let ((null-type (specifier-type 'null
)))
902 (loop for type in
(values-type-required type
)
906 (loop for type in
(values-type-optional type
)
909 do
(res (type-union type null-type
)))
911 (loop with rest
= (acond ((values-type-rest type
)
912 (type-union it null-type
))
918 ;;; Return a list of OPERATION applied to the types in TYPES1 and
919 ;;; TYPES2, padding with REST2 as needed. TYPES1 must not be shorter
920 ;;; than TYPES2. The second value is T if OPERATION always returned a
921 ;;; true second value.
922 (defun fixed-values-op (types1 types2 rest2 operation
)
923 (declare (list types1 types2
) (type ctype rest2
) (type function operation
))
925 (values (mapcar (lambda (t1 t2
)
926 (multiple-value-bind (res win
)
927 (funcall operation t1 t2
)
933 (make-list (- (length types1
) (length types2
))
934 :initial-element rest2
)))
937 ;;; If TYPE isn't a values type, then make it into one.
938 (defun-cached (%coerce-to-values
:hash-bits
8 :hash-function
#'type-%bits
)
940 (cond ((multiple-value-bind (res sure
)
941 (csubtypep (specifier-type 'null
) type
)
942 (and (not res
) sure
))
943 ;; FIXME: What should we do with (NOT SURE)?
944 (make-values-type (list type
) nil
*universal-type
*))
946 (make-values-type nil
(list type
) *universal-type
*))))
948 (defun coerce-to-values (type)
949 (declare (type ctype type
))
950 (cond ((or (eq type
*universal-type
*)
951 (eq type
*wild-type
*))
953 ((values-type-p type
)
955 (t (%coerce-to-values type
))))
957 ;;; Return type, corresponding to ANSI short form of VALUES type
959 (defun make-short-values-type (types)
960 (declare (list types
))
961 (let ((last-required (position-if
963 (not/type
(csubtypep (specifier-type 'null
) type
)))
967 (make-values-type (subseq types
0 (1+ last-required
))
968 (subseq types
(1+ last-required
))
970 (make-values-type nil types
*universal-type
*))))
972 (defun make-single-value-type (type)
973 (make-values-type (list type
)))
975 ;;; Do the specified OPERATION on TYPE1 and TYPE2, which may be any
976 ;;; type, including VALUES types. With VALUES types such as:
979 ;;; we compute the more useful result
980 ;;; (VALUES (<operation> a0 b0) (<operation> a1 b1))
981 ;;; rather than the precise result
982 ;;; (<operation> (values a0 a1) (values b0 b1))
983 ;;; This has the virtue of always keeping the VALUES type specifier
984 ;;; outermost, and retains all of the information that is really
985 ;;; useful for static type analysis. We want to know what is always
986 ;;; true of each value independently. It is worthless to know that if
987 ;;; the first value is B0 then the second will be B1.
989 ;;; If the VALUES count signatures differ, then we produce a result with
990 ;;; the required VALUE count chosen by NREQ when applied to the number
991 ;;; of required values in TYPE1 and TYPE2. Any &KEY values become
992 ;;; &REST T (anyone who uses keyword values deserves to lose.)
994 ;;; The second value is true if the result is definitely empty or if
995 ;;; OPERATION returned true as its second value each time we called
996 ;;; it. Since we approximate the intersection of VALUES types, the
997 ;;; second value being true doesn't mean the result is exact.
998 (defun args-type-op (type1 type2 operation nreq
)
999 (declare (type ctype type1 type2
)
1000 (type function operation nreq
))
1001 (when (eq type1 type2
)
1003 (multiple-value-bind (types1 rest1
)
1004 (values-type-types type1
)
1005 (multiple-value-bind (types2 rest2
)
1006 (values-type-types type2
)
1007 (multiple-value-bind (rest rest-exact
)
1008 (funcall operation rest1 rest2
)
1009 (multiple-value-bind (res res-exact
)
1010 (if (< (length types1
) (length types2
))
1011 (fixed-values-op types2 types1 rest1 operation
)
1012 (fixed-values-op types1 types2 rest2 operation
))
1013 (let* ((req (funcall nreq
1014 (length (args-type-required type1
))
1015 (length (args-type-required type2
))))
1016 (required (subseq res
0 req
))
1017 (opt (subseq res req
)))
1018 (values required opt rest
1019 (and rest-exact res-exact
))))))))
1021 (defun values-type-op (type1 type2 operation nreq
)
1022 (multiple-value-bind (required optional rest exactp
)
1023 (args-type-op type1 type2 operation nreq
)
1024 (values (make-values-type required optional rest
)
1027 (defun compare-key-args (type1 type2
)
1028 (let ((keys1 (args-type-keywords type1
))
1029 (keys2 (args-type-keywords type2
)))
1030 (and (= (length keys1
) (length keys2
))
1031 (eq (args-type-allowp type1
)
1032 (args-type-allowp type2
))
1033 (loop for key1 in keys1
1034 for match
= (find (key-info-name key1
)
1035 keys2
:key
#'key-info-name
)
1037 (type= (key-info-type key1
)
1038 (key-info-type match
)))))))
1040 (defun type=-args
(type1 type2
)
1041 (macrolet ((compare (comparator field
)
1042 (let ((reader (symbolicate '#:args-type- field
)))
1043 `(,comparator
(,reader type1
) (,reader type2
)))))
1045 (cond ((null (args-type-rest type1
))
1046 (values (null (args-type-rest type2
)) t
))
1047 ((null (args-type-rest type2
))
1050 (compare type
= rest
)))
1051 (and/type
(and/type
(compare type
=-list required
)
1052 (compare type
=-list optional
))
1053 (if (or (args-type-keyp type1
) (args-type-keyp type2
))
1054 (values (compare-key-args type1 type2
) t
)
1057 ;;; Do a union or intersection operation on types that might be values
1058 ;;; types. The result is optimized for utility rather than exactness,
1059 ;;; but it is guaranteed that it will be no smaller (more restrictive)
1060 ;;; than the precise result.
1062 ;;; The return convention seems to be analogous to
1063 ;;; TYPES-EQUAL-OR-INTERSECT. -- WHN 19990910.
1064 (defun-cached (values-type-union :hash-function
#'hash-ctype-pair
1066 ((type1 eq
) (type2 eq
))
1067 (declare (type ctype type1 type2
))
1068 (cond ((or (eq type1
*wild-type
*) (eq type2
*wild-type
*)) *wild-type
*)
1069 ((eq type1
*empty-type
*) type2
)
1070 ((eq type2
*empty-type
*) type1
)
1072 (values (values-type-op type1 type2
#'type-union
#'min
)))))
1074 (defun-cached (values-type-intersection :hash-function
#'hash-ctype-pair
1076 ((type1 eq
) (type2 eq
))
1077 (declare (type ctype type1 type2
))
1078 (cond ((eq type1
*wild-type
*)
1079 (coerce-to-values type2
))
1080 ((or (eq type2
*wild-type
*) (eq type2
*universal-type
*))
1082 ((or (eq type1
*empty-type
*) (eq type2
*empty-type
*))
1084 ((and (not (values-type-p type2
))
1085 (values-type-required type1
))
1086 (let ((req1 (values-type-required type1
)))
1087 (make-values-type (cons (type-intersection (first req1
) type2
) (rest req1
))
1088 (values-type-optional type1
)
1089 (values-type-rest type1
))))
1091 (values (values-type-op type1
(coerce-to-values type2
)
1095 ;;; This is like TYPES-EQUAL-OR-INTERSECT, except that it sort of
1096 ;;; works on VALUES types. Note that due to the semantics of
1097 ;;; VALUES-TYPE-INTERSECTION, this might return (VALUES T T) when
1098 ;;; there isn't really any intersection.
1099 (defun values-types-equal-or-intersect (type1 type2
)
1100 (cond ((or (eq type1
*empty-type
*) (eq type2
*empty-type
*))
1102 ((or (eq type1
*wild-type
*) (eq type2
*wild-type
*))
1105 (let ((res (values-type-intersection type1 type2
)))
1106 (values (not (eq res
*empty-type
*))
1109 ;;; a SUBTYPEP-like operation that can be used on any types, including
1111 (defun-cached (values-subtypep :hash-function
#'hash-ctype-pair
1114 ((type1 eq
) (type2 eq
))
1115 (declare (type ctype type1 type2
))
1116 (cond ((or (eq type2
*wild-type
*) (eq type2
*universal-type
*)
1117 (eq type1
*empty-type
*))
1119 ((eq type1
*wild-type
*)
1120 (values (eq type2
*wild-type
*) t
))
1121 ((or (eq type2
*empty-type
*)
1122 (not (values-types-equal-or-intersect type1 type2
)))
1124 ((and (not (values-type-p type2
))
1125 (values-type-required type1
))
1126 (csubtypep (first (values-type-required type1
))
1128 (t (setq type2
(coerce-to-values type2
))
1129 (multiple-value-bind (types1 rest1
) (values-type-types type1
)
1130 (multiple-value-bind (types2 rest2
) (values-type-types type2
)
1131 (cond ((< (length (values-type-required type1
))
1132 (length (values-type-required type2
)))
1134 ((< (length types1
) (length types2
))
1137 (do ((t1 types1
(rest t1
))
1138 (t2 types2
(rest t2
)))
1142 do
(multiple-value-bind (res win
)
1143 (csubtypep type rest2
)
1145 (return (values nil nil
)))
1147 (return (values nil t
)))))
1148 (csubtypep rest1 rest2
))
1149 (multiple-value-bind (res win-p
)
1150 (csubtypep (first t1
) (first t2
))
1152 (return (values nil nil
)))
1154 (return (values nil t
))))))))))))
1156 ;;;; type method interfaces
1158 ;;; like SUBTYPEP, only works on CTYPE structures
1159 (defun-cached (csubtypep :hash-function
#'hash-ctype-pair
1163 ((type1 eq
) (type2 eq
))
1164 (declare (type ctype type1 type2
))
1165 (cond ((or (eq type1 type2
)
1166 (eq type1
*empty-type
*)
1167 (eq type2
*universal-type
*))
1171 (invoke-type-method :simple-subtypep
:complex-subtypep-arg2
1173 :complex-arg1
:complex-subtypep-arg1
)))))
1175 ;;; Like EQUAL but uses EQL for MEMBER and EQL.
1176 (defun equal-type-specifiers-p (x y
)
1177 (labels ((equal-rest (test x y
)
1180 (funcall test
(car x
) (car y
))
1181 (equal-rest test
(cdr x
) (cdr y
)))
1182 (funcall test x y
)))
1187 (cdr x
)) ;; don't bother if there are no parameters
1190 (let ((x (typexpand x
))
1194 ;; &key (name ...) can be confused with a type
1195 (neq (first y
) 'function
)
1196 (equal-types (first x
) (first y
))
1197 ;; (EQL x) expands to (MEMBER x).
1198 (equal-rest (if (eq (first x
) 'member
)
1203 (equal-types x y
)))))
1207 ;;; Just parse the type specifiers and call CSUBTYPE.
1208 ;;; Well, not "just" - Despite memoization of parsing and CSUBTYPEP,
1209 ;;; it's nonetheless better to test EQUAL first, which is ~10x faster
1210 ;;; in the positive case, and insignificant in the negative.
1211 ;;; The specifiers might not be legal type specifiers,
1212 ;;; but we're not obligated to police that:
1213 ;;; "This version eliminates the requirement to signal an error."
1214 ;;; http://www.lispworks.com/documentation/HyperSpec/Issues/iss335_w.htm
1215 ;;; (Status: Passed, as amended, Jun89 X3J13)
1217 ;;; Also, inferring from the version of the text that was obsoleted
1218 ;;; - which while it has no direct impact on the final requirement,
1219 ;;; implies something about what would have been legal -
1220 ;;; "SUBTYPEP must always return values T T in the case where the two
1221 ;;; type specifiers (or their expansions) are EQUAL."
1222 ;;; i.e. though it is not longer technically a MUST, it suggests that EQUAL is
1223 ;;; in fact a valid implementation, at least where it computes T.
1224 (defun subtypep (type1 type2
&optional environment
)
1225 "Return two values indicating the relationship between type1 and type2.
1226 If values are T and T, type1 definitely is a subtype of type2.
1227 If values are NIL and T, type1 definitely is not a subtype of type2.
1228 If values are NIL and NIL, it couldn't be determined."
1229 (declare (type lexenv-designator environment
) (ignore environment
))
1230 (declare (explicit-check))
1232 (and (sb-c:policy sb-c
::*policy
* (not (or (> debug
1)
1234 (equal-type-specifiers-p type1 type2
))
1238 (csubtypep (specifier-type type1
) (specifier-type type2
))))
1240 (declaim (start-block))
1242 ;;; Helper for TYPE= so that we can separately cache the :SIMPLE-= method.
1243 (sb-impl::!define-hash-cache %simple-type
=
1244 ((type1 eq
) (type2 eq
))
1245 :hash-function
#'hash-ctype-pair
1246 :hash-bits
11 :values
2)
1248 ;;; If two types are definitely equivalent, return true. The second
1249 ;;; value indicates whether the first value is definitely correct.
1250 ;;; This should only fail in the presence of HAIRY types.
1251 (defun-cached (type= :hash-function
#'hash-ctype-pair
1255 ((type1 eq
) (type2 eq
))
1256 (declare (type ctype type1 type2
))
1257 (macrolet ((quick-fail-simple-=-mask
()
1258 ;; The set of type-classes for which not EQ implies not TYPE=.
1259 (loop for class in
'(character-set classoid member named
1261 #+sb-simd-pack simd-pack
1262 #+sb-simd-pack-256 simd-pack-256
)
1263 sum
(ash 1 (type-class-name->id class
))))
1264 (quick-fail-complex-= ()
1265 ;; Fail if neither arg is in a class that defines a COMPLEX-= method
1266 (let ((mask (loop for class in classes-having-complex-
=-method
1267 sum
(ash 1 (type-class-name->id class
)))))
1268 `(not (logtest (logior (ash 1 id1
) (ash 1 id2
)) ,mask
)))))
1269 (if (eq type1 type2
)
1271 (let ((id1 (type-class-id type1
))
1272 (id2 (type-class-id type2
)))
1274 (if (quick-fail-complex-=)
1276 (memoize (invoke-type-method :none
:complex-
= type1 type2
))))
1277 ((logbitp id1
(quick-fail-simple-=-mask
))
1279 (t ; use the SIMPLE-= method
1280 ;; A cached answer for swapped args is the same, so always put the smaller
1281 ;; hash first, and we might win with a previous answer.
1282 #+nil
; not 100% sure this is legal even with SIMPLE-=
1283 (when (< (type-hash-value type2
) (type-hash-value type1
))
1284 (rotatef type1 type2
))
1285 (sb-impl::with-cache
(%simple-type
= type1 type2
)
1286 (funcall (type-class-simple-=
1287 (type-id->type-class
(type-class-id type1
)))
1290 ;;; Not exactly the negation of TYPE=, since when the relationship is
1291 ;;; uncertain, we still return NIL, NIL. This is useful in cases where
1292 ;;; the conservative assumption is =.
1293 (defun type/= (type1 type2
)
1294 (declare (type ctype type1 type2
))
1295 (multiple-value-bind (res win
) (type= type1 type2
)
1297 (values (not res
) t
)
1300 (declaim (end-block))
1302 ;;; the type method dispatch case of TYPE-UNION2
1303 (defun %type-union2
(type1 type2
)
1304 ;; As in %TYPE-INTERSECTION2, it seems to be a good idea to give
1305 ;; both argument orders a chance at COMPLEX-INTERSECTION2. Unlike
1306 ;; %TYPE-INTERSECTION2, though, I don't have a specific case which
1307 ;; demonstrates this is actually necessary. Also unlike
1308 ;; %TYPE-INTERSECTION2, there seems to be no need to distinguish
1309 ;; between not finding a method and having a method return NIL.
1311 (invoke-type-method :simple-union2
:complex-union2
1314 (declare (inline 1way
))
1315 (or (1way type1 type2
)
1316 (1way type2 type1
))))
1318 ;;; Find a type which includes both types. Any inexactness is
1319 ;;; represented by the fuzzy element types; we return a single value
1320 ;;; that is precise to the best of our knowledge. This result is
1321 ;;; simplified into the canonical form, thus is not a UNION-TYPE
1322 ;;; unless we find no other way to represent the result.
1323 (defun-cached (type-union2 :hash-function
#'hash-ctype-pair
1326 ((type1 eq
) (type2 eq
))
1327 ;; KLUDGE: This was generated from TYPE-INTERSECTION2 by Ye Olde Cut And
1328 ;; Paste technique of programming. If it stays around (as opposed to
1329 ;; e.g. fading away in favor of some CLOS solution) the shared logic
1330 ;; should probably become shared code. -- WHN 2001-03-16
1331 (declare (type ctype type1 type2
))
1333 (if (eq type1 type2
)
1337 ;; CSUBTYPEP for array-types answers questions about the
1338 ;; specialized type, yet for union we want to take the
1339 ;; expressed type in account too.
1340 ((and (not (and (array-type-p type1
) (array-type-p type2
)))
1341 (or (setf t2
(csubtypep type1 type2
))
1342 (csubtypep type2 type1
)))
1343 (if t2 type2 type1
))
1344 ((or (union-type-p type1
)
1345 (union-type-p type2
))
1346 ;; Unions of UNION-TYPE should have the UNION-TYPE-TYPES
1347 ;; values broken out and united separately. The full TYPE-UNION
1348 ;; function knows how to do this, so let it handle it.
1349 (type-union type1 type2
))
1351 ;; the ordinary case: we dispatch to type methods
1352 (%type-union2 type1 type2
)))))))
1354 ;;; the type method dispatch case of TYPE-INTERSECTION2
1355 (defun %type-intersection2
(type1 type2
)
1356 ;; We want to give both argument orders a chance at
1357 ;; COMPLEX-INTERSECTION2. Without that, the old CMU CL type
1358 ;; methods could give noncommutative results, e.g.
1359 ;; (TYPE-INTERSECTION2 *EMPTY-TYPE* SOME-HAIRY-TYPE)
1361 ;; (TYPE-INTERSECTION2 SOME-HAIRY-TYPE *EMPTY-TYPE*)
1362 ;; => #<NAMED-TYPE NIL>, T
1363 ;; We also need to distinguish between the case where we found a
1364 ;; type method, and it returned NIL, and the case where we fell
1365 ;; through without finding any type method. An example of the first
1366 ;; case is the intersection of a HAIRY-TYPE with some ordinary type.
1367 ;; An example of the second case is the intersection of two
1368 ;; completely-unrelated types, e.g. CONS and NUMBER, or SYMBOL and
1371 ;; (Why yes, CLOS probably *would* be nicer..)
1373 (invoke-type-method :simple-intersection2
:complex-intersection2
1375 :default
:call-other-method
)))
1376 (declare (inline 1way
))
1377 (let ((xy (1way type1 type2
)))
1378 (or (and (not (eql xy
:call-other-method
)) xy
)
1379 (let ((yx (1way type2 type1
)))
1380 (or (and (not (eql yx
:call-other-method
)) yx
)
1381 (cond ((and (eql xy
:call-other-method
)
1382 (eql yx
:call-other-method
))
1387 (defun-cached (type-intersection2 :hash-function
#'hash-ctype-pair
1391 ((type1 eq
) (type2 eq
))
1392 (declare (type ctype type1 type2
))
1393 (if (eq type1 type2
)
1394 ;; FIXME: For some reason, this doesn't catch e.g. type1 =
1395 ;; type2 = (SPECIFIER-TYPE
1396 ;; 'SOME-UNKNOWN-TYPE). Investigate. - CSR, 2002-04-10
1400 ((or (intersection-type-p type1
)
1401 (intersection-type-p type2
))
1402 ;; Intersections of INTERSECTION-TYPE should have the
1403 ;; INTERSECTION-TYPE-TYPES values broken out and intersected
1404 ;; separately. The full TYPE-INTERSECTION function knows how
1405 ;; to do that, so let it handle it.
1406 (type-intersection type1 type2
))
1408 ;; the ordinary case: we dispatch to type methods
1409 (%type-intersection2 type1 type2
))))))
1411 ;;; a test useful for checking whether a derived type matches a
1414 ;;; The first value is true unless the types don't intersect and
1415 ;;; aren't equal. The second value is true if the first value is
1416 ;;; definitely correct. NIL is considered to intersect with any type.
1417 ;;; If T is a subtype of either type, then we also return T, T. This
1418 ;;; way we recognize that hairy types might intersect with T.
1420 ;;; Well now given the statement above that this is "useful for ..."
1421 ;;; a particular thing, I see how treating *empty-type* magically could
1422 ;;; be useful, however given all the _other_ calls to this function within
1423 ;;; this file, it seems suboptimal, because logically it is wrong.
1424 (defun types-equal-or-intersect (type1 type2
)
1425 (declare (type ctype type1 type2
))
1426 (if (or (eq type1
*empty-type
*) (eq type2
*empty-type
*))
1428 (let ((intersection2 (type-intersection2 type1 type2
)))
1429 (cond ((not intersection2
)
1430 (if (or (csubtypep *universal-type
* type1
)
1431 (csubtypep *universal-type
* type2
))
1434 ((eq intersection2
*empty-type
*) (values nil t
))
1435 (t (values t t
))))))
1437 ;;; Return a Common Lisp type specifier corresponding to the TYPE
1439 (defun type-specifier (type &optional simplify-fun-types
)
1440 (declare (type ctype type
))
1441 (funcall (type-class-unparse (type-class type
))
1442 (if simplify-fun-types
+unparse-fun-type-simplify
+ 0)
1445 ;;; Return the type structure corresponding to a type specifier.
1447 ;;; Note: VALUES-SPECIFIER-TYPE-CACHE-CLEAR must be called whenever a
1448 ;;; type is defined (or redefined).
1450 ;;; As I understand things, :FORTHCOMING-DEFCLASS-TYPE behaves contrarily
1451 ;;; to the CLHS intent, which is to make the type known to the compiler.
1452 ;;; If we compile in one file:
1453 ;;; (DEFCLASS FRUITBAT () ())
1454 ;;; (DEFUN FRUITBATP (X) (TYPEP X 'FRUITBAT))
1455 ;;; we see that it emits a call to %TYPEP with the symbol FRUITBAT as its
1456 ;;; argument, whereas it should involve CLASSOID-CELL-TYPEP and LAYOUT-OF,
1457 ;;; which (correctly) signals an error if the class were not defined by the
1458 ;;; time of the call. Delayed re-parsing of FRUITBAT into any random specifier
1459 ;;; at call time is wrong.
1461 ;;; FIXME: symbols which are :PRIMITIVE are inconsistently accepted as singleton
1462 ;;; lists. e.g. (BIT) and (ATOM) are considered legal, but (FIXNUM) and
1463 ;;; (CHARACTER) are not. It has to do with whether the primitive is actually
1464 ;;; a DEFTYPE. The CLHS glossary implies that the singleton is *always* legal.
1465 ;;; "For every atomic type specifier, x, there is an _equivalent_ [my emphasis]
1466 ;;; compound type specifier with no arguments supplied, (x)."
1467 ;;; By that same reasonining, is (x) accepted if x names a class?
1470 ;;; The xc host uses an ordinary hash table for memoization.
1472 (let ((table (make-hash-table :test
'equal
)))
1473 (defun !values-specifier-type-memo-wrapper
(thunk specifier
)
1474 (or (gethash specifier table
)
1475 (let ((parse (funcall thunk
)))
1476 ;; THUNK must nonlocally exit to avoid caching
1477 (aver (not (contains-unknown-type-p parse
)))
1478 (setf (gethash specifier table
) parse
))))
1479 (defun values-specifier-type-cache-clear ()
1481 ;;; This cache is sized extremely generously, which has payoff
1482 ;;; elsewhere: it improves the TYPE= and CSUBTYPEP functions,
1483 ;;; since EQ types are an immediate win.
1484 ;;; EQL isn't the best comparator, but EQUAL would be wrong
1485 ;;; because EQL specifiers must not use a weaker comparison.
1486 ;;; This means that we won't match things like (INTEGER (0) 4) to an existing
1487 ;;; entry unless it is EQ. This is probably not a disaster.
1490 (sb-impl::!define-hash-cache values-specifier-type
1491 ((orig list-elements-eql
))
1492 :hash-function
#'sxhash
:hash-bits
10)
1493 (declaim (inline !values-specifier-type-memo-wrapper
))
1494 (defun !values-specifier-type-memo-wrapper
(thunk specifier
)
1495 (sb-impl::with-cache
(values-specifier-type specifier
)
1498 (declaim (inline make-type-context
))
1499 (defstruct (type-context
1500 (:constructor make-type-context
1501 (spec &optional proto-classoid
(options 0)))
1504 (spec nil
:read-only t
)
1505 (proto-classoid nil
:read-only t
)
1506 (options 0 :type fixnum
))
1507 (defconstant +type-parse-cache-inhibit
+ 1)
1508 (defconstant +type-parse-signal-inhibit
+ 2)
1509 (defmacro type-context-cacheable
(x)
1510 `(not (logtest (type-context-options ,x
) +type-parse-cache-inhibit
+)))
1513 (progn (declaim (inline class-classoid
))
1514 (defun class-classoid (class)
1515 (layout-classoid (sb-pcl::class-wrapper class
))))
1517 ;;; HAIRY type-class has to be defined prior to defining %PARSE-TYPE.
1518 ;; ENUMERABLE-P is T because a hairy type could be equivalent to a MEMBER type.
1519 ;; e.g. any SATISFIES with a predicate returning T over a finite domain.
1520 ;; But in practice there's nothing that can be done with this information,
1521 ;; because we don't call random predicates when performing operations on types
1522 ;; as objects, only when checking for inclusion of something in the type.
1523 (define-type-class hairy
:enumerable t
:might-contain-other-types t
)
1525 ;;; Parsing of type specifiers comes in many variations:
1526 ;;; SINGLE-VALUE-SPECIFIER-TYPE:
1527 ;;; disallow VALUES even if single value, but allow *
1529 ;;; disallow (VALUES ...) even if single value, and disallow *
1530 ;;; VALUES-SPECIFIER-TYPE:
1531 ;;; allow VALUES, disallow *
1532 ;;; TYPE-OR-NIL-IF-UNKNOWN:
1533 ;;; like SPECIFIER-TYPE, but return NIL if contains unknown
1534 ;;; all the above are funneled through BASIC-PARSE-TYPESPEC.
1536 ;;; The recursive %PARSE-TYPE function is used for nested invocations
1537 ;;; of type spec parsing, passing the outermost context through on each call.
1538 ;;; Callers should use the BASIC-PARSE-TYPESPEC interface.
1540 ;;; Hint for when you bork this and/or bork the :UNPARSE methods - do:
1541 ;;; (remove-method #'print-object (find-method #'print-object nil
1542 ;;; (list (find-class 'ctype) (find-class 't))))
1543 ;;; so that 'backtrace' doesn't encounter an infinite chain of errors.
1545 (macrolet ((fail (spec)
1546 `(error "bad thing to be a type specifier: ~/sb-impl:print-type-specifier/"
1548 (defun %parse-type
(spec context
)
1549 (declare (type type-context context
))
1550 (prog* ((head (if (listp spec
) (car spec
) spec
))
1551 (builtin (if (symbolp head
)
1552 (info :type
:builtin head
)
1553 (return (fail spec
)))))
1554 (when (deprecated-thing-p 'type head
)
1555 (setf (type-context-options context
)
1556 (logior (type-context-options context
) +type-parse-cache-inhibit
+))
1557 (signal 'parse-deprecated-type
:specifier spec
))
1559 ;; If spec is non-atomic, the :BUILTIN value is inapplicable.
1560 ;; There used to be compound builtins, but not any more.
1561 (when builtin
(return builtin
))
1562 ;; Any spec that apparently refers to a defstruct form
1563 ;; that's being macroexpanded should refer to that type.
1564 (awhen (type-context-proto-classoid context
)
1565 (when (eq (classoid-name it
) spec
) (return it
)))
1566 (case (info :type
:kind spec
)
1567 (:instance
(return (find-classoid spec
)))
1568 (:forthcoming-defclass-type
(go unknown
))))
1569 ;; Expansion brings up an interesting question - should the cache
1570 ;; contain entries for intermediary types? Say A -> B -> REAL.
1571 ;; As it stands, we cache the ctype corresponding to A but not B.
1572 (awhen (info :type
:expander head
)
1573 (when (listp it
) ; The function translates directly to a CTYPE.
1574 (return (or (funcall (car it
) context spec
) (fail spec
))))
1575 ;; The function produces a type expression.
1576 (let ((expansion (funcall it
(ensure-list spec
))))
1577 (return (if (typep expansion
'instance
)
1578 (basic-parse-typespec expansion context
)
1579 (%parse-type expansion context
)))))
1580 ;; If the spec is (X ...) and X has neither a translator
1581 ;; nor expander, and is a builtin, such as FIXNUM, fail now.
1582 ;; But - see FIXME at top - it would be consistent with
1583 ;; DEFTYPE to reject spec only if not a singleton.
1584 (when builtin
(return (fail spec
)))
1585 ;; SPEC has a legal form, so return an unknown type.
1586 (unless (logtest (type-context-options context
) +type-parse-signal-inhibit
+)
1587 (signal 'parse-unknown-type
:specifier spec
))
1589 (setf (type-context-options context
)
1590 (logior (type-context-options context
) +type-parse-cache-inhibit
+))
1591 (return (make-unknown-type spec
))))
1593 ;;; BASIC-PARSE-TYPESPEC can grok some simple cases that involve turning an object
1594 ;;; used as a type specifier into an internalized type object (which might be
1595 ;;; the selfsame object, in the case of a CLASSOID).
1597 ;;; FIXME: nothing in the spec precludes calling TYPEP on a type specifier composed
1598 ;;; of dynamic-extent lists. Such a specifier must be uncacheable.
1599 ;;; Worse- the MEMBER type can have problems with the items per se, because the parse
1600 ;;; retains the items. There is no _practical_ reason to have such a type, as the atoms
1601 ;;; for which MEMBER tends to be used (symbol, number) can't be DX-allocated.
1602 ;;; Nonetheless, memoizing arbitrary user-supplied data is not careful enough.
1603 (defun basic-parse-typespec (type-specifier context
)
1604 (declare (type type-context context
))
1605 (when (typep type-specifier
'instance
)
1606 ;; An instance never needs the type parser cache, because it almost always
1607 ;; represents itself or a slot in itself.
1608 (flet ((classoid-to-ctype (classoid)
1609 ;; A few classoids have translations,
1610 ;; e.g. the classoid CONS is a CONS-TYPE.
1611 ;; Hmm, perhaps this should signal PARSE-UNKNOWN-TYPE
1612 ;; if CLASSOID is an instance of UNDEFINED-CLASSOID ?
1614 (or (and (built-in-classoid-p classoid
)
1615 (built-in-classoid-translation classoid
))
1617 (return-from basic-parse-typespec
1618 (cond ((classoid-p type-specifier
) (classoid-to-ctype type-specifier
))
1619 ;; Avoid TYPEP on SB-MOP:EQL-SPECIALIZER and CLASS because
1620 ;; the fake metaobjects do not allow type analysis, and
1621 ;; would cause a compiler error as it tries to decide
1622 ;; whether any clause of this COND subsumes another.
1623 ;; Moreover, we don't require the host to support MOP.
1625 ((sb-pcl::classp type-specifier
)
1626 ;; A CLOS class is translated to its CLASSOID, or the classoid's translation.
1627 (classoid-to-ctype (sb-pcl::class-classoid type-specifier
)))
1629 ((sb-pcl::eql-specializer-p type-specifier
)
1630 ;; EQL specializers are are seldom used and not 100% portable,
1631 ;; though they are part of the AMOP.
1632 ;; See https://sourceforge.net/p/sbcl/mailman/message/11217378/
1633 ;; We rely on caching of singleton EQL types to make this efficient.
1634 (make-eql-type (sb-mop::eql-specializer-object type-specifier
)))
1635 ((layout-p type-specifier
)
1636 (layout-classoid type-specifier
))
1637 (t (fail type-specifier
))))))
1638 (when (atom type-specifier
)
1639 ;; Try to bypass the cache, which avoids using a cache line for standard
1640 ;; atomic specifiers. This is a trade-off- cache seek might be faster,
1641 ;; but this solves the problem that a full call to (TYPEP #\A 'FIXNUM)
1642 ;; consed a cache line every time the cache missed on FIXNUM (etc).
1643 (awhen (info :type
:builtin type-specifier
)
1644 (return-from basic-parse-typespec it
)))
1646 ;; If CONTEXT was non-cacheable as supplied, the cache is bypassed
1647 ;; for any nested lookup, and we don't insert the result.
1648 (if (not (type-context-cacheable context
))
1649 (%parse-type
(uncross type-specifier
) context
)
1650 ;; Otherwise, try for a cache hit first, and usually update the cache.
1651 (!values-specifier-type-memo-wrapper
1653 (let ((answer (%parse-type
(uncross type-specifier
) context
)))
1654 (if (and (type-context-cacheable context
)
1655 #-sb-xc-host
(heap-allocated-p type-specifier
))
1657 ;; Lookup was cacheable, but result isn't.
1658 ;; Non-caching ensures that we see every occurrence of an unknown
1659 ;; type no matter how deeply nested it is in the expression.
1660 ;; e.g. (OR UNKNOWN-FOO CONS) and (OR INTEGER UNKNOWN-FOO)
1661 ;; should both signal the PARSE-UNKNOWN condition, which would
1662 ;; not happen if the first cached UNKNOWN-FOO.
1664 ;; During make-host-2 I'm seeing the types &OPTIONAL-AND-&KEY-IN-LAMBDA-LIST,
1665 ;; SIMPLE-ERROR, DISASSEM-STATE as non-cacheable,
1666 ;; and much, much more during make-target-2.
1667 ;; The condition types are obvious, because we mention them before
1669 ;; DISASSEM-STATE comes from building **TYPE-SPEC-INTERR-SYMBOLS**
1670 ;; where we have a fixed list of types which get assigned single-byte
1674 (unless (type-context-cacheable context
)
1675 (format t
"~&non-cacheable: ~S ~%" type-specifier
))
1676 (return-from basic-parse-typespec answer
)))))
1680 ;;; This takes no CONTEXT (which implies lack of recursion) because
1681 ;;; you can't reasonably place a VALUES type inside another type.
1682 (defun values-specifier-type (type-specifier)
1683 ;; This catches uses of literal '* where it shouldn't appear, but it
1684 ;; accidentally lets other uses slip through. We'd have to catch '*
1685 ;; post-type-expansion to be more strict, but it isn't very important.
1686 (cond ((eq type-specifier
'*)
1687 (warn "* is not permitted as a type specifier")
1690 (dx-let ((context (make-type-context type-specifier
)))
1691 (basic-parse-typespec type-specifier context
)))))
1693 ;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to
1694 ;;; never return a VALUES type.
1695 ;;; CONTEXT is either an instance of TYPE-CONTEXT or NIL.
1696 ;;; SUBCONTEXT is a symbol denoting the head of the current expression, or NIL.
1697 (defun specifier-type (type-specifier &optional context subcontext
)
1700 (basic-parse-typespec type-specifier context
)
1701 (dx-let ((context (make-type-context type-specifier
)))
1702 (basic-parse-typespec type-specifier context
))))
1703 (wildp (eq ctype
*wild-type
*)))
1704 ;; We have to see how it was spelled to give an intelligent message.
1705 ;; If it's instance of VALUES-TYPE, then it was spelled as VALUES
1706 ;; whereas if it isn't, the user either spelled it as (VALUES) or *.
1707 ;; The case where this heuristic doesn't work is a DEFTYPE that expands
1708 ;; to *, but that's not worth worrying about.
1709 (cond ((or (values-type-p ctype
)
1710 (and wildp
(consp type-specifier
)))
1711 (error "VALUES type illegal in this context:~% ~
1712 ~/sb-impl:print-type-specifier/"
1716 (setf (type-context-options context
)
1717 (logior (type-context-options context
)
1718 +type-parse-cache-inhibit
+)))
1720 (warn "* is not permitted as an argument to the ~S type specifier"
1722 (warn "* is not permitted as a type specifier~@[ in the context ~S~]"
1723 ;; If the entire surrounding context is * then there's not much
1724 ;; else to say. Otherwise, show the original expression.
1725 (when (and context
(neq (type-context-spec context
) '*))
1726 (type-context-spec context
))))
1731 (defun single-value-specifier-type (x &optional context
)
1734 (specifier-type x context
)))
1736 ;;; When cross-compiling SPECIFIER-TYPE with a quoted argument,
1737 ;;; it can be rendered as a literal object unless it mentions
1738 ;;; certain classoids.
1740 ;;; This is important for type system initialization.
1742 ;;; After the target is built, we remove this transform, both because calls
1743 ;;; to SPECIFIER-TYPE do not arise organically through user code,
1744 ;;; and because it is possible that user changes to types could make parsing
1745 ;;; return a different thing, e.g. changing a DEFTYPE to a DEFCLASS.
1748 (labels ((xform (type-spec env parser
)
1749 (if (not (constantp type-spec env
))
1751 (let* ((expr (constant-form-value type-spec env
))
1752 (parse (funcall parser expr
)))
1753 (if (cold-dumpable-type-p parse
)
1756 (cold-dumpable-type-p (ctype)
1757 (when (contains-unknown-type-p ctype
)
1758 (bug "SPECIFIER-TYPE transform parsed an unknown type: ~S" ctype
))
1759 (map-type (lambda (type)
1760 (when (and (classoid-p type
) (eq (classoid-name type
) 'class
))
1761 (return-from cold-dumpable-type-p nil
)))
1764 (sb-c:define-source-transform specifier-type
(type-spec &environment env
)
1765 (xform type-spec env
#'specifier-type
))
1766 (sb-c:define-source-transform values-specifier-type
(type-spec &environment env
)
1767 (xform type-spec env
#'values-specifier-type
)))
1769 (defun typexpand-1 (type-specifier &optional env
)
1770 "Takes and expands a type specifier once like MACROEXPAND-1.
1771 Returns two values: the expansion, and a boolean that is true when
1772 expansion happened."
1773 (declare (type type-specifier type-specifier
))
1774 (declare (type lexenv-designator env
) (ignore env
))
1775 (let* ((spec type-specifier
)
1776 (atom (if (listp spec
) (car spec
) spec
))
1777 (expander (and (symbolp atom
) (info :type
:expander atom
))))
1778 ;; We do not expand builtins even though it'd be
1779 ;; possible to do so sometimes (e.g. STRING) for two
1782 ;; a) From a user's point of view, CL types are opaque.
1784 ;; b) so (EQUAL (TYPEXPAND 'STRING) (TYPEXPAND-ALL 'STRING))
1785 (if (and (functionp expander
) (not (info :type
:builtin atom
)))
1786 (values (funcall expander
(if (symbolp spec
) (list spec
) spec
)) t
)
1787 (values type-specifier nil
))))
1789 (defun typexpand (type-specifier &optional env
)
1790 "Takes and expands a type specifier repeatedly like MACROEXPAND.
1791 Returns two values: the expansion, and a boolean that is true when
1792 expansion happened."
1793 ;; TYPE-SPECIFIER is of type TYPE-SPECIFIER, but it is preferable to
1794 ;; defer to TYPEXPAND-1 for the typecheck. Similarly for ENV.
1795 (multiple-value-bind (expansion expanded
)
1796 (typexpand-1 type-specifier env
)
1798 (values (typexpand expansion env
) t
)
1799 (values expansion expanded
))))
1801 ;;; Take a list of type specifiers, computing the translation of each
1802 ;;; specifier and defining it as a builtin type.
1803 ;;; Seee the comments in 'type-init' for why this is a slightly
1804 ;;; screwy way to go about it.
1805 (declaim (ftype (function (list) (values)) !precompute-types
))
1806 (defun !precompute-types
(specs)
1807 (dolist (spec specs
)
1808 (let ((res (handler-bind
1809 ((parse-unknown-type
1811 (declare (ignore c
))
1812 ;; We can handle conditions at this point,
1813 ;; but win32 can not perform i/o here because
1814 ;; !MAKE-COLD-STDERR-STREAM has no implementation.
1815 ;; FIXME: where is this coming from???
1817 (progn (write-string "//caught: parse-unknown ")
1820 (specifier-type spec
))))
1821 (unless (unknown-type-p res
)
1822 (setf (info :type
:builtin spec
) res
)
1823 (setf (info :type
:kind spec
) :primitive
))))
1826 ;;; Parse TYPE-SPECIFIER, returning NIL if any sub-part of it is unknown
1827 (defun type-or-nil-if-unknown (type-specifier &optional allow-values
)
1828 (dx-let ((context (make-type-context type-specifier
)))
1829 (let ((result (if allow-values
1830 (basic-parse-typespec type-specifier context
)
1831 (specifier-type type-specifier context
))))
1832 ;; If it was non-cacheable, either it contained a deprecated type
1833 ;; or unknown type, or was a pending defstruct definition.
1834 (if (and (not (type-context-cacheable context
))
1835 (contains-unknown-type-p result
))
1839 (defun-cached (type-negation :hash-function
#'type-%bits
1843 (declare (type ctype type
))
1844 (funcall (type-class-negate (type-class type
)) type
))
1846 (defun-cached (type-singleton-p :hash-function
#'type-%bits
1850 (declare (type ctype type
))
1851 (let ((function (type-class-singleton-p (type-class type
))))
1853 (funcall function type
)
1857 ;;;; general TYPE-UNION and TYPE-INTERSECTION operations
1859 ;;;; These are fully general operations on CTYPEs: they'll always
1860 ;;;; return a CTYPE representing the result.
1862 ;;; shared logic for unions and intersections: Return a list of
1863 ;;; types representing the same types as INPUT-TYPES, but with
1864 ;;; COMPOUND-TYPEs satisfying %COMPOUND-TYPE-P broken up into their
1865 ;;; component types, and with any SIMPLIFY2 simplifications applied.
1867 ((def (name compound-type-p simplify2
)
1868 `(defun ,name
(types)
1870 (multiple-value-bind (first rest
)
1871 (if (,compound-type-p
(car types
))
1872 (values (car (compound-type-types (car types
)))
1873 (append (cdr (compound-type-types (car types
)))
1875 (values (car types
) (cdr types
)))
1876 (let ((rest (,name rest
)) u
)
1877 (dolist (r rest
(cons first rest
))
1878 (when (setq u
(,simplify2 first r
))
1879 (return (,name
(nsubstitute u r rest
)))))))))))
1880 (def simplify-intersections intersection-type-p type-intersection2
)
1881 (def simplify-unions union-type-p type-union2
))
1883 (defun maybe-distribute-one-union (union-type types
)
1884 (let* ((intersection (%type-intersection types
))
1885 (union (mapcar (lambda (x) (type-intersection x intersection
))
1886 (union-type-types union-type
))))
1887 (if (notany (lambda (x) (or (hairy-type-p x
)
1888 (intersection-type-p x
)))
1893 (define-type-class intersection
1894 :enumerable
#'compound-type-enumerable
1895 :might-contain-other-types t
)
1897 (defun type-intersection (&rest input-types
)
1898 (declare (dynamic-extent input-types
))
1899 (%type-intersection input-types
))
1900 (defun-cached (%type-intersection
:hash-bits
10 :hash-function
#'hash-ctype-list
)
1901 ((input-types list-elts-eq
(ensure-heap-list input-types
)))
1902 (let ((simplified-types (simplify-intersections input-types
)))
1903 (declare (type list simplified-types
))
1904 ;; We want to have a canonical representation of types (or failing
1905 ;; that, punt to HAIRY-TYPE). Canonical representation would have
1906 ;; intersections inside unions but not vice versa, since you can
1907 ;; always achieve that by the distributive rule. But we don't want
1908 ;; to just apply the distributive rule, since it would be too easy
1909 ;; to end up with unreasonably huge type expressions. So instead
1910 ;; we try to generate a simple type by distributing the union; if
1911 ;; the type can't be made simple, we punt to HAIRY-TYPE.
1912 (if (and (cdr simplified-types
) (some #'union-type-p simplified-types
))
1913 (let* ((first-union (find-if #'union-type-p simplified-types
))
1914 (other-types (coerce (remove first-union simplified-types
)
1916 (distributed (maybe-distribute-one-union first-union
1919 (%type-union distributed
)
1921 (%make-hairy-type
`(and ,@(map 'list
#'type-specifier
1923 (bug "Unexpected %MAKE-HAIRY-TYPE")))
1925 ((null simplified-types
) *universal-type
*)
1926 ((null (cdr simplified-types
)) (car simplified-types
))
1927 (t (new-ctype intersection-type
1928 #'compound-type-flags
1929 (some #'type-enumerable simplified-types
)
1930 (intern-ctype-set simplified-types
)))))))
1932 (defun make-union-type (enumerable types
)
1933 (new-ctype union-type
#'compound-type-flags enumerable
(intern-ctype-set types
)))
1934 (defun type-union (&rest input-types
)
1935 (declare (dynamic-extent input-types
))
1936 (%type-union input-types
))
1937 (defun-cached (%type-union
:hash-bits
8 :hash-function
#'hash-ctype-list
)
1938 ((input-types list-elts-eq
(ensure-heap-list input-types
)))
1939 (let ((simplified-types (simplify-unions input-types
)))
1941 ((null simplified-types
) *empty-type
*)
1942 ((null (cdr simplified-types
)) (car simplified-types
))
1944 (every #'type-enumerable simplified-types
)
1945 simplified-types
)))))
1949 (defun cons-type-might-be-empty-type (type)
1950 (declare (type cons-type type
))
1951 (let ((car-type (cons-type-car-type type
))
1952 (cdr-type (cons-type-cdr-type type
)))
1954 (if (cons-type-p car-type
)
1955 (cons-type-might-be-empty-type car-type
)
1956 (multiple-value-bind (yes surep
)
1957 (type= car-type
*empty-type
*)
1960 (if (cons-type-p cdr-type
)
1961 (cons-type-might-be-empty-type cdr-type
)
1962 (multiple-value-bind (yes surep
)
1963 (type= cdr-type
*empty-type
*)
1967 (defun cons-type-length-info (type)
1968 (declare (type cons-type type
))
1969 (do ((min 1 (1+ min
))
1970 (cdr (cons-type-cdr-type type
) (cons-type-cdr-type cdr
)))
1971 ((not (cons-type-p cdr
))
1973 ((csubtypep cdr
(specifier-type 'null
))
1975 ((csubtypep *universal-type
* cdr
)
1977 ((type/= (type-intersection (specifier-type 'cons
) cdr
) *empty-type
*)
1979 ((type/= (type-intersection (specifier-type 'null
) cdr
) *empty-type
*)
1981 (t (values min
:maybe
))))
1984 ;;; This macro aids in producing a constant ctype instance with less worry about
1985 ;;; execution order of LOAD-TIME-VALUE with respect to toplevel forms.
1986 ;;; In make-host-1, the answer is computed just-in-time and memoized,
1987 ;;; and in make-host-2 it's a literal object at macroexpansion time.
1988 (defmacro inline-cache-ctype
(constructor specifier
)
1989 (declare (ignorable constructor specifier
))
1990 ;; CLISP incorrectly coalesces LOAD-TIME-VALUE expressions that are EQUAL,
1991 ;; so provide some assurance that they aren't.
1992 #+sb-xc-host
`(let ((cell (load-time-value (list nil
',specifier
))))
1993 (or (car cell
) (setf (car cell
) ,constructor
)))
1994 #-sb-xc-host
(specifier-type specifier
))
1996 ;;; Return T if TYPE is one defined in the language spec, and whose representation
1997 ;;; in SBCL's type-class taxonomy entails that of an INTERSECTION-TYPE.
1998 ;;; This function can be called no sooner than 'deftypes-for-targets' gets loaded,
1999 ;;; so that we don't see undefined types.
2000 (macrolet ((specifier-type-once-only (spec)
2001 `(inline-cache-ctype (the intersection-type
(specifier-type ',spec
))
2003 (defun cl-std-intersection-type-p (type)
2004 (cond ((eq type
(specifier-type-once-only keyword
)) 'keyword
)
2005 ((eq type
(specifier-type-once-only compiled-function
)) 'compiled-function
))))
2007 (define-type-method (named :complex-
=) (type1 type2
)
2009 ((and (eq type2
*empty-type
*)
2010 (or (and (intersection-type-p type1
)
2011 ;; not allowed to be unsure on these...
2012 (not (cl-std-intersection-type-p type1
)))
2013 (and (cons-type-p type1
)
2014 (cons-type-might-be-empty-type type1
))))
2015 ;; things like (AND (EQL 0) (SATISFIES ODDP)) or (AND FUNCTION
2016 ;; STREAM) can get here. In general, we can't really tell
2017 ;; whether these are equal to NIL or not, so
2019 ((type-might-contain-other-types-p type1
)
2020 (invoke-complex-=-other-method type1 type2
))
2021 (t (values nil t
))))
2023 (define-type-method (named :simple-subtypep
) (type1 type2
)
2024 (aver (not (eq type1
*wild-type
*))) ; * isn't really a type.
2025 (aver (not (eq type1 type2
)))
2026 (values (or (eq type1
*empty-type
*)
2027 (eq type2
*wild-type
*)
2028 (eq type2
*universal-type
*)) t
))
2030 (define-type-method (named :complex-subtypep-arg1
) (type1 type2
)
2031 ;; This AVER causes problems if we write accurate methods for the
2032 ;; union (and possibly intersection) types which then delegate to
2033 ;; us; while a user shouldn't get here, because of the odd status of
2034 ;; *wild-type* a type-intersection executed by the compiler can. -
2037 ;; (aver (not (eq type1 *wild-type*))) ; * isn't really a type.
2038 (cond ((eq type1
*empty-type
*)
2040 (;; When TYPE2 might be the universal type in disguise
2041 (type-might-contain-other-types-p type2
)
2042 ;; Now that the UNION and HAIRY COMPLEX-SUBTYPEP-ARG2 methods
2043 ;; can delegate to us (more or less as CALL-NEXT-METHOD) when
2044 ;; they're uncertain, we can't just barf on COMPOUND-TYPE and
2045 ;; HAIRY-TYPEs as we used to. Instead we deal with the
2046 ;; problem (where at least part of the problem is cases like
2047 ;; (SUBTYPEP T '(SATISFIES FOO))
2049 ;; (SUBTYPEP T '(AND (SATISFIES FOO) (SATISFIES BAR)))
2050 ;; where the second type is a hairy type like SATISFIES, or
2051 ;; is a compound type which might contain a hairy type) by
2052 ;; returning uncertainty.
2054 ((eq type1
*funcallable-instance-type
*)
2055 (values (eq type2
(specifier-type 'function
)) t
))
2057 ;; This case would have been picked off by the SIMPLE-SUBTYPEP
2058 ;; method, and so shouldn't appear here.
2059 (aver (not (named-type-p type2
)))
2060 ;; Since TYPE2 is not EQ *UNIVERSAL-TYPE* and is not another
2061 ;; named type in disguise, TYPE2 is not a superset of TYPE1.
2064 ;;; Return T if members of this classoid certainly have INSTANCE-POINTER-LOWTAG.
2065 ;;; Logically it is the near opposite of CLASSOID-NON-INSTANCE-P, but not quite.
2066 ;;; CTYPEs which are not represented as a classoid return NIL for both predicates
2067 ;;; as do PCL types which may be either funcallable or non-funcallable.
2069 ;;; But some of that generality seems wrong. I don't think it would be allowed
2070 ;;; to have (as merely an example) an EQL-SPECIALIZER which is funcallable,
2071 ;;; having FUN-POINTER-LOWTAG instead of INSTANCE-POINTER-LOWTAG). Yet we think
2072 ;;; it could happen, because the parse of the type (AND EQL-SPECIALIZER INSTANCE)
2073 ;;; yields #<INTERSECTION-TYPE (AND SB-MOP:EQL-SPECIALIZER INSTANCE)>
2074 ;;; versus simplifying down to EQL-SPECIALIZER.
2075 #|
(loop for c being each hash-key of
(classoid-subclasses (find-classoid 't
))
2076 do
(let ((not-i (classoid-non-instance-p c
))
2077 (i (classoid-definitely-instancep c
)))
2078 (unless (eq (not not-i
) i
) (format t
"~S -> ~A and ~A~%" c not-i i
)))) |
#
2079 (defun classoid-definitely-instancep (x)
2080 (or (structure-classoid-p x
)
2081 (condition-classoid-p x
)
2082 ;; PATHNAMEs are INSTANCEs based on the lowtag criterion
2083 (or (eq x
(specifier-type 'logical-pathname
))
2084 (eq x
(specifier-type 'pathname
)))))
2085 (eval-when (:compile-toplevel
:execute
)
2086 (pushnew 'classoid-definitely-instancep sb-vm
::*backend-cross-foldable-predicates
*))
2088 (defun classoid-is-or-inherits (sub super
)
2089 (or (classoid-inherits-from sub super
)
2090 (eq sub
(find-classoid super
))))
2092 (define-type-method (named :complex-subtypep-arg2
) (type1 type2
)
2093 (aver (not (eq type2
*wild-type
*))) ; * isn't really a type.
2094 (cond ((eq type2
*universal-type
*)
2096 ;; some CONS types can conceal danger
2097 ((and (cons-type-p type1
) (cons-type-might-be-empty-type type1
))
2099 ((type-might-contain-other-types-p type1
)
2100 ;; those types can be other types in disguise. So we'd
2102 (invoke-complex-subtypep-arg1-method type1 type2
))
2103 ((and (or (eq type2
*instance-type
*)
2104 (eq type2
*funcallable-instance-type
*))
2105 (member-type-p type1
))
2106 ;; member types can be subtypep INSTANCE and
2107 ;; FUNCALLABLE-INSTANCE in surprising ways.
2108 (invoke-complex-subtypep-arg1-method type1 type2
))
2109 ((and (eq type2
*extended-sequence-type
*) (classoid-p type1
))
2110 (values (if (classoid-inherits-from type1
'sequence
) t nil
) t
))
2111 ((and (eq type2
*instance-type
*) (classoid-p type1
))
2112 (cond ((or (classoid-non-instance-p type1
)
2113 (classoid-is-or-inherits type1
'function
))
2115 ((classoid-definitely-instancep type1
)
2119 ((and (eq type2
*funcallable-instance-type
*) (classoid-p type1
))
2120 (if (and (not (classoid-non-instance-p type1
))
2121 (classoid-inherits-from type1
'function
))
2124 ((and (eq type2
*instance-type
*) (alien-type-type-p type1
))
2127 ;; FIXME: This seems to rely on there only being 4 or 5
2128 ;; NAMED-TYPE values, and the exclusion of various
2129 ;; possibilities above. It would be good to explain it and/or
2130 ;; rewrite it so that it's clearer.
2133 (define-type-method (named :simple-intersection2
) (type1 type2
)
2135 ((and (eq type1
*extended-sequence-type
*)
2136 (or (eq type2
*instance-type
*)
2137 (eq type2
*funcallable-instance-type
*)))
2139 ((and (or (eq type1
*instance-type
*)
2140 (eq type1
*funcallable-instance-type
*))
2141 (eq type2
*extended-sequence-type
*))
2144 (hierarchical-intersection2 type1 type2
))))
2146 (define-type-method (named :complex-intersection2
) (type1 type2
)
2147 ;; FIXME: This assertion failed when I added it in sbcl-0.6.11.13.
2148 ;; Perhaps when bug 85 is fixed it can be reenabled.
2149 ;;(aver (not (eq type2 *wild-type*))) ; * isn't really a type.
2150 (flet ((empty-unless-hairy (type)
2151 (unless (or (type-might-contain-other-types-p type
)
2152 (member-type-p type
))
2155 ((eq type2
*extended-sequence-type
*)
2157 ((satisfies classoid-definitely-instancep
) *empty-type
*) ; dubious!
2159 ((classoid-non-instance-p type1
) *empty-type
*)
2160 ((classoid-inherits-from type1
'sequence
) type1
)))
2161 (t (empty-unless-hairy type1
))))
2162 ((eq type2
*instance-type
*)
2164 ((satisfies classoid-definitely-instancep
) type1
)
2165 (classoid (when (or (classoid-non-instance-p type1
)
2166 (classoid-is-or-inherits type1
'function
))
2168 (alien-type-type type1
)
2169 (t (empty-unless-hairy type1
))))
2170 ((eq type2
*funcallable-instance-type
*)
2172 ((satisfies classoid-definitely-instancep
) *empty-type
*)
2175 ((classoid-non-instance-p type1
) *empty-type
*)
2176 ((classoid-inherits-from type1
'function
) type1
)
2177 ((type= type1
(find-classoid 'function
)) type2
)))
2179 (t (empty-unless-hairy type1
))))
2180 (t (hierarchical-intersection2 type1 type2
)))))
2182 (define-type-method (named :complex-union2
) (type1 type2
)
2183 ;; Perhaps when bug 85 is fixed this can be reenabled.
2184 ;;(aver (not (eq type2 *wild-type*))) ; * isn't really a type.
2186 ((eq type2
*extended-sequence-type
*)
2187 (cond ((not (classoid-p type1
)) nil
)
2188 ((and (not (classoid-non-instance-p type1
))
2189 (classoid-inherits-from type1
'sequence
))
2191 ((eq type2
*instance-type
*)
2192 (when (and (classoid-p type1
)
2193 (neq type1
(specifier-type 'function
))
2194 (not (classoid-non-instance-p type1
))
2195 (not (classoid-inherits-from type1
'function
)))
2197 ((eq type2
*funcallable-instance-type
*)
2198 (cond ((not (classoid-p type1
)) nil
)
2199 ((classoid-non-instance-p type1
) nil
)
2200 ((not (classoid-inherits-from type1
'function
)) nil
)
2201 ((eq type1
(specifier-type 'function
)) type1
)
2203 (t (hierarchical-union2 type1 type2
))))
2205 (define-type-method (named :negate
) (x)
2206 (aver (not (eq x
*wild-type
*)))
2208 ((eq x
*universal-type
*) *empty-type
*)
2209 ((eq x
*empty-type
*) *universal-type
*)
2210 ((or (eq x
*instance-type
*)
2211 (eq x
*funcallable-instance-type
*)
2212 (eq x
*extended-sequence-type
*))
2213 (make-negation-type x
))
2214 (t (bug "NAMED type unexpected: ~S" x
))))
2216 (define-type-method (named :unparse
) (flags x
)
2217 (named-type-name x
))
2219 ;;;; hairy and unknown types
2221 (define-type-method (hairy :negate
) (x) (make-negation-type x
))
2223 (define-type-method (hairy :unparse
) (flags x
)
2224 (if (and (logtest flags
+ctype-unparse-disambiguate
+) (unknown-type-p x
))
2226 (hairy-type-specifier x
)))
2228 (define-type-method (hairy :simple-subtypep
) (type1 type2
)
2229 (let ((hairy-spec1 (hairy-type-specifier type1
))
2230 (hairy-spec2 (hairy-type-specifier type2
)))
2231 (cond ((list-elements-eql hairy-spec1 hairy-spec2
)
2233 ((maybe-reparse-specifier! type1
)
2234 (csubtypep type1 type2
))
2235 ((maybe-reparse-specifier! type2
)
2236 (csubtypep type1 type2
))
2238 (values nil nil
)))))
2240 (define-type-method (hairy :complex-subtypep-arg2
) (type1 type2
)
2241 (if (maybe-reparse-specifier! type2
)
2242 (csubtypep type1 type2
)
2243 (let ((specifier (hairy-type-specifier type2
)))
2244 (cond ((and (consp specifier
) (eql (car specifier
) 'satisfies
))
2245 (case (cadr specifier
)
2246 ((keywordp) (if (type= type1
(specifier-type 'symbol
))
2248 (invoke-complex-subtypep-arg1-method type1 type2
)))
2249 (t (invoke-complex-subtypep-arg1-method type1 type2
))))
2251 (invoke-complex-subtypep-arg1-method type1 type2
))))))
2253 (define-type-method (hairy :complex-subtypep-arg1
) (type1 type2
)
2254 (if (maybe-reparse-specifier! type1
)
2255 (csubtypep type1 type2
)
2258 (define-type-method (hairy :complex-
=) (type1 type2
)
2259 (if (maybe-reparse-specifier! type2
)
2263 ;;; Without some special HAIRY cases, we massively pollute the type caches
2264 ;;; with objects that are all equivalent to *EMPTY-TYPE*. e.g.
2265 ;;; (AND (SATISFIES LEGAL-FUN-NAME-P) (SIMPLE-ARRAY CHARACTER (*))) and
2266 ;;; (AND (SATISFIES KEYWORDP) CONS). Since the compiler doesn't know
2267 ;;; that they're just *EMPTY-TYPE*, its keeps building more and more complex
2268 ;;; expressions involving them. I'm not sure why those two are so prevalent
2269 ;;; but they definitely seem to be. We can improve performance by reducing
2270 ;;; them to *EMPTY-TYPE*.
2271 (define-type-method (hairy :simple-intersection2
:complex-intersection2
)
2273 (acond ((type= type1 type2
)
2275 ((eq type2
(specifier-type '(satisfies keywordp
)))
2276 ;; (AND (MEMBER A) (SATISFIES KEYWORDP)) is possibly non-empty
2277 ;; if A is re-homed as :A. However as a special case that really
2278 ;; does occur, (AND (MEMBER NIL) (SATISFIES KEYWORDP))
2279 ;; is empty because of the illegality of changing NIL's package.
2280 (if (eq type1
(specifier-type 'null
))
2282 (multiple-value-bind (answer certain
)
2283 (types-equal-or-intersect type1
(specifier-type 'symbol
))
2284 (and (not answer
) certain
*empty-type
*))))
2285 ((eq type2
(specifier-type '(satisfies legal-fun-name-p
)))
2286 (multiple-value-bind (answer certain
)
2287 (types-equal-or-intersect type1
(specifier-type 'symbol
))
2290 (multiple-value-bind (answer certain
)
2291 (types-equal-or-intersect type1
(specifier-type 'cons
))
2292 (and (not answer
) certain
*empty-type
*)))))
2293 ((and (typep (hairy-type-specifier type2
) '(cons (eql satisfies
)))
2294 (info :function
:predicate-truth-constraint
2295 (cadr (hairy-type-specifier type2
))))
2296 (multiple-value-bind (answer certain
)
2297 (types-equal-or-intersect type1
(specifier-type it
))
2298 (and (not answer
) certain
*empty-type
*)))))
2300 (define-type-method (hairy :simple-union2
)
2302 (if (type= type1 type2
)
2306 (define-type-method (hairy :simple-
=) (type1 type2
)
2307 ;; Specifiers really want to be compared by something that is more liberal than EQL
2308 ;; but it doesn't really matter too much because the containing objects would probably
2309 ;; be EQ if there was a cache hit on parsing.
2310 (if (list-elements-eql (hairy-type-specifier type1
) (hairy-type-specifier type2
))
2314 ;;; This list exists so that we can turn builtin (SATISFIES fn) types into types
2315 ;;; amenable to algebra, because apparently there are some masochistic users
2316 ;;; who expect (SUBTYPEP 'COMPLEX '(AND NUMBER (SATISFIES REALP))) => NIL and T.
2317 ;;; There are possibly other entries that could go here,
2318 ;;; e.g. (SATISFIES ARRAY-HEADER-P) is something involving the AND, NOT, OR
2319 ;;; combinators. But it might render the expression too hairy to operate on.
2320 (dolist (pair '((arrayp array
)
2322 (bit-vector-p bit-vector
)
2323 (characterp character
)
2324 ;; can't turn (SATISFIES COMPILED-FUNCTION-P) into COMPILED-FUNCTION
2325 ;; because COMPILED-FUNCTION is defined in terms of SATISFIES.
2326 ;; (compiled-function-p compiled-function)
2330 (functionp function
)
2331 (hash-table-p hash-table
)
2333 ;; KEYWORD is (SATISFIES KEYWORDP), so we can't turn
2334 ;; the predicate into KEYWORD
2338 (pathnamep pathname
)
2339 (random-state-p random-state
)
2340 (rationalp rational
)
2341 (readtablep readtable
)
2343 (simple-bit-vector-p simple-bit-vector
)
2344 (simple-string-p simple-string
)
2345 (simple-vector-p simple-vector
)
2350 (destructuring-bind (function type
) pair
2351 (setf (info :function
:predicate-for function
) type
)))
2353 (def-type-translator satisfies
:list
(&whole whole predicate-name
)
2354 ;; "* may appear as the argument to a SATISFIES type specifier, but it
2355 ;; indicates the literal symbol *" (which in practice is not useful)
2356 (unless (symbolp predicate-name
)
2357 (error 'simple-type-error
2358 :datum predicate-name
2359 :expected-type
'symbol
2360 :format-control
"The SATISFIES predicate name is not a symbol: ~S"
2361 :format-arguments
(list predicate-name
)))
2362 (case predicate-name
2363 (adjustable-array-p (specifier-type '(and array
(not simple-array
))))
2364 (t (let ((type (info :function
:predicate-for predicate-name
)))
2366 (specifier-type type
)
2367 (%make-hairy-type whole
))))))
2371 ;; Former comment was:
2372 ;; FIXME: is this right? It's what they had before, anyway
2373 ;; But I think the reason it's right is that "enumerable :t" is equivalent
2374 ;; to "maybe" which is actually the conservative assumption, same as HAIRY.
2375 (define-type-class negation
:enumerable t
:might-contain-other-types t
)
2377 (define-type-method (negation :negate
) (x)
2378 (negation-type-type x
))
2380 (define-type-method (negation :unparse
) (flags x
)
2381 (if (type= (negation-type-type x
) (specifier-type 'cons
))
2383 `(not ,(type-unparse flags
(negation-type-type x
)))))
2385 (define-type-method (negation :simple-subtypep
) (type1 type2
)
2386 (csubtypep (negation-type-type type2
) (negation-type-type type1
)))
2388 (define-type-method (negation :complex-subtypep-arg2
) (type1 type2
)
2389 (let* ((complement-type2 (negation-type-type type2
))
2390 (intersection2 (type-intersection2 type1
2393 ;; FIXME: if uncertain, maybe try arg1?
2394 (type= intersection2
*empty-type
*)
2395 (invoke-complex-subtypep-arg1-method type1 type2
))))
2397 (define-type-method (negation :complex-subtypep-arg1
) (type1 type2
)
2398 ;; "Incrementally extended heuristic algorithms tend inexorably toward the
2399 ;; incomprehensible." -- http://www.unlambda.com/~james/lambda/lambda.txt
2401 ;; You may not believe this. I couldn't either. But then I sat down
2402 ;; and drew lots of Venn diagrams. Comments involving a and b refer
2403 ;; to the call (subtypep '(not a) 'b) -- CSR, 2002-02-27.
2405 ;; (Several logical truths in this block are true as long as
2406 ;; b/=T. As of sbcl-0.7.1.28, it seems impossible to construct a
2407 ;; case with b=T where we actually reach this type method, but
2408 ;; we'll test for and exclude this case anyway, since future
2409 ;; maintenance might make it possible for it to end up in this
2411 (multiple-value-bind (equal certain
)
2412 (type= type2
*universal-type
*)
2414 (return (values nil nil
)))
2416 (return (values t t
))))
2417 (let ((complement-type1 (negation-type-type type1
)))
2418 ;; Do the special cases first, in order to give us a chance if
2419 ;; subtype/supertype relationships are hairy.
2420 (multiple-value-bind (equal certain
)
2421 (type= complement-type1 type2
)
2422 ;; If a = b, ~a is not a subtype of b (unless b=T, which was
2425 (return (values nil nil
)))
2427 (return (values nil t
))))
2428 ;; KLUDGE: ANSI requires that the SUBTYPEP result between any
2429 ;; two built-in atomic type specifiers never be uncertain. This
2430 ;; is hard to do cleanly for the built-in types whose
2431 ;; definitions include (NOT FOO), i.e. CONS and RATIO. However,
2432 ;; we can do it with this hack, which uses our global knowledge
2433 ;; that our implementation of the type system uses disjoint
2434 ;; implementation types to represent disjoint sets (except when
2435 ;; types are contained in other types). (This is a KLUDGE
2436 ;; because it's fragile. Various changes in internal
2437 ;; representation in the type system could make it start
2438 ;; confidently returning incorrect results.) -- WHN 2002-03-08
2439 (unless (or (type-might-contain-other-types-p complement-type1
)
2440 (type-might-contain-other-types-p type2
))
2441 ;; Because of the way our types which don't contain other
2442 ;; types are disjoint subsets of the space of possible values,
2443 ;; (SUBTYPEP '(NOT AA) 'B)=NIL when AA and B are simple (and B
2444 ;; is not T, as checked above).
2445 (return (values nil t
)))
2446 ;; The old (TYPE= TYPE1 TYPE2) branch would never be taken, as
2447 ;; TYPE1 and TYPE2 will only be equal if they're both NOT types,
2448 ;; and then the :SIMPLE-SUBTYPEP method would be used instead.
2449 ;; But a CSUBTYPEP relationship might still hold:
2450 (multiple-value-bind (equal certain
)
2451 (csubtypep complement-type1 type2
)
2452 ;; If a is a subtype of b, ~a is not a subtype of b (unless
2453 ;; b=T, which was excluded above).
2455 (return (values nil nil
)))
2457 (return (values nil t
))))
2458 (multiple-value-bind (equal certain
)
2459 (csubtypep type2 complement-type1
)
2460 ;; If b is a subtype of a, ~a is not a subtype of b. (FIXME:
2461 ;; That's not true if a=T. Do we know at this point that a is
2464 (return (values nil nil
)))
2466 (return (values nil t
))))
2467 ;; old CSR comment ca. 0.7.2, now obsoleted by the SIMPLE-CTYPE?
2468 ;; KLUDGE case above: Other cases here would rely on being able
2469 ;; to catch all possible cases, which the fragility of this type
2470 ;; system doesn't inspire me; for instance, if a is type= to ~b,
2471 ;; then we want T, T; if this is not the case and the types are
2472 ;; disjoint (have an intersection of *empty-type*) then we want
2473 ;; NIL, T; else if the union of a and b is the *universal-type*
2474 ;; then we want T, T. So currently we still claim to be unsure
2475 ;; about e.g. (subtypep '(not fixnum) 'single-float).
2477 ;; OTOH we might still get here:
2480 (define-type-method (negation :complex-
=) (type1 type2
)
2481 ;; (NOT FOO) isn't equivalent to anything that's not a negation
2482 ;; type, except possibly a type that might contain it in disguise.
2483 (declare (ignore type2
))
2484 (if (type-might-contain-other-types-p type1
)
2488 (define-type-method (negation :simple-intersection2
) (type1 type2
)
2489 (let ((not1 (negation-type-type type1
))
2490 (not2 (negation-type-type type2
)))
2492 ((csubtypep not1 not2
) type2
)
2493 ((csubtypep not2 not1
) type1
)
2494 ;; Why no analagous clause to the disjoint in the SIMPLE-UNION2
2495 ;; method, below? The clause would read
2497 ;; ((EQ (TYPE-UNION NOT1 NOT2) *UNIVERSAL-TYPE*) *EMPTY-TYPE*)
2499 ;; but with proper canonicalization of negation types, there's
2500 ;; no way of constructing two negation types with union of their
2501 ;; negations being the universal type.
2503 (aver (not (eq (type-union not1 not2
) *universal-type
*)))
2506 (defun maybe-complex-array-refinement (type1 type2
)
2507 ;; a :MAYBE complex array <type> intersected with (NOT <type'>)
2508 ;; where <type'> is the same in all aspects as <type> except that
2509 ;; its complexp value is in {T,NIL} should return <type> altered
2510 ;; with its COMPLEXP being the negation of the value from <type'>.
2511 ;; As a particular case which is no longer special in handling it,
2512 ;; the righthand side could be TYPE= to (NOT SIMPLE-ARRAY)
2513 ;; which will match any lefthand side and do what it always did.
2514 (let* ((ntype (negation-type-type type2
))
2515 (ndims (array-type-dimensions ntype
))
2516 (ncomplexp (array-type-complexp ntype
))
2517 (nseltype (array-type-specialized-element-type ntype
))
2518 (neltype (array-type-element-type ntype
)))
2519 (when (and (eq (array-type-complexp type1
) :maybe
)
2520 (neq ncomplexp
:maybe
)
2522 (equal (array-type-dimensions type1
) ndims
))
2523 (or (eq nseltype
*wild-type
*)
2524 (eq (array-type-specialized-element-type type1
) nseltype
))
2525 (or (eq neltype
*wild-type
*)
2526 (type= (array-type-element-type type1
) neltype
)))
2527 (make-array-type (array-type-dimensions type1
)
2528 :complexp
(not (array-type-complexp ntype
))
2529 :specialized-element-type
(array-type-specialized-element-type type1
)
2530 :element-type
(array-type-element-type type1
)))))
2532 (defun remove-integer-bounds (type)
2533 (let ((low (numeric-type-low type
))
2534 (high (numeric-type-high type
)))
2536 :class
(numeric-type-class type
)
2537 :format
(numeric-type-format type
)
2538 :complexp
(numeric-type-complexp type
)
2539 :low
(if (integerp low
) (list low
) low
)
2540 :high
(if (integerp high
) (list high
) high
))))
2542 (define-type-method (negation :complex-intersection2
) (type1 type2
)
2544 ((csubtypep type1
(negation-type-type type2
)) *empty-type
*)
2545 ((eq (type-intersection type1
(negation-type-type type2
)) *empty-type
*)
2547 ((and (array-type-p type1
) (array-type-p (negation-type-type type2
)))
2548 (maybe-complex-array-refinement type1 type2
))
2549 ((and (numeric-type-p type1
)
2550 (eql (numeric-type-class type1
) 'rational
)
2551 (csubtypep (sb-kernel:specifier-type
'integer
) (negation-type-type type2
))
2552 (or (integerp (numeric-type-low type1
)) (integerp (numeric-type-high type1
))))
2553 (type-intersection (remove-integer-bounds type1
) type2
))
2556 (define-type-method (negation :simple-union2
) (type1 type2
)
2557 (let ((not1 (negation-type-type type1
))
2558 (not2 (negation-type-type type2
)))
2560 ((csubtypep not1 not2
) type1
)
2561 ((csubtypep not2 not1
) type2
)
2562 ((eq (type-intersection not1 not2
) *empty-type
*)
2566 (define-type-method (negation :complex-union2
) (type1 type2
)
2568 ((csubtypep (negation-type-type type2
) type1
) *universal-type
*)
2569 ((eq (type-intersection type1
(negation-type-type type2
)) *empty-type
*)
2573 (define-type-method (negation :simple-
=) (type1 type2
)
2574 (type= (negation-type-type type1
) (negation-type-type type2
)))
2576 (def-type-translator not
:list
((:context context
) typespec
)
2577 ;; "* is not permitted as an argument to the NOT type specifier."
2578 (type-negation (specifier-type typespec context
'not
)))
2582 (declaim (inline numtype-aspects-eq
))
2583 (defun numtype-aspects-eq (type1 type2
)
2584 (eq (numeric-type-aspects type1
) (numeric-type-aspects type2
)))
2586 (declaim (inline bounds-unbounded-p
))
2587 (defun bounds-unbounded-p (low high
)
2588 (and (null low
) (eq high low
)))
2590 ;;; Coerce a numeric type bound to the given type while handling
2591 ;;; exclusive bounds.
2592 (defun coerce-numeric-bound (bound type
)
2596 (cond ((and (floatp thing
) (float-infinity-p thing
))
2597 (return-from coerce-numeric-bound nil
))
2598 ((or (eql thing -
0d0
)
2603 ((float single-float
)
2604 (cond ((or (eql thing -
0d0
)
2607 ((sb-xc:<= most-negative-single-float thing most-positive-single-float
)
2608 (coerce thing
'single-float
))
2610 (return-from coerce-numeric-bound nil
))))
2612 (cond ((or (eql thing -
0d0
)
2615 ((sb-xc:<= most-negative-double-float thing most-positive-double-float
)
2616 (coerce thing
'double-float
))
2618 (return-from coerce-numeric-bound nil
)))))))
2622 (list (c (car bound
)))
2626 (return-from coerce-numeric-bound nil
))))))
2628 (defun %make-union-numeric-type
(class format complexp low high
)
2629 (declare (type (member integer rational float nil
) class
))
2630 (macrolet ((unionize (&rest specs
)
2632 ,@(loop for
(class format coerce simple-coerce
) in specs
2633 collect
`(make-numeric-type
2637 :low
,(if simple-coerce
2638 `(coerce low
',coerce
)
2639 `(coerce-numeric-bound low
',coerce
))
2640 :high
,(if simple-coerce
2641 `(coerce high
',coerce
)
2642 `(coerce-numeric-bound high
',coerce
)))))))
2643 (cond ((and (null class
) (member complexp
'(:real
:complex
)))
2644 (cond ((not (bounds-unbounded-p low high
))
2645 (cond ((and (floatp low
) (float-infinity-p low
)
2647 ;; low and high are some float
2648 ;; infinity. not representable as a
2650 (let ((complexp :real
)) ; TODO what if complexp was :complex?
2651 (unionize (float single-float single-float t
)
2652 (float double-float double-float t
))))
2654 (unionize (rational nil rational
)
2655 (float single-float single-float
)
2656 (float double-float double-float
)))))
2657 ((eq complexp
:complex
)
2658 (specifier-type 'complex
))
2660 (specifier-type 'real
))))
2661 ((and (eq class
'float
) (member complexp
'(:real
:complex
))
2663 (cond ((not (bounds-unbounded-p low high
))
2664 (if (and (floatp low
) (float-infinity-p low
)
2666 (let ((complexp :real
))
2667 (unionize (float single-float single-float t
)
2668 (float double-float double-float t
)
2669 #+long-float
((error "long-float"))))
2670 (unionize (float single-float single-float
)
2671 (float double-float double-float
)
2672 #+long-float
((error "long-float")))))
2673 ((eq complexp
:complex
)
2674 (specifier-type '(complex float
)))
2676 (specifier-type 'float
))))
2677 ((and (null complexp
)
2678 (or class format low high
))
2679 (type-union (make-numeric-type :class class
:format format
:complexp
:complex
2680 :low low
:high high
)
2681 (make-numeric-type :class class
:format format
:complexp
:real
2682 :low low
:high high
))))))
2684 (defun modified-numeric-type (base
2686 (class (numeric-type-class base
))
2687 (format (numeric-type-format base
))
2688 (complexp (numeric-type-complexp base
))
2689 (low (numeric-type-low base
))
2690 (high (numeric-type-high base
)))
2691 (make-numeric-type :class class
2697 ;;; If it's longer than N
2698 (defun weaken-numeric-type-union (n type
)
2699 (cond ((union-type-p type
)
2700 (let* ((types (union-type-types type
))
2703 (loop for type in types
2704 for new
= (if (numeric-union-type-p type
)
2705 (weaken-numeric-type-union n type
)
2708 (unless (eq new type
)
2712 (%type-union new-types
)
2714 ((and (numeric-union-type-p type
)
2715 (> (truncate (length (numeric-union-type-ranges type
))
2716 (if (memq (numeric-type-class type
) '(integer rational
))
2720 (weaken-numeric-union type
))
2725 (setf (info :type
:kind
'number
) :primitive
)
2726 (setf (info :type
:builtin
'number
)
2728 (hashset-insert *numeric-union-type-hashset
*
2729 (!alloc-numeric-union-type
#.
(make-ctype-bits 'numeric-union
)
2730 (get-numtype-aspects nil nil nil
)
2732 #-sb-xc-host
(specifier-type 'number
)))
2734 (defun upgraded-complex-part-ctype (typespec &optional context
)
2735 (let ((ctype (specifier-type typespec context
)))
2737 ((eq ctype
*empty-type
*)
2739 ;; this is the two types NIL and (EQL 0)
2740 ((csubtypep ctype
(sb-kernel:specifier-type
'(eql 0)))
2742 ((not (csubtypep ctype
(specifier-type 'real
)))
2743 (error "The component type for COMPLEX is not a subtype of REAL: ~S"
2745 ((csubtypep ctype
(specifier-type 'rational
))
2746 (specifier-type 'rational
))
2747 ((csubtypep ctype
(specifier-type 'single-float
))
2748 (specifier-type 'single-float
))
2749 ((csubtypep ctype
(specifier-type 'double-float
))
2750 (specifier-type 'double-float
))
2751 ((csubtypep ctype
(specifier-type 'float
))
2752 (specifier-type 'float
))
2753 ((not (types-equal-or-intersect ctype
(specifier-type 'double-float
)))
2754 (specifier-type '(or rational single-float
)))
2755 ((not (types-equal-or-intersect ctype
(specifier-type 'single-float
)))
2756 (specifier-type '(or rational double-float
)))
2758 (specifier-type 'real
)))))
2760 (def-type-translator complex
((:context context
) &optional
(typespec '*))
2761 (declare (inline !compute-numtype-aspect-id
))
2762 (if (eq typespec
'*)
2763 (specifier-type '(complex real
))
2764 (labels ((complex1 (component-type)
2765 (new-ctype numeric-union-type
2766 0 (get-numtype-aspects :complex
2767 (numeric-type-class component-type
)
2768 (numeric-type-format component-type
))
2769 (numeric-union-type-ranges component-type
))))
2770 (let ((ctype (upgraded-complex-part-ctype typespec context
)))
2771 ;; this is the two types NIL and (EQL 0)
2772 (if (csubtypep ctype
(sb-kernel:specifier-type
'(eql 0)))
2778 (%type-union
(mapcar #'complex1
(union-type-types ctype
))))))))))
2780 ;;; If X is *, return NIL, otherwise return the bound, which must be a
2781 ;;; member of TYPE or a one-element list of a member of TYPE.
2782 ;;; This is not necessarily the canonical bound. An integer bound
2783 ;;; should always be an atom, which we'll enforce later if needed.
2784 (defmacro valid-bound
(bound type
)
2785 `(cond ((eq ,bound
'*) nil
)
2786 ((sb-xc:typep
(if (singleton-p ,bound
) (car ,bound
) ,bound
) ',type
) ,bound
)
2788 (error ,(format nil
"~A bound is not * or ~A ~A or list of one ~:*~A: ~~S"
2789 (string-capitalize bound
)
2790 (if (eq type
'integer
) "an" "a")
2791 (string-downcase type
))
2794 (def-type-translator integer
(&optional
(low '*) (high '*))
2795 (let ((lb (valid-bound low integer
))
2796 (hb (valid-bound high integer
)))
2797 (make-numeric-type :class
'integer
:complexp
:real
:low lb
:high hb
)))
2799 (defmacro !def-bounded-type
(type class format
)
2800 `(def-type-translator ,type
(&optional
(low '*) (high '*))
2801 (let ((lb (valid-bound low
,type
))
2802 (hb (valid-bound high
,type
)))
2803 (make-numeric-type :class
',class
:format
',format
:low lb
:high hb
))))
2805 (!def-bounded-type rational rational nil
)
2807 ;;; Unlike CMU CL, we represent the types FLOAT and REAL as
2808 ;;; UNION-TYPEs of more primitive types, in order to make
2809 ;;; type representation more unique, avoiding problems in the
2810 ;;; simplification of things like
2811 ;;; (subtypep '(or (single-float -1.0 1.0) (single-float 0.1))
2812 ;;; '(or (real -1 7) (single-float 0.1) (single-float -1.0 1.0)))
2813 ;;; When we allowed REAL to remain as a separate NUMERIC-TYPE,
2814 ;;; it was too easy for the first argument to be simplified to
2815 ;;; '(SINGLE-FLOAT -1.0), and for the second argument to be simplified
2816 ;;; to '(OR (REAL -1 7) (SINGLE-FLOAT 0.1)) and then for the
2817 ;;; SUBTYPEP to fail (returning NIL,T instead of T,T) because
2818 ;;; the first argument can't be seen to be a subtype of any of the
2819 ;;; terms in the second argument.
2821 ;;; The old CMU CL way was:
2822 ;;; (!def-bounded-type float float nil)
2823 ;;; (!def-bounded-type real nil nil)
2825 ;;; FIXME: If this new way works for a while with no weird new
2826 ;;; problems, we can go back and rip out support for separate FLOAT
2827 ;;; and REAL flavors of NUMERIC-TYPE. The new way was added in
2828 ;;; sbcl-0.6.11.22, 2001-03-21.
2829 (defun coerce-bound (bound type upperp inner-coerce-bound-fun
)
2830 (declare (type function inner-coerce-bound-fun
))
2833 (funcall inner-coerce-bound-fun bound type upperp
)))
2835 (macrolet ((make-bound (val)
2836 `(let ((coerced ,val
))
2837 (if (listp bound
) (list coerced
) coerced
))))
2839 (defun inner-coerce-real-bound (bound type upperp
)
2840 (let ((nl most-negative-long-float
)
2841 (pl most-positive-long-float
))
2842 (let ((nbound (if (listp bound
) (car bound
) bound
)))
2845 (make-bound (rational nbound
)))
2848 ((floatp nbound
) bound
)
2850 ;; Coerce to the widest float format available, to avoid
2851 ;; unnecessary loss of precision, but don't coerce
2852 ;; unrepresentable numbers.
2855 (when (sb-xc:< nbound nl
) (return-from inner-coerce-real-bound nl
)))
2857 (when (sb-xc:> nbound pl
) (return-from inner-coerce-real-bound pl
))))
2858 (make-bound (coerce nbound
'long-float
)))))))))
2860 (defun inner-coerce-float-bound (bound type upperp
)
2861 (let ((nd most-negative-double-float
)
2862 (pd most-positive-double-float
)
2863 (ns most-negative-single-float
)
2864 (ps most-positive-single-float
))
2865 (let ((nbound (if (listp bound
) (car bound
) bound
)))
2869 ((cl:typep nbound
'single-float
) bound
)
2873 (when (sb-xc:< nbound ns
) (return-from inner-coerce-float-bound ns
)))
2875 (when (sb-xc:> nbound ps
) (return-from inner-coerce-float-bound ps
))))
2876 (make-bound (coerce nbound
'single-float
)))))
2879 ((cl:typep nbound
'double-float
) bound
)
2883 (when (sb-xc:< nbound nd
) (return-from inner-coerce-float-bound nd
)))
2885 (when (sb-xc:> nbound pd
) (return-from inner-coerce-float-bound pd
))))
2886 (make-bound (coerce nbound
'double-float
)))))))))
2889 (defun coerced-real-bound (bound type upperp
)
2890 (coerce-bound bound type upperp
#'inner-coerce-real-bound
))
2891 (defun coerced-float-bound (bound type upperp
)
2892 (coerce-bound bound type upperp
#'inner-coerce-float-bound
))
2893 (def-type-translator real
(&optional
(low '*) (high '*))
2894 (specifier-type `(or (float ,(coerced-real-bound low
'float nil
)
2895 ,(coerced-real-bound high
'float t
))
2896 (rational ,(coerced-real-bound low
'rational nil
)
2897 ,(coerced-real-bound high
'rational t
)))))
2898 (def-type-translator float
(&optional
(low '*) (high '*))
2900 `(or (single-float ,(coerced-float-bound low
'single-float nil
)
2901 ,(coerced-float-bound high
'single-float t
))
2902 (double-float ,(coerced-float-bound low
'double-float nil
)
2903 ,(coerced-float-bound high
'double-float t
))
2904 #+long-float
,(error "stub: no long float support yet"))))
2906 (macrolet ((define-float-format (f) `(!def-bounded-type
,f float
,f
)))
2907 (define-float-format single-float
)
2908 (define-float-format double-float
))
2910 ;;; Given two float formats, return the one with more precision. If
2911 ;;; either one is null, return NIL.
2912 (defun float-format-max (f1 f2
)
2914 (dolist (f *float-formats
* (error "bad float format: ~S" f1
))
2915 (when (or (eq f f1
) (eq f f2
))
2918 ;;; Return the result of an operation on TYPE1 and TYPE2 according to
2919 ;;; the rules of numeric contagion. This is NUMBER, some float
2920 ;;; format (possibly complex) or RATIONAL or a UNION-TYPE of
2921 ;;; these. Due to rational canonicalization, there isn't much we can
2922 ;;; do here with integers or rational complex numbers.
2924 ;;; If either argument is not a NUMERIC-TYPE, then return NUMBER. This
2925 ;;; is useful mainly for allowing types that are technically numbers,
2926 ;;; but not a NUMERIC-TYPE.
2927 (defun numeric-contagion (type1 type2
&key
(rational t
)
2929 (cond ((and (numeric-type-p type1
) (numeric-type-p type2
))
2930 (let ((class1 (numeric-type-class type1
))
2931 (class2 (numeric-type-class type2
))
2932 (format1 (numeric-type-format type1
))
2933 (format2 (numeric-type-format type2
))
2934 (complexp1 (numeric-type-complexp type1
))
2935 (complexp2 (numeric-type-complexp type2
)))
2936 (cond ((eq class1
'float
)
2939 :format
(ecase class2
2940 (float (float-format-max format1 format2
))
2941 ((integer rational
) format1
)
2943 ;; A double-float with any real number is a
2946 (if (eq format1
'double-float
)
2949 ;; A long-float with any real number is a
2952 (if (eq format1
'long-float
)
2955 :complexp
(cond ((and (eq complexp1
:real
)
2956 (eq complexp2
:real
))
2958 ((or (eq complexp1
:complex
)
2959 (eq complexp2
:complex
))
2961 ((eq class2
'float
) (numeric-contagion type2 type1
))
2962 ((and (eq complexp1
:real
) (eq complexp2
:real
))
2964 (or (neq class1
'integer
)
2965 (neq class2
'integer
)))
2967 :class
(and class1 class2
'rational
)
2973 (typep (numeric-type-low type1
) 'unsigned-byte
)
2974 (typep (numeric-type-low type2
) 'unsigned-byte
)
2977 (specifier-type 'number
)))))
2978 ((eq type1
(specifier-type 'ratio
))
2979 (numeric-contagion (specifier-type 'rational
) type2
))
2980 ((eq type2
(specifier-type 'ratio
))
2981 (numeric-contagion type1
(specifier-type 'rational
)))
2983 (flet ((try-union (a b
)
2985 (loop for type in
(union-type-types a
)
2986 for contagion
= (numeric-contagion type b
:rational rational
:unsigned unsigned
)
2987 do
(setf union
(if union
2988 (type-union union contagion
)
2990 until
(eq union
(specifier-type 'number
)))
2992 (cond ((union-type-p type1
)
2993 (try-union type1 type2
))
2994 ((union-type-p type2
)
2995 (try-union type2 type1
))
2997 (specifier-type 'number
)))))))
3001 (define-type-class array
:enumerable nil
:might-contain-other-types nil
)
3003 ;; All character-set types are enumerable, but it's not possible for
3004 ;; one to be TYPE= to a MEMBER type because (MEMBER #\x) is not
3005 ;; internally represented as a MEMBER type. So in case it wasn't
3006 ;; clear already ENUMERABLE-P does not mean "possibly a MEMBER type in
3007 ;; the Lisp-theoretic sense", but means "could be implemented in SBCL
3008 ;; as a MEMBER type".
3009 (define-type-class character-set
:enumerable nil
:might-contain-other-types nil
)
3011 (defun make-character-set-type (pairs)
3013 (return-from make-character-set-type
*empty-type
*))
3014 ;; aver that the cars of the list elements are sorted into increasing order
3015 (do ((p pairs
(cdr p
)))
3017 (aver (<= (the %char-code
(caar p
)) (the %char-code
(caadr p
)))))
3019 (if (and (singleton-p pairs
)
3020 (eql (truly-the %char-code
(caar pairs
))
3021 ;; only the CARs were checked above
3022 (the %char-code
(cdar pairs
))))
3023 pairs
; don't need to preprocess the pairs
3025 (do ((pairs pairs
(cdr pairs
)))
3026 ((null pairs
) (nreverse result
))
3027 (destructuring-bind (low . high
) (car pairs
)
3028 (declare (type %char-code low high
))
3029 (loop for
(low1 . high1
) in
(cdr pairs
)
3030 if
(<= (the %char-code low1
) (1+ high
))
3031 do
(progn (setf high
(max high
(the %char-code high1
)))
3032 (setf pairs
(cdr pairs
)))
3033 else do
(return nil
))
3035 ((>= low char-code-limit
))
3037 (t (push (cons (max 0 low
)
3038 (min high
(1- char-code-limit
)))
3041 (macrolet ((range (low high
)
3042 `(return-from make-character-set-type
3044 (!alloc-character-set-type
(make-ctype-bits 'character-set
)
3046 (character-set ((,low .
,high
)))))))
3047 (let* ((pair (car pairs
))
3050 (cond ((eql high
(1- char-code-limit
))
3052 (range 0 #.
(1- char-code-limit
)))
3054 ((eql low base-char-code-limit
)
3055 (range #.base-char-code-limit
3056 #.
(1- char-code-limit
)))))
3058 ((and (eql low
0) (eql high
(1- base-char-code-limit
)))
3059 (range 0 #.
(1- base-char-code-limit
)))))))
3060 (new-ctype character-set-type
0 pairs
)))
3062 (defun character-set-type-from-characters (characters)
3063 ;; Constructor asserts that pairs are properly sorted
3064 (make-character-set-type (mapcar (lambda (x)
3065 (let ((code (sb-xc:char-code x
)))
3067 (sort (delete-duplicates characters
) #'<
3068 :key
#'sb-xc
:char-code
))))
3070 (declaim (ftype (sfunction (t &key
(:complexp t
)
3072 (:specialized-element-type t
))
3073 ctype
) make-array-type
))
3074 (defun make-array-type (dimensions &key
(complexp :maybe
) element-type
3075 (specialized-element-type *wild-type
*))
3076 (%make-array-type dimensions complexp element-type specialized-element-type
))
3078 (define-type-method (array :simple-
=) (type1 type2
)
3079 (cond ((not (and (equal (array-type-dimensions type1
)
3080 (array-type-dimensions type2
))
3081 (eq (array-type-complexp type1
)
3082 (array-type-complexp type2
))))
3084 ((or (contains-unknown-type-p (array-type-element-type type1
))
3085 (contains-unknown-type-p (array-type-element-type type2
)))
3086 (type= (array-type-element-type type1
)
3087 (array-type-element-type type2
)))
3089 (values (eq (array-type-specialized-element-type type1
)
3090 (array-type-specialized-element-type type2
))
3093 (define-type-method (array :negate
) (type)
3094 ;; FIXME (and hint to PFD): we're vulnerable here to attacks of the
3095 ;; form "are (AND ARRAY (NOT (ARRAY T))) and (OR (ARRAY BIT) (ARRAY
3096 ;; NIL) (ARRAY CHAR) ...) equivalent?" -- CSR, 2003-12-10
3097 ;; A symptom of the aforementioned is that the following are not TYPE=
3098 ;; (AND (VECTOR T) (NOT SIMPLE-ARRAY)) ; an ARRAY-TYPE
3099 ;; (AND (VECTOR T) (NOT SIMPLE-VECTOR)) ; an INTERSECTION-TYPE
3100 ;; even though (VECTOR T) makes it so that the (NOT) clause in each can
3101 ;; only provide one additional bit of information: that the vector
3102 ;; is complex as opposed to simple. The rank and element-type are fixed.
3103 (if (and (eq (array-type-dimensions type
) '*)
3104 (eq (array-type-complexp type
) 't
)
3105 (eq (array-type-element-type type
) *wild-type
*))
3106 ;; (NOT <hairy-array>) = either SIMPLE-ARRAY or (NOT ARRAY).
3107 ;; This is deliberately asymmetric - trying to say that NOT simple-array
3108 ;; equals hairy-array leads to infinite recursion.
3109 (type-union (make-array-type '* :complexp nil
3110 :element-type
*wild-type
*)
3112 (make-array-type '* :element-type
*wild-type
*)))
3113 (make-negation-type type
)))
3115 (define-type-method (array :unparse
) (flags type
)
3116 (let* ((dims (array-type-dimensions type
))
3117 ;; Compare the specialised element type and the
3118 ;; derived element type. If the derived type
3119 ;; is so small that it jumps to a smaller upgraded
3120 ;; element type, use the specialised element type.
3122 ;; This protects from unparsing
3123 ;; (and (vector (or bit symbol))
3124 ;; (vector (or bit character)))
3125 ;; i.e., the intersection of two T array types,
3127 (stype (array-type-specialized-element-type type
))
3128 (dtype (array-type-element-type type
))
3129 (utype (%upgraded-array-element-type dtype
))
3130 (eltype (type-unparse flags
3131 (if (type= stype utype
)
3134 (complexp (array-type-complexp type
)))
3138 ((t) '(and array
(not simple-array
)))
3140 ((nil) 'simple-array
))
3142 ((t) `(and (array ,eltype
) (not simple-array
)))
3143 ((:maybe
) `(array ,eltype
))
3144 ((nil) `(simple-array ,eltype
)))))
3145 ((= (length dims
) 1)
3148 (if (eq (car dims
) '*)
3151 ((base-char #-sb-unicode character
) 'base-string
)
3153 (t `(vector ,eltype
)))
3155 (bit `(bit-vector ,(car dims
)))
3156 ((base-char #-sb-unicode character
)
3157 `(base-string ,(car dims
)))
3158 (t `(vector ,eltype
,(car dims
)))))))
3159 (if (eql complexp
:maybe
)
3161 `(and ,answer
(not simple-array
))))
3162 (if (eq (car dims
) '*)
3164 (bit 'simple-bit-vector
)
3165 ((base-char #-sb-unicode character
) 'simple-base-string
)
3166 ((t) 'simple-vector
)
3167 (t `(simple-array ,eltype
(*))))
3169 (bit `(simple-bit-vector ,(car dims
)))
3170 ((base-char #-sb-unicode character
)
3171 `(simple-base-string ,(car dims
)))
3172 ((t) `(simple-vector ,(car dims
)))
3173 (t `(simple-array ,eltype
,dims
))))))
3176 ((t) `(and (array ,eltype
,dims
) (not simple-array
)))
3177 ((:maybe
) `(array ,eltype
,dims
))
3178 ((nil) `(simple-array ,eltype
,dims
)))))))
3180 (define-type-method (array :simple-subtypep
) (type1 type2
)
3181 (let ((dims1 (array-type-dimensions type1
))
3182 (dims2 (array-type-dimensions type2
))
3183 (complexp2 (array-type-complexp type2
)))
3184 (cond (;; not subtypep unless dimensions are compatible
3185 (not (or (eq dims2
'*)
3186 (and (not (eq dims1
'*))
3187 ;; (sbcl-0.6.4 has trouble figuring out that
3188 ;; DIMS1 and DIMS2 must be lists at this
3189 ;; point, and knowing that is important to
3190 ;; compiling EVERY efficiently.)
3191 (= (length (the list dims1
))
3192 (length (the list dims2
)))
3193 (every (lambda (x y
)
3194 (or (eq y
'*) (eql x y
)))
3196 (the list dims2
)))))
3198 ;; not subtypep unless complexness is compatible
3199 ((not (or (eq complexp2
:maybe
)
3200 (eq (array-type-complexp type1
) complexp2
)))
3202 ;; Since we didn't fail any of the tests above, we win
3203 ;; if the TYPE2 element type is wild.
3204 ((eq (array-type-element-type type2
) *wild-type
*)
3206 (;; Since we didn't match any of the special cases above, if
3207 ;; either element type is unknown we can only give a good
3208 ;; answer if they are the same.
3209 (or (contains-unknown-type-p (array-type-element-type type1
))
3210 (contains-unknown-type-p (array-type-element-type type2
)))
3211 (if (type= (array-type-element-type type1
)
3212 (array-type-element-type type2
))
3215 (;; Otherwise, the subtype relationship holds iff the
3216 ;; types are equal, and they're equal iff the specialized
3217 ;; element types are identical.
3219 (values (type= (array-type-specialized-element-type type1
)
3220 (array-type-specialized-element-type type2
))
3223 (!define-superclasses array
((vector vector
) (array)) !cold-init-forms
)
3225 (defun array-types-intersect (type1 type2
)
3226 (declare (type array-type type1 type2
))
3227 (let ((dims1 (array-type-dimensions type1
))
3228 (dims2 (array-type-dimensions type2
))
3229 (complexp1 (array-type-complexp type1
))
3230 (complexp2 (array-type-complexp type2
)))
3231 ;; See whether dimensions are compatible.
3232 (cond ((not (or (eq dims1
'*) (eq dims2
'*)
3233 (and (= (length dims1
) (length dims2
))
3234 (every (lambda (x y
)
3235 (or (eq x
'*) (eq y
'*) (= x y
)))
3238 ;; See whether complexpness is compatible.
3239 ((not (or (eq complexp1
:maybe
)
3240 (eq complexp2
:maybe
)
3241 (eq complexp1 complexp2
)))
3245 ;; If either element type is wild, then they intersect.
3246 ;; Otherwise, the types must be identical.
3248 ;; FIXME: There seems to have been a fair amount of
3249 ;; confusion about the distinction between requested element
3250 ;; type and specialized element type; here is one of
3251 ;; them. If we request an array to hold objects of an
3252 ;; unknown type, we can do no better than represent that
3253 ;; type as an array specialized on wild-type. We keep the
3254 ;; requested element-type in the -ELEMENT-TYPE slot, and
3255 ;; *WILD-TYPE* in the -SPECIALIZED-ELEMENT-TYPE. So, here,
3256 ;; we must test for the SPECIALIZED slot being *WILD-TYPE*,
3257 ;; not just the ELEMENT-TYPE slot. Maybe the return value
3258 ;; in that specific case should be T, NIL? Or maybe this
3259 ;; function should really be called
3260 ;; ARRAY-TYPES-COULD-POSSIBLY-INTERSECT? In any case, this
3261 ;; was responsible for bug #123, and this whole issue could
3262 ;; do with a rethink and/or a rewrite. -- CSR, 2002-08-21
3263 ((or (eq (array-type-specialized-element-type type1
) *wild-type
*)
3264 (eq (array-type-specialized-element-type type2
) *wild-type
*)
3265 (type= (array-type-specialized-element-type type1
)
3266 (array-type-specialized-element-type type2
)))
3272 (defun unite-array-types-complexp (type1 type2
)
3273 (let ((complexp1 (array-type-complexp type1
))
3274 (complexp2 (array-type-complexp type2
)))
3276 ((eq complexp1 complexp2
)
3277 ;; both types are the same complexp-ity
3278 (values complexp1 t
))
3279 ((eq complexp1
:maybe
)
3280 ;; type1 is wild-complexp
3281 (values :maybe type1
))
3282 ((eq complexp2
:maybe
)
3283 ;; type2 is wild-complexp
3284 (values :maybe type2
))
3286 ;; both types partition the complexp-space
3287 (values :maybe nil
)))))
3289 (defun unite-array-types-dimensions (type1 type2
)
3290 (let ((dims1 (array-type-dimensions type1
))
3291 (dims2 (array-type-dimensions type2
)))
3292 (cond ((equal dims1 dims2
)
3293 ;; both types are same dimensionality
3296 ;; type1 is wild-dimensions
3299 ;; type2 is wild-dimensions
3301 ((not (= (length dims1
) (length dims2
)))
3302 ;; types have different number of dimensions
3303 (values :incompatible nil
))
3305 ;; we need to check on a per-dimension basis
3306 (let* ((supertype1 t
)
3309 (result (mapcar (lambda (dim1 dim2
)
3314 (setf supertype2 nil
)
3317 (setf supertype1 nil
)
3320 (setf compatible nil
))))
3323 ((or (not compatible
)
3324 (and (not supertype1
)
3326 (values :incompatible nil
))
3327 ((and supertype1 supertype2
)
3328 (values result supertype1
))
3330 (values result
(if supertype1 type1 type2
)))))))))
3332 (defun unite-array-types-element-types (type1 type2
)
3333 ;; FIXME: We'd love to be able to unite the full set of specialized
3334 ;; array element types up to *wild-type*, but :simple-union2 is
3335 ;; performed pairwise, so we don't have a good hook for it and our
3336 ;; representation doesn't allow us to easily detect the situation
3338 ;; But see SIMPLIFY-ARRAY-UNIONS which is able to do something like that.
3339 (let* ((eltype1 (array-type-element-type type1
))
3340 (eltype2 (array-type-element-type type2
))
3341 (stype1 (array-type-specialized-element-type type1
))
3342 (stype2 (array-type-specialized-element-type type2
))
3343 (wild1 (eq eltype1
*wild-type
*))
3344 (wild2 (eq eltype2
*wild-type
*)))
3347 (values eltype1 stype1 t
))
3349 (values eltype1 stype1 type1
))
3351 (values eltype2 stype2 type2
))
3352 ((type= eltype1 eltype2
)
3353 (values eltype1 stype1 t
))
3354 ((not (type= stype1 stype2
))
3355 ;; non-wild types that don't share UAET don't unite
3356 (values :incompatible nil nil
))
3357 ((csubtypep eltype1 eltype2
)
3358 (values eltype2 stype2 type2
))
3359 ((csubtypep eltype2 eltype1
)
3360 (values eltype1 stype1 type1
))
3362 (values :incompatible nil nil
)))))
3364 (defun unite-array-types-supertypes-compatible-p (&rest supertypes
)
3365 ;; supertypes are compatible if they are all T, if there is a single
3366 ;; NIL and all the rest are T, or if all non-T supertypes are the
3367 ;; same and not NIL.
3368 (let ((interesting-supertypes
3369 (remove t supertypes
)))
3370 (or (not interesting-supertypes
)
3371 (equal interesting-supertypes
'(nil))
3372 ;; supertypes are (OR BOOLEAN ARRAY-TYPE), so...
3373 (typep (remove-duplicates interesting-supertypes
)
3374 '(cons array-type null
)))))
3376 (define-type-method (array :simple-union2
) (type1 type2
)
3377 (multiple-value-bind
3378 (result-eltype result-stype eltype-supertype
)
3379 (unite-array-types-element-types type1 type2
)
3380 (multiple-value-bind
3381 (result-complexp complexp-supertype
)
3382 (unite-array-types-complexp type1 type2
)
3383 (multiple-value-bind
3384 (result-dimensions dimensions-supertype
)
3385 (unite-array-types-dimensions type1 type2
)
3386 (when (and (not (eq result-dimensions
:incompatible
))
3387 (not (eq result-eltype
:incompatible
))
3388 (unite-array-types-supertypes-compatible-p
3389 eltype-supertype complexp-supertype dimensions-supertype
))
3390 (make-array-type result-dimensions
3391 :complexp result-complexp
3392 :element-type result-eltype
3393 :specialized-element-type result-stype
))))))
3395 (defun array-intersection (type1 type2 use-specialized
)
3396 (if (array-types-intersect type1 type2
)
3397 (let* ((dims1 (array-type-dimensions type1
))
3398 (dims2 (array-type-dimensions type2
))
3399 (complexp1 (array-type-complexp type1
))
3400 (complexp2 (array-type-complexp type2
))
3401 (eltype1 (array-type-element-type type1
))
3402 (eltype2 (array-type-element-type type2
))
3403 (stype1 (array-type-specialized-element-type type1
))
3404 (stype2 (array-type-specialized-element-type type2
))
3405 (specialized-element-type
3407 ((eq stype1
*wild-type
*) stype2
)
3408 ((eq stype2
*wild-type
*) stype1
)
3410 (aver (type= stype1 stype2
))
3412 (make-array-type (cond ((eq dims1
'*) dims2
)
3413 ((eq dims2
'*) dims1
)
3415 (mapcar (lambda (x y
) (if (eq x
'*) y x
))
3417 :complexp
(if (eq complexp1
:maybe
) complexp2 complexp1
)
3420 specialized-element-type
)
3421 ((eq eltype1
*wild-type
*) eltype2
)
3422 ((eq eltype2
*wild-type
*) eltype1
)
3423 (t (type-intersection eltype1 eltype2
)))
3424 :specialized-element-type specialized-element-type
))
3427 (define-type-method (array :simple-intersection2
) (type1 type2
)
3428 (array-intersection type1 type2 nil
))
3430 ;;; Check a supplied dimension list to determine whether it is legal,
3431 ;;; and return it in canonical form (as either '* or a list).
3432 (defun canonical-array-dimensions (dims)
3437 (error "Arrays can't have a negative number of dimensions: ~S" dims
))
3438 (when (>= dims array-rank-limit
)
3439 (error "array type with too many dimensions: ~S" dims
))
3440 (make-list dims
:initial-element
'*))
3442 (when (>= (length dims
) array-rank-limit
)
3443 (error "array type with too many dimensions: ~S" dims
))
3446 (unless (and (integerp dim
)
3448 (< dim array-dimension-limit
))
3449 (error "bad dimension in array type: ~S" dim
))))
3452 (error "Array dimensions is not a list, integer or *:~% ~S" dims
))))
3457 (define-type-class member
:enumerable t
3458 :might-contain-other-types nil
)
3460 ;; Return possibly a union of a MEMBER type and a NUMERIC type,
3461 ;; or just one or the other, or *EMPTY-TYPE* depending on what's in the XSET
3462 ;; and the FP-ZEROES. XSET must not contains characters or real numbers.
3463 ;; MEMBER types go into one of three hash containers:
3464 ;; - *EQL-TYPE-CACHE* holds singleton types. A weak hash-table suffices for this.
3465 ;; - *MEMBER-TYPE-HASHSET* holds types whose members are {NUMBER|CHARACTER|SYMBOL}.
3466 ;; Intrinsically each element has a stable hash, making it possible to
3467 ;; hash-cons XSETs without complications for EQ-comparable keys.
3468 ;; - *MEMBER/EQ-TYPE-HASHSET* is the general case, allowing a mixture of objects
3469 ;;; hashed by content-dependent hash and/or pseudorandom opaque hash.
3470 (defun make-member-type (xset fp-zeroes
)
3471 ;; if we have a pair of zeros (e.g. 0.0d0 and -0.0d0), then we can
3472 ;; canonicalize to (DOUBLE-FLOAT 0.0d0 0.0d0), because numeric
3473 ;; ranges are compared by arithmetic operators (while MEMBERship is
3474 ;; compared by EQL). -- CSR, 2003-04-23
3475 (declare (sb-c::tlab
:system
))
3476 (map-xset (lambda (elt)
3477 (when (or (characterp elt
) (realp elt
))
3478 (bug "MEMBER type contains ~S" elt
)))
3484 (fp-zeroes ; avoid doing two passes of nothing
3486 (dolist (z fp-zeroes
)
3487 (let ((sign (float-sign-bit z
))
3492 #+long-float
(long-float 4)))))
3493 (cond ((= pass
0) ; first pass: track presence of +-0 of each float format
3494 (setf (ldb (byte 1 (+ pair-idx sign
)) presence
) 1))
3495 ;; second pass: if not both signs present, then it's an unpaired zero
3496 ((/= (ldb (byte 2 pair-idx
) presence
) #b11
)
3498 ((= sign
0) ; take the +0 as canonical when both +-0 are present
3499 (push (make-numeric-type :complexp
:real
:class
'float
:low z
:high z
3500 :format
(float-format-name z
))
3502 ((and (= (xset-count xset
) 1)
3503 (eq (car (xset-members xset
)) nil
))
3504 ;; Bypass the hashset for type NULL because it's so important
3505 (return-from make-member-type
3506 (inline-cache-ctype (!alloc-member-type
(make-ctype-bits 'member
)
3507 (!new-xset
'(nil) 1)
3510 (let* ((count (+ (length unpaired
) (xset-count xset
)))
3513 (dx-let ((temp (!alloc-member-type
(ctype-class-bits 'member
)
3517 (let ((container *eql-type-cache
*)
3518 (key (first (or unpaired
(xset-data xset
)))))
3519 (with-system-mutex ((hash-table-lock container
))
3520 ;; This is like ENSURE-GETHASH but it potentially copies the key
3521 (or (gethash key container
)
3522 (let ((copy (copy-ctype temp
)))
3523 ;; re-fetch KEY from XSET in case it was copied.
3524 ;; hope no off-heap pointers buried within KEY.
3525 (setf (gethash (first (member-type-members copy
)) container
)
3527 ((xset-every (lambda (x) (typep x
'(or symbol number character
))) xset
)
3528 (hashset-insert-if-absent *member-type-hashset
* temp
#'copy-ctype
))
3531 ((container *member
/eq-type-hashset
*)
3533 (with-system-mutex (*xset-mutex
*)
3534 (xset-generate-stable-hashes xset
)
3535 (acond ((hashset-find container temp
)
3536 (xset-delete-stable-hashes xset
) ; inside the mutex scope
3539 (values (hashset-insert container
(copy-ctype temp
))
3541 (unless foundp
; "use" the var binding if #+sb-xc-host
3542 #-sb-xc-host
; attach finalizer (outside the mutex scope)
3543 (let ((xset (member-type-xset result
))) ; in case XSET was copied
3546 (with-system-mutex (*xset-mutex
*)
3547 (xset-delete-stable-hashes xset
))))))
3549 ;; The actual member-type contains the XSET (with no FP zeroes),
3550 ;; and a list of unpaired zeroes.
3551 (if (not float-types
)
3552 (or member-type
*empty-type
*)
3553 (let ((types (if member-type
3554 (cons member-type float-types
)
3557 (make-union-type t types
)
3560 (defun member-type-size (type)
3561 (+ (length (member-type-fp-zeroes type
))
3562 (xset-count (member-type-xset type
))))
3564 (defun member-type-member-p (x type
)
3566 (and (member x
(member-type-fp-zeroes type
)) t
)
3567 (xset-member-p x
(member-type-xset type
))))
3569 (defun mapcar-member-type-members (function type
)
3570 (declare (function function
))
3571 (collect ((results))
3572 (map-xset (lambda (x)
3573 (results (funcall function x
)))
3574 (member-type-xset type
))
3575 (dolist (zero (member-type-fp-zeroes type
))
3576 (results (funcall function zero
)))
3579 (defun mapc-member-type-members (function type
)
3580 (declare (function function
))
3581 (map-xset function
(member-type-xset type
))
3582 (dolist (zero (member-type-fp-zeroes type
))
3583 (funcall function zero
)))
3585 (defun member-type-members (type)
3586 (append (member-type-fp-zeroes type
)
3587 (xset-members (member-type-xset type
))))
3589 (define-type-method (member :negate
) (type)
3590 (let ((xset (member-type-xset type
))
3591 (fp-zeroes (member-type-fp-zeroes type
)))
3593 ;; Hairy case, which needs to do a bit of float type
3594 ;; canonicalization.
3595 (apply #'type-intersection
3596 (if (xset-empty-p xset
)
3598 (make-negation-type (make-member-type xset nil
)))
3601 (let* ((opposite (sb-xc:- x
))
3602 (type (ctype-of opposite
)))
3605 (modified-numeric-type type
:low nil
:high nil
))
3606 (modified-numeric-type type
:low nil
:high
(list opposite
))
3607 (make-eql-type opposite
)
3608 (modified-numeric-type type
:low
(list opposite
) :high nil
))))
3611 (make-negation-type type
))))
3613 (define-type-method (member :unparse
) (flags type
)
3614 (cond ((eq type
(specifier-type 'null
)) 'null
) ; NULL type is EQ-comparable
3615 ((eq type
(specifier-type 'boolean
)) 'boolean
) ; so is BOOLEAN
3616 (t `(member ,@(member-type-members type
)))))
3618 (define-type-method (member :singleton-p
) (type)
3619 (if (eql 1 (member-type-size type
))
3620 (values t
(first (member-type-members type
)))
3623 (define-type-method (member :simple-subtypep
) (type1 type2
)
3624 (values (and (xset-subset-p (member-type-xset type1
)
3625 (member-type-xset type2
))
3626 (subsetp (member-type-fp-zeroes type1
)
3627 (member-type-fp-zeroes type2
)))
3630 (define-type-method (member :complex-subtypep-arg1
) (type1 type2
)
3632 (mapc-member-type-members
3634 (multiple-value-bind (ok surep
) (ctypep elt type2
)
3636 (return-from punt
(values nil nil
)))
3638 (return-from punt
(values nil t
)))))
3642 ;;; We punt if the odd type is enumerable and intersects with the
3643 ;;; MEMBER type. If not enumerable, then it is definitely not a
3644 ;;; subtype of the MEMBER type.
3645 (define-type-method (member :complex-subtypep-arg2
) (type1 type2
)
3646 (cond ((not (type-enumerable type1
)) (values nil t
))
3647 ((types-equal-or-intersect type1 type2
)
3648 (invoke-complex-subtypep-arg1-method type1 type2
))
3649 (t (values nil t
))))
3651 (define-type-method (member :simple-intersection2
) (type1 type2
)
3652 (make-member-type (xset-intersection (member-type-xset type1
)
3653 (member-type-xset type2
))
3654 (intersection (member-type-fp-zeroes type1
)
3655 (member-type-fp-zeroes type2
))))
3657 (define-type-method (member :complex-intersection2
) (type1 type2
)
3658 (let ((xset (alloc-xset))
3662 (mapc-member-type-members
3664 (multiple-value-bind (ok sure
) (ctypep member type1
)
3667 (if (or ok
(not sure
))
3668 (if (fp-zero-p member
)
3669 (pushnew member fp-zeroes
)
3670 (add-to-xset member xset
))
3671 (setf any-skipped t
))))
3674 (if (and (xset-empty-p xset
) (not fp-zeroes
))
3676 (make-member-type xset fp-zeroes
))))
3679 (type-intersection type1 member
))
3682 ;;; We don't need a :COMPLEX-UNION2, since the only interesting case is
3683 ;;; a union type, and the member/union interaction is handled by the
3684 ;;; union type method.
3685 (define-type-method (member :simple-union2
) (type1 type2
)
3686 (make-member-type (xset-union (member-type-xset type1
)
3687 (member-type-xset type2
))
3688 (union (member-type-fp-zeroes type1
)
3689 (member-type-fp-zeroes type2
))))
3691 (define-type-method (member :complex-
=) (type1 type2
)
3692 (if (type-enumerable type1
)
3693 (multiple-value-bind (val win
) (csubtypep type2 type1
)
3694 (if (or val
(not win
))
3699 (def-type-translator member
:list
(&rest members
)
3700 ;; "* may appear as an argument to a MEMBER type specifier, but it indicates the
3701 ;; literal symbol *, and does not represent an unspecified value."
3703 (let ((xset (alloc-xset)) fp-zeros other-reals characters
)
3704 ;; Calling REMOVE-DUPLICATES up front as used to be done is wasteful because the XSET can't
3705 ;; have dups in it. Elements that don't go in the XSET have to be de-duplicated.
3706 ;; There are at most 4 fp-zeros, so calling PUSHNEW is fine. For the rest, we can suppose
3707 ;; that DELETE-DUPLICATES is as good as it gets. (It could/should use a hash-table above
3708 ;; a cetain length input, but does not)
3711 (character (push m characters
))
3712 (real (if (fp-zero-p m
) (pushnew m fp-zeros
) (push m other-reals
)))
3713 (t (add-to-xset m xset
))))
3715 (make-member-type xset fp-zeros
)
3716 (character-set-type-from-characters characters
)
3717 (mapcar #'ctype-of-number
(delete-duplicates other-reals
))))
3719 (defun make-eql-type (elt)
3720 ;; Start by looking in the hash-table, there's no reason not to.
3721 ;; i.e. provided that ELT is one that should go in the hash-table, then the key
3722 ;; is not a DX instance of the type, unlike for most CTYPES.
3723 (or (let ((table *eql-type-cache
*))
3724 (with-system-mutex ((hash-table-lock table
)) (gethash elt table
)))
3725 ;; It would be less messy to just call the parser for MEMBER, but there's no way
3726 ;; to prevent it from consing. It always calls REMOVE-DUPLICATES on its input,
3727 ;; and further builds up fresh data lists for the constructor(s).
3730 ;; just checking an expectation of self-build here, no real reason to prohibit
3731 #+sb-xc-host
(bug "Unexpected singleton character type")
3732 (let* ((codepoint (sb-xc:char-code elt
))
3733 (pairs (list (cons codepoint codepoint
))))
3734 ;; PAIRS will get copied if needed, but not for the host
3735 #-sb-xc-host
(declare (dynamic-extent pairs
))
3736 (make-character-set-type pairs
)))
3738 (unless (fp-zero-p elt
)
3739 ;; we do see singleton fp zeros in self-build but not other floats
3740 #+sb-xc-host
(bug "Unexpected singleton REAL type")
3741 ;; This is a little redundant with CTYPE-OF-NUMBER,
3742 ;; but imho easier to understand.
3743 (multiple-value-bind (class format
)
3745 (float (values 'float
(float-format-name elt
)))
3748 (make-numeric-type :class class
:format format
:low elt
:high elt
)))))
3749 ;; The thing is definitely implemented as a MEMBER type. Just a question of
3750 ;; whether to put ELT in the XSET.
3751 (multiple-value-bind (xset fp-zeros
)
3752 (if (realp elt
) ; is a floating-point zero
3753 (values (load-time-value (alloc-xset) t
) ; an always-empty XSET
3755 (let ((xset (alloc-xset)))
3756 (add-to-xset elt xset
)
3758 (make-member-type xset fp-zeros
))))
3760 ;;;; intersection types
3762 ;;;; Until version 0.6.10.6, SBCL followed the original CMU CL approach
3763 ;;;; of punting on all AND types, not just the unreasonably complicated
3764 ;;;; ones. The change was motivated by trying to get the KEYWORD type
3765 ;;;; to behave sensibly:
3766 ;;;; ;; reasonable definition
3767 ;;;; (DEFTYPE KEYWORD () '(AND SYMBOL (SATISFIES KEYWORDP)))
3768 ;;;; ;; reasonable behavior
3769 ;;;; (AVER (SUBTYPEP 'KEYWORD 'SYMBOL))
3770 ;;;; Without understanding a little about the semantics of AND, we'd
3771 ;;;; get (SUBTYPEP 'KEYWORD 'SYMBOL)=>NIL,NIL and, for entirely
3772 ;;;; parallel reasons, (SUBTYPEP 'RATIO 'NUMBER)=>NIL,NIL. That's
3775 ;;;; We still follow the example of CMU CL to some extent, by punting
3776 ;;;; (to the opaque HAIRY-TYPE) on sufficiently complicated types
3779 (define-type-method (intersection :negate
) (type)
3781 (mapcar #'type-negation
(intersection-type-types type
))))
3783 ;;; A few intersection types have special names. The others just get
3784 ;;; mechanically unparsed.
3785 (define-type-method (intersection :unparse
) (flags type
)
3786 (or (cl-std-intersection-type-p type
)
3787 `(and ,@(type-unparse flags
(intersection-type-types type
)))))
3789 (define-type-method (intersection :singleton-p
) (type)
3790 (loop for constituent in
(intersection-type-types type
)
3792 (multiple-value-bind (single value
) (type-singleton-p constituent
)
3794 (return (values single value
))))
3795 finally
(return (values nil nil
))))
3797 ;;; shared machinery for type equality: true if every type in the set
3798 ;;; TYPES1 matches a type in the set TYPES2 and vice versa
3799 (defun type=-set
(types1 types2
)
3800 (flet ((type<=-set
(x y
)
3801 (declare (type list x y
))
3802 (every/type
(lambda (x y-element
)
3803 (any/type
#'type
= y-element x
))
3805 (and/type
(type<=-set types1 types2
)
3806 (type<=-set types2 types1
))))
3808 ;;; Two intersection types are equal if their subtypes are equal sets.
3810 ;;; FIXME: Might it be better to use
3811 ;;; (AND (SUBTYPEP X Y) (SUBTYPEP Y X))
3812 ;;; instead, since SUBTYPEP is the usual relationship that we care
3813 ;;; most about, so it would be good to leverage any ingenuity there
3814 ;;; in this more obscure method?
3816 ;;; Possibly yes, but then the SUBTYPEP methods would have to be
3817 ;;; rewritten not to use TYPE= (see the discussion around UNION
3819 (define-type-method (intersection :simple-
=) (type1 type2
)
3820 (type=-set
(intersection-type-types type1
)
3821 (intersection-type-types type2
)))
3823 (define-type-method (intersection :complex-
=) (type1 type2
)
3824 (let ((seen-uncertain nil
))
3825 (dolist (itype (intersection-type-types type2
)
3828 (invoke-complex-=-other-method type1 type2
)))
3829 (let ((trial-intersection (type-intersection2 type1 itype
)))
3830 (if (null trial-intersection
)
3831 (setq seen-uncertain
(type-might-contain-other-types-p itype
))
3832 ;; C != (Ai n Aj...) if (C n Ai) < C.
3834 ;; (CSUBTYPEP (AND C Ai) C) is T, T by construction.
3835 ;; We ask (SUBTYPEP C (AND C Ai)):
3837 ;; T , T : OK, continue -- C = (AND C Ai)
3838 ;; NIL, T : return early -- C > (AND C Ai)
3839 ;; NIL, NIL: don't know! If we get to the end, return NIL, NIL, but
3840 ;; give other types in the intersection a chance to return
3842 (multiple-value-bind (subtype certain?
)
3843 (csubtypep type1 trial-intersection
)
3845 ((not certain?
) (setq seen-uncertain t
))
3846 ((not subtype
) (return (values nil t
))))))))))
3848 (defun %intersection-complex-subtypep-arg1
(type1 type2
)
3849 (type= type1
(type-intersection type1 type2
)))
3851 (defun %intersection-simple-subtypep
(type1 type2
)
3852 (every/type
#'%intersection-complex-subtypep-arg1
3854 (intersection-type-types type2
)))
3856 (define-type-method (intersection :simple-subtypep
) (type1 type2
)
3857 (%intersection-simple-subtypep type1 type2
))
3859 (define-type-method (intersection :complex-subtypep-arg1
) (type1 type2
)
3860 (%intersection-complex-subtypep-arg1 type1 type2
))
3862 (defun %intersection-complex-subtypep-arg2
(type1 type2
)
3863 (every/type
#'csubtypep type1
(intersection-type-types type2
)))
3865 (define-type-method (intersection :complex-subtypep-arg2
) (type1 type2
)
3866 (%intersection-complex-subtypep-arg2 type1 type2
))
3868 ;;; FIXME: This will look eeriely familiar to readers of the UNION
3869 ;;; :SIMPLE-INTERSECTION2 :COMPLEX-INTERSECTION2 method. That's
3870 ;;; because it was generated by cut'n'paste methods. Given that
3871 ;;; intersections and unions have all sorts of symmetries known to
3872 ;;; mathematics, it shouldn't be beyond the ken of some programmers to
3873 ;;; reflect those symmetries in code in a way that ties them together
3874 ;;; more strongly than having two independent near-copies :-/
3875 (define-type-method (intersection :simple-union2
:complex-union2
)
3877 ;; Within this method, type2 is guaranteed to be an intersection
3879 (aver (intersection-type-p type2
))
3880 ;; Make sure to call only the applicable methods...
3881 (cond ((and (intersection-type-p type1
)
3882 (%intersection-simple-subtypep type1 type2
)) type2
)
3883 ((and (intersection-type-p type1
)
3884 (%intersection-simple-subtypep type2 type1
)) type1
)
3885 ((and (not (intersection-type-p type1
))
3886 (%intersection-complex-subtypep-arg2 type1 type2
))
3888 ((and (not (intersection-type-p type1
))
3889 (%intersection-complex-subtypep-arg1 type2 type1
))
3891 ;; KLUDGE: This special (and somewhat hairy) magic is required
3892 ;; to deal with the RATIONAL/INTEGER special case. The UNION
3893 ;; of (INTEGER * -1) and (AND (RATIONAL * -1/2) (NOT INTEGER))
3894 ;; should be (RATIONAL * -1/2) -- CSR, 2003-02-28
3895 ((and (csubtypep type2
(specifier-type 'ratio
))
3896 (numeric-type-p type1
)
3897 (csubtypep type1
(specifier-type 'integer
))
3902 :low
(if (null (numeric-type-low type1
))
3904 (list (1- (numeric-type-low type1
))))
3905 :high
(if (null (numeric-type-high type1
))
3907 (list (1+ (numeric-type-high type1
)))))))
3908 (let* ((intersected (intersection-type-types type2
))
3909 (remaining (remove (specifier-type '(not integer
))
3912 (and (not (equal intersected remaining
))
3913 (type-union type1
(%type-intersection remaining
)))))
3915 (let ((accumulator *universal-type
*))
3916 (do ((t2s (intersection-type-types type2
) (cdr t2s
)))
3917 ((null t2s
) accumulator
)
3918 (let ((union (type-union type1
(car t2s
))))
3919 (when (union-type-p union
)
3920 ;; we have to give up here -- there are all sorts of
3921 ;; ordering worries, but it's better than before.
3922 ;; Doing exactly the same as in the UNION
3923 ;; :SIMPLE/:COMPLEX-INTERSECTION2 method causes stack
3924 ;; overflow with the mutual recursion never bottoming
3926 (if (and (eq accumulator
*universal-type
*)
3928 ;; KLUDGE: if we get here, we have a partially
3929 ;; simplified result. While this isn't by any
3930 ;; means a universal simplification, including
3931 ;; this logic here means that we can get (OR
3932 ;; KEYWORD (NOT KEYWORD)) canonicalized to T.
3936 (type-intersection accumulator union
))))))))
3938 (def-type-translator and
:list
((:context context
) &rest type-specifiers
)
3939 ;; "* is not permitted as an argument to the AND type specifier."
3940 (%type-intersection
(mapcar (lambda (x) (specifier-type x context
'and
))
3945 (define-type-class union
3946 :enumerable
#'compound-type-enumerable
3947 :might-contain-other-types t
)
3949 (define-type-method (union :negate
) (type)
3950 (declare (type ctype type
))
3951 (%type-intersection
(mapcar #'type-negation
(union-type-types type
))))
3953 ;;; Unlike ARRAY-TYPE-DIMENSIONS this handles union types, which
3954 ;;; includes the type STRING.
3955 (defun ctype-array-dimensions (type)
3956 (labels ((process-compound-type (types)
3958 (dolist (type types
)
3959 (unless (or (hairy-type-p type
)
3960 (negation-type-p type
))
3961 (let ((current-dimensions (determine type
)))
3962 (cond ((eq current-dimensions
'*)
3963 (return-from ctype-array-dimensions
'*))
3965 (not (equal current-dimensions dimensions
)))
3966 (if (= (length dimensions
)
3967 (length current-dimensions
))
3969 (loop for dimension in dimensions
3970 for current-dimension in current-dimensions
3971 collect
(if (eql dimension current-dimension
)
3974 (return-from ctype-array-dimensions
'*)))
3977 (setf dimensions current-dimensions
))))))
3982 (array-type-dimensions type
))
3984 (process-compound-type (union-type-types type
)))
3986 (process-compound-type
3987 (mapcar #'ctype-of
(member-type-members type
))))
3989 (process-compound-type (intersection-type-types type
))))))
3992 (defun ctype-array-union-dimensions (type)
3993 (if (union-type-p type
)
3995 for type in
(union-type-types type
)
3996 for dim
= (ctype-array-dimensions type
)
4000 (pushnew dim dims
:test
#'equal
)
4001 finally
(return dims
))
4002 (list (ctype-array-dimensions type
))))
4004 (defun ctype-array-specialized-element-types (type)
4006 (labels ((process-compound-type (types)
4007 (loop for type in types
4008 unless
(or (hairy-type-p type
)
4009 (negation-type-p type
))
4010 do
(determine type
)))
4014 (when (eq (array-type-specialized-element-type type
) *wild-type
*)
4015 (return-from ctype-array-specialized-element-types
4017 (pushnew (array-type-specialized-element-type type
)
4018 types
:test
#'type
=))
4020 (process-compound-type (union-type-types type
)))
4022 (process-compound-type (intersection-type-types type
)))
4024 (process-compound-type
4025 (mapcar #'ctype-of
(member-type-members type
)))))))
4029 (defun ctype-array-any-specialization-p (type)
4030 (labels ((process-compound-type (types)
4031 (loop for type in types
4032 unless
(or (hairy-type-p type
)
4033 (negation-type-p type
))
4034 do
(determine type
)))
4038 (unless (eq (array-type-element-type type
) *wild-type
*)
4039 (return-from ctype-array-any-specialization-p t
)))
4041 (process-compound-type (union-type-types type
)))
4043 (process-compound-type (intersection-type-types type
))))))
4046 ;;; Union unparsing involves looking for certain important type atoms in our
4047 ;;; internal representation - a/k/a "interned types" - those which have a unique
4048 ;;; object that models them; and then deciding whether some conjunction of
4049 ;;; particular atoms unparses to a prettier symbolic type.
4050 (eval-when (:compile-toplevel
:load-toplevel
:execute
)
4051 (defparameter *special-union-types
*
4052 ;; This is order-sensitive. Prefer to recognize SEQUENCE
4053 ;; and extract 4 components (NULL,CONS,VECTOR,EXTENDED-SEQUENCE)
4054 ;; before considering LIST and extracting 2, etc.
4055 '(sequence list real float complex bignum
)))
4057 (defun union-unparse (flags types
)
4058 (declare (ignorable flags
))
4059 ;; This logic diverges between +/- sb-xc-host because the machinery
4060 ;; to parse types is obviously not usable here during make-host-1,
4061 ;; so the macro has to generate code that is lazier about parsing.
4062 (collect ((recognized))
4063 (let ((remainder (flatten-numeric-union-types types
)))
4065 ;; Try to recognize each special type in order.
4066 ;; Don't use SUBTYPEP here; compare atoms instead. We're not trying
4067 ;; to answer complicated questions - only see whether the argument TYPE
4068 ;; contains (at least) each of the exact same things in SPECIAL.
4069 (dolist (special *special-union-types
*)
4070 (let ((parts (flatten-numeric-union-types (specifier-type special
))))
4071 (when (every (lambda (part) (memq part remainder
)) parts
)
4072 ;; Remove the parts from the remainder
4073 (dolist (part parts
) (setq remainder
(delq1 part remainder
)))
4074 (recognized special
)))) ; add to the output
4078 (let* ((constituent-types
4079 (mapcar (lambda (type-specifier)
4080 (flatten-numeric-union-types (specifier-type type-specifier
)))
4081 *special-union-types
*))
4082 ;; Get the set of atoms that we need to pick out
4083 (atoms (remove-duplicates (apply #'append constituent-types
))))
4084 (labels ((atom->bit
(atom) (ash 1 (position atom atoms
)))
4085 (compute-mask (parts) (apply #'+ (mapcar #'atom-
>bit parts
))))
4087 (dolist (part remainder
)
4090 (cond ,@(mapcar (lambda (atom)
4091 `((eq part
,atom
) ,(atom->bit atom
)))
4094 ;; Now we have a bitmask of all the interesting type atoms in the
4095 ;; compound type. Try to match sets of bits, and remember it is
4096 ;; possible to match more than one set,
4097 ;; e.g. (OR STRING FLOAT BIGNUM) matches 3 pairs of bits.
4098 ,@(mapcar (lambda (name parts
&aux
(mask (compute-mask parts
)))
4099 `(when (= (logand bits
,mask
) ,mask
) ; is all of these
4100 (setq bits
(logand bits
,(lognot mask
))) ; Subtract the bits
4101 ,@(mapcar (lambda (atom)
4102 `(setq remainder
(delq1 ,atom remainder
)))
4104 (recognized ',name
))) ; add to the output
4105 *special-union-types
* constituent-types
))))))
4107 ;; See if we can pair any two constituent types that resolve to
4108 ;; ({STRING|SIMPLE-STRING|non-SIMPLE-STRING} n).
4109 ;; Repeat until there are no more pairs. This is a kludge.
4111 (loop for tail on remainder
4112 do
(let* ((x (car tail
))
4114 (and (array-type-p x
) ; If X is a CHARACTER vector
4115 (eq (array-type-element-type x
) (specifier-type 'character
))
4116 (singleton-p (array-type-dimensions x
))
4117 ;; And can be matched with a BASE-CHAR vector
4118 (member-if (lambda (y)
4119 (and (array-type-p y
)
4120 (eq (array-type-element-type y
)
4121 (specifier-type 'base-char
))
4122 (eq (array-type-complexp y
)
4123 (array-type-complexp x
))
4124 (equal (array-type-dimensions y
)
4125 (array-type-dimensions x
))))
4127 (when peer
; then together they comprise a subtype of STRING
4128 (let* ((dim (car (array-type-dimensions x
)))
4130 (if (array-type-complexp x
)
4131 (if (eq dim
'*) 'string
`(string ,dim
))
4132 (if (eq dim
'*) 'simple-string
`(simple-string ,dim
)))))
4133 (recognized (if (eq (array-type-complexp x
) 't
)
4134 `(and ,string-type
(not simple-array
))
4136 (rplaca tail nil
) ; We'll delete these list elements later
4137 (rplaca peer nil
))))
4142 (loop for x in remainder
4143 when
(and (numeric-type-p x
)
4144 (eq (numeric-type-complexp x
) :real
))
4145 do
(case (numeric-type-class x
)
4151 (case (numeric-type-format x
)
4155 (setf single x
))))))
4156 (when (and double single
)
4157 (let ((low (numeric-type-low single
))
4158 (high (numeric-type-high single
)))
4160 (and (not (float-infinity-or-nan-p x
))
4163 ;; equalp doesn't work on floats in sb-xc-host
4172 (when (and (match low
(numeric-type-low double
))
4173 (match high
(numeric-type-high double
)))
4174 (setf remainder
(delq1 double
(delq1 single remainder
)))
4175 (cond ((or (and rational
4176 (match low
(numeric-type-low rational
))
4177 (match high
(numeric-type-high rational
)))
4178 (and (setf rational integer
)
4179 (numberp (numeric-type-low rational
))
4180 (eql (numeric-type-low rational
)
4181 (numeric-type-high rational
)) ;; (rational 1 1) is an integer.
4182 (match low
(numeric-type-low rational
))
4183 (match high
(numeric-type-high rational
))))
4184 (setf remainder
(delq1 rational remainder
))
4185 (let ((low (numeric-type-low rational
))
4186 (high (numeric-type-high rational
)))
4187 (recognized (cond (high
4188 `(real ,(or low
'*) ,high
))
4192 (recognized (cond (high
4193 `(float ,(or low
'*) ,high
))
4195 `(float ,low
)))))))))))
4196 (let ((list (nconc (recognized)
4197 (type-unparse flags
(delete nil remainder
)))))
4198 (if (cdr list
) `(or ,@list
) (car list
))))))
4200 (define-type-method (union :unparse
) (flags type
)
4201 (union-unparse flags
(union-type-types type
)))
4203 ;;; Two union types are equal if they are each subtypes of each
4204 ;;; other. We need to be this clever because our complex subtypep
4205 ;;; methods are now more accurate; we don't get infinite recursion
4206 ;;; because the simple-subtypep method delegates to complex-subtypep
4207 ;;; of the individual types of type1. - CSR, 2002-04-09
4209 ;;; Previous comment, now obsolete, but worth keeping around because
4210 ;;; it is true, though too strong a condition:
4212 ;;; Two union types are equal if their subtypes are equal sets.
4213 (define-type-method (union :simple-
=) (type1 type2
)
4214 (multiple-value-bind (subtype certain?
)
4215 (csubtypep type1 type2
)
4217 (csubtypep type2 type1
)
4218 ;; we might as well become as certain as possible.
4221 (multiple-value-bind (subtype certain?
)
4222 (csubtypep type2 type1
)
4223 (values nil
(and (not subtype
) certain?
)))))))
4225 (define-type-method (union :complex-
=) (type1 type2
)
4226 (declare (ignore type1
))
4227 (if (some #'type-might-contain-other-types-p
4228 (union-type-types type2
))
4232 ;;; Similarly, a union type is a subtype of another if and only if
4233 ;;; every element of TYPE1 is a subtype of TYPE2.
4234 (defun union-simple-subtypep (type1 type2
)
4235 (every/type
(swapped-args-fun #'union-complex-subtypep-arg2
)
4237 (union-type-types type1
)))
4239 (define-type-method (union :simple-subtypep
) (type1 type2
)
4240 (union-simple-subtypep type1 type2
))
4242 (defun union-complex-subtypep-arg1 (type1 type2
)
4243 (every/type
(swapped-args-fun #'csubtypep
)
4245 (union-type-types type1
)))
4247 (define-type-method (union :complex-subtypep-arg1
) (type1 type2
)
4248 (union-complex-subtypep-arg1 type1 type2
))
4250 (defun union-complex-subtypep-arg2 (type1 type2
)
4251 ;; At this stage, we know that type2 is a union type and type1
4252 ;; isn't. We might as well check this, though:
4253 (aver (union-type-p type2
))
4254 (aver (not (union-type-p type1
)))
4255 ;; was: (any/type #'csubtypep type1 (union-type-types type2)), which
4256 ;; turns out to be too restrictive, causing bug 91.
4258 ;; the following reimplementation might look dodgy. It is dodgy. It
4259 ;; depends on the union :complex-= method not doing very much work
4260 ;; -- certainly, not using subtypep. Reasoning:
4262 ;; A is a subset of (B1 u B2)
4263 ;; <=> A n (B1 u B2) = A
4264 ;; <=> (A n B1) u (A n B2) = A
4266 ;; But, we have to be careful not to delegate this type= to
4267 ;; something that could invoke subtypep, which might get us back
4268 ;; here -> stack explosion. We therefore ensure that the second type
4269 ;; (which is the one that's dispatched on) is either a union type
4270 ;; (where we've ensured that the complex-= method will not call
4271 ;; subtypep) or something with no union types involved, in which
4272 ;; case we'll never come back here.
4274 ;; If we don't do this, then e.g.
4275 ;; (SUBTYPEP '(MEMBER 3) '(OR (SATISFIES FOO) (SATISFIES BAR)))
4276 ;; would loop infinitely, as the member :complex-= method is
4277 ;; implemented in terms of subtypep.
4279 ;; Ouch. - CSR, 2002-04-10
4280 (cond ((fun-designator-type-p type1
)
4281 (type= type2
(specifier-type 'function-designator
)))
4283 (multiple-value-bind (sub-value sub-certain?
)
4286 ;; Upgrading rules do not work with intersections
4287 (if (and (array-type-p type1
)
4288 (not (contains-unknown-type-p (array-type-element-type type1
))))
4290 (if (array-type-p x
)
4291 (array-intersection type1 x t
)
4292 (type-intersection type1 x
)))
4293 (union-type-types type2
))
4295 (type-intersection type1 x
))
4296 (union-type-types type2
)))))
4298 (values sub-value sub-certain?
)
4299 ;; The ANY/TYPE expression above is a sufficient condition for
4300 ;; subsetness, but not a necessary one, so we might get a more
4301 ;; certain answer by this CALL-NEXT-METHOD-ish step when the
4302 ;; ANY/TYPE expression is uncertain.
4303 (invoke-complex-subtypep-arg1-method type1 type2
))))))
4305 (define-type-method (union :complex-subtypep-arg2
) (type1 type2
)
4306 (union-complex-subtypep-arg2 type1 type2
))
4308 (define-type-method (union :simple-intersection2
:complex-intersection2
)
4310 ;; The CSUBTYPEP clauses here let us simplify e.g.
4311 ;; (TYPE-INTERSECTION2 (SPECIFIER-TYPE 'LIST)
4312 ;; (SPECIFIER-TYPE '(OR LIST VECTOR)))
4313 ;; (where LIST is (OR CONS NULL)).
4315 ;; The tests are more or less (CSUBTYPEP TYPE1 TYPE2) and vice
4316 ;; versa, but it's important that we pre-expand them into
4317 ;; specialized operations on individual elements of
4318 ;; UNION-TYPE-TYPES, instead of using the ordinary call to
4319 ;; CSUBTYPEP, in order to avoid possibly invoking any methods which
4320 ;; might in turn invoke (TYPE-INTERSECTION2 TYPE1 TYPE2) and thus
4321 ;; cause infinite recursion.
4323 ;; Within this method, type2 is guaranteed to be a union type:
4324 (aver (union-type-p type2
))
4325 ;; Make sure to call only the applicable methods...
4326 (cond ((and (union-type-p type1
)
4327 (union-simple-subtypep type1 type2
)) type1
)
4328 ((and (union-type-p type1
)
4329 (union-simple-subtypep type2 type1
)) type2
)
4330 ((and (not (union-type-p type1
))
4331 (union-complex-subtypep-arg2 type1 type2
))
4333 ((and (not (union-type-p type1
))
4334 (union-complex-subtypep-arg1 type2 type1
))
4337 ;; KLUDGE: This code accumulates a sequence of TYPE-UNION2
4338 ;; operations in a particular order, and gives up if any of
4339 ;; the sub-unions turn out not to be simple. In other cases
4340 ;; ca. sbcl-0.6.11.15, that approach to taking a union was a
4341 ;; bad idea, since it can overlook simplifications which
4342 ;; might occur if the terms were accumulated in a different
4343 ;; order. It's possible that that will be a problem here too.
4344 ;; However, I can't think of a good example to demonstrate
4345 ;; it, and without an example to demonstrate it I can't write
4346 ;; test cases, and without test cases I don't want to
4347 ;; complicate the code to address what's still a hypothetical
4348 ;; problem. So I punted. -- WHN 2001-03-20
4349 (let ((accumulator *empty-type
*))
4350 (dolist (t2 (union-type-types type2
) accumulator
)
4352 (type-union accumulator
4353 (type-intersection type1 t2
))))))))
4355 (def-type-translator or
:list
((:context context
) &rest type-specifiers
)
4356 ;; "* is not permitted as an argument to the OR type specifier."
4357 (let ((type (%type-union
(mapcar (lambda (x) (specifier-type x context
'or
))
4359 (if (union-type-p type
)
4360 (sb-kernel::simplify-array-unions type
)
4364 ;;;; ALIEN-TYPE types
4366 (define-type-class alien
:enumerable nil
:might-contain-other-types nil
)
4368 (define-type-method (alien :negate
) (type) (make-negation-type type
))
4370 (define-type-method (alien :unparse
) (flags type
)
4371 `(alien ,(unparse-alien-type (alien-type-type-alien-type type
))))
4373 (define-type-method (alien :simple-subtypep
) (type1 type2
)
4374 (values (alien-subtype-p (alien-type-type-alien-type type1
)
4375 (alien-type-type-alien-type type2
))
4378 (define-type-method (alien :simple-
=) (type1 type2
)
4379 (let ((alien-type-1 (alien-type-type-alien-type type1
))
4380 (alien-type-2 (alien-type-type-alien-type type2
)))
4381 (values (or (eq alien-type-1 alien-type-2
)
4382 (alien-type-= alien-type-1 alien-type-2
))
4385 (def-type-translator alien
(&optional
(alien-type nil
))
4386 (typecase alien-type
4388 (make-alien-type-type))
4390 (make-alien-type-type alien-type
))
4392 (make-alien-type-type (parse-alien-type alien-type
(make-null-lexenv))))))
4394 (defun make-alien-type-type (&optional alien-type
)
4396 (let ((lisp-rep-type (compute-lisp-rep-type alien-type
)))
4398 (single-value-specifier-type lisp-rep-type
)
4399 (%make-alien-type-type alien-type
)))
4405 (def-type-translator cons
((:context context
)
4406 &optional
(car-type-spec '*) (cdr-type-spec '*))
4407 (let ((car-type (single-value-specifier-type car-type-spec context
))
4408 (cdr-type (single-value-specifier-type cdr-type-spec context
)))
4409 (make-cons-type car-type cdr-type
)))
4411 (define-type-class cons
:enumerable nil
:might-contain-other-types nil
)
4413 (defun make-cons-type (car-type cdr-type
)
4414 (aver (not (or (eq car-type
*wild-type
*)
4415 (eq cdr-type
*wild-type
*))))
4416 (cond ((or (eq car-type
*empty-type
*)
4417 (eq cdr-type
*empty-type
*))
4419 ;; Bypass the hashset for plain CONS
4420 ((and (eq car-type
*universal-type
*) (eq cdr-type
*universal-type
*))
4421 (inline-cache-ctype (!alloc-cons-type
(make-ctype-bits 'cons
)
4422 *universal-type
* *universal-type
*)
4425 (new-ctype cons-type
4426 (logand (logior (type-%bits car-type
) (type-%bits cdr-type
))
4428 car-type cdr-type
))))
4430 ;;; Return TYPE converted to canonical form for a situation where the
4431 ;;; "type" '* (which SBCL still represents as a type even though ANSI
4432 ;;; CL defines it as a related but different kind of placeholder) is
4433 ;;; equivalent to type T.
4434 (defun type-*-to-t
(type)
4435 (if (type= type
*wild-type
*)
4439 (define-type-method (cons :negate
) (type)
4440 (if (and (eq (cons-type-car-type type
) *universal-type
*)
4441 (eq (cons-type-cdr-type type
) *universal-type
*))
4442 (make-negation-type type
)
4444 (make-negation-type (specifier-type 'cons
))
4446 ((and (not (eq (cons-type-car-type type
) *universal-type
*))
4447 (not (eq (cons-type-cdr-type type
) *universal-type
*)))
4450 (type-negation (cons-type-car-type type
))
4454 (type-negation (cons-type-cdr-type type
)))))
4455 ((not (eq (cons-type-car-type type
) *universal-type
*))
4457 (type-negation (cons-type-car-type type
))
4459 ((not (eq (cons-type-cdr-type type
) *universal-type
*))
4462 (type-negation (cons-type-cdr-type type
))))
4463 (t (bug "Weird CONS type ~S" type
))))))
4465 (define-type-method (cons :unparse
) (flags type
)
4466 (if (eq type
(specifier-type 'cons
))
4468 `(cons ,(type-unparse flags
(cons-type-car-type type
))
4469 ,(type-unparse flags
(cons-type-cdr-type type
)))))
4471 (define-type-method (cons :simple-
=) (type1 type2
)
4472 (declare (type cons-type type1 type2
))
4473 (multiple-value-bind (car-match car-win
)
4474 (type= (cons-type-car-type type1
) (cons-type-car-type type2
))
4475 (multiple-value-bind (cdr-match cdr-win
)
4476 (type= (cons-type-cdr-type type1
) (cons-type-cdr-type type2
))
4477 (cond ((and car-match cdr-match
)
4478 (aver (and car-win cdr-win
))
4482 ;; FIXME: Ideally we would like to detect and handle
4483 ;; (CONS UNKNOWN INTEGER) (CONS UNKNOWN SYMBOL) => NIL, T
4484 ;; but just returning a secondary true on (and car-win cdr-win)
4485 ;; unfortunately breaks other things. --NS 2006-08-16
4486 (and (or (and (not car-match
) car-win
)
4487 (and (not cdr-match
) cdr-win
))
4488 (not (and (cons-type-might-be-empty-type type1
)
4489 (cons-type-might-be-empty-type type2
))))))))))
4491 (define-type-method (cons :simple-subtypep
) (type1 type2
)
4492 (declare (type cons-type type1 type2
))
4493 (multiple-value-bind (val-car win-car
)
4494 (csubtypep (cons-type-car-type type1
) (cons-type-car-type type2
))
4495 (multiple-value-bind (val-cdr win-cdr
)
4496 (csubtypep (cons-type-cdr-type type1
) (cons-type-cdr-type type2
))
4497 (if (and val-car val-cdr
)
4498 (values t
(and win-car win-cdr
))
4499 (values nil
(or (and (not val-car
) win-car
)
4500 (and (not val-cdr
) win-cdr
)))))))
4502 ;;; Give up if a precise type is not possible, to avoid returning
4503 ;;; overly general types.
4504 (define-type-method (cons :simple-union2
) (type1 type2
)
4505 (declare (type cons-type type1 type2
))
4506 (let ((car-type1 (cons-type-car-type type1
))
4507 (car-type2 (cons-type-car-type type2
))
4508 (cdr-type1 (cons-type-cdr-type type1
))
4509 (cdr-type2 (cons-type-cdr-type type2
))
4511 ;; UGH. -- CSR, 2003-02-24
4512 (macrolet ((frob-car (car1 car2 cdr1 cdr2
&optional not1
)
4513 `(let ((intersection (type-intersection ,car2
4514 ,(or not1
`(type-negation ,car1
)))))
4515 (unless (type= intersection
,car2
)
4517 (make-cons-type ,car1
(type-union ,cdr1
,cdr2
))
4518 (make-cons-type intersection
,cdr2
))))))
4519 (cond ((type= car-type1 car-type2
)
4520 (make-cons-type car-type1
4521 (type-union cdr-type1 cdr-type2
)))
4522 ((type= cdr-type1 cdr-type2
)
4523 (make-cons-type (type-union car-type1 car-type2
)
4525 ;; (or (cons A1 D1) (cons A2 D2))
4527 ;; if A1 is a subtype of A2, this is equivalent to
4529 ;; (or (cons A1 (or D1 D2)) (cons (and A2 (not A1)) D2))
4530 ((csubtypep car-type1 car-type2
)
4531 (frob-car car-type1 car-type2 cdr-type1 cdr-type2
))
4532 ((csubtypep car-type2 car-type1
)
4533 (frob-car car-type2 car-type1 cdr-type2 cdr-type1
))
4536 ;; (or (cons A1 D1) (cons A2 D2))
4540 ;; (or (cons (and A1 A2) (or D1 D2))
4541 ;; (cons (and A1 (not A2)) D1)
4542 ;; (cons (and (not A1) A2) D2))
4544 ;; (or (cons (integer 0 8) (integer 5 15))
4545 ;; (cons (integer 3 15) (integer 4 14))
4549 ;; (or (cons (integer 3 8) (integer 4 15))
4550 ;; (cons (integer 0 2) (integer 5 15))
4551 ;; (cons (integer 9 15) (integer 4 14))
4553 ;; if A1 and A2 are disjoint no further simplification is
4554 ;; possible. However, if they are not disjoint, and we
4555 ;; can tell that they are not disjoint, we should be able
4556 ;; to break the type up into smaller pieces.
4557 ((not (eql (setf car-intersection
(type-intersection car-type1 car-type2
))
4559 (let ((cdr-union (type-union cdr-type1 cdr-type2
))
4560 (car-not1 (type-negation car-type1
))
4561 (car-not2 (type-negation car-type2
)))
4563 (make-cons-type car-intersection cdr-union
)
4564 (make-cons-type (type-intersection car-type1 car-not2
) cdr-type1
)
4565 (make-cons-type (type-intersection car-not1 car-type2
) cdr-type2
))))
4566 ;; Don't put these in -- consider the effect of taking the
4567 ;; union of (CONS (INTEGER 0 2) (INTEGER 5 7)) and
4568 ;; (CONS (INTEGER 0 3) (INTEGER 5 6)).
4570 ((csubtypep cdr-type1 cdr-type2
)
4571 (frob-cdr car-type1 car-type2 cdr-type1 cdr-type2
))
4573 ((csubtypep cdr-type2 cdr-type1
)
4574 (frob-cdr car-type2 car-type1 cdr-type2 cdr-type1
))))))
4576 (define-type-method (cons :simple-intersection2
) (type1 type2
)
4577 (declare (type cons-type type1 type2
))
4578 (let ((car-int2 (type-intersection2 (cons-type-car-type type1
)
4579 (cons-type-car-type type2
)))
4580 (cdr-int2 (type-intersection2 (cons-type-cdr-type type1
)
4581 (cons-type-cdr-type type2
))))
4583 ((and car-int2 cdr-int2
) (make-cons-type car-int2 cdr-int2
))
4584 (car-int2 (make-cons-type car-int2
4586 (cons-type-cdr-type type1
)
4587 (cons-type-cdr-type type2
))))
4588 (cdr-int2 (make-cons-type
4589 (type-intersection (cons-type-car-type type1
)
4590 (cons-type-car-type type2
))
4593 (!define-superclasses cons
((cons)) !cold-init-forms
)
4595 ;;;; CHARACTER-SET types
4598 ;; 1. (SPECIFIER-TYPE '(CHARACTER-SET ((20 . 19)))) stores pairs exactly as
4599 ;; given, and unparses to the rather bogus #<CHARACTER-SET-TYPE (MEMBER)>
4600 ;; 2. (SPECIFIER-TYPE '(CHARACTER-SET ((20 . 20) (15 . 15)))) fails
4601 ;; because of the pre-sorting requirement.
4602 ;; But since this is not standard syntax I don't think we can ever see those
4603 ;; specifiers unless from an unparse of a valid internal representation.
4604 (def-type-translator character-set
4605 (&optional
(pairs `((0 .
,(1- char-code-limit
)))))
4606 (make-character-set-type pairs
))
4608 (define-type-method (character-set :negate
) (type)
4609 (let ((pairs (character-set-type-pairs type
)))
4610 (if (and (= (length pairs
) 1)
4612 (= (cdar pairs
) (1- char-code-limit
)))
4613 (make-negation-type type
)
4614 (let ((not-character
4616 (make-character-set-type
4617 `((0 .
,(1- char-code-limit
)))))))
4620 (make-character-set-type
4622 (when (> (caar pairs
) 0)
4623 (push (cons 0 (1- (caar pairs
))) not-pairs
))
4624 (do* ((tail pairs
(cdr tail
))
4625 (high1 (cdar tail
) (cdar tail
))
4626 (low2 (caadr tail
) (caadr tail
)))
4628 (when (< (cdar tail
) (1- char-code-limit
))
4629 (push (cons (1+ (cdar tail
))
4630 (1- char-code-limit
))
4632 (nreverse not-pairs
))
4633 (push (cons (1+ high1
) (1- low2
)) not-pairs
)))))))))
4635 (define-type-method (character-set :unparse
) (flags type
)
4637 ;; TODO: can we improve unparsing of (OR STANDARD-CHAR (MEMBER #\Tab))
4638 ;; to restore it back into itself rather than
4639 ;; #<CHARACTER-SET-TYPE (CHARACTER-SET ((9 . 10) (32 . 126)))> ?
4640 ;; Probably need to take TYPE-DIFFERENCE of TYPE with each known
4641 ;; character-set type to see if any result is simpler.
4642 ((eq type
(specifier-type 'character
)) 'character
)
4643 ((eq type
(specifier-type 'base-char
)) 'base-char
)
4644 ((eq type
(specifier-type 'extended-char
)) 'extended-char
)
4645 ((eq type
(specifier-type 'standard-char
)) 'standard-char
)
4647 ;; Unparse into either MEMBER or CHARACTER-SET. We use MEMBER if there
4648 ;; are at most as many characters as there are character code ranges.
4649 ;; (basically saying to use MEMBER if each range is one character)
4650 (let* ((pairs (character-set-type-pairs type
))
4651 (count (length pairs
))
4652 (chars (loop named outer
4653 for
(low . high
) in pairs
4654 nconc
(loop for code from low upto high
4655 collect
(code-char code
)
4656 when
(minusp (decf count
))
4657 do
(return-from outer t
)))))
4659 `(character-set ,pairs
)
4660 `(member ,@chars
))))))
4662 (define-type-method (character-set :singleton-p
) (type)
4663 (let* ((pairs (character-set-type-pairs type
))
4664 (pair (first pairs
)))
4665 (if (and (typep pairs
'(cons t null
))
4666 (eql (car pair
) (cdr pair
)))
4667 (values t
(code-char (car pair
)))
4670 (define-type-method (character-set :simple-subtypep
) (type1 type2
)
4672 (dolist (pair (character-set-type-pairs type1
) t
)
4673 (unless (position pair
(character-set-type-pairs type2
)
4674 :test
(lambda (x y
) (and (>= (car x
) (car y
))
4675 (<= (cdr x
) (cdr y
)))))
4679 (define-type-method (character-set :simple-union2
) (type1 type2
)
4680 ;; KLUDGE: the canonizing in the MAKE-CHARACTER-SET-TYPE function
4681 ;; actually does the union for us. It might be a little fragile to
4683 (make-character-set-type
4685 (copy-alist (character-set-type-pairs type1
))
4686 (copy-alist (character-set-type-pairs type2
))
4689 (define-type-method (character-set :simple-intersection2
) (type1 type2
)
4690 ;; KLUDGE: brute force.
4693 (dolist (pair1 (character-set-type-pairs type1
)
4694 (make-character-set-type
4695 (sort pairs
#'< :key
#'car
)))
4696 (dolist (pair2 (character-set-type-pairs type2
))
4698 ((<= (car pair1
) (car pair2
) (cdr pair1
))
4699 (push (cons (car pair2
) (min (cdr pair1
) (cdr pair2
))) pairs
))
4700 ((<= (car pair2
) (car pair1
) (cdr pair2
))
4701 (push (cons (car pair1
) (min (cdr pair1
) (cdr pair2
))) pairs
))))))
4703 (make-character-set-type
4704 (intersect-type-pairs
4705 (character-set-type-pairs type1
)
4706 (character-set-type-pairs type2
))))
4709 ;;; Intersect two ordered lists of pairs
4710 ;;; Each list is of the form ((start1 . end1) ... (startn . endn)),
4711 ;;; where start1 <= end1 < start2 <= end2 < ... < startn <= endn.
4712 ;;; Each pair represents the integer interval start..end.
4714 (defun intersect-type-pairs (alist1 alist2
)
4715 (if (and alist1 alist2
)
4717 (pair1 (pop alist1
))
4718 (pair2 (pop alist2
)))
4720 (when (> (car pair1
) (car pair2
))
4721 (rotatef pair1 pair2
)
4722 (rotatef alist1 alist2
))
4723 (let ((pair1-cdr (cdr pair1
)))
4725 ((> (car pair2
) pair1-cdr
)
4726 ;; No over lap -- discard pair1
4727 (unless alist1
(return))
4728 (setq pair1
(pop alist1
)))
4729 ((<= (cdr pair2
) pair1-cdr
)
4730 (push (cons (car pair2
) (cdr pair2
)) res
)
4732 ((= (cdr pair2
) pair1-cdr
)
4733 (unless alist1
(return))
4734 (unless alist2
(return))
4735 (setq pair1
(pop alist1
)
4736 pair2
(pop alist2
)))
4737 (t ;; (< (cdr pair2) pair1-cdr)
4738 (unless alist2
(return))
4739 (setq pair1
(cons (1+ (cdr pair2
)) pair1-cdr
))
4740 (setq pair2
(pop alist2
)))))
4741 (t ;; (> (cdr pair2) (cdr pair1))
4742 (push (cons (car pair2
) pair1-cdr
) res
)
4743 (unless alist1
(return))
4744 (setq pair2
(cons (1+ pair1-cdr
) (cdr pair2
)))
4745 (setq pair1
(pop alist1
))))))
4750 ;;; Return the type that describes all objects that are in X but not
4752 (defun type-difference (x y
)
4753 (type-intersection x
(type-negation y
)))
4755 (def-type-translator array
((:context context
)
4756 &optional
(element-type '*)
4758 (let ((eltype (if (eq element-type
'*)
4760 (specifier-type element-type context
))))
4761 (make-array-type (canonical-array-dimensions dimensions
)
4763 :element-type eltype
4764 :specialized-element-type
(%upgraded-array-element-type
4767 (def-type-translator simple-array
((:context context
)
4768 &optional
(element-type '*)
4770 (let ((eltype (if (eq element-type
'*)
4772 (specifier-type element-type context
))))
4773 (make-array-type (canonical-array-dimensions dimensions
)
4775 :element-type eltype
4776 :specialized-element-type
(%upgraded-array-element-type
4779 ;;;; SIMD-PACK types
4782 (defmacro parsed-simd-pack-element-type
(index)
4783 ;; For make-host-1, delay parsing until after 'deftypes-for-target' is loaded,
4784 ;; as it contains the needed definitions for SIGNED-BYTE and UNSIGNED-BYTE.
4785 ;; make-host-2 can splice in a constant vector.
4786 #+sb-xc-host
`(specifier-type (aref +simd-pack-element-types
+ ,index
))
4787 #-sb-xc-host
`(aref ,(coerce (loop for x across
+simd-pack-element-types
+
4788 collect
(specifier-type x
))
4794 ;;; FIXME: the pretty-print of this error message is just ghastly. How about:
4795 ;;; "must be a subtype of ({SIGNED-BYTE|UNSIGNED-BYTE} {8|16|32|64}) or {SINGLE|DOUBLE}-FLOAT"
4796 ;;; Users sophisticated enough to code with simd-packs will understand what it means.
4797 (defun simd-type-parser-helper (element-type-spec type-name ctor
)
4798 (when (eq element-type-spec
'*)
4799 (return-from simd-type-parser-helper
(funcall ctor
+simd-pack-wild
+)))
4800 (let ((element-type (single-value-specifier-type element-type-spec
)))
4801 (when (eq element-type
*empty-type
*)
4802 (return-from simd-type-parser-helper
*empty-type
*))
4803 (dotimes (i (length +simd-pack-element-types
+)
4804 (error "~S element type must be a subtype of ~
4805 ~{~/sb-impl:print-type-specifier/~#[~;, or ~
4807 type-name
(coerce +simd-pack-element-types
+ 'list
)))
4808 (when (csubtypep element-type
(parsed-simd-pack-element-type i
))
4809 (return (funcall ctor
(ash 1 i
)))))))
4811 (defun simd-type-unparser-helper (base-type mask
)
4812 (cond ((= mask
+simd-pack-wild
+) base-type
)
4813 ((= (logcount mask
) 1)
4814 `(,base-type
,(elt +simd-pack-element-types
+ (sb-vm::simd-pack-mask-
>tag mask
))))
4816 `(or ,@(loop for et across
+simd-pack-element-types
+ for i from
0
4817 when
(logbitp i mask
)
4818 collect
`(,base-type
,et
)))))))
4822 (define-type-class simd-pack
:enumerable nil
:might-contain-other-types nil
)
4824 ;; Though this involves a recursive call to parser, parsing context need not
4825 ;; be passed down, because an unknown-type condition is an immediate failure.
4826 (def-type-translator simd-pack
(&optional
(element-type-spec '*))
4827 (simd-type-parser-helper element-type-spec
'simd-pack
#'%make-simd-pack-type
))
4829 (define-type-method (simd-pack :negate
) (type)
4830 (let ((not-pack (make-negation-type (specifier-type 'simd-pack
)))
4831 (mask (logxor (simd-pack-type-tag-mask type
) +simd-pack-wild
+)))
4834 (type-union not-pack
(%make-simd-pack-type mask
)))))
4836 (define-type-method (simd-pack :unparse
) (flags type
)
4837 (simd-type-unparser-helper 'simd-pack
(simd-pack-type-tag-mask type
)))
4839 (define-type-method (simd-pack :simple-subtypep
) (type1 type2
)
4840 (declare (type simd-pack-type type1 type2
))
4841 (values (zerop (logandc2 (simd-pack-type-tag-mask type1
)
4842 (simd-pack-type-tag-mask type2
)))
4845 (define-type-method (simd-pack :simple-union2
) (type1 type2
)
4846 (declare (type simd-pack-type type1 type2
))
4847 (%make-simd-pack-type
(logior (simd-pack-type-tag-mask type1
)
4848 (simd-pack-type-tag-mask type2
))))
4850 (define-type-method (simd-pack :simple-intersection2
) (type1 type2
)
4851 (declare (type simd-pack-type type1 type2
))
4852 (let ((intersection (logand (simd-pack-type-tag-mask type1
)
4853 (simd-pack-type-tag-mask type2
))))
4854 (if (eql intersection
0) *empty-type
* (%make-simd-pack-type intersection
))))
4856 (!define-superclasses simd-pack
((simd-pack)) !cold-init-forms
))
4860 (define-type-class simd-pack-256
:enumerable nil
:might-contain-other-types nil
)
4862 ;; Though this involves a recursive call to parser, parsing context need not
4863 ;; be passed down, because an unknown-type condition is an immediate failure.
4864 (def-type-translator simd-pack-256
(&optional
(element-type-spec '*))
4865 (simd-type-parser-helper element-type-spec
'simd-pack-256
#'%make-simd-pack-256-type
))
4867 (define-type-method (simd-pack-256 :negate
) (type)
4868 (let ((not-pack (make-negation-type (specifier-type 'simd-pack-256
)))
4869 (mask (logxor (simd-pack-256-type-tag-mask type
) +simd-pack-wild
+)))
4872 (type-union not-pack
(%make-simd-pack-256-type mask
)))))
4874 (define-type-method (simd-pack-256 :unparse
) (flags type
)
4875 (simd-type-unparser-helper 'simd-pack-256
(simd-pack-256-type-tag-mask type
)))
4877 (define-type-method (simd-pack-256 :simple-subtypep
) (type1 type2
)
4878 (declare (type simd-pack-256-type type1 type2
))
4879 (values (zerop (logandc2 (simd-pack-256-type-tag-mask type1
)
4880 (simd-pack-256-type-tag-mask type2
)))
4883 (define-type-method (simd-pack-256 :simple-union2
) (type1 type2
)
4884 (declare (type simd-pack-256-type type1 type2
))
4885 (%make-simd-pack-256-type
(logior (simd-pack-256-type-tag-mask type1
)
4886 (simd-pack-256-type-tag-mask type2
))))
4888 (define-type-method (simd-pack-256 :simple-intersection2
) (type1 type2
)
4889 (declare (type simd-pack-256-type type1 type2
))
4890 (let ((intersection (logand (simd-pack-256-type-tag-mask type1
)
4891 (simd-pack-256-type-tag-mask type2
))))
4892 (if (eql intersection
0) *empty-type
* (%make-simd-pack-256-type intersection
))))
4894 (!define-superclasses simd-pack-256
((simd-pack-256)) !cold-init-forms
))
4896 ;;;; utilities shared between cross-compiler and target system
4898 ;;; Does the type derived from compilation of an actual function
4899 ;;; definition satisfy declarations of a function's type?
4900 (defun defined-ftype-matches-declared-ftype-p (defined-ftype declared-ftype
)
4901 (declare (type ctype defined-ftype declared-ftype
))
4902 (flet ((is-built-in-class-function-p (ctype)
4903 (and (built-in-classoid-p ctype
)
4904 (eq (built-in-classoid-name ctype
) 'function
))))
4905 (cond (;; DECLARED-FTYPE could certainly be #<BUILT-IN-CLASS FUNCTION>;
4906 ;; that's what happens when we (DECLAIM (FTYPE FUNCTION FOO)).
4907 (is-built-in-class-function-p declared-ftype
)
4908 ;; In that case, any definition satisfies the declaration.
4910 (;; It's not clear whether or how DEFINED-FTYPE might be
4911 ;; #<BUILT-IN-CLASS FUNCTION>, but it's not obviously
4912 ;; invalid, so let's handle that case too, just in case.
4913 (is-built-in-class-function-p defined-ftype
)
4914 ;; No matter what DECLARED-FTYPE might be, we can't prove
4915 ;; that an object of type FUNCTION doesn't satisfy it, so
4916 ;; we return success no matter what.
4918 (;; Otherwise both of them must be FUN-TYPE objects.
4920 ;; FIXME: For now we only check compatibility of the return
4921 ;; type, not argument types, and we don't even check the
4922 ;; return type very precisely (as per bug 94a). It would be
4923 ;; good to do a better job. Perhaps to check the
4924 ;; compatibility of the arguments, we should (1) redo
4925 ;; VALUES-TYPES-EQUAL-OR-INTERSECT as
4926 ;; ARGS-TYPES-EQUAL-OR-INTERSECT, and then (2) apply it to
4927 ;; the ARGS-TYPE slices of the FUN-TYPEs. (ARGS-TYPE
4928 ;; is a base class both of VALUES-TYPE and of FUN-TYPE.)
4929 (values-types-equal-or-intersect
4930 (fun-type-returns defined-ftype
)
4931 (fun-type-returns declared-ftype
))))))
4933 ;;; This messy case of CTYPE for NUMBER is shared between the
4934 ;;; cross-compiler and the target system.
4935 ;;; XXX: Is there a bug here with signed zeros, or are we confident that the
4936 ;;; answer is always supposed to be a NUMERIC-TYPE and never (MEMBER -0.0) ?
4937 ;;; I'm not sure whether NaNs should be numeric types versus MEMBER (like
4938 ;;; singleton signed zero without the "other" sign), but it may not matter.
4939 ;;; At a bare minimum this prevents crashing in min/max.
4940 (defun ctype-of-number (x)
4941 (let ((num (if (complexp x
) (realpart x
) x
)))
4942 (multiple-value-bind (complexp low high
)
4944 (values :complex nil nil
))
4945 ((and (floatp num
) (float-nan-p num
))
4946 (values :real nil nil
))
4948 (values :real num num
)))
4949 (make-numeric-type :class
(etypecase num
4950 (integer (if (complexp x
)
4953 (rational 'rational
)
4955 :format
(and (floatp num
) (float-format-name num
))
4960 ;;; The following function is a generic driver for approximating
4961 ;;; set-valued functions over types. Putting this here because it'll
4962 ;;; probably be useful for a lot of type analyses.
4964 ;;; Let f be a function from values of type X to Y, e.g., ARRAY-RANK.
4966 ;;; We compute an over or under-approximation of the set
4968 ;;; F(TYPE) = { f(x) : x in TYPE /\ x in X } \subseteq Y
4970 ;;; via set-valued approximations of f, OVER and UNDER.
4972 ;;; These functions must have the property that
4973 ;;; Forall TYPE, OVER(TYPE) \superseteq F(TYPE) and
4974 ;;; Forall TYPE, UNDER(TYPE) \subseteq F(TYPE)
4976 ;;; The driver is also parameterised over the finite set
4979 ;;; Union, intersection and difference are binary functions to compute
4980 ;;; set union, intersection and difference. Top and bottom are the
4981 ;;; concrete representations for the universe and empty sets; we never
4982 ;;; call the set functions on top or bottom, so it's safe to use
4983 ;;; special values there.
4987 ;;; TYPE: the ctype for which we wish to approximate F(TYPE)
4988 ;;; OVERAPPROXIMATE: true if we wish to overapproximate, nil otherwise.
4989 ;;; You usually want T.
4990 ;;; UNION/INTERSECTION/DIFFERENCE: implementations of finite set operations.
4991 ;;; Conform to cl::(union/intersection/set-difference). Passing NIL will
4992 ;;; disable some cleverness and result in quicker computation of coarser
4993 ;;; approximations. However, passing difference without union and intersection
4994 ;;; will probably not end well.
4995 ;;; TOP/BOTTOM: concrete representation of the universe and empty set. Finite
4996 ;;; set operations are never called on TOP/BOTTOM, so it's safe to use special
4998 ;;; OVER/UNDER: the set-valued approximations of F.
5000 ;;; Implementation details.
5002 ;;; It's a straightforward walk down the type.
5003 ;;; Union types -> take the union of children, intersection ->
5004 ;;; intersect. There is some complication for negation types: we must
5005 ;;; not only negate the result, but also flip from overapproximating
5006 ;;; to underapproximating in the children (or vice versa).
5008 ;;; We represent sets as a pair of (negate-p finite-set) in order to
5009 ;;; support negation types.
5011 (declaim (maybe-inline generic-abstract-type-function
))
5012 (defun generic-abstract-type-function
5013 (type overapproximate
5014 union intersection difference
5017 (labels ((union* (x y
)
5018 ;; wrappers to avoid calling union/intersection on
5020 (cond ((or (eql x top
)
5026 (funcall union x y
))))
5027 (intersection* (x y
)
5028 (cond ((or (eql x bottom
)
5034 (funcall intersection x y
))))
5035 (unite (not-x-p x not-y-p y
)
5036 ;; if we only have one negated set, it's x.
5038 (rotatef not-x-p not-y-p
)
5040 (cond ((and not-x-p not-y-p
)
5041 ;; -x \/ -y = -(x /\ y)
5042 (normalize t
(intersection* x y
)))
5044 ;; -x \/ y = -(x \ y)
5054 (funcall difference x y
)))))
5056 (values nil
(union* x y
)))))
5057 (intersect (not-x-p x not-y-p y
)
5059 (rotatef not-x-p not-y-p
)
5061 (cond ((and not-x-p not-y-p
)
5062 ;; -x /\ -y = -(x \/ y)
5063 (normalize t
(union* x y
)))
5066 (cond ((or (eql x top
) (eql y bottom
))
5067 (values nil bottom
))
5073 (values nil
(funcall difference y x
)))))
5075 (values nil
(intersection* x y
)))))
5076 (normalize (not-x-p x
)
5077 ;; catch some easy cases of redundant negation.
5078 (cond ((not not-x-p
)
5086 (default (overapproximate)
5088 (if overapproximate top bottom
))
5089 (walk-union (types overapproximate
)
5090 ;; Only do this if union is provided.
5092 (return-from walk-union
(default overapproximate
)))
5093 ;; Reduce/union from bottom.
5094 (let ((not-acc-p nil
)
5096 (dolist (type types
(values not-acc-p acc
))
5097 (multiple-value-bind (not x
)
5098 (walk type overapproximate
)
5099 (setf (values not-acc-p acc
)
5100 (unite not-acc-p acc not x
)))
5101 ;; Early exit on top set.
5102 (when (and (eql acc top
)
5104 (return (values nil top
))))))
5105 (walk-intersection (types overapproximate
)
5106 ;; Skip if we don't know how to intersect sets
5107 (unless intersection
5108 (return-from walk-intersection
(default overapproximate
)))
5109 ;; Reduce/intersection from top
5110 (let ((not-acc-p nil
)
5112 (dolist (type types
(values not-acc-p acc
))
5113 (multiple-value-bind (not x
)
5114 (walk type overapproximate
)
5115 (setf (values not-acc-p acc
)
5116 (intersect not-acc-p acc not x
)))
5117 (when (and (eql acc bottom
)
5119 (return (values nil bottom
))))))
5120 (walk-negate (type overapproximate
)
5121 ;; Don't introduce negated types if we don't know how to
5124 (return-from walk-negate
(default overapproximate
)))
5125 (multiple-value-bind (not x
)
5126 (walk type
(not overapproximate
))
5127 (normalize (not not
) x
)))
5128 (walk (type overapproximate
)
5131 (walk-union (union-type-types type
) overapproximate
))
5132 ((cons (member or union
))
5133 (walk-union (rest type
) overapproximate
))
5135 (walk-intersection (intersection-type-types type
) overapproximate
))
5136 ((cons (member and intersection
))
5137 (walk-intersection (rest type
) overapproximate
))
5139 (walk-negate (negation-type-type type
) overapproximate
))
5141 (walk-negate (second type
) overapproximate
))
5149 (funcall under type
)
5150 (default nil
))))))))
5151 (multiple-value-call #'normalize
(walk type overapproximate
))))
5153 ;;; Standard list representation of sets. Use CL:* for the universe.
5154 (defun list-abstract-type-function (type over
&key under
(overapproximate t
))
5155 #-sb-xc-host
(declare (inline generic-abstract-type-function
))
5156 (generic-abstract-type-function
5157 type overapproximate
5158 #'union
#'intersection
#'set-difference
5163 ;;; This decides if two type expressions are equal ignoring the order of terms
5164 ;;; in AND and OR. It doesn't decide equivalence, but it's good enough
5165 ;;; to do some sanity checking in type.before-xc and genesis.
5166 (defun brute-force-type-specifier-equalp (a b
)
5167 (labels ((compare (a b
)
5172 (eq (car a
) (car b
))
5175 (order-insensitive-equal (cdr a
) (cdr b
)))
5177 (compare (cadr a
) (cadr b
))))))))
5178 (order-insensitive-equal (a b
)
5179 (and (= (length a
) (length b
))
5180 (every (lambda (elt) (member elt b
:test
#'compare
)) a
)
5181 (every (lambda (elt) (member elt a
:test
#'compare
)) b
))))
5185 (defun numeric-union-type-enumerable (type)
5186 (let* ((aspects (numeric-union-type-aspects type
))
5187 (class (numtype-aspects-class aspects
)))
5188 (cond ((and (eq class
'integer
)
5189 (let ((ranges (numeric-union-type-ranges type
)))
5190 (and (aref ranges
1)
5191 (aref ranges
(1- (length ranges
))))))
5192 t
) ; finite integer range
5193 ((and (numeric-type-p type
)
5194 (let ((low (numeric-type-low type
))
5195 (high (numeric-type-high type
)))
5197 (typep low
'(and atom
(not null
))) ; inclusive bound
5199 ;; In the absence of thorough regression tests around infinity/nan handling
5200 ;; as part of MEMBER types, I'm not sure what to do here. Just guessing.
5201 (not (and (floatp low
) (float-nan-p low
))))))
5204 (define-type-class numeric-union
:enumerable
#'numeric-union-type-enumerable
:might-contain-other-types nil
)
5206 (!define-superclasses numeric-union
((number)) !cold-init-forms
)
5208 (defconstant range-integer-run
1)
5209 (defconstant range-ratio-run
2)
5210 (defconstant range-rational-run
3)
5212 (defun make-numeric-type (&key class format
(complexp :real
) low high
)
5213 (declare (type (member integer rational float nil
) class
))
5214 (declare (inline !compute-numtype-aspect-id
))
5215 (let ((union-type (%make-union-numeric-type
5216 class format complexp low high
)))
5217 (when union-type
(return-from make-numeric-type union-type
)))
5218 (multiple-value-bind (low high
)
5221 ;; INTEGER types always have their LOW and HIGH bounds
5222 ;; represented as inclusive, not exclusive values.
5223 (values (if (consp low
) (1+ (type-bound-number low
)) low
)
5224 (if (consp high
) (1- (type-bound-number high
)) high
)))
5226 ;; no canonicalization necessary
5228 ;; if interval is empty
5230 (if (or (consp low
) (consp high
)) ; if either bound is exclusive
5231 (sb-xc:>= (type-bound-number low
) (type-bound-number high
))
5232 (sb-xc:> low high
)))
5233 (return-from make-numeric-type
*empty-type
*))
5234 (when (and (eq class
'rational
) (integerp low
) (eql low high
))
5235 (setf class
'integer
))
5236 (flet ((normalize-zero (x)
5240 ((equal x
'(-0d0)) '(0d0))
5241 ((equal x
'(-0f0)) '(0f0))
5243 (declare (inline normalize-zero
))
5244 (let ((low (normalize-zero low
))
5245 (high (normalize-zero high
)))
5246 (new-ctype numeric-union-type
0 (get-numtype-aspects complexp class format
)
5249 (vector range-integer-run low high
))
5251 (vector (collapse-rational-run range-rational-run low high
) low high
))
5253 (vector low high
))))))))
5255 (defun number-unparse (type)
5256 (let* ((complexp (numeric-type-complexp type
))
5257 (low (numeric-type-low type
))
5258 (high (numeric-type-high type
))
5259 (base (case (numeric-type-class type
)
5261 (rational 'rational
)
5262 (float (or (numeric-type-format type
) 'float
))
5265 (cond ((and (eq base
'integer
) high low
)
5266 (let ((high-count (logcount high
))
5267 (high-length (integer-length high
)))
5269 (cond ((= high
0) '(integer 0 0))
5271 ((and (= high-count high-length
)
5272 (plusp high-length
))
5273 `(unsigned-byte ,high-length
))
5275 `(mod ,(1+ high
)))))
5276 ((and (= low most-negative-fixnum
)
5277 (= high most-positive-fixnum
))
5279 ((and (= low
(lognot high
))
5280 (= high-count high-length
)
5282 `(signed-byte ,(1+ high-length
)))
5284 `(integer ,low
,high
)))))
5285 (high `(,base
,(or low
'*) ,high
))
5287 (if (and (eq base
'integer
) (= low
0))
5293 (aver (neq base
'real
))
5296 (aver (neq base
'real
))
5297 `(complex ,base
+bounds
))
5299 (aver (eq base
+bounds
'real
))
5302 (define-type-method (numeric-union :unparse
) (flags type
)
5303 (if (numeric-type-p type
)
5304 (cond ((eq type
(specifier-type 'ratio
))
5306 ((eq (numeric-type-class type
) 'rational
)
5307 (let ((unparsed (number-unparse type
)))
5308 (if (eq (aref (numeric-union-type-ranges type
) 0) range-ratio-run
)
5309 (if (typep unparsed
'(cons (eql complex
)))
5310 `(complex (and ,(second unparsed
) (not integer
)))
5311 `(and ,unparsed
(not integer
)))
5314 (number-unparse type
)))
5315 (union-unparse flags
(flatten-numeric-union-types type
))))
5317 (define-type-method (numeric-union :negate
) (x) (make-negation-type x
))
5319 (defun flip-exclusion (x positive run
)
5320 (if (= run range-integer-run
)
5325 (let ((x (if (consp x
)
5332 (let ((car (car x
)))
5333 (if (and (= run range-ratio-run
)
5339 (defun flip-exclusion2 (current-x x positive run low
)
5340 (let ((result (flip-exclusion x positive run
)))
5342 (low-le-low-p result current-x
)
5343 (high-ge-high-p result current-x
))
5347 (defun min-rational-low (low run rational-low
)
5348 (if (low-le-low-p rational-low low
)
5350 (if (= run range-integer-run
)
5351 (if (and (consp rational-low
)
5352 (integerp (car rational-low
)))
5355 (let ((new-low (if (integerp rational-low
)
5356 (list (1- rational-low
))
5357 (list (floor (if (consp rational-low
)
5360 (if (low-le-low-p new-low low
)
5364 (defun max-rational-high (high run rational-high
)
5365 (if (high-ge-high-p rational-high high
)
5367 (if (= run range-integer-run
)
5368 (if (and (consp rational-high
)
5369 (integerp (car rational-high
)))
5372 (let ((new-high (if (integerp rational-high
)
5373 (list (1+ rational-high
))
5374 (list (ceiling (if (consp rational-high
)
5377 (if (high-ge-high-p new-high high
)
5381 (defun max-low-rational (low1 low2
)
5382 (multiple-value-bind (max min
) (if (low-le-low-p low1 low2
)
5385 (cond ((and (consp max
)
5386 (integerp (car max
)))
5389 ;; If the are no integers between min and max then use min
5391 (= (1+ (floor (if (consp min
)
5400 (defun min-high-rational (high1 high2
)
5401 (multiple-value-bind (max min
) (if (high-ge-high-p high1 high2
)
5402 (values high1 high2
)
5403 (values high2 high1
))
5404 (cond ((and (consp min
)
5405 (integerp (car min
)))
5408 ;; If the are no integers between min and max then use max
5410 (= (1- (ceiling (if (consp max
)
5419 (defun low-le-low-p (a b
)
5426 (sb-xc:<= (car a
) (car b
))
5427 (sb-xc:< (car a
) b
)))
5429 (sb-xc:<= a
(if (consp b
)
5433 (defun high-ge-high-p (a b
)
5440 (sb-xc:>= (car a
) (car b
))
5441 (sb-xc:> (car a
) b
)))
5443 (sb-xc:>= a
(if (consp b
)
5447 (defun high-gt-high-p (a b
)
5454 (sb-xc:> (car a
) (car b
))
5455 (sb-xc:>= a
(car b
))))
5457 (sb-xc:> (if (consp a
)
5462 (defun low-gt-high-p (a b
)
5468 (sb-xc:>= (car a
) (if (consp b
)
5471 (sb-xc:>= a
(car b
)))
5475 (defun coerce-rational-bound (x low run
)
5477 (cond ((= run range-integer-run
)
5480 (floor (1+ (car x
)))
5483 (ceiling (1- (car x
)))
5485 ((and (= run range-ratio-run
)
5491 (defun collapse-rational-run (run low high
)
5492 (cond ((or (not low
) (not high
)
5493 (/= run range-rational-run
))
5500 ;; No integers between bounds
5501 (if (or (and (consp low
)
5503 (integerp (car low
))
5506 (and (not (integerp low
))
5507 (not (integerp high
))
5508 (= (- (ceiling (if (consp high
)
5511 (floor (if (consp low
)
5518 (defun store-rational-range (low high run mask result
)
5519 (labels ((join-p (left-high left-run right-low right-run
)
5520 (cond ((not right-low
)
5524 ((= (logior left-run right-run
) range-integer-run
)
5525 (sb-xc:<= right-low
(1+ left-high
)))
5526 ((let ((open-left-high (if (consp left-high
)
5529 (open-right-low (if (consp right-low
)
5533 (not (and (= right-run left-run range-ratio-run
)
5534 (integerp open-right-low
))) ;; can join (1) and (1) for ratios
5537 (sb-xc:< open-right-low open-left-high
)
5538 (sb-xc:<= open-right-low open-left-high
)))))))
5539 (unless (or (low-gt-high-p low high
)
5546 (eql (car high
) low
))))
5547 (setf run
(collapse-rational-run run low high
))
5548 (setf mask
(logior mask
(the (integer 0 3) run
)))
5549 (let ((last-high (first result
))
5550 (last-low (second result
))
5551 (last-run (third result
)))
5552 (cond ((cond ((or (not last-run
)
5553 (not (join-p last-high last-run low run
)))
5555 ;; Join the same runs
5557 (cond ((high-gt-high-p last-high high
))
5559 (setf (car result
) high
)
5561 ((= run range-rational-run
)
5562 (let ((rational-low (min-rational-low last-low last-run low
))
5563 (rational-high (max-rational-high last-high last-run high
)))
5565 (cond ((low-le-low-p rational-low last-low
)
5566 ;; It might now be joinable to the preceding rational
5567 (let ((prev-high (fourth result
))
5568 (prev-run (sixth result
)))
5569 (cond ((and (eql prev-run range-rational-run
)
5570 (join-p prev-high range-rational-run
5571 rational-low range-rational-run
))
5576 (setf (third result
) range-rational-run
)
5577 (setf (second result
) rational-low
))))
5578 (setf (car result
) rational-high
))
5581 (flip-exclusion rational-low nil last-run
))
5582 (push range-rational-run result
)
5583 (push rational-low result
)
5584 (push rational-high result
)))
5585 (cond ((high-gt-high-p last-high rational-high
)
5586 (push last-run result
)
5587 (push (flip-exclusion rational-high t last-run
) result
)
5588 (push last-high result
))))
5590 ((= last-run range-rational-run
)
5591 (let ((rational-high (max-rational-high high run last-high
)))
5592 (setf (car result
) rational-high
)
5593 (unless (high-ge-high-p rational-high high
)
5595 (push (flip-exclusion rational-high t run
) result
)
5596 (push high result
)))
5598 ;; Mix ratio and integers, the overlap would be rational
5600 (let ((rational-low (max-low-rational last-low low
))
5601 (rational-high (min-high-rational last-high high
))
5602 (new-run range-rational-run
))
5603 (setf new-run
(collapse-rational-run range-rational-run rational-low rational-high
))
5604 (cond ((low-le-low-p rational-low last-low
)
5605 ;; It might now be joinable to the preceding rational
5606 (let ((prev-high (fourth result
))
5607 (prev-run (sixth result
)))
5608 (cond ((and (eql prev-run range-rational-run
)
5609 (join-p prev-high range-rational-run
5610 rational-low range-rational-run
))
5615 (setf (third result
) new-run
)
5616 (setf (second result
) rational-low
))))
5617 (setf (first result
) rational-high
))
5620 (flip-exclusion rational-low nil last-run
))
5621 (push new-run result
)
5622 (push rational-low result
)
5623 (push rational-high result
)))
5624 (cond ((high-gt-high-p last-high rational-high
)
5625 (push last-run result
)
5626 (push (flip-exclusion rational-high t last-run
) result
)
5627 (push last-high result
))
5628 ((high-gt-high-p high rational-high
)
5630 (push (flip-exclusion rational-high t run
) result
)
5631 (push high result
)))
5636 (push high result
))))))
5637 (values result mask
))
5639 (defun union-rational (ranges1 ranges2
)
5640 (declare (simple-vector ranges1 ranges2
))
5645 (declare (type (integer 0 3) mask
))
5646 (flet ((store (run low high
)
5647 (setf (values result mask
)
5648 (store-rational-range low high run mask result
))))
5650 (cond ((>= i1
(length ranges1
))
5651 (loop while
(< i2
(length ranges2
))
5652 do
(store (aref ranges2 i2
)
5653 (aref ranges2
(+ i2
1))
5654 (aref ranges2
(+ i2
2)))
5657 ((>= i2
(length ranges2
))
5658 (loop while
(< i1
(length ranges1
))
5659 do
(store (aref ranges1 i1
)
5660 (aref ranges1
(+ i1
1))
5661 (aref ranges1
(+ i1
2)))
5664 ((let ((low1 (aref ranges1
(1+ i1
)))
5665 (low2 (aref ranges2
(1+ i2
))))
5666 (cond ((low-le-low-p low1 low2
)
5667 (store (aref ranges1 i1
)
5669 (aref ranges1
(+ i1
2)))
5672 (store (aref ranges2 i2
)
5674 (aref ranges2
(+ i2
2)))
5676 (values (coerce (reverse result
) 'vector
) mask
))))
5678 (defun intersect-rational (ranges1 ranges2
)
5679 (declare (simple-vector ranges1 ranges2
))
5684 (declare (type (integer 0 3)))
5685 (flet ((store (run low high
)
5686 (setf (values result mask
)
5687 (store-rational-range low high run mask result
))))
5689 (cond ((>= i1
(length ranges1
))
5691 ((>= i2
(length ranges2
))
5693 ((let ((run1 (the (integer 0 3) (aref ranges1 i1
)))
5694 (low1 (aref ranges1
(+ i1
1)))
5695 (run2 (the (integer 0 3) (aref ranges2 i2
)))
5696 (high1 (aref ranges1
(+ i1
2)))
5697 (low2 (aref ranges2
(+ i2
1)))
5698 (high2 (aref ranges2
(+ i2
2))))
5699 (cond ((not (logtest run1 run2
))
5700 (if (high-gt-high-p high2 high1
)
5704 (let ((new-run (logand run1 run2
)))
5705 (cond ((low-gt-high-p low2 high1
)
5707 ((low-gt-high-p low1 high2
)
5710 (let ((low (coerce-rational-bound
5711 (if (low-le-low-p low1 low2
)
5715 (high (coerce-rational-bound
5716 (if (high-ge-high-p high1 high2
)
5720 (store new-run low high
))
5721 (if (high-gt-high-p high2 high1
)
5723 (incf i2
3))))))))))))
5724 (values (coerce (reverse result
) 'vector
) mask
)))
5726 (defun difference-rational (ranges1 ranges2
)
5727 (declare (simple-vector ranges1 ranges2
))
5732 (declare (type (integer 0 3) mask
))
5733 (flet ((store (run low high
)
5734 (setf (values result mask
)
5735 (store-rational-range low high run mask result
))))
5737 (cond ((>= i1
(length ranges1
))
5739 ((>= i2
(length ranges2
))
5740 (loop while
(< i1
(length ranges1
))
5741 do
(store (aref ranges1 i1
)
5742 (aref ranges1
(+ i1
1))
5743 (aref ranges1
(+ i1
2)))
5746 ((let ((run (the (integer 0 3) (aref ranges1 i1
)))
5747 (low (aref ranges1
(+ i1
1)))
5748 (high (aref ranges1
(+ i1
2))))
5749 (loop while
(< i2
(length ranges2
))
5751 (let ((run2 (the (integer 0 3) (aref ranges2 i2
)))
5752 (low2 (aref ranges2
(+ i2
1)))
5753 (high2 (aref ranges2
(+ i2
2))))
5754 (cond ((low-gt-high-p low2 high
)
5756 ((low-gt-high-p low high2
)
5759 (let ((bottom (low-le-low-p low2 low
))
5760 (top (high-ge-high-p high2 high
))
5761 (overlap-run (logandc2 run run2
)))
5762 (if (eql overlap-run
0)
5763 (cond ((and top bottom
)
5767 (setf high
(flip-exclusion low2 nil run
))
5771 (setf low
(flip-exclusion2 low high2 t run t
)))
5774 (store run low
(flip-exclusion low2 nil run
))
5775 (setf low
(flip-exclusion high2 t run
))))
5777 (cond ((and top bottom
)
5779 (coerce-rational-bound low t overlap-run
)
5780 (coerce-rational-bound high nil overlap-run
))
5784 (store run low
(flip-exclusion low2 nil run
))
5786 (coerce-rational-bound low2 t overlap-run
)
5787 (coerce-rational-bound high nil overlap-run
))
5793 (coerce-rational-bound low t overlap-run
)
5794 (coerce-rational-bound high2 nil overlap-run
))
5795 (setf low
(flip-exclusion2 low high2 t run t
)))
5798 (store run low
(flip-exclusion low2 nil run
))
5800 (coerce-rational-bound low2 t overlap-run
)
5801 (coerce-rational-bound high2 nil overlap-run
))
5802 (setf low
(flip-exclusion high2 t run
)))))))))
5803 finally
(store run low high
)
5805 (values (coerce (reverse result
) 'vector
) mask
))))
5807 (defun subtype-rational (ranges1 ranges2
)
5808 (declare (simple-vector ranges1 ranges2
))
5811 (loop (cond ((>= i1
(length ranges1
))
5813 ((>= i2
(length ranges2
))
5815 ((let ((run1 (the (integer 0 3) (aref ranges1 i1
)))
5816 (low1 (aref ranges1
(+ i1
1)))
5817 (high1 (aref ranges1
(+ i1
2))))
5819 while
(< i2
(length ranges2
))
5821 (let ((run2 (the (integer 0 3) (aref ranges2 i2
)))
5822 (low2 (aref ranges2
(+ i2
1)))
5823 (high2 (aref ranges2
(+ i2
2))))
5824 (cond ((low-gt-high-p low2 high1
)
5826 ((low-gt-high-p low1 high2
)
5828 ((not (and (logtest run1 run2
)
5832 (unless (low-le-low-p low2 low1
)
5834 (cond ((high-ge-high-p high2 high1
)
5838 (setf low1
(flip-exclusion high2 t run1
))
5839 (incf i2
3)))))))))))))
5841 (declaim (inline typep-rational typep-integer typep-float
))
5842 (defun typep-rational (rational run ranges2
)
5843 (declare (simple-vector ranges2
)
5844 (type (integer 0 3) run
))
5845 (loop for i2 below
(length ranges2
) by
3
5847 (cond ((low-gt-high-p (aref ranges2
(+ i2
1)) rational
)
5849 ((low-gt-high-p rational
5850 (aref ranges2
(+ i2
2))))
5852 (the (integer 0 3) (aref ranges2 i2
))))
5857 (defun typep-integer (rational ranges2
)
5858 (declare (simple-vector ranges2
))
5859 (loop for i2 below
(length ranges2
) by
3
5861 (let ((low2 (aref ranges2
(+ i2
1))))
5865 ((let ((high2 (aref ranges2
(+ i2
2))))
5867 (> rational high2
))))
5871 (defun typep-float (float ranges2
)
5872 (declare (simple-vector ranges2
))
5873 (loop for i2 below
(length ranges2
) by
2
5875 (cond ((low-gt-high-p (aref ranges2 i2
) float
)
5877 ((low-gt-high-p float
(aref ranges2
(1+ i2
))))
5881 (defun union-float (ranges1 ranges2
)
5882 (declare (simple-vector ranges1 ranges2
))
5886 (labels ((join-p (left-high right-low
)
5887 (cond ((not right-low
)
5891 ((let ((open-left-high (if (consp left-high
)
5894 (open-right-low (if (consp right-low
)
5897 (if (and (consp left-high
)
5899 (sb-xc:< open-right-low open-left-high
)
5900 (sb-xc:<= open-right-low open-left-high
))))))
5902 (let ((last-high (car result
)))
5904 (high-ge-high-p last-high high
)))
5906 (join-p last-high low
))
5907 (setf (car result
) high
))
5910 (push high result
))))))
5912 (cond ((>= i1
(length ranges1
))
5913 (loop while
(< i2
(length ranges2
))
5914 do
(store (aref ranges2 i2
)
5915 (aref ranges2
(1+ i2
)))
5918 ((>= i2
(length ranges2
))
5919 (loop while
(< i1
(length ranges1
))
5920 do
(store (aref ranges1 i1
)
5921 (aref ranges1
(1+ i1
)))
5924 ((let ((low1 (aref ranges1 i1
))
5925 (low2 (aref ranges2 i2
)))
5926 (cond ((low-le-low-p low1 low2
)
5928 (aref ranges1
(1+ i1
)))
5932 (aref ranges2
(1+ i2
)))
5934 (coerce (reverse result
) 'vector
))))
5936 (defun intersect-float (ranges1 ranges2
)
5937 (declare (simple-vector ranges1 ranges2
))
5941 (labels ((store (low high
)
5943 (push high result
)))
5944 (loop (cond ((= i1
(length ranges1
))
5946 ((= i2
(length ranges2
))
5948 ((let ((low1 (aref ranges1 i1
))
5949 (high1 (aref ranges1
(1+ i1
)))
5950 (low2 (aref ranges2 i2
))
5951 (high2 (aref ranges2
(1+ i2
))))
5952 (cond ((low-gt-high-p low2 high1
)
5954 ((low-gt-high-p low1 high2
)
5957 (store (if (low-le-low-p low1 low2
)
5960 (if (high-ge-high-p high1 high2
)
5963 (if (high-gt-high-p high2 high1
)
5966 (coerce (reverse result
) 'vector
)))
5968 (defun difference-float (ranges1 ranges2
)
5969 (declare (simple-vector ranges1 ranges2
))
5973 (labels ((store (low high
)
5975 (push high result
)))
5976 (loop (cond ((= i1
(length ranges1
))
5978 ((= i2
(length ranges2
))
5979 (loop while
(< i1
(length ranges1
))
5980 do
(store (aref ranges1 i1
)
5981 (aref ranges1
(1+ i1
)))
5984 ((let ((low1 (aref ranges1 i1
))
5985 (high1 (aref ranges1
(1+ i1
))))
5986 (loop while
(< i2
(length ranges2
))
5988 (let ((low2 (aref ranges2 i2
))
5989 (high2 (aref ranges2
(1+ i2
))))
5990 (cond ((low-gt-high-p low2 high1
)
5992 ((low-gt-high-p low1 high2
)
5995 (let ((top (high-ge-high-p high2 high1
))
5996 (bottom (low-le-low-p low2 low1
)))
5997 (flet ((flip-exclusion (x)
6001 (cond ((and top bottom
)
6005 (setf high1
(flip-exclusion low2
))
6009 (setf low1
(flip-exclusion high2
)))
6012 (store low1
(flip-exclusion low2
))
6013 (setf low1
(flip-exclusion high2
)))))))))
6014 finally
(store low1 high1
)
6016 (coerce (reverse result
) 'vector
))))
6018 (defun subtype-float (ranges1 ranges2
)
6019 (declare (simple-vector ranges1 ranges2
))
6022 (loop (cond ((= i1
(length ranges1
))
6024 ((= i2
(length ranges2
))
6026 ((let ((low1 (aref ranges1 i1
))
6027 (high1 (aref ranges1
(1+ i1
)))
6028 (low2 (aref ranges2 i2
))
6029 (high2 (aref ranges2
(1+ i2
))))
6030 (cond ((low-gt-high-p low2 high1
)
6032 ((low-gt-high-p low1 high2
)
6036 (low-le-low-p low2 low1
)
6037 (high-ge-high-p high2 high1
))
6041 (define-type-method (numeric-union :simple-union2
) (type1 type2
)
6042 (declare (inline !compute-numtype-aspect-id
))
6043 (let ((aspects1 (numeric-union-type-aspects type1
))
6044 (aspects2 (numeric-union-type-aspects type2
))
6047 (get-numtype-aspects nil nil nil
))))
6048 (cond ((eq aspects1 number-aspect
)
6050 ((eq aspects2 number-aspect
)
6052 ((not (eq (numtype-aspects-complexp aspects1
) (numtype-aspects-complexp aspects2
)))
6054 ((not (eq (numtype-aspects-precision aspects1
) (numtype-aspects-precision aspects2
)))
6056 ((memq (numtype-aspects-class aspects1
) '(integer rational
))
6057 (when (memq (numtype-aspects-class aspects2
) '(integer rational
))
6058 (cond ((eq type1
(specifier-type 'rational
))
6060 ((eq type2
(specifier-type 'rational
))
6062 ((and (eq type1
(specifier-type 'integer
))
6063 (eq (numtype-aspects-class aspects2
) 'integer
))
6065 ((and (eq type2
(specifier-type 'integer
))
6066 (eq (numtype-aspects-class aspects1
) 'integer
))
6069 (multiple-value-bind (ranges mask
) (union-rational (numeric-union-type-ranges type1
)
6070 (numeric-union-type-ranges type2
))
6072 (new-ctype numeric-union-type
0
6073 (get-numtype-aspects (numtype-aspects-complexp aspects1
)
6075 (#.range-integer-run
'integer
)
6076 ; FIXME: add a new class for ratios, for faster operations that use different types.
6081 (new-ctype numeric-union-type
0 aspects1
6082 (union-float (numeric-union-type-ranges type1
)
6083 (numeric-union-type-ranges type2
)))))))
6085 (define-type-method (numeric-union :simple-intersection2
) (type1 type2
)
6086 (declare (inline !compute-numtype-aspect-id
))
6087 (let ((aspects1 (numeric-union-type-aspects type1
))
6088 (aspects2 (numeric-union-type-aspects type2
))
6091 (get-numtype-aspects nil nil nil
))))
6092 (cond ((eq aspects1 number-aspect
)
6094 ((eq aspects2 number-aspect
)
6096 ((not (eq (numtype-aspects-complexp aspects1
) (numtype-aspects-complexp aspects2
)))
6098 ((not (eq (numtype-aspects-precision aspects1
) (numtype-aspects-precision aspects2
)))
6100 ((memq (numtype-aspects-class aspects1
) '(integer rational
))
6101 (if (memq (numtype-aspects-class aspects2
) '(integer rational
))
6102 (cond ((eq type1
(specifier-type 'rational
))
6104 ((eq type2
(specifier-type 'rational
))
6106 ((and (eq type1
(specifier-type 'integer
))
6107 (eq (numtype-aspects-class aspects2
) 'integer
))
6109 ((and (eq type2
(specifier-type 'integer
))
6110 (eq (numtype-aspects-class aspects1
) 'integer
))
6113 (multiple-value-bind (ranges mask
) (intersect-rational (numeric-union-type-ranges type1
)
6114 (numeric-union-type-ranges type2
))
6115 (if (= (length ranges
) 0)
6117 (new-ctype numeric-union-type
0
6118 (get-numtype-aspects (numtype-aspects-complexp aspects1
)
6120 (#.range-integer-run
'integer
)
6126 (let ((ranges (intersect-float (numeric-union-type-ranges type1
)
6127 (numeric-union-type-ranges type2
))))
6128 (if (= (length ranges
) 0)
6130 (new-ctype numeric-union-type
0 aspects1 ranges
)))))))
6132 (define-type-method (numeric-union :complex-intersection2
) (type1 type2
)
6133 (declare (inline !compute-numtype-aspect-id
))
6134 (cond ((and (negation-type-p type1
)
6135 (numeric-union-type-p (setf type1
(negation-type-type type1
))))
6136 (let ((aspects1 (numeric-union-type-aspects type1
))
6137 (aspects2 (numeric-union-type-aspects type2
))
6140 (get-numtype-aspects nil nil nil
))))
6141 (cond ((eq aspects1 number-aspect
)
6143 ((eq aspects2 number-aspect
)
6145 ((not (eq (numtype-aspects-complexp aspects1
) (numtype-aspects-complexp aspects2
)))
6147 ((not (eq (numtype-aspects-precision aspects1
) (numtype-aspects-precision aspects2
)))
6149 ((memq (numtype-aspects-class aspects1
) '(integer rational
))
6150 (if (memq (numtype-aspects-class aspects2
) '(integer rational
))
6151 (cond ((eq type1
(specifier-type 'rational
))
6153 ((and (eq type1
(specifier-type 'integer
))
6154 (eq (numtype-aspects-class aspects2
) 'integer
))
6157 (multiple-value-bind (ranges mask
) (difference-rational (numeric-union-type-ranges type2
)
6158 (numeric-union-type-ranges type1
))
6159 (if (= (length ranges
) 0)
6161 (new-ctype numeric-union-type
0
6162 (get-numtype-aspects (numtype-aspects-complexp aspects1
)
6164 (#.range-integer-run
'integer
)
6170 (let ((ranges (difference-float (numeric-union-type-ranges type2
)
6171 (numeric-union-type-ranges type1
))))
6172 (if (= (length ranges
) 0)
6174 (new-ctype numeric-union-type
0 aspects1 ranges
)))))))
6175 (:call-other-method
)))
6177 (define-type-method (numeric-union :complex-union2
) (type1 type2
)
6178 (cond ((and (negation-type-p type1
)
6179 (typep (negation-type-type type1
) 'numeric-union-type
))
6180 (let ((intersection (type-intersection2 (negation-type-type type1
)
6181 (type-negation type2
))))
6182 (when (ctype-p intersection
)
6183 (type-negation intersection
))))))
6185 (define-type-method (numeric-union :simple-subtypep
) (type1 type2
)
6186 (let ((aspects1 (numeric-union-type-aspects type1
))
6187 (aspects2 (numeric-union-type-aspects type2
))
6190 (aref *numeric-aspects-v
*
6191 (!compute-numtype-aspect-id nil nil nil
)))))
6192 (cond ((eq aspects2 number-aspect
)
6194 ((or (eq aspects1 number-aspect
)
6195 (not (eq (numtype-aspects-complexp aspects1
) (numtype-aspects-complexp aspects2
)))
6196 (not (eq (numtype-aspects-precision aspects1
) (numtype-aspects-precision aspects2
))))
6198 ((memq (numtype-aspects-class aspects1
) '(integer rational
))
6199 (if (or (eq (numtype-aspects-class aspects1
)
6200 (numtype-aspects-class aspects2
))
6201 (and (eq (numtype-aspects-class aspects1
) 'integer
)
6202 (eq (numtype-aspects-class aspects2
) 'rational
)))
6204 ((eq type2
(specifier-type 'rational
))
6206 ((eq type2
(specifier-type 'integer
))
6207 (values (eq (numtype-aspects-class aspects1
) 'integer
) t
))
6209 (values (subtype-rational (numeric-union-type-ranges type1
)
6210 (numeric-union-type-ranges type2
))
6214 (values (subtype-float (numeric-union-type-ranges type1
)
6215 (numeric-union-type-ranges type2
))
6218 (defun flatten-numeric-union-types (types)
6221 (flatten-numeric-union-types (union-type-types types
)))
6225 (numeric-union-to-numeric-types types
))
6227 (loop for type in types
6228 if
(numeric-union-type-p type
)
6229 nconc
(numeric-union-to-numeric-types type
)
6230 else collect type
))))
6232 (defun numeric-union-to-numeric-types (type)
6233 (declare (inline !compute-numtype-aspect-id
))
6234 (let ((ranges (numeric-union-type-ranges type
))
6235 (aspects (numeric-union-type-aspects type
)))
6236 (if (memq (numtype-aspects-class aspects
) '(integer rational
))
6237 (loop for i below
(length ranges
) by
3
6238 for run
= (aref ranges i
)
6239 for low
= (aref ranges
(+ i
1))
6240 for high
= (aref ranges
(+ i
2))
6242 (new-ctype numeric-union-type
0
6243 (get-numtype-aspects (numtype-aspects-complexp aspects
)
6245 (#.range-integer-run
'integer
)
6248 (vector run low high
)))
6249 (loop for i below
(length ranges
) by
2
6250 for low
= (aref ranges i
)
6251 for high
= (aref ranges
(1+ i
))
6253 (new-ctype numeric-union-type
0 aspects
(vector low high
))))))
6255 (defun numeric-union-bounds (type)
6256 (let ((ranges (numeric-union-type-ranges type
))
6257 (aspects (numeric-union-type-aspects type
)))
6258 (if (memq (numtype-aspects-class aspects
) '(integer rational
))
6259 (values (aref ranges
1) (aref ranges
(1- (length ranges
))))
6260 (values (aref ranges
0) (aref ranges
(1- (length ranges
)))))))
6262 (defun weaken-numeric-union (type)
6263 (let ((ranges (numeric-union-type-ranges type
))
6264 (aspects (numeric-union-type-aspects type
)))
6265 (if (memq (numtype-aspects-class aspects
) '(integer rational
))
6266 (new-ctype numeric-union-type
0
6268 (vector (ecase (numtype-aspects-class aspects
)
6269 (rational range-rational-run
)
6270 (integer range-integer-run
))
6272 (aref ranges
(1- (length ranges
)))))
6273 (new-ctype numeric-union-type
0
6275 (vector (aref ranges
0)
6276 (aref ranges
(1- (length ranges
))))))))
6278 (defun numeric-union-typep (object type
)
6279 (if (eq type
(specifier-type 'number
))
6281 (labels ((check (object)
6284 (case (numeric-type-class type
)
6286 (typep-integer object
(numeric-union-type-ranges type
)))
6288 (typep-rational object range-integer-run
(numeric-union-type-ranges type
)))))
6290 (and (eq (numeric-type-format type
) 'single-float
)
6291 (typep-float object
(numeric-union-type-ranges type
))))
6293 (and (eq (numeric-type-format type
) 'double-float
)
6294 (typep-float object
(numeric-union-type-ranges type
))))
6296 (and (eq (numeric-type-class type
) 'rational
)
6297 (typep-rational object range-ratio-run
(numeric-union-type-ranges type
)))))))
6298 (cond ((eq (numeric-type-complexp type
) :complex
)
6299 (and (complexp object
)
6300 (check (imagpart object
))
6301 (check (realpart object
))))
6305 (define-type-method (numeric-union :singleton-p
) (type)
6306 (if (numeric-type-p type
)
6307 (let ((low (numeric-type-low type
))
6308 (high (numeric-type-high type
)))
6311 (eql (numeric-type-complexp type
) :real
)
6312 (if (eq (numeric-type-class type
) 'float
)
6313 ;; (float 0.0 0.0) fits both -0.0 and 0.0
6315 (member (numeric-type-class type
) '(integer rational
))))
6321 ;;;; miscellaneous interfaces
6323 ;;; Clear memoization of all type system operations that can be
6324 ;;; altered by type definition/redefinition.
6326 (defun clear-type-caches ()
6327 ;; FIXME: We would like to differentiate between different cache
6328 ;; kinds, but at the moment all our caches pretty much are type
6330 (drop-all-hash-caches)
6333 (!defun-from-collected-cold-init-forms
!type-cold-init
)
6335 ;;; Ensure that the type CALLABLE gets interned with its constituent types
6336 ;;; in exactly the expected order. If flipped, there will be a complaint from
6337 ;;; compiler/generic/interr because we expect OBJECT-NOT-CALLABLE to unparse
6338 ;;; in a certain way. This DEFVAR is performed solely for side-effect.
6339 (defvar *preload-type
*
6340 (list (intern-ctype-set (list (specifier-type 'function
)
6341 (specifier-type 'symbol
)))
6342 ;; .. any others as required