'(sb!alien:alien))
(member target-type
'(system-area-pointer
- funcallable-instance
sb!alien-internals:alien-value)))
(values nil t))
(;; special case when TARGET-TYPE isn't a type spec, but
(target-type-is-in
'(array simple-string simple-vector string vector))
(values (typep host-object target-type) t))
+ (;; sequence is not guaranteed to be an exhaustive
+ ;; partition, but it includes at least lists and vectors.
+ (target-type-is-in '(sequence))
+ (if (or (vectorp host-object) (listp host-object))
+ (values t t)
+ (if (typep host-object target-type)
+ (warn-and-give-up)
+ (values nil t))))
(;; general cases of vectors
- (and (not (unknown-type-p (values-specifier-type target-type)))
+ (and (not (hairy-type-p (values-specifier-type target-type)))
(sb!xc:subtypep target-type 'cl:vector))
(if (vectorp host-object)
(warn-and-give-up) ; general-case vectors being way too hard
(values nil t))) ; but "obviously not a vector" being easy
(;; general cases of arrays
- (and (not (unknown-type-p (values-specifier-type target-type)))
+ (and (not (hairy-type-p (values-specifier-type target-type)))
(sb!xc:subtypep target-type 'cl:array))
(if (arrayp host-object)
(warn-and-give-up) ; general-case arrays being way too hard
(t
(values nil t))))
(;; Complexes suffer the same kind of problems as arrays
- (and (not (unknown-type-p (values-specifier-type target-type)))
+ (and (not (hairy-type-p (values-specifier-type target-type)))
(sb!xc:subtypep target-type 'cl:complex))
(if (complexp host-object)
(warn-and-give-up) ; general-case complexes being way too hard
;;; cross-compile time only.
(defun ctypep (obj ctype)
(check-type ctype ctype)
- (let (;; the Common Lisp type specifier corresponding to CTYPE
- (type (type-specifier ctype)))
- (check-type type (or symbol cons))
- (cross-typep obj type)))
+ ;; There is at least one possible endless recursion in the
+ ;; cross-compiler type system: (SUBTYPEP NULL (OR UNKOWN0 UNKNOWN1)
+ ;; runs out of stack. The right way would probably be to not
+ ;; implement CTYPEP in terms of TYPE-SPECIFIER (:UNPARSE, that may
+ ;; call TYPE=, that in turn may call CTYPEP). Until then, pick a few
+ ;; cherries off.
+ (cond ((member-type-p ctype)
+ (if (member-type-member-p obj ctype)
+ (values t t)
+ (values nil t)))
+ ((union-type-p ctype)
+ (any/type #'ctypep obj (union-type-types ctype)))
+ (t
+ (let ( ;; the Common Lisp type specifier corresponding to CTYPE
+ (type (type-specifier ctype)))
+ (check-type type (or symbol cons))
+ (cross-typep obj type)))))
(defun ctype-of (x)
(typecase x