extend ARRAY-TYPE-UPGRADED-ELEMENT-TYPE to work with member types
[sbcl.git] / src / compiler / array-tran.lisp
index efa768b..38defe4 100644 (file)
@@ -73,7 +73,7 @@
                  (apply #'type-intersection element-supertypes)))))
     (union-type
      (let ((union-types (union-type-types type))
-           (element-type *empty-type*)
+           (element-type nil)
            (element-supertypes nil))
        (dolist (union-type union-types)
          (multiple-value-bind (cur-type cur-supertype)
@@ -81,7 +81,7 @@
            (cond
              ((eq element-type *wild-type*)
               nil)
-             ((eq element-type *empty-type*)
+             ((eq element-type nil)
               (setf element-type cur-type))
              ((or (eq cur-type *wild-type*)
                   ;; If each of the two following tests fail, it is not
        (values element-type
                (when (eq *wild-type* element-type)
                  (apply #'type-union element-supertypes)))))
+    (member-type
+     ;; Convert member-type to an union-type.
+     (array-type-upgraded-element-type
+      (apply #'type-union (mapcar #'ctype-of (member-type-members type)))))
     (t
      ;; KLUDGE: there is no good answer here, but at least
      ;; *wild-type* won't cause HAIRY-DATA-VECTOR-{REF,SET} to be
         ;; we can already decide on the result of the optimization without
         ;; even taking a look at the dimensions.
         (flet ((subscript-bounds (subscript)
-                 (let* ((type (lvar-type subscript))
-                        (low (numeric-type-low type))
-                        (high (numeric-type-high type)))
+                 (let* ((type1 (lvar-type subscript))
+                        (type2 (if (csubtypep type1 (specifier-type 'integer))
+                                   (weaken-integer-type type1)
+                                   (give-up)))
+                        (low (numeric-type-low type2))
+                        (high (numeric-type-high type2)))
                    (cond
                      ((and (or (not (bound-known-p low)) (minusp low))
                            (or (not (bound-known-p high)) (not (minusp high))))
 ;;; can pick them apart in the DEFTRANSFORMS, and transform '(3) style
 ;;; dimensions to integer args directly.
 (define-source-transform make-array (dimensions &rest keyargs &environment env)
-  (if (and (fun-lexically-notinline-p 'list)
-           (fun-lexically-notinline-p 'vector))
+  (if (or (and (fun-lexically-notinline-p 'list)
+               (fun-lexically-notinline-p 'vector))
+          (oddp (length keyargs)))
       (values nil t)
       (multiple-value-bind (new-dimensions rank)
           (flet ((constant-dims (dimensions)