Optimize the compiler a bit.
[sbcl.git] / src / code / early-type.lisp
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3 ;;;;
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
9
10 (in-package "SB!KERNEL")
11
12 (!begin-collecting-cold-init-forms)
13
14 ;;;; representations of types
15
16 ;;; A HAIRY-TYPE represents anything too weird to be described
17 ;;; reasonably or to be useful, such as NOT, SATISFIES, unknown types,
18 ;;; and unreasonably complicated types involving AND. We just remember
19 ;;; the original type spec.
20 (defstruct (hairy-type (:include ctype
21                                  (class-info (type-class-or-lose 'hairy))
22                                  (enumerable t)
23                                  (might-contain-other-types-p t))
24                        (:copier nil)
25                        #!+cmu (:pure nil))
26   ;; the Common Lisp type-specifier of the type we represent
27   (specifier nil :type t))
28
29 (!define-type-class hairy)
30
31 ;;; An UNKNOWN-TYPE is a type not known to the type system (not yet
32 ;;; defined). We make this distinction since we don't want to complain
33 ;;; about types that are hairy but defined.
34 (defstruct (unknown-type (:include hairy-type)
35                          (:copier nil)))
36
37 (defun maybe-reparse-specifier (type)
38   (when (unknown-type-p type)
39     (let* ((spec (unknown-type-specifier type))
40            (name (if (consp spec)
41                      (car spec)
42                      spec)))
43       (when (info :type :kind name)
44         (let ((new-type (specifier-type spec)))
45           (unless (unknown-type-p new-type)
46             new-type))))))
47
48 ;;; Evil macro.
49 (defmacro maybe-reparse-specifier! (type)
50   (assert (symbolp type))
51   (with-unique-names (new-type)
52     `(let ((,new-type (maybe-reparse-specifier ,type)))
53        (when ,new-type
54          (setf ,type ,new-type)
55          t))))
56
57 (defstruct (negation-type (:include ctype
58                                     (class-info (type-class-or-lose 'negation))
59                                     ;; FIXME: is this right?  It's
60                                     ;; what they had before, anyway
61                                     (enumerable t)
62                                     (might-contain-other-types-p t))
63                           (:copier nil)
64                           #!+cmu (:pure nil))
65   (type (missing-arg) :type ctype))
66
67 (!define-type-class negation)
68
69 ;;; ARGS-TYPE objects are used both to represent VALUES types and
70 ;;; to represent FUNCTION types.
71 (defstruct (args-type (:include ctype)
72                       (:constructor nil)
73                       (:copier nil))
74   ;; Lists of the type for each required and optional argument.
75   (required nil :type list)
76   (optional nil :type list)
77   ;; The type for the rest arg. NIL if there is no &REST arg.
78   (rest nil :type (or ctype null))
79   ;; true if &KEY arguments are specified
80   (keyp nil :type boolean)
81   ;; list of KEY-INFO structures describing the &KEY arguments
82   (keywords nil :type list)
83   ;; true if other &KEY arguments are allowed
84   (allowp nil :type boolean))
85
86 (defun canonicalize-args-type-args (required optional rest &optional keyp)
87   (when (eq rest *empty-type*)
88     ;; or vice-versa?
89     (setq rest nil))
90   (loop with last-not-rest = nil
91         for i from 0
92         for opt in optional
93         do (cond ((eq opt *empty-type*)
94                   (return (values required (subseq optional i) rest)))
95                  ((and (not keyp) (neq opt rest))
96                   (setq last-not-rest i)))
97         finally (return (values required
98                                 (cond (keyp
99                                        optional)
100                                       (last-not-rest
101                                        (subseq optional 0 (1+ last-not-rest))))
102                                 rest))))
103
104 (defun parse-args-types (lambda-list-like-thing)
105   (multiple-value-bind
106         (required optional restp rest keyp keys allowp auxp aux
107                   morep more-context more-count llk-p)
108       (parse-lambda-list-like-thing lambda-list-like-thing :silent t)
109     (declare (ignore aux morep more-context more-count))
110     (when auxp
111       (error "&AUX in a FUNCTION or VALUES type: ~S." lambda-list-like-thing))
112     (let ((required (mapcar #'single-value-specifier-type required))
113           (optional (mapcar #'single-value-specifier-type optional))
114           (rest (when restp (single-value-specifier-type rest)))
115           (keywords
116            (collect ((key-info))
117              (dolist (key keys)
118                (unless (proper-list-of-length-p key 2)
119                  (error "Keyword type description is not a two-list: ~S." key))
120                (let ((kwd (first key)))
121                  (when (find kwd (key-info) :key #'key-info-name)
122                    (error "~@<repeated keyword ~S in lambda list: ~2I~_~S~:>"
123                           kwd lambda-list-like-thing))
124                  (key-info
125                   (make-key-info
126                    :name kwd
127                    :type (single-value-specifier-type (second key))))))
128              (key-info))))
129       (multiple-value-bind (required optional rest)
130           (canonicalize-args-type-args required optional rest keyp)
131         (values required optional rest keyp keywords allowp llk-p)))))
132
133 (defstruct (values-type
134             (:include args-type
135                       (class-info (type-class-or-lose 'values)))
136             (:constructor %make-values-type)
137             (:predicate %values-type-p)
138             (:copier nil)))
139
140 (declaim (inline value-type-p))
141 (defun values-type-p (x)
142   (or (eq x *wild-type*)
143       (%values-type-p x)))
144
145 (defun-cached (make-values-type-cached
146                :hash-bits 8
147                :hash-function (lambda (req opt rest allowp)
148                                 (logand (logxor
149                                          (type-list-cache-hash req)
150                                          (type-list-cache-hash opt)
151                                          (if rest
152                                              (type-hash-value rest)
153                                              42)
154                                          (if allowp
155                                              #.(logand #xFF (sxhash t))
156                                              #.(logand #xFF (sxhash nil))))
157                                         #xFF)))
158     ((required equal-but-no-car-recursion)
159      (optional equal-but-no-car-recursion)
160      (rest eq)
161      (allowp eq))
162   (%make-values-type :required required
163                      :optional optional
164                      :rest rest
165                      :allowp allowp))
166
167 (defun make-values-type (&key required optional rest allowp)
168   (multiple-value-bind (required optional rest)
169       (canonicalize-args-type-args required optional rest)
170     (cond ((and (null required)
171                 (null optional)
172                 (eq rest *universal-type*))
173            *wild-type*)
174           ((memq *empty-type* required)
175            *empty-type*)
176           (t (make-values-type-cached required optional
177                                       rest allowp)))))
178
179 (!define-type-class values)
180
181 ;;; (SPECIFIER-TYPE 'FUNCTION) and its subtypes
182 (defstruct (fun-type (:include args-type
183                                (class-info (type-class-or-lose 'function)))
184                      (:constructor
185                       make-fun-type (&key required optional rest
186                                           keyp keywords allowp
187                                           wild-args
188                                           returns
189                                      &aux (rest (if (eq rest *empty-type*)
190                                                     nil
191                                                     rest)))))
192   ;; true if the arguments are unrestrictive, i.e. *
193   (wild-args nil :type boolean)
194   ;; type describing the return values. This is a values type
195   ;; when multiple values were specified for the return.
196   (returns (missing-arg) :type ctype))
197
198 ;;; The CONSTANT-TYPE structure represents a use of the CONSTANT-ARG
199 ;;; "type specifier", which is only meaningful in function argument
200 ;;; type specifiers used within the compiler. (It represents something
201 ;;; that the compiler knows to be a constant.)
202 (defstruct (constant-type
203             (:include ctype
204                       (class-info (type-class-or-lose 'constant)))
205             (:copier nil))
206   ;; The type which the argument must be a constant instance of for this type
207   ;; specifier to win.
208   (type (missing-arg) :type ctype))
209
210 ;;; The NAMED-TYPE is used to represent *, T and NIL, the standard
211 ;;; special cases, as well as other special cases needed to
212 ;;; interpolate between regions of the type hierarchy, such as
213 ;;; INSTANCE (which corresponds to all those classes with slots which
214 ;;; are not funcallable), FUNCALLABLE-INSTANCE (those classes with
215 ;;; slots which are funcallable) and EXTENDED-SEQUUENCE (non-LIST
216 ;;; non-VECTOR classes which are also sequences).  These special cases
217 ;;; are the ones that aren't really discussed by Baker in his
218 ;;; "Decision Procedure for SUBTYPEP" paper.
219 (defstruct (named-type (:include ctype
220                                  (class-info (type-class-or-lose 'named)))
221                        (:copier nil))
222   (name nil :type symbol))
223
224 ;;; a list of all the float "formats" (i.e. internal representations;
225 ;;; nothing to do with #'FORMAT), in order of decreasing precision
226 (eval-when (:compile-toplevel :load-toplevel :execute)
227   (defparameter *float-formats*
228     '(long-float double-float single-float short-float)))
229
230 ;;; The type of a float format.
231 (deftype float-format () `(member ,@*float-formats*))
232
233 ;;; A NUMERIC-TYPE represents any numeric type, including things
234 ;;; such as FIXNUM.
235 (defstruct (numeric-type (:include ctype
236                                    (class-info (type-class-or-lose 'number)))
237                          (:constructor %make-numeric-type)
238                          (:copier nil))
239   ;; the kind of numeric type we have, or NIL if not specified (just
240   ;; NUMBER or COMPLEX)
241   ;;
242   ;; KLUDGE: A slot named CLASS for a non-CLASS value is bad.
243   ;; Especially when a CLASS value *is* stored in another slot (called
244   ;; CLASS-INFO:-). Perhaps this should be called CLASS-NAME? Also
245   ;; weird that comment above says "Numeric-Type is used to represent
246   ;; all numeric types" but this slot doesn't allow COMPLEX as an
247   ;; option.. how does this fall into "not specified" NIL case above?
248   ;; Perhaps someday we can switch to CLOS and make NUMERIC-TYPE
249   ;; be an abstract base class and INTEGER-TYPE, RATIONAL-TYPE, and
250   ;; whatnot be concrete subclasses..
251   (class nil :type (member integer rational float nil) :read-only t)
252   ;; "format" for a float type (i.e. type specifier for a CPU
253   ;; representation of floating point, e.g. 'SINGLE-FLOAT -- nothing
254   ;; to do with #'FORMAT), or NIL if not specified or not a float.
255   ;; Formats which don't exist in a given implementation don't appear
256   ;; here.
257   (format nil :type (or float-format null) :read-only t)
258   ;; Is this a complex numeric type?  Null if unknown (only in NUMBER).
259   ;;
260   ;; FIXME: I'm bewildered by FOO-P names for things not intended to
261   ;; interpreted as truth values. Perhaps rename this COMPLEXNESS?
262   (complexp :real :type (member :real :complex nil) :read-only t)
263   ;; The upper and lower bounds on the value, or NIL if there is no
264   ;; bound. If a list of a number, the bound is exclusive. Integer
265   ;; types never have exclusive bounds, i.e. they may have them on
266   ;; input, but they're canonicalized to inclusive bounds before we
267   ;; store them here.
268   (low nil :type (or number cons null) :read-only t)
269   (high nil :type (or number cons null) :read-only t))
270
271 ;;; Impose canonicalization rules for NUMERIC-TYPE. Note that in some
272 ;;; cases, despite the name, we return *EMPTY-TYPE* instead of a
273 ;;; NUMERIC-TYPE.
274 (defun make-numeric-type (&key class format (complexp :real) low high
275                                enumerable)
276   ;; if interval is empty
277   (if (and low
278            high
279            (if (or (consp low) (consp high)) ; if either bound is exclusive
280                (>= (type-bound-number low) (type-bound-number high))
281                (> low high)))
282       *empty-type*
283       (multiple-value-bind (canonical-low canonical-high)
284           (case class
285             (integer
286              ;; INTEGER types always have their LOW and HIGH bounds
287              ;; represented as inclusive, not exclusive values.
288              (values (if (consp low)
289                          (1+ (type-bound-number low))
290                          low)
291                      (if (consp high)
292                          (1- (type-bound-number high))
293                          high)))
294             (t
295              ;; no canonicalization necessary
296              (values low high)))
297         (when (and (eq class 'rational)
298                    (integerp canonical-low)
299                    (integerp canonical-high)
300                    (= canonical-low canonical-high))
301           (setf class 'integer))
302         (%make-numeric-type :class class
303                             :format format
304                             :complexp complexp
305                             :low canonical-low
306                             :high canonical-high
307                             :enumerable enumerable))))
308
309 (defun modified-numeric-type (base
310                               &key
311                               (class      (numeric-type-class      base))
312                               (format     (numeric-type-format     base))
313                               (complexp   (numeric-type-complexp   base))
314                               (low        (numeric-type-low        base))
315                               (high       (numeric-type-high       base))
316                               (enumerable (numeric-type-enumerable base)))
317   (make-numeric-type :class class
318                      :format format
319                      :complexp complexp
320                      :low low
321                      :high high
322                      :enumerable enumerable))
323
324 (defstruct (character-set-type
325             (:include ctype
326                       (class-info (type-class-or-lose 'character-set)))
327             (:constructor %make-character-set-type)
328             (:copier nil))
329   (pairs (missing-arg) :type list :read-only t))
330 (defun make-character-set-type (&key pairs)
331   ; (aver (equal (mapcar #'car pairs)
332   ;              (sort (mapcar #'car pairs) #'<)))
333   ;; aver that the cars of the list elements are sorted into increasing order
334   (aver (or (null pairs)
335             (do ((p pairs (cdr p)))
336                 ((null (cdr p)) t)
337               (when (> (caar p) (caadr p)) (return nil)))))
338   (let ((pairs (let (result)
339                 (do ((pairs pairs (cdr pairs)))
340                     ((null pairs) (nreverse result))
341                   (destructuring-bind (low . high) (car pairs)
342                     (loop for (low1 . high1) in (cdr pairs)
343                           if (<= low1 (1+ high))
344                           do (progn (setf high (max high high1))
345                                     (setf pairs (cdr pairs)))
346                           else do (return nil))
347                     (cond
348                       ((>= low sb!xc:char-code-limit))
349                       ((< high 0))
350                       (t (push (cons (max 0 low)
351                                      (min high (1- sb!xc:char-code-limit)))
352                                result))))))))
353     (if (null pairs)
354        *empty-type*
355        (%make-character-set-type :pairs pairs))))
356
357 ;;; An ARRAY-TYPE is used to represent any array type, including
358 ;;; things such as SIMPLE-BASE-STRING.
359 (defstruct (array-type (:include ctype
360                                  (class-info (type-class-or-lose 'array)))
361                        (:constructor %make-array-type)
362                        (:copier nil))
363   ;; the dimensions of the array, or * if unspecified. If a dimension
364   ;; is unspecified, it is *.
365   (dimensions '* :type (or list (member *)))
366   ;; Is this not a simple array type? (:MAYBE means that we don't know.)
367   (complexp :maybe :type (member t nil :maybe))
368   ;; the element type as originally specified
369   (element-type (missing-arg) :type ctype)
370   ;; the element type as it is specialized in this implementation
371   (specialized-element-type *wild-type* :type ctype))
372 (define-cached-synonym make-array-type)
373
374 ;;; A MEMBER-TYPE represent a use of the MEMBER type specifier. We
375 ;;; bother with this at this level because MEMBER types are fairly
376 ;;; important and union and intersection are well defined.
377 (defstruct (member-type (:include ctype
378                                   (class-info (type-class-or-lose 'member))
379                                   (enumerable t))
380                         (:copier nil)
381                         (:constructor %make-member-type (xset fp-zeroes))
382                         #-sb-xc-host (:pure nil))
383   (xset (missing-arg) :type xset)
384   (fp-zeroes (missing-arg) :type list))
385 (defun make-member-type (&key xset fp-zeroes members)
386   (unless xset
387     (aver (not fp-zeroes))
388     (setf xset (alloc-xset))
389     (dolist (elt members)
390       (if (fp-zero-p elt)
391           (pushnew elt fp-zeroes)
392           (add-to-xset elt xset))))
393   ;; if we have a pair of zeros (e.g. 0.0d0 and -0.0d0), then we can
394   ;; canonicalize to (DOUBLE-FLOAT 0.0d0 0.0d0), because numeric
395   ;; ranges are compared by arithmetic operators (while MEMBERship is
396   ;; compared by EQL).  -- CSR, 2003-04-23
397   (let ((unpaired nil)
398         (union-types nil))
399     (do ((tail (cdr fp-zeroes) (cdr tail))
400          (zero (car fp-zeroes) (car tail)))
401         ((not zero))
402       (macrolet ((frob (c)
403                    `(let ((neg (neg-fp-zero zero)))
404                       (if (member neg tail)
405                           (push (ctype-of ,c) union-types)
406                           (push zero unpaired)))))
407         (etypecase zero
408           (single-float (frob 0.0f0))
409           (double-float (frob 0.0d0))
410           #!+long-float
411           (long-float (frob 0.0l0)))))
412     ;; The actual member-type contains the XSET (with no FP zeroes),
413     ;; and a list of unpaired zeroes.
414     (let ((member-type (unless (and (xset-empty-p xset) (not unpaired))
415                          (%make-member-type xset unpaired))))
416       (cond (union-types
417              (make-union-type t (if member-type
418                                     (cons member-type union-types)
419                                     union-types)))
420             (member-type
421              member-type)
422             (t
423              *empty-type*)))))
424
425 (defun member-type-size (type)
426   (+ (length (member-type-fp-zeroes type))
427      (xset-count (member-type-xset type))))
428
429 (defun member-type-member-p (x type)
430   (if (fp-zero-p x)
431       (and (member x (member-type-fp-zeroes type)) t)
432       (xset-member-p x (member-type-xset type))))
433
434 (defun mapcar-member-type-members (function type)
435   (declare (function function))
436   (collect ((results))
437     (map-xset (lambda (x)
438                 (results (funcall function x)))
439               (member-type-xset type))
440     (dolist (zero (member-type-fp-zeroes type))
441       (results (funcall function zero)))
442     (results)))
443
444 (defun mapc-member-type-members (function type)
445   (declare (function function))
446   (map-xset function (member-type-xset type))
447   (dolist (zero (member-type-fp-zeroes type))
448     (funcall function zero)))
449
450 (defun member-type-members (type)
451   (append (member-type-fp-zeroes type)
452           (xset-members (member-type-xset type))))
453
454 ;;; A COMPOUND-TYPE is a type defined out of a set of types, the
455 ;;; common parent of UNION-TYPE and INTERSECTION-TYPE.
456 (defstruct (compound-type (:include ctype
457                                     (might-contain-other-types-p t))
458                           (:constructor nil)
459                           (:copier nil))
460   (types nil :type list :read-only t))
461
462 ;;; A UNION-TYPE represents a use of the OR type specifier which we
463 ;;; couldn't canonicalize to something simpler. Canonical form:
464 ;;;   1. All possible pairwise simplifications (using the UNION2 type
465 ;;;      methods) have been performed. Thus e.g. there is never more
466 ;;;      than one MEMBER-TYPE component. FIXME: As of sbcl-0.6.11.13,
467 ;;;      this hadn't been fully implemented yet.
468 ;;;   2. There are never any UNION-TYPE components.
469 (defstruct (union-type (:include compound-type
470                                  (class-info (type-class-or-lose 'union)))
471                        (:constructor %make-union-type (enumerable types))
472                        (:copier nil)))
473 (define-cached-synonym make-union-type)
474
475 ;;; An INTERSECTION-TYPE represents a use of the AND type specifier
476 ;;; which we couldn't canonicalize to something simpler. Canonical form:
477 ;;;   1. All possible pairwise simplifications (using the INTERSECTION2
478 ;;;      type methods) have been performed. Thus e.g. there is never more
479 ;;;      than one MEMBER-TYPE component.
480 ;;;   2. There are never any INTERSECTION-TYPE components: we've
481 ;;;      flattened everything into a single INTERSECTION-TYPE object.
482 ;;;   3. There are never any UNION-TYPE components. Either we should
483 ;;;      use the distributive rule to rearrange things so that
484 ;;;      unions contain intersections and not vice versa, or we
485 ;;;      should just punt to using a HAIRY-TYPE.
486 (defstruct (intersection-type (:include compound-type
487                                         (class-info (type-class-or-lose
488                                                      'intersection)))
489                               (:constructor %make-intersection-type
490                                             (enumerable types))
491                               (:copier nil)))
492
493 ;;; Return TYPE converted to canonical form for a situation where the
494 ;;; "type" '* (which SBCL still represents as a type even though ANSI
495 ;;; CL defines it as a related but different kind of placeholder) is
496 ;;; equivalent to type T.
497 (defun type-*-to-t (type)
498   (if (type= type *wild-type*)
499       *universal-type*
500       type))
501
502 ;;; A CONS-TYPE is used to represent a CONS type.
503 (defstruct (cons-type (:include ctype (class-info (type-class-or-lose 'cons)))
504                       (:constructor
505                        %make-cons-type (car-type
506                                         cdr-type))
507                       (:copier nil))
508   ;; the CAR and CDR element types (to support ANSI (CONS FOO BAR) types)
509   ;;
510   ;; FIXME: Most or all other type structure slots could also be :READ-ONLY.
511   (car-type (missing-arg) :type ctype :read-only t)
512   (cdr-type (missing-arg) :type ctype :read-only t))
513 (defun make-cons-type (car-type cdr-type)
514   (aver (not (or (eq car-type *wild-type*)
515                  (eq cdr-type *wild-type*))))
516   (if (or (eq car-type *empty-type*)
517           (eq cdr-type *empty-type*))
518       *empty-type*
519       (%make-cons-type car-type cdr-type)))
520
521 (defun cons-type-length-info (type)
522   (declare (type cons-type type))
523   (do ((min 1 (1+ min))
524        (cdr (cons-type-cdr-type type) (cons-type-cdr-type cdr)))
525       ((not (cons-type-p cdr))
526        (cond
527          ((csubtypep cdr (specifier-type 'null))
528           (values min t))
529          ((csubtypep *universal-type* cdr)
530           (values min nil))
531          ((type/= (type-intersection (specifier-type 'cons) cdr) *empty-type*)
532           (values min nil))
533          ((type/= (type-intersection (specifier-type 'null) cdr) *empty-type*)
534           (values min t))
535          (t (values min :maybe))))
536     ()))
537
538 ;;; A SIMD-PACK-TYPE is used to represent a SIMD-PACK type.
539 #!+sb-simd-pack
540 (defstruct (simd-pack-type
541             (:include ctype (class-info (type-class-or-lose 'simd-pack)))
542             (:constructor %make-simd-pack-type (element-type))
543             (:copier nil))
544   (element-type (missing-arg)
545    :type (cons #||(member #.*simd-pack-element-types*) ||#)
546    :read-only t))
547
548 #!+sb-simd-pack
549 (defun make-simd-pack-type (element-type)
550   (aver (neq element-type *wild-type*))
551   (if (eq element-type *empty-type*)
552       *empty-type*
553       (%make-simd-pack-type
554        (dolist (pack-type *simd-pack-element-types*
555                           (error "~S element type must be a subtype of ~
556                                      ~{~S~#[~;, or ~:;, ~]~}."
557                                  'simd-pack *simd-pack-element-types*))
558          (when (csubtypep element-type (specifier-type pack-type))
559            (return (list pack-type)))))))
560
561 \f
562 ;;;; type utilities
563
564 ;;; Return the type structure corresponding to a type specifier. We
565 ;;; pick off structure types as a special case.
566 ;;;
567 ;;; Note: VALUES-SPECIFIER-TYPE-CACHE-CLEAR must be called whenever a
568 ;;; type is defined (or redefined).
569 (defun-cached (values-specifier-type
570                :hash-function (lambda (x)
571                                 (logand (sxhash x) #x3FF))
572                :hash-bits 10
573                :init-wrapper !cold-init-forms)
574               ((orig equal-but-no-car-recursion))
575   (let ((u (uncross orig)))
576     (or (info :type :builtin u)
577         (let ((spec (typexpand u)))
578           (cond
579            ((and (not (eq spec u))
580                  (info :type :builtin spec)))
581            ((and (consp spec) (symbolp (car spec))
582                  (info :type :builtin (car spec))
583                  (let ((expander (info :type :expander (car spec))))
584                    (and expander (values-specifier-type (funcall expander spec))))))
585            ((eq (info :type :kind spec) :instance)
586             (find-classoid spec))
587            ((typep spec 'classoid)
588             (if (typep spec 'built-in-classoid)
589                 (or (built-in-classoid-translation spec) spec)
590                 spec))
591            (t
592             (when (and (atom spec)
593                        (member spec '(and or not member eql satisfies values)))
594               (error "The symbol ~S is not valid as a type specifier." spec))
595             (let* ((lspec (if (atom spec) (list spec) spec))
596                    (fun (info :type :translator (car lspec))))
597               (cond (fun
598                      (funcall fun lspec))
599                     ((or (and (consp spec) (symbolp (car spec))
600                               (not (info :type :builtin (car spec))))
601                          (and (symbolp spec) (not (info :type :builtin spec))))
602                      (when (and *type-system-initialized*
603                                 (not (eq (info :type :kind spec)
604                                          :forthcoming-defclass-type)))
605                        (signal 'parse-unknown-type :specifier spec))
606                      ;; (The RETURN-FROM here inhibits caching; this
607                      ;; does not only make sense from a compiler
608                      ;; diagnostics point of view but is also
609                      ;; indispensable for proper workingness of
610                      ;; VALID-TYPE-SPECIFIER-P.)
611                      (return-from values-specifier-type
612                        (make-unknown-type :specifier spec)))
613                     (t
614                      (error "bad thing to be a type specifier: ~S"
615                             spec))))))))))
616
617 ;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to
618 ;;; never return a VALUES type.
619 (defun specifier-type (x)
620   (let ((res (values-specifier-type x)))
621     (when (or (values-type-p res)
622               ;; bootstrap magic :-(
623               (and (named-type-p res)
624                    (eq (named-type-name res) '*)))
625       (error "VALUES type illegal in this context:~%  ~S" x))
626     res))
627
628 (defun single-value-specifier-type (x)
629   (if (eq x '*)
630       *universal-type*
631       (specifier-type x)))
632
633 (defun typexpand-1 (type-specifier &optional env)
634   #!+sb-doc
635   "Takes and expands a type specifier once like MACROEXPAND-1.
636 Returns two values: the expansion, and a boolean that is true when
637 expansion happened."
638   (declare (type type-specifier type-specifier))
639   (declare (ignore env))
640   (multiple-value-bind (expander lspec)
641       (let ((spec type-specifier))
642         (cond ((and (symbolp spec) (info :type :builtin spec))
643                ;; We do not expand builtins even though it'd be
644                ;; possible to do so sometimes (e.g. STRING) for two
645                ;; reasons:
646                ;;
647                ;; a) From a user's point of view, CL types are opaque.
648                ;;
649                ;; b) so (EQUAL (TYPEXPAND 'STRING) (TYPEXPAND-ALL 'STRING))
650                (values nil nil))
651               ((symbolp spec)
652                (values (info :type :expander spec) (list spec)))
653               ((and (consp spec) (symbolp (car spec)) (info :type :builtin (car spec)))
654                ;; see above
655                (values nil nil))
656               ((and (consp spec) (symbolp (car spec)))
657                (values (info :type :expander (car spec)) spec))
658               (t nil)))
659     (if expander
660         (values (funcall expander lspec) t)
661         (values type-specifier nil))))
662
663 (defun typexpand (type-specifier &optional env)
664   #!+sb-doc
665   "Takes and expands a type specifier repeatedly like MACROEXPAND.
666 Returns two values: the expansion, and a boolean that is true when
667 expansion happened."
668   (declare (type type-specifier type-specifier))
669   (multiple-value-bind (expansion flag)
670       (typexpand-1 type-specifier env)
671     (if flag
672         (values (typexpand expansion env) t)
673         (values expansion flag))))
674
675 (defun typexpand-all (type-specifier &optional env)
676   #!+sb-doc
677   "Takes and expands a type specifier recursively like MACROEXPAND-ALL."
678   (declare (type type-specifier type-specifier))
679   (declare (ignore env))
680   ;; I first thought this would not be a good implementation because
681   ;; it signals an error on e.g. (CONS 1 2) until I realized that
682   ;; walking and calling TYPEXPAND would also result in errors, and
683   ;; it actually makes sense.
684   ;;
685   ;; There's still a small problem in that
686   ;;   (TYPEXPAND-ALL '(CONS * FIXNUM)) => (CONS T FIXNUM)
687   ;; whereas walking+typexpand would result in (CONS * FIXNUM).
688   ;;
689   ;; Similiarly, (TYPEXPAND-ALL '(FUNCTION (&REST T) *)) => FUNCTION.
690   (type-specifier (values-specifier-type type-specifier)))
691
692 (defun defined-type-name-p (name &optional env)
693   #!+sb-doc
694   "Returns T if NAME is known to name a type specifier, otherwise NIL."
695   (declare (symbol name))
696   (declare (ignore env))
697   (and (info :type :kind name) t))
698
699 (defun valid-type-specifier-p (type-specifier &optional env)
700   #!+sb-doc
701   "Returns T if TYPE-SPECIFIER is a valid type specifier, otherwise NIL.
702
703 There may be different metrics on what constitutes a \"valid type
704 specifier\" depending on context. If this function does not suit your
705 exact need, you may be able to craft a particular solution using a
706 combination of DEFINED-TYPE-NAME-P and the TYPEXPAND functions.
707
708 The definition of \"valid type specifier\" employed by this function
709 is based on the following mnemonic:
710
711           \"Would TYPEP accept it as second argument?\"
712
713 Except that unlike TYPEP, this function fully supports compound
714 FUNCTION type specifiers, and the VALUES type specifier, too.
715
716 In particular, VALID-TYPE-SPECIFIER-P will return NIL if
717 TYPE-SPECIFIER is not a class, not a symbol that is known to name a
718 type specifier, and not a cons that represents a known compound type
719 specifier in a syntactically and recursively correct way.
720
721 Examples:
722
723   (valid-type-specifier-p '(cons * *))     => T
724   (valid-type-specifier-p '#:foo)          => NIL
725   (valid-type-specifier-p '(cons * #:foo)) => NIL
726   (valid-type-specifier-p '(cons 1 *)      => NIL
727
728 Experimental."
729   (declare (ignore env))
730   (handler-case (prog1 t (values-specifier-type type-specifier))
731     (parse-unknown-type () nil)
732     (error () nil)))
733
734 ;;; Note that the type NAME has been (re)defined, updating the
735 ;;; undefined warnings and VALUES-SPECIFIER-TYPE cache.
736 (defun %note-type-defined (name)
737   (declare (symbol name))
738   (note-name-defined name :type)
739   (values-specifier-type-cache-clear)
740   (values))
741
742 \f
743 (!defun-from-collected-cold-init-forms !early-type-cold-init)