1 ;;;; This software is part of the SBCL system. See the README file for
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.
10 (in-package "SB!KERNEL")
12 (!begin-collecting-cold-init-forms)
14 ;;;; representations of types
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))
23 (might-contain-other-types-p t))
26 ;; the Common Lisp type-specifier of the type we represent
27 (specifier nil :type t))
29 (!define-type-class hairy)
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)
37 (defun maybe-reparse-specifier (type)
38 (when (unknown-type-p type)
39 (let* ((spec (unknown-type-specifier type))
40 (name (if (consp spec)
43 (when (info :type :kind name)
44 (let ((new-type (specifier-type spec)))
45 (unless (unknown-type-p new-type)
49 (defmacro maybe-reparse-specifier! (type)
50 (assert (symbolp type))
51 (with-unique-names (new-type)
52 `(let ((,new-type (maybe-reparse-specifier ,type)))
54 (setf ,type ,new-type)
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
62 (might-contain-other-types-p t))
65 (type (missing-arg) :type ctype))
67 (!define-type-class negation)
69 ;;; ARGS-TYPE objects are used both to represent VALUES types and
70 ;;; to represent FUNCTION types.
71 (defstruct (args-type (:include ctype)
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))
86 (defun canonicalize-args-type-args (required optional rest &optional keyp)
87 (when (eq rest *empty-type*)
90 (loop with last-not-rest = nil
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
101 (subseq optional 0 (1+ last-not-rest))))
104 (defun parse-args-types (lambda-list-like-thing)
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))
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)))
116 (collect ((key-info))
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))
127 :type (single-value-specifier-type (second key))))))
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)))))
133 (defstruct (values-type
135 (class-info (type-class-or-lose 'values)))
136 (:constructor %make-values-type)
137 (:predicate %values-type-p)
140 (declaim (inline value-type-p))
141 (defun values-type-p (x)
142 (or (eq x *wild-type*)
145 (defun-cached (make-values-type-cached
147 :hash-function (lambda (req opt rest allowp)
149 (type-list-cache-hash req)
150 (type-list-cache-hash opt)
152 (type-hash-value rest)
156 ((required equal-but-no-car-recursion)
157 (optional equal-but-no-car-recursion)
160 (%make-values-type :required required
165 (defun make-values-type (&key required optional rest allowp)
166 (multiple-value-bind (required optional rest)
167 (canonicalize-args-type-args required optional rest)
168 (cond ((and (null required)
170 (eq rest *universal-type*))
172 ((memq *empty-type* required)
174 (t (make-values-type-cached required optional
177 (!define-type-class values)
179 ;;; (SPECIFIER-TYPE 'FUNCTION) and its subtypes
180 (defstruct (fun-type (:include args-type
181 (class-info (type-class-or-lose 'function)))
183 make-fun-type (&key required optional rest
187 &aux (rest (if (eq rest *empty-type*)
190 ;; true if the arguments are unrestrictive, i.e. *
191 (wild-args nil :type boolean)
192 ;; type describing the return values. This is a values type
193 ;; when multiple values were specified for the return.
194 (returns (missing-arg) :type ctype))
196 ;;; The CONSTANT-TYPE structure represents a use of the CONSTANT-ARG
197 ;;; "type specifier", which is only meaningful in function argument
198 ;;; type specifiers used within the compiler. (It represents something
199 ;;; that the compiler knows to be a constant.)
200 (defstruct (constant-type
202 (class-info (type-class-or-lose 'constant)))
204 ;; The type which the argument must be a constant instance of for this type
206 (type (missing-arg) :type ctype))
208 ;;; The NAMED-TYPE is used to represent *, T and NIL, the standard
209 ;;; special cases, as well as other special cases needed to
210 ;;; interpolate between regions of the type hierarchy, such as
211 ;;; INSTANCE (which corresponds to all those classes with slots which
212 ;;; are not funcallable), FUNCALLABLE-INSTANCE (those classes with
213 ;;; slots which are funcallable) and EXTENDED-SEQUUENCE (non-LIST
214 ;;; non-VECTOR classes which are also sequences). These special cases
215 ;;; are the ones that aren't really discussed by Baker in his
216 ;;; "Decision Procedure for SUBTYPEP" paper.
217 (defstruct (named-type (:include ctype
218 (class-info (type-class-or-lose 'named)))
220 (name nil :type symbol))
222 ;;; a list of all the float "formats" (i.e. internal representations;
223 ;;; nothing to do with #'FORMAT), in order of decreasing precision
224 (eval-when (:compile-toplevel :load-toplevel :execute)
225 (defparameter *float-formats*
226 '(long-float double-float single-float short-float)))
228 ;;; The type of a float format.
229 (deftype float-format () `(member ,@*float-formats*))
231 ;;; A NUMERIC-TYPE represents any numeric type, including things
233 (defstruct (numeric-type (:include ctype
234 (class-info (type-class-or-lose 'number)))
235 (:constructor %make-numeric-type)
237 ;; the kind of numeric type we have, or NIL if not specified (just
238 ;; NUMBER or COMPLEX)
240 ;; KLUDGE: A slot named CLASS for a non-CLASS value is bad.
241 ;; Especially when a CLASS value *is* stored in another slot (called
242 ;; CLASS-INFO:-). Perhaps this should be called CLASS-NAME? Also
243 ;; weird that comment above says "Numeric-Type is used to represent
244 ;; all numeric types" but this slot doesn't allow COMPLEX as an
245 ;; option.. how does this fall into "not specified" NIL case above?
246 ;; Perhaps someday we can switch to CLOS and make NUMERIC-TYPE
247 ;; be an abstract base class and INTEGER-TYPE, RATIONAL-TYPE, and
248 ;; whatnot be concrete subclasses..
249 (class nil :type (member integer rational float nil) :read-only t)
250 ;; "format" for a float type (i.e. type specifier for a CPU
251 ;; representation of floating point, e.g. 'SINGLE-FLOAT -- nothing
252 ;; to do with #'FORMAT), or NIL if not specified or not a float.
253 ;; Formats which don't exist in a given implementation don't appear
255 (format nil :type (or float-format null) :read-only t)
256 ;; Is this a complex numeric type? Null if unknown (only in NUMBER).
258 ;; FIXME: I'm bewildered by FOO-P names for things not intended to
259 ;; interpreted as truth values. Perhaps rename this COMPLEXNESS?
260 (complexp :real :type (member :real :complex nil) :read-only t)
261 ;; The upper and lower bounds on the value, or NIL if there is no
262 ;; bound. If a list of a number, the bound is exclusive. Integer
263 ;; types never have exclusive bounds, i.e. they may have them on
264 ;; input, but they're canonicalized to inclusive bounds before we
266 (low nil :type (or number cons null) :read-only t)
267 (high nil :type (or number cons null) :read-only t))
269 ;;; Impose canonicalization rules for NUMERIC-TYPE. Note that in some
270 ;;; cases, despite the name, we return *EMPTY-TYPE* instead of a
272 (defun make-numeric-type (&key class format (complexp :real) low high
274 ;; if interval is empty
277 (if (or (consp low) (consp high)) ; if either bound is exclusive
278 (>= (type-bound-number low) (type-bound-number high))
281 (multiple-value-bind (canonical-low canonical-high)
284 ;; INTEGER types always have their LOW and HIGH bounds
285 ;; represented as inclusive, not exclusive values.
286 (values (if (consp low)
287 (1+ (type-bound-number low))
290 (1- (type-bound-number high))
293 ;; no canonicalization necessary
295 (when (and (eq class 'rational)
296 (integerp canonical-low)
297 (integerp canonical-high)
298 (= canonical-low canonical-high))
299 (setf class 'integer))
300 (%make-numeric-type :class class
305 :enumerable enumerable))))
307 (defun modified-numeric-type (base
309 (class (numeric-type-class base))
310 (format (numeric-type-format base))
311 (complexp (numeric-type-complexp base))
312 (low (numeric-type-low base))
313 (high (numeric-type-high base))
314 (enumerable (numeric-type-enumerable base)))
315 (make-numeric-type :class class
320 :enumerable enumerable))
322 (defstruct (character-set-type
324 (class-info (type-class-or-lose 'character-set)))
325 (:constructor %make-character-set-type)
327 (pairs (missing-arg) :type list :read-only t))
328 (defun make-character-set-type (&key pairs)
329 ; (aver (equal (mapcar #'car pairs)
330 ; (sort (mapcar #'car pairs) #'<)))
331 ;; aver that the cars of the list elements are sorted into increasing order
332 (aver (or (null pairs)
333 (do ((p pairs (cdr p)))
335 (when (> (caar p) (caadr p)) (return nil)))))
336 (let ((pairs (let (result)
337 (do ((pairs pairs (cdr pairs)))
338 ((null pairs) (nreverse result))
339 (destructuring-bind (low . high) (car pairs)
340 (loop for (low1 . high1) in (cdr pairs)
341 if (<= low1 (1+ high))
342 do (progn (setf high (max high high1))
343 (setf pairs (cdr pairs)))
344 else do (return nil))
346 ((>= low sb!xc:char-code-limit))
348 (t (push (cons (max 0 low)
349 (min high (1- sb!xc:char-code-limit)))
353 (%make-character-set-type :pairs pairs))))
355 ;;; An ARRAY-TYPE is used to represent any array type, including
356 ;;; things such as SIMPLE-BASE-STRING.
357 (defstruct (array-type (:include ctype
358 (class-info (type-class-or-lose 'array)))
359 (:constructor %make-array-type)
361 ;; the dimensions of the array, or * if unspecified. If a dimension
362 ;; is unspecified, it is *.
363 (dimensions '* :type (or list (member *)))
364 ;; Is this not a simple array type? (:MAYBE means that we don't know.)
365 (complexp :maybe :type (member t nil :maybe))
366 ;; the element type as originally specified
367 (element-type (missing-arg) :type ctype)
368 ;; the element type as it is specialized in this implementation
369 (specialized-element-type *wild-type* :type ctype))
370 (define-cached-synonym make-array-type)
372 ;;; A MEMBER-TYPE represent a use of the MEMBER type specifier. We
373 ;;; bother with this at this level because MEMBER types are fairly
374 ;;; important and union and intersection are well defined.
375 (defstruct (member-type (:include ctype
376 (class-info (type-class-or-lose 'member))
379 (:constructor %make-member-type (xset fp-zeroes))
380 #-sb-xc-host (:pure nil))
381 (xset (missing-arg) :type xset)
382 (fp-zeroes (missing-arg) :type list))
383 (defun make-member-type (&key xset fp-zeroes members)
385 (aver (not fp-zeroes))
386 (setf xset (alloc-xset))
387 (dolist (elt members)
389 (pushnew elt fp-zeroes)
390 (add-to-xset elt xset))))
391 ;; if we have a pair of zeros (e.g. 0.0d0 and -0.0d0), then we can
392 ;; canonicalize to (DOUBLE-FLOAT 0.0d0 0.0d0), because numeric
393 ;; ranges are compared by arithmetic operators (while MEMBERship is
394 ;; compared by EQL). -- CSR, 2003-04-23
397 (do ((tail (cdr fp-zeroes) (cdr tail))
398 (zero (car fp-zeroes) (car tail)))
401 `(let ((neg (neg-fp-zero zero)))
402 (if (member neg tail)
403 (push (ctype-of ,c) union-types)
404 (push zero unpaired)))))
406 (single-float (frob 0.0f0))
407 (double-float (frob 0.0d0))
409 (long-float (frob 0.0l0)))))
410 ;; The actual member-type contains the XSET (with no FP zeroes),
411 ;; and a list of unpaired zeroes.
412 (let ((member-type (unless (and (xset-empty-p xset) (not unpaired))
413 (%make-member-type xset unpaired))))
415 (make-union-type t (if member-type
416 (cons member-type union-types)
423 (defun member-type-size (type)
424 (+ (length (member-type-fp-zeroes type))
425 (xset-count (member-type-xset type))))
427 (defun member-type-member-p (x type)
429 (and (member x (member-type-fp-zeroes type)) t)
430 (xset-member-p x (member-type-xset type))))
432 (defun mapcar-member-type-members (function type)
433 (declare (function function))
435 (map-xset (lambda (x)
436 (results (funcall function x)))
437 (member-type-xset type))
438 (dolist (zero (member-type-fp-zeroes type))
439 (results (funcall function zero)))
442 (defun mapc-member-type-members (function type)
443 (declare (function function))
444 (map-xset function (member-type-xset type))
445 (dolist (zero (member-type-fp-zeroes type))
446 (funcall function zero)))
448 (defun member-type-members (type)
449 (append (member-type-fp-zeroes type)
450 (xset-members (member-type-xset type))))
452 ;;; A COMPOUND-TYPE is a type defined out of a set of types, the
453 ;;; common parent of UNION-TYPE and INTERSECTION-TYPE.
454 (defstruct (compound-type (:include ctype
455 (might-contain-other-types-p t))
458 (types nil :type list :read-only t))
460 ;;; A UNION-TYPE represents a use of the OR type specifier which we
461 ;;; couldn't canonicalize to something simpler. Canonical form:
462 ;;; 1. All possible pairwise simplifications (using the UNION2 type
463 ;;; methods) have been performed. Thus e.g. there is never more
464 ;;; than one MEMBER-TYPE component. FIXME: As of sbcl-0.6.11.13,
465 ;;; this hadn't been fully implemented yet.
466 ;;; 2. There are never any UNION-TYPE components.
467 (defstruct (union-type (:include compound-type
468 (class-info (type-class-or-lose 'union)))
469 (:constructor %make-union-type (enumerable types))
471 (define-cached-synonym make-union-type)
473 ;;; An INTERSECTION-TYPE represents a use of the AND type specifier
474 ;;; which we couldn't canonicalize to something simpler. Canonical form:
475 ;;; 1. All possible pairwise simplifications (using the INTERSECTION2
476 ;;; type methods) have been performed. Thus e.g. there is never more
477 ;;; than one MEMBER-TYPE component.
478 ;;; 2. There are never any INTERSECTION-TYPE components: we've
479 ;;; flattened everything into a single INTERSECTION-TYPE object.
480 ;;; 3. There are never any UNION-TYPE components. Either we should
481 ;;; use the distributive rule to rearrange things so that
482 ;;; unions contain intersections and not vice versa, or we
483 ;;; should just punt to using a HAIRY-TYPE.
484 (defstruct (intersection-type (:include compound-type
485 (class-info (type-class-or-lose
487 (:constructor %make-intersection-type
491 ;;; Return TYPE converted to canonical form for a situation where the
492 ;;; "type" '* (which SBCL still represents as a type even though ANSI
493 ;;; CL defines it as a related but different kind of placeholder) is
494 ;;; equivalent to type T.
495 (defun type-*-to-t (type)
496 (if (type= type *wild-type*)
500 ;;; A CONS-TYPE is used to represent a CONS type.
501 (defstruct (cons-type (:include ctype (class-info (type-class-or-lose 'cons)))
503 %make-cons-type (car-type
506 ;; the CAR and CDR element types (to support ANSI (CONS FOO BAR) types)
508 ;; FIXME: Most or all other type structure slots could also be :READ-ONLY.
509 (car-type (missing-arg) :type ctype :read-only t)
510 (cdr-type (missing-arg) :type ctype :read-only t))
511 (defun make-cons-type (car-type cdr-type)
512 (aver (not (or (eq car-type *wild-type*)
513 (eq cdr-type *wild-type*))))
514 (if (or (eq car-type *empty-type*)
515 (eq cdr-type *empty-type*))
517 (%make-cons-type car-type cdr-type)))
519 (defun cons-type-length-info (type)
520 (declare (type cons-type type))
521 (do ((min 1 (1+ min))
522 (cdr (cons-type-cdr-type type) (cons-type-cdr-type cdr)))
523 ((not (cons-type-p cdr))
525 ((csubtypep cdr (specifier-type 'null))
527 ((csubtypep *universal-type* cdr)
529 ((type/= (type-intersection (specifier-type 'cons) cdr) *empty-type*)
531 ((type/= (type-intersection (specifier-type 'null) cdr) *empty-type*)
533 (t (values min :maybe))))
536 ;;; A SIMD-PACK-TYPE is used to represent a SIMD-PACK type.
538 (defstruct (simd-pack-type
539 (:include ctype (class-info (type-class-or-lose 'simd-pack)))
540 (:constructor %make-simd-pack-type (element-type))
542 (element-type (missing-arg)
543 :type (cons #||(member #.*simd-pack-element-types*) ||#)
547 (defun make-simd-pack-type (element-type)
548 (aver (neq element-type *wild-type*))
549 (if (eq element-type *empty-type*)
551 (%make-simd-pack-type
552 (dolist (pack-type *simd-pack-element-types*
553 (error "~S element type must be a subtype of ~
554 ~{~S~#[~;, or ~:;, ~]~}."
555 'simd-pack *simd-pack-element-types*))
556 (when (csubtypep element-type (specifier-type pack-type))
557 (return (list pack-type)))))))
562 ;;; Return the type structure corresponding to a type specifier. We
563 ;;; pick off structure types as a special case.
565 ;;; Note: VALUES-SPECIFIER-TYPE-CACHE-CLEAR must be called whenever a
566 ;;; type is defined (or redefined).
567 (defun-cached (values-specifier-type
568 :hash-function (lambda (x)
569 (logand (sxhash x) #x3FF))
571 :init-wrapper !cold-init-forms)
572 ((orig equal-but-no-car-recursion))
573 (let ((u (uncross orig)))
574 (or (info :type :builtin u)
575 (let ((spec (typexpand u)))
577 ((and (not (eq spec u))
578 (info :type :builtin spec)))
579 ((and (consp spec) (symbolp (car spec))
580 (info :type :builtin (car spec))
581 (let ((expander (info :type :expander (car spec))))
582 (and expander (values-specifier-type (funcall expander spec))))))
583 ((eq (info :type :kind spec) :instance)
584 (find-classoid spec))
585 ((typep spec 'classoid)
586 (if (typep spec 'built-in-classoid)
587 (or (built-in-classoid-translation spec) spec)
590 (when (and (atom spec)
591 (member spec '(and or not member eql satisfies values)))
592 (error "The symbol ~S is not valid as a type specifier." spec))
593 (let* ((lspec (if (atom spec) (list spec) spec))
594 (fun (info :type :translator (car lspec))))
597 ((or (and (consp spec) (symbolp (car spec))
598 (not (info :type :builtin (car spec))))
599 (and (symbolp spec) (not (info :type :builtin spec))))
600 (when (and *type-system-initialized*
601 (not (eq (info :type :kind spec)
602 :forthcoming-defclass-type)))
603 (signal 'parse-unknown-type :specifier spec))
604 ;; (The RETURN-FROM here inhibits caching; this
605 ;; does not only make sense from a compiler
606 ;; diagnostics point of view but is also
607 ;; indispensable for proper workingness of
608 ;; VALID-TYPE-SPECIFIER-P.)
609 (return-from values-specifier-type
610 (make-unknown-type :specifier spec)))
612 (error "bad thing to be a type specifier: ~S"
615 ;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to
616 ;;; never return a VALUES type.
617 (defun specifier-type (x)
618 (let ((res (values-specifier-type x)))
619 (when (or (values-type-p res)
620 ;; bootstrap magic :-(
621 (and (named-type-p res)
622 (eq (named-type-name res) '*)))
623 (error "VALUES type illegal in this context:~% ~S" x))
626 (defun single-value-specifier-type (x)
631 (defun typexpand-1 (type-specifier &optional env)
633 "Takes and expands a type specifier once like MACROEXPAND-1.
634 Returns two values: the expansion, and a boolean that is true when
636 (declare (type type-specifier type-specifier))
637 (declare (ignore env))
638 (multiple-value-bind (expander lspec)
639 (let ((spec type-specifier))
640 (cond ((and (symbolp spec) (info :type :builtin spec))
641 ;; We do not expand builtins even though it'd be
642 ;; possible to do so sometimes (e.g. STRING) for two
645 ;; a) From a user's point of view, CL types are opaque.
647 ;; b) so (EQUAL (TYPEXPAND 'STRING) (TYPEXPAND-ALL 'STRING))
650 (values (info :type :expander spec) (list spec)))
651 ((and (consp spec) (symbolp (car spec)) (info :type :builtin (car spec)))
654 ((and (consp spec) (symbolp (car spec)))
655 (values (info :type :expander (car spec)) spec))
658 (values (funcall expander lspec) t)
659 (values type-specifier nil))))
661 (defun typexpand (type-specifier &optional env)
663 "Takes and expands a type specifier repeatedly like MACROEXPAND.
664 Returns two values: the expansion, and a boolean that is true when
666 (declare (type type-specifier type-specifier))
667 (multiple-value-bind (expansion flag)
668 (typexpand-1 type-specifier env)
670 (values (typexpand expansion env) t)
671 (values expansion flag))))
673 (defun typexpand-all (type-specifier &optional env)
675 "Takes and expands a type specifier recursively like MACROEXPAND-ALL."
676 (declare (type type-specifier type-specifier))
677 (declare (ignore env))
678 ;; I first thought this would not be a good implementation because
679 ;; it signals an error on e.g. (CONS 1 2) until I realized that
680 ;; walking and calling TYPEXPAND would also result in errors, and
681 ;; it actually makes sense.
683 ;; There's still a small problem in that
684 ;; (TYPEXPAND-ALL '(CONS * FIXNUM)) => (CONS T FIXNUM)
685 ;; whereas walking+typexpand would result in (CONS * FIXNUM).
687 ;; Similiarly, (TYPEXPAND-ALL '(FUNCTION (&REST T) *)) => FUNCTION.
688 (type-specifier (values-specifier-type type-specifier)))
690 (defun defined-type-name-p (name &optional env)
692 "Returns T if NAME is known to name a type specifier, otherwise NIL."
693 (declare (symbol name))
694 (declare (ignore env))
695 (and (info :type :kind name) t))
697 (defun valid-type-specifier-p (type-specifier &optional env)
699 "Returns T if TYPE-SPECIFIER is a valid type specifier, otherwise NIL.
701 There may be different metrics on what constitutes a \"valid type
702 specifier\" depending on context. If this function does not suit your
703 exact need, you may be able to craft a particular solution using a
704 combination of DEFINED-TYPE-NAME-P and the TYPEXPAND functions.
706 The definition of \"valid type specifier\" employed by this function
707 is based on the following mnemonic:
709 \"Would TYPEP accept it as second argument?\"
711 Except that unlike TYPEP, this function fully supports compound
712 FUNCTION type specifiers, and the VALUES type specifier, too.
714 In particular, VALID-TYPE-SPECIFIER-P will return NIL if
715 TYPE-SPECIFIER is not a class, not a symbol that is known to name a
716 type specifier, and not a cons that represents a known compound type
717 specifier in a syntactically and recursively correct way.
721 (valid-type-specifier-p '(cons * *)) => T
722 (valid-type-specifier-p '#:foo) => NIL
723 (valid-type-specifier-p '(cons * #:foo)) => NIL
724 (valid-type-specifier-p '(cons 1 *) => NIL
727 (declare (ignore env))
728 (handler-case (prog1 t (values-specifier-type type-specifier))
729 (parse-unknown-type () nil)
732 ;;; Note that the type NAME has been (re)defined, updating the
733 ;;; undefined warnings and VALUES-SPECIFIER-TYPE cache.
734 (defun %note-type-defined (name)
735 (declare (symbol name))
736 (note-name-defined name :type)
737 (values-specifier-type-cache-clear)
741 (!defun-from-collected-cold-init-forms !early-type-cold-init)