UPGRADED-ARRAY-ELEMENT-TYPE: more thoroughly signal errors on unknown types.
[sbcl.git] / src / compiler / generic / vm-type.lisp
index f8494cf..9d0a031 100644 (file)
@@ -17,6 +17,8 @@
 ;;;; FIXME: I'm not sure where to put this. -- WHN 19990817
 
 (def!type sb!vm:word () `(unsigned-byte ,sb!vm:n-word-bits))
+(def!type sb!vm:signed-word () `(signed-byte ,sb!vm:n-word-bits))
+
 \f
 ;;;; implementation-dependent DEFTYPEs
 
@@ -59,7 +61,7 @@
 ;;; PATHNAME pieces, as returned by the PATHNAME-xxx functions
 (sb!xc:deftype pathname-host () '(or sb!impl::host null))
 (sb!xc:deftype pathname-device ()
-  '(or simple-string (member nil :unspecific)))
+  '(or simple-string (member nil :unspecific :unc)))
 (sb!xc:deftype pathname-directory () 'list)
 (sb!xc:deftype pathname-name ()
   '(or simple-string sb!impl::pattern (member nil :unspecific :wild)))
@@ -76,7 +78,7 @@
 ;;; FIXME: see also DEFCONSTANT MAXIMUM-BIGNUM-LENGTH in
 ;;; src/code/bignum.lisp.  -- CSR, 2004-07-19
 (sb!xc:deftype bignum-index ()
-  '(integer 0 #.(1- (ash 1 (- 32 sb!vm:n-widetag-bits)))))
+  '(integer 0 #.(1- (ash 1 (- sb!vm:n-word-bits sb!vm:n-widetag-bits)))))
 \f
 ;;;; hooks into the type system
 
@@ -94,6 +96,9 @@
         (types `(simple-array ,type ,dims))))
     (types)))
 
+(sb!xc:deftype complex-vector (&optional element-type length)
+  `(and (vector ,element-type ,length) (not simple-array)))
+
 ;;; Return the symbol that describes the format of FLOAT.
 (declaim (ftype (function (float) symbol) float-format-name))
 (defun float-format-name (x)
     (double-float 'double-float)
     #!+long-float (long-float 'long-float)))
 
+(defun contains-unknown-type-p (ctype)
+  (cond ((unknown-type-p ctype) t)
+        ((intersection-type-p ctype)
+         (some #'contains-unknown-type-p (intersection-type-types ctype)))
+        ((union-type-p ctype)
+         (some #'contains-unknown-type-p (union-type-types ctype)))))
+
 ;;; This function is called when the type code wants to find out how
 ;;; an array will actually be implemented. We set the
 ;;; SPECIALIZED-ELEMENT-TYPE to correspond to the actual
                   ;; assuming that the upgraded-element-type should be
                   ;; equal to T, given the way that the AREF
                   ;; DERIVE-TYPE optimizer works.  -- CSR, 2002-08-19
-                  (unknown-type-p eltype))
+                  (contains-unknown-type-p eltype))
               *wild-type*
               (dolist (stype-name *specialized-array-element-types*
                                   *universal-type*)
   "Return the element type that will actually be used to implement an array
    with the specifier :ELEMENT-TYPE Spec."
   (declare (ignore environment))
-  (if (unknown-type-p (specifier-type spec))
-      (error "undefined type: ~S" spec)
-      (type-specifier (array-type-specialized-element-type
-                       (specifier-type `(array ,spec))))))
+  (handler-case
+      ;; Can't rely on SPECIFIER-TYPE to signal PARSE-UNKNOWN-TYPE in
+      ;; the case of (AND KNOWN UNKNOWN), since the result of the
+      ;; outter call to SPECIFIER-TYPE can be cached by the code that
+      ;; doesn't catch PARSE-UNKNOWN-TYPE signal.
+      (if (contains-unknown-type-p (specifier-type spec))
+          (error "Undefined type: ~S" spec)
+          (type-specifier (array-type-specialized-element-type
+                           (specifier-type `(array ,spec)))))
+    (parse-unknown-type (c)
+      (error "Undefined type: ~S" (parse-unknown-type-specifier c)))))
 
 (defun sb!xc:upgraded-complex-part-type (spec &optional environment)
   #!+sb-doc
 ;;; Return the most specific integer type that can be quickly checked that
 ;;; includes the given type.
 (defun containing-integer-type (subtype)
-  (dolist (type '(fixnum
-                  (signed-byte 32)
-                  (unsigned-byte 32)
+  (dolist (type `(fixnum
+                  (signed-byte ,sb!vm:n-word-bits)
+                  (unsigned-byte ,sb!vm:n-word-bits)
                   integer)
                 (error "~S isn't an integer type?" subtype))
     (when (csubtypep subtype (specifier-type type))
     (numeric-type
      (cond ((type= type (specifier-type 'fixnum))
             'sb!c:check-fixnum)
+           #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
            ((type= type (specifier-type '(signed-byte 32)))
             'sb!c:check-signed-byte-32)
+           #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
            ((type= type (specifier-type '(unsigned-byte 32)))
             'sb!c:check-unsigned-byte-32)
+           #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+           ((type= type (specifier-type '(signed-byte 64)))
+            'sb!c:check-signed-byte-64)
+           #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+           ((type= type (specifier-type '(unsigned-byte 64)))
+            'sb!c:check-unsigned-byte-64)
            (t nil)))
     (fun-type
      'sb!c:check-fun)