TYPE/= do, and writing an explanation which is so clear that one
can see immediately what it's supposed to mean in odd cases like
(TYPE= '(SATISFIES X) 'INTEGER) when X isn't defined yet.
+
+409: MORE TYPE SYSTEM PROBLEMS
+ Found while investigating an optimization failure for extended
+ sequences. The extended sequence type implementation was altered to
+ work around the problem, but the fundamental problem remains, to wit:
+ (sb-kernel:type= (sb-kernel:specifier-type '(or float ratio))
+ (sb-kernel:specifier-type 'single-float))
+ returns NIL, NIL on sbcl-1.0.3.
+ (probably related to bug #408)
+
+410: read circularities and type declarations
+ Consider the definition
+ (defstruct foo (a 0 :type (not symbol)))
+ followed by
+ (setf *print-circle* t) ; just in case
+ (read-from-string "#1=#s(foo :a #1#)")
+ This gives a type error (#:G1 is not a (NOT SYMBOL)) because of the
+ implementation of read circularity, using a symbol as a marker for
+ the previously-referenced object.
"%MAKE-SYMBOL"
"%FUNCALLABLE-INSTANCE-FUNCTION" "SYMBOL-HASH"
+ "EXTENDED-SEQUENCE" "*EXTENDED-SEQUENCE-TYPE*"
+ "EXTENDED-SEQUENCE-P"
+
"BUILT-IN-CLASSOID" "CONDITION-CLASSOID-P"
"CONDITION-CLASSOID-SLOTS" "MAKE-UNDEFINED-CLASSOID"
"FIND-CLASSOID" "CLASSOID" "CLASSOID-DIRECT-SUPERCLASSES"
;; uncertain, since a subclass of both might be defined
nil)))
-;;; KLUDGE: we need this for the special-case SEQUENCE type, which
-;;; (because of multiple inheritance with ARRAY for the VECTOR types)
-;;; doesn't have the nice hierarchical properties we want. This is
-;;; basically DELEGATE-COMPLEX-INTERSECTION2 with a special-case for
-;;; SEQUENCE/ARRAY interactions.
-(!define-type-method (classoid :complex-intersection2) (type1 class2)
- (cond
- ((and (eq class2 (find-classoid 'sequence))
- (array-type-p type1))
- (type-intersection2 (specifier-type 'vector) type1))
- (t
- (let ((method (type-class-complex-intersection2 (type-class-info type1))))
- (if (and method (not (eq method #'delegate-complex-intersection2)))
- :call-other-method
- (hierarchical-intersection2 type1 class2))))))
-
;;; KLUDGE: we need this to deal with the special-case INSTANCE and
;;; FUNCALLABLE-INSTANCE types (which used to be CLASSOIDs until CSR
;;; discovered that this was incompatible with the MOP class
:inherits (array)
:prototype-form (make-array nil))
(sequence
+ :translation (or cons (member nil) vector extended-sequence)
:state :read-only
:depth 2)
(vector
;;; a consed sequence result. If a vector, is a simple array.
(sb!xc:deftype consed-sequence ()
- '(or (simple-array * (*)) (and sequence (not vector))))
+ '(or (simple-array * (*)) list extended-sequence))
;;; the :END arg to a sequence
(sb!xc:deftype sequence-end () '(or null index))
;; specifier to win.
(type (missing-arg) :type ctype))
-;;; The NAMED-TYPE is used to represent *, T and NIL. These types must
-;;; be super- or sub-types of all types, not just classes and * and
-;;; NIL aren't classes anyway, so it wouldn't make much sense to make
-;;; them built-in classes.
+;;; The NAMED-TYPE is used to represent *, T and NIL, the standard
+;;; special cases, as well as other special cases needed to
+;;; interpolate between regions of the type hierarchy, such as
+;;; INSTANCE (which corresponds to all those classes with slots which
+;;; are not funcallable), FUNCALLABLE-INSTANCE (those classes with
+;;; slots which are funcallable) and EXTENDED-SEQUUENCE (non-LIST
+;;; non-VECTOR classes which are also sequences). These special cases
+;;; are the ones that aren't really discussed by Baker in his
+;;; "Decision Procedure for SUBTYPEP" paper.
(defstruct (named-type (:include ctype
(class-info (type-class-or-lose 'named)))
(:copier nil))
;; required to be a subclass of STANDARD-OBJECT. -- CSR,
;; 2005-09-09
(frob instance *instance-type*)
- (frob funcallable-instance *funcallable-instance-type*))
+ (frob funcallable-instance *funcallable-instance-type*)
+ ;; new in sbcl-1.0.3.3: necessary to act as a join point for the
+ ;; extended sequence hierarchy. (Might be removed later if we use
+ ;; a dedicated FUNDAMENTAL-SEQUENCE class for this.)
+ (frob extended-sequence *extended-sequence-type*))
(setf *universal-fun-type*
(make-fun-type :wild-args t
:returns *wild-type*)))
;; member types can be subtypep INSTANCE and
;; FUNCALLABLE-INSTANCE in surprising ways.
(invoke-complex-subtypep-arg1-method type1 type2))
+ ((and (eq type2 *extended-sequence-type*) (classoid-p type1))
+ (let* ((layout (classoid-layout type1))
+ (inherits (layout-inherits layout))
+ (sequencep (find (classoid-layout (find-classoid 'sequence))
+ inherits)))
+ (values (if sequencep t nil) t)))
((and (eq type2 *instance-type*) (classoid-p type1))
(if (member type1 *non-instance-classoid-types* :key #'find-classoid)
(values nil t)
;; Perhaps when bug 85 is fixed it can be reenabled.
;;(aver (not (eq type2 *wild-type*))) ; * isn't really a type.
(cond
+ ((eq type2 *extended-sequence-type*)
+ (typecase type1
+ (structure-classoid *empty-type*)
+ (classoid
+ (if (member type1 *non-instance-classoid-types* :key #'find-classoid)
+ *empty-type*
+ (if (find (classoid-layout (find-classoid 'sequence))
+ (layout-inherits (classoid-layout type1)))
+ type1
+ nil)))
+ (t
+ (if (or (type-might-contain-other-types-p type1)
+ (member-type-p type1))
+ nil
+ *empty-type*))))
((eq type2 *instance-type*)
(typecase type1
(structure-classoid type1)
;; Perhaps when bug 85 is fixed this can be reenabled.
;;(aver (not (eq type2 *wild-type*))) ; * isn't really a type.
(cond
+ ((eq type2 *extended-sequence-type*)
+ (if (classoid-p type1)
+ (if (or (member type1 *non-instance-classoid-types*
+ :key #'find-classoid)
+ (not (find (classoid-layout (find-classoid 'sequence))
+ (layout-inherits (classoid-layout type1)))))
+ nil
+ type2)
+ nil))
((eq type2 *instance-type*)
(if (classoid-p type1)
(if (or (member type1 *non-instance-classoid-types*
((eq x *universal-type*) *empty-type*)
((eq x *empty-type*) *universal-type*)
((or (eq x *instance-type*)
- (eq x *funcallable-instance-type*))
+ (eq x *funcallable-instance-type*)
+ (eq x *extended-sequence-type*))
(make-negation-type :type x))
(t (bug "NAMED type unexpected: ~S" x))))
(do ((data (%array-data-vector x) (%array-data-vector data)))
((not (array-header-p data)) (simple-vector-p data))))))
+;;; Is X an extended sequence?
+(defun extended-sequence-p (x)
+ (and (not (listp x))
+ (not (vectorp x))
+ (let* ((slayout #.(info :type :compiler-layout 'sequence))
+ (depthoid #.(layout-depthoid (info :type :compiler-layout 'sequence)))
+ (layout (layout-of x)))
+ (when (layout-invalid layout)
+ (setq layout (update-object-layout-or-invalid x slayout)))
+ (if (eq layout slayout)
+ t
+ (let ((inherits (layout-inherits layout)))
+ (declare (optimize (safety 0)))
+ (and (> (length inherits) depthoid)
+ (eq (svref inherits depthoid) slayout)))))))
+
;;; Is X a SEQUENCE? Harder than just (OR VECTOR LIST)
(defun sequencep (x)
(or (listp x)
(defvar *universal-fun-type*)
(defvar *instance-type*)
(defvar *funcallable-instance-type*)
+(defvar *extended-sequence-type*)
;;; a vector that maps type codes to layouts, used for quickly finding
;;; the layouts of built-in classes
((* t) t)
((instance) (%instancep object))
((funcallable-instance) (funcallable-instance-p object))
+ ((extended-sequence) (extended-sequence-p object))
((nil) nil)))
(numeric-type
(and (numberp object)
((t *) (values *backend-t-primitive-type* t))
((instance) (exactly instance))
((funcallable-instance) (part-of function))
+ ((extended-sequence) (any))
((nil) (any))))
(character-set-type
(let ((pairs (character-set-type-pairs type)))
#!+sb-unicode character-string-p
#!+sb-unicode simple-character-string-p
array-header-p
- sequencep
+ sequencep extended-sequence-p
simple-array-p simple-array-nil-p vector-nil-p
simple-array-unsigned-byte-2-p
simple-array-unsigned-byte-4-p simple-array-unsigned-byte-7-p
(define-type-predicate rationalp rational)
(define-type-predicate realp real)
(define-type-predicate sequencep sequence)
+ (define-type-predicate extended-sequence-p extended-sequence)
(define-type-predicate simple-bit-vector-p simple-bit-vector)
(define-type-predicate simple-string-p simple-string)
(define-type-predicate simple-vector-p simple-vector)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.3.4"
+"1.0.3.5"