;;; the original type spec.
(defstruct (hairy-type (:include ctype
(class-info (type-class-or-lose 'hairy))
- (enumerable t))
+ (enumerable t)
+ (might-contain-other-types-p t))
(:copier nil)
#!+cmu (:pure nil))
- ;; the Common Lisp type-specifier
+ ;; the Common Lisp type-specifier of the type we represent
(specifier nil :type t))
(!define-type-class hairy)
(defstruct (unknown-type (:include hairy-type)
(:copier nil)))
+(defstruct (negation-type (:include ctype
+ (class-info (type-class-or-lose 'negation))
+ ;; FIXME: is this right? It's
+ ;; what they had before, anyway
+ (enumerable t)
+ (might-contain-other-types-p t))
+ (:copier nil)
+ #!+cmu (:pure nil))
+ (type (missing-arg) :type ctype))
+
+(!define-type-class negation)
+
;;; ARGS-TYPE objects are used both to represent VALUES types and
;;; to represent FUNCTION types.
(defstruct (args-type (:include ctype)
(defstruct (values-type
(:include args-type
(class-info (type-class-or-lose 'values)))
+ (:constructor %make-values-type)
(:copier nil)))
+(define-cached-synonym make-values-type)
(!define-type-class values)
;;; things such as SIMPLE-STRING.
(defstruct (array-type (:include ctype
(class-info (type-class-or-lose 'array)))
+ (:constructor %make-array-type)
(:copier nil))
;; the dimensions of the array, or * if unspecified. If a dimension
;; is unspecified, it is *.
(element-type (missing-arg) :type ctype)
;; the element type as it is specialized in this implementation
(specialized-element-type *wild-type* :type ctype))
+(define-cached-synonym make-array-type)
;;; A MEMBER-TYPE represent a use of the MEMBER type specifier. We
;;; bother with this at this level because MEMBER types are fairly
;;; A COMPOUND-TYPE is a type defined out of a set of types, the
;;; common parent of UNION-TYPE and INTERSECTION-TYPE.
-(defstruct (compound-type (:include ctype)
+(defstruct (compound-type (:include ctype
+ (might-contain-other-types-p t))
(:constructor nil)
(:copier nil))
(types nil :type list :read-only t))
(class-info (type-class-or-lose 'union)))
(:constructor %make-union-type (enumerable types))
(:copier nil)))
+(define-cached-synonym make-union-type)
;;; An INTERSECTION-TYPE represents a use of the AND type specifier
;;; which we couldn't canonicalize to something simpler. Canonical form:
type))
;;; A CONS-TYPE is used to represent a CONS type.
-(defstruct (cons-type (:include ctype (:class-info (type-class-or-lose 'cons)))
+(defstruct (cons-type (:include ctype (class-info (type-class-or-lose 'cons)))
(:constructor
;; ANSI says that for CAR and CDR subtype
;; specifiers '* is equivalent to T. In order
;;; type is defined (or redefined).
(defun-cached (values-specifier-type
:hash-function (lambda (x)
- ;; FIXME: The THE FIXNUM stuff is
- ;; redundant in SBCL (or modern CMU
- ;; CL) because of type inference.
- (the fixnum
- (logand (the fixnum (sxhash x))
- #x3FF)))
+ (logand (sxhash x) #x3FF))
:hash-bits 10
:init-wrapper !cold-init-forms)
- ((orig eq))
+ ((orig equal-but-no-car-recursion))
(let ((u (uncross orig)))
(or (info :type :builtin u)
(let ((spec (type-expand u)))
(funcall fun lspec))
((or (and (consp spec) (symbolp (car spec)))
(symbolp spec))
- (when *type-system-initialized*
+ (when (and *type-system-initialized*
+ (not (eq (info :type :kind spec)
+ :forthcoming-defclass-type)))
(signal 'parse-unknown-type :specifier spec))
;; (The RETURN-FROM here inhibits caching.)
(return-from values-specifier-type
(error "bad thing to be a type specifier: ~S"
spec))))))))))
-;;; Like VALUES-SPECIFIER-TYPE, except that we guarantee to never
-;;; return a VALUES type.
+;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to
+;;; never return a VALUES type.
(defun specifier-type (x)
(let ((res (values-specifier-type x)))
(when (values-type-p res)
(error "VALUES type illegal in this context:~% ~S" x))
res))
+(defun single-value-specifier-type (x)
+ (let ((res (specifier-type x)))
+ (if (eq res *wild-type*)
+ *universal-type*
+ res)))
+
;;; Similar to MACROEXPAND, but expands DEFTYPEs. We don't bother
;;; returning a second value.
(defun type-expand (form)