1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; While most of SBCL is derived from the CMU CL system, the test
5 ;;;; files (like this one) were written from scratch after the fork
8 ;;;; This software is in the public domain and is provided with
9 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
10 ;;;; more information.
12 (enable-test-parallelism)
14 (assert (not (sb-kernel:member-type-p
(sb-kernel:make-eql-type
#\z
))))
15 (assert (not (sb-kernel:member-type-p
(sb-kernel:make-eql-type
1.0))))
16 (assert (sb-kernel:member-type-p
(sb-kernel:make-eql-type -
0.0s0
)))
18 (with-test (:name
(typexpand-1 typexpand typexpand-all
:check-lexenv
))
19 (flet ((try (f) (assert-error (funcall f
'hash-table
3))))
20 (mapc #'try
'(typexpand-1 typexpand typexpand-all
))))
22 (with-test (:name
:no-
*-as-t
) ; lp#1860919
23 (assert-signal (sb-kernel:specifier-type
'(function (*) t
)) warning
)
24 (dolist (f '((lambda (x) (the * x
))
25 (lambda (x) (declare (* x
)) x
)
26 (lambda (x) (declare (type * x
)) x
)))
27 (multiple-value-bind (f warn err
)
28 (let ((*error-output
* (make-broadcast-stream))) (compile nil f
))
30 (assert (and warn err
)))))
32 (with-test (:name
(typep sb-kernel
:ctypep
))
34 (declare (notinline mapcar
))
35 (mapcar (lambda (args)
36 (destructuring-bind (obj type-spec result
) args
37 (flet ((matches-result?
(x)
38 (eq (if x t nil
) result
)))
39 (assert (matches-result?
(typep obj type-spec
)))
40 (assert (matches-result?
(sb-kernel:ctypep
42 (sb-kernel:specifier-type
44 '((nil (or null vector
) t
)
45 (nil (or number vector
) nil
)
46 (12 (or null vector
) nil
)
47 (12 (and (or number vector
) real
) t
)))))
50 ;;; This test is motivated by bug #195, which previously had (THE REAL
51 ;;; #(1 2 3)) give an error which prints as "This is not a (OR
52 ;;; SINGLE-FLOAT DOUBLE-FLOAT RATIONAL)". We ideally want all of the
53 ;;; defined-by-ANSI types to unparse as themselves or at least
54 ;;; something similar (e.g. CHARACTER can unparse to BASE-CHAR, since
55 ;;; the types are equivalent in current SBCL, and EXTENDED-CHAR can
56 ;;; unparse to NIL, since there are no EXTENDED-CHARs currently).
57 (with-test (:name
:standard-types
)
58 (let ((standard-types '(;; from table 4-2 in section 4.2.3 in the
89 standard-generic-function
147 floating-point-inexact
150 floating-point-invalid-operation
153 floating-point-overflow
155 floating-point-underflow
157 (dolist (type standard-types
)
158 #+nil
(format t
"~&~S~%" type
)
159 (assert (not (sb-kernel:unknown-type-p
(sb-kernel:specifier-type type
))))
160 (assert (atom (sb-kernel:type-specifier
(sb-kernel:specifier-type type
)))))))
162 ;;; a bug underlying the reported bug #221: The SB-KERNEL type code
163 ;;; signalled an error on this expression.
164 (with-test (:name
(subtypep function values
:bug-221
))
165 (subtypep '(function (fixnum) (values package boolean
))
166 '(function (t) (values package boolean
))))
168 ;;; bug reported by Valtteri Vuorik
169 (with-test (:name
(subtypep function
&rest
))
170 (checked-compile '(lambda () (member (char "foo" 0) '(#\.
#\
/) :test
#'char
=)))
171 (assert-tri-eq t t
(subtypep '(function ()) '(function (&rest t
))))
172 (assert-tri-eq nil t
(subtypep '(function (&rest t
)) '(function ())))
173 (assert-tri-eq t t
(subtypep '(function)
174 '(function (&optional t
&rest t
))))
175 (assert-tri-eq nil t
(subtypep '(function) '(function (t &rest t
))))
176 (assert-tri-eq t t
(subtypep 'function
'(function)))
177 (assert-tri-eq t t
(subtypep '(function) 'function
)))
179 ;;; Absent any exciting generalizations of |R, the type RATIONAL is
180 ;;; partitioned by RATIO and INTEGER. Ensure that the type system
181 ;;; knows about this. [ the type system is permitted to return NIL,
182 ;;; NIL for these, so if future maintenance breaks these tests that
183 ;;; way, that's fine. What the SUBTYPEP calls are _not_ allowed to
184 ;;; return is NIL, T, because that's completely wrong. ]
185 (with-test (:name
(subtypep integer ratio rational
))
186 (assert-tri-eq t t
(subtypep '(or integer ratio
) 'rational
))
187 (assert-tri-eq t t
(subtypep 'rational
'(or integer ratio
))))
189 ;;; Likewise, these are allowed to return NIL, NIL, but shouldn't
191 (with-test (:name
(subtypep or and not
))
192 (assert-tri-eq t t
(subtypep t
'(or real
(not real
))))
193 (assert-tri-eq t t
(subtypep t
'(or keyword
(not keyword
))))
194 (assert-tri-eq t t
(subtypep '(and cons
(not (cons symbol integer
)))
195 '(or (cons (not symbol
) *) (cons * (not integer
)))))
196 (assert-tri-eq t t
(subtypep '(or (cons (not symbol
) *) (cons * (not integer
)))
197 '(and cons
(not (cons symbol integer
)))))
198 (assert-tri-eq t t
(subtypep '(or (eql 0) (rational (0) 10))
200 (assert-tri-eq t t
(subtypep '(rational 0 10)
201 '(or (eql 0) (rational (0) 10)))))
203 ;;; Until sbcl-0.7.13.7, union of CONS types when the CDRs were the
204 ;;; same type gave exceedingly wrong results
205 (with-test (:name
(subtypep cons
:same-cdr
))
206 (let ((a '(or (cons fixnum single-float
) (cons bignum single-float
)))
207 (b '(cons single-float single-float
))
208 (c '(cons integer single-float
)))
209 (assert-tri-eq nil t
(subtypep a b
))
210 (assert-tri-eq t t
(subtypep c a
))))
212 (with-test (:name
(subtypep :unknown-type
))
213 (checked-compile-and-assert (:allow-style-warnings t
)
215 (subtypep '(and null some-unknown-type
) 'another-unknown-type
))
216 (() (values nil nil
) :allow-conditions
'sb-kernel
:parse-unknown-type
)))
219 (with-test (:name
(coerce function
:on
:macro
))
220 (dolist (fun '(and if
))
221 (assert-error (coerce fun
'function
))))
223 (with-test (:name
(typep array class-of
))
225 (let ((x (make-array 0 :element-type
`(unsigned-byte ,(1+ i
)))))
226 (eval `(typep ,x
(class-of ,x
))))))
228 (with-test (:name
(typep complex member
))
229 (assert (not (typep #c
(1 2) '(member #c
(2 1)))))
230 (assert (typep #c
(1 2) '(member #c
(1 2)))))
232 (with-test (:name
(subtypep complex
))
233 (assert-tri-eq t t
(subtypep 'nil
'(complex nil
)))
234 (assert-tri-eq t t
(subtypep '(complex nil
) 'nil
))
235 (assert-tri-eq t t
(subtypep 'nil
'(complex (eql 0))))
236 (assert-tri-eq t t
(subtypep '(complex (eql 0)) 'nil
))
237 (assert-tri-eq t t
(subtypep 'nil
'(complex (integer 0 0))))
238 (assert-tri-eq t t
(subtypep '(complex (integer 0 0)) 'nil
))
239 (assert-tri-eq t t
(subtypep 'nil
'(complex (rational 0 0))))
240 (assert-tri-eq t t
(subtypep '(complex (rational 0 0)) 'nil
))
241 (assert-tri-eq t t
(subtypep 'complex
'(complex real
)))
242 (assert-tri-eq t t
(subtypep '(complex real
) 'complex
))
243 (assert-tri-eq t t
(subtypep '(complex (eql 1)) '(complex (member 1 2))))
244 (assert-tri-eq t t
(subtypep '(complex ratio
) '(complex rational
)))
245 (assert-tri-eq t t
(subtypep '(complex ratio
) 'complex
))
246 (assert-tri-eq nil t
(subtypep '(complex (integer 1 2))
247 '(member #c
(1 1) #c
(1 2) #c
(2 1) #c
(2 2)))))
249 (with-test (:name
(typep real
))
250 (assert (typep 0 `(real ,(ash -
1 10000) ,(ash 1 10000)))))
252 (with-test (:name
(subtypep real
))
253 (assert-tri-eq t t
(subtypep `(real ,(ash -
1 1000) ,(ash 1 1000))
254 `(real ,(ash -
1 10000) ,(ash 1 10000))))
255 (assert-tri-eq t t
(subtypep `(real (,(ash -
1 1000)) (,(ash 1 1000)))
256 `(real ,(ash -
1 1000) ,(ash 1 1000)))))
258 ;;; Bug, found by Paul F. Dietz
259 (with-test (:name
(typep subtypep complex rational
))
260 (let* ((x (eval #c
(-1 1/2)))
262 (assert (subtypep type
'(complex rational
)))
263 (assert (typep x type
))))
265 ;;; Test derivation of LOG{AND,IOR,XOR} bounds for unsigned arguments.
267 ;;; Fear the Loop of Doom!
269 ;;; (In fact, this is such a fearsome loop that executing it with the
270 ;;; evaluator would take ages... Disable it under those circumstances.)
271 #+#.
(cl:if
(cl:eq sb-ext
:*evaluator-mode
* :compile
) '(and) '(or))
272 (with-test (:name
(:type-derivation
:logical-operations
:correctness
) :slow t
)
274 (size (ash 1 n-bits
)))
275 (labels ((brute-force (a b c d op
)
276 (loop with min
= (ash 1 n-bits
)
278 for i from a upto b do
279 (loop for j from c upto d do
280 (let ((x (funcall op i j
)))
281 (setf min
(min min x
)
283 finally
(return (values min max
))))
284 (test (a b c d op deriver
)
285 (multiple-value-bind (brute-low brute-high
)
286 (brute-force a b c d op
)
287 (multiple-value-bind (test-low test-high
)
289 (sb-c::specifier-type
`(integer ,a
,b
))
290 (sb-c::specifier-type
`(integer ,c
,d
)))
291 (unless (and (= brute-low test-low
)
292 (= brute-high test-high
))
293 (format t
"FAIL: ~A [~D, ~D] [~D, ~D]~%EXPECTED [~D, ~D] GOT [~D, ~D]~%"
295 brute-low brute-high test-low test-high
)
296 (assert (and (= brute-low test-low
)
297 (= brute-high test-high
))))))))
298 (dolist (op '(logand logior logxor
))
299 (let ((deriver (intern (format nil
"~A-DERIVE-UNSIGNED-BOUNDS" op
)
300 (find-package :sb-c
))))
301 #+(or) (format t
"testing type derivation: ~A~%" deriver
)
302 (loop for a from
0 below size do
303 (loop for b from a below size do
304 (loop for c from
0 below size do
305 (loop for d from c below size do
306 (test a b c d op deriver
))))))))))
308 (with-test (:name
(:type-derivation
:logical-operations
:scaling
) :slow t
)
309 (let ((type-x1 (sb-c::specifier-type
`(integer ,(expt 2 10000)
311 (type-x2 (sb-c::specifier-type
`(integer ,(expt 2 100000)
313 (type-y (sb-c::specifier-type
'(integer 0 1))))
314 (dolist (op '(logand logior logxor
))
315 (let* ((deriver (intern (format nil
"~A-DERIVE-TYPE-AUX" op
)
316 (find-package :sb-c
)))
317 (scale (/ (runtime (funcall deriver type-x2 type-y
))
318 (runtime (funcall deriver type-x1 type-y
)))))
319 ;; Linear scaling is good, quadratical bad. Draw the line
320 ;; near the geometric mean of the corresponding SCALEs.
322 (error "Bad scaling of ~a: input 10 times but runtime ~a times as large."
325 ;;; SUBTYPEP on CONS types wasn't taking account of the fact that a
326 ;;; CONS type could be the empty type (but no other non-CONS type) in
328 (with-test (:name
(subtypep cons
:empty
))
329 (multiple-value-bind (yes win
)
330 (subtypep '(and function stream
) 'nil
)
331 (multiple-value-bind (cyes cwin
)
332 (subtypep '(cons (and function stream
) t
)
334 (assert (eq yes cyes
))
335 (assert (eq win cwin
)))))
337 (with-test (:name
:intelligent-satisfies
)
338 (assert (sb-kernel:type
= (sb-kernel:specifier-type
'(satisfies realp
))
339 (sb-kernel:specifier-type
'real
)))
340 ;; Part of an example in https://bugs.launchpad.net/sbcl/+bug/309455
341 (multiple-value-bind (answer certain
)
342 (subtypep 'complex
'(and number
(satisfies realp
)))
343 (assert (not answer
))
346 ;;; CONS type SUBTYPEP could be too enthusiastic about thinking it was
348 (with-test (:name
(subtypep cons satisfies
))
349 (assert-tri-eq nil nil
(subtypep '(satisfies foo
) '(satisfies bar
)))
350 (assert-tri-eq nil nil
(subtypep '(cons (satisfies foo
) t
)
351 '(cons (satisfies bar
) t
))))
353 (with-test (:name
(subtypep generic-function function
))
354 (assert-tri-eq t t
(subtypep 'generic-function
'function
)))
356 ;;; this would be in some internal test suite like type.before-xc.lisp
357 ;;; except that generic functions don't exist at that stage.
358 (with-test (:name
(subtypep generic-function sb-kernel
:funcallable-instance
))
359 (assert-tri-eq t t
(subtypep 'generic-function
360 'sb-kernel
:funcallable-instance
)))
362 ;;; all sorts of answers are right for this one, but it used to
363 ;;; trigger an AVER instead.
364 (with-test (:name
(subtypep function satisfies
:smoke
))
365 (subtypep '(function ()) '(and (function ()) (satisfies identity
))))
367 (with-test (:name
(sb-kernel:specifier-type
:unknown-type
))
368 (assert (sb-kernel:unknown-type-p
(sb-kernel:specifier-type
'an-unkown-type
))))
370 (with-test (:name
(sb-kernel:type
= array
))
371 (assert-tri-eq t t
(ctype= '(or (simple-array an-unkown-type
(*))
372 (simple-array an-unkown-type
))
373 '(or (simple-array an-unkown-type
(*))
374 (simple-array an-unkown-type
))))
375 (assert-tri-eq t t
(ctype= '(simple-array an-unkown-type
(*))
376 '(simple-array an-unkown-type
(*))))
377 (assert-tri-eq nil t
(ctype= '(simple-array an-unkown-type
(*))
378 '(array an-unkown-type
(*))))
379 (assert-tri-eq nil t
(ctype= '(simple-array an-unkown-type
(7))
380 '(simple-array an-unkown-type
(8)))))
382 (with-test (:name
(sb-kernel:type
= cons
))
383 (assert-tri-eq nil t
(ctype= 'cons
'(cons single-float single-float
)))
384 (assert-tri-eq nil t
(ctype= '(cons integer
) '(cons))))
386 (with-test (:name
(typep subtypep sb-kernel
:instance
))
387 (assert (typep #p
"" 'sb-kernel
:instance
))
388 (assert-tri-eq t t
(subtypep '(member #p
"") 'sb-kernel
:instance
)))
390 (with-test (:name
(sb-kernel:type
= :simd-pack
))
391 (dolist (x '(single-float double-float
))
392 (let ((spec `(simd-pack ,x
)))
393 (assert (equal (multiple-value-list (ctype= spec spec
)) '(t t
))))))
395 (with-test (:name
(typep :character-set
:negation
))
396 (flet ((generate-chars ()
398 collect
(code-char (random char-code-limit
)))))
400 (let* ((chars (generate-chars))
401 (type `(member ,@chars
))
402 (not-type `(not ,type
)))
404 (assert (typep char type
))
405 (assert (not (typep char not-type
))))
406 (let ((other-chars (generate-chars)))
407 (dolist (char other-chars
)
408 (unless (member char chars
)
409 (assert (not (typep char type
)))
410 (assert (typep char not-type
)))))))))
412 (with-test (:name
(check-type :store-value
:complex-place
))
413 (let ((a (cons 0.0 2))
414 (handler-invoked nil
))
415 (handler-bind ((error
418 (assert (not handler-invoked
))
419 (setf handler-invoked t
)
420 (invoke-restart 'store-value
1))))
421 (check-type (car a
) integer
))
422 (assert (eql (car a
) 1))))
424 ;;; The VOP FIXNUMP/UNSIGNED-BYTE-64 was broken on x86-64, failing
425 ;;; the first ASSERT below. The second ASSERT takes care that the fix
426 ;;; doesn't overshoot the mark.
427 (with-test (:name
(typep :fixnum-if-unsigned-byte
))
428 (checked-compile-and-assert ()
430 (declare (type (unsigned-byte #.sb-vm
:n-word-bits
) x
))
431 (typep x
(quote fixnum
)))
432 (((1+ most-positive-fixnum
)) nil
)
433 ((most-positive-fixnum) t
)))
435 (with-test (:name
(typep :member
:uses eql
))
436 (assert (eval '(typep 1/3 '(member 1/3 nil
))))
437 (assert (eval '(typep 1.0 '(member 1.0 t
))))
438 (assert (eval '(typep #c
(1.1
1.2) '(member #c
(1.1
1.2)))))
439 (assert (eval '(typep #c
(1 1) '(member #c
(1 1)))))
440 (let ((bignum1 (+ 12 most-positive-fixnum
))
441 (bignum2 (- (+ 15 most-positive-fixnum
) 3)))
442 (assert (eval `(typep ,bignum1
'(member ,bignum2
))))))
444 (with-test (:name
:opt
+rest
+key-canonicalization
)
445 (let ((type '(function (&optional t
&rest t
&key
(:x t
) (:y t
)) *)))
446 (assert (equal type
(sb-kernel:type-specifier
(sb-kernel:specifier-type type
))))))
448 (with-test (:name
:bug-369
)
449 (let ((types (mapcar #'sb-c
::values-specifier-type
450 '((values (vector package
) &optional
)
451 (values (vector package
) &rest t
)
452 (values (vector hash-table
) &rest t
)
453 (values (vector hash-table
) &optional
)
456 (values nil
&optional
)
458 (values sequence
&optional
)
459 (values sequence
&rest t
)
460 (values list
&optional
)
461 (values list
&rest t
)))))
464 (let ((i (sb-c::values-type-intersection x y
)))
465 (assert (sb-c::type
= i
(sb-c::values-type-intersection i x
)))
466 (assert (sb-c::type
= i
(sb-c::values-type-intersection i y
))))))))
468 (with-test (:name
(subtypep keyword symbol
:bug-485972
))
469 (assert-tri-eq nil t
(subtypep 'symbol
'keyword
))
470 (assert-tri-eq t t
(subtypep 'keyword
'symbol
)))
472 ;; WARNING: this test case would fail by recursing into the stack's guard page.
473 (with-test (:name
(sb-kernel:specifier-type or and satisfies
:bug-883498
))
474 (sb-kernel:specifier-type
476 (and (satisfies foo
) (rational -
3/2 -
3/2)))))
478 ;; The infinite recursion mentioned in the previous test was caused by an
479 ;; attempt to get the following right.
480 (with-test (:name
:quirky-integer-rational-union
)
481 (assert-tri-eq t t
(subtypep '(or (integer * -
1)
482 (and (rational * -
1/2) (not integer
)))
484 (assert-tri-eq t t
(subtypep '(rational * -
1/2)
486 (and (rational * -
1/2) (not integer
))))))
488 ;; for the longest time (at least 05525d3a), single-value-type would
489 ;; return CHARACTER on this.
490 (with-test (:name
:single-value-
&optional-type
)
491 (assert (sb-c::type
= (sb-c::single-value-type
492 (sb-c::values-specifier-type
'(values &optional character
)))
493 (sb-c::specifier-type
'(or null character
)))))
495 ;; lp#1317308 - TYPE-OF must not return a type specifier
496 ;; involving AND,EQL,MEMBER,NOT,OR,SATISFIES,or VALUES.
497 (with-test (:name
:ANSIly-report-hairy-array-type
)
498 (let ((simp-t (make-array 9))
499 (simp-bit (make-array 16 :element-type
'bit
)))
500 ;; TYPE-OF doesn't have an optimization that returns a constant specifier
501 ;; from a non-constant array of known type. If it did, we'd probably
502 ;; want to check that these results are all equal:
503 ;; - the runtime-determined type
504 ;; - the compile-time-determined constant type
505 ;; - the compile-time-determined type of an equivalent object
506 ;; that is in fact a compile-time constant
507 (flet ((our-type-of (x) (sb-kernel:type-specifier
(sb-kernel:ctype-of x
))))
508 (let ((hairy-t (make-array 3 :displaced-to simp-t
)))
509 (assert (equal (our-type-of hairy-t
)
511 (assert (equal (type-of hairy-t
) '(vector t
3))))
512 (let ((hairy-t (make-array '(3 2) :displaced-to simp-t
)))
513 (assert (equal (our-type-of hairy-t
)
515 (assert (equal (type-of hairy-t
) '(array t
(3 2)))))
517 (make-array 5 :displaced-to simp-bit
:element-type
'bit
)))
518 (assert (equal (our-type-of hairy-bit
)
520 (assert (equal (type-of hairy-bit
) '(bit-vector 5)))))))
522 (with-test (:name
(subtypep array
:bug-309098
))
523 (let ((u `(or ,@(map 'list
(lambda (x) `(array ,(sb-vm:saetp-specifier x
)))
524 sb-vm
:*specialized-array-element-type-properties
*))))
525 (assert-tri-eq t t
(subtypep 'array u
))))
527 (with-test (:name
:bug-1258716
)
528 (let ((intersection (sb-kernel:type-intersection
529 (sb-kernel:specifier-type
'simple-vector
)
530 (sb-kernel:specifier-type
`(vector #:unknown
)))))
531 (assert (sb-kernel:array-type-p intersection
))
532 ;; and not *wild-type*
533 (assert (sb-kernel:type
= (sb-kernel:array-type-specialized-element-type intersection
)
534 sb-kernel
:*universal-type
*))))
536 (with-test (:name
:parse-safely
)
537 (dolist (x '(array integer cons
))
538 (assert (handler-case (sb-kernel:specifier-type
`(,x .
0))
539 (sb-kernel::arg-count-error
() t
)
540 (error (c) (print c
) nil
)))))
542 (with-test (:name
:unparse-safely
)
543 (let* ((intersection (sb-kernel:type-intersection
544 (sb-kernel:specifier-type
'(vector (or bit character
)))
545 (sb-kernel:specifier-type
`(vector (or bit symbol
)))))
546 (round-trip (sb-kernel:specifier-type
547 (sb-kernel:type-specifier intersection
))))
548 (assert (sb-kernel:type
= intersection round-trip
))
549 (assert (sb-kernel:array-type-p intersection
))
550 ;; and not *wild-type*
551 (assert (sb-kernel:type
/= (sb-kernel:array-type-specialized-element-type intersection
)
552 (sb-kernel:specifier-type
'bit
)))))
555 (with-test (:name
(adjust-array :changes type-of
))
556 ;; I think adjusting an array to enlarge it must read all the old data,
557 ;; which would be undefined behavior if you hadn't initialized the array.
558 (let ((a (make-array 10 :adjustable t
:initial-element
0)))
559 (assert (equal (type-of a
) '(vector t
10)))
561 (assert (equal (type-of a
) '(vector t
20)))))
563 (with-test (:name
:unknown-type-strongly-uncacheable
)
564 ;; VALUES-SPECIFIER-TYPE should not cache a specifier any part of which
565 ;; is unknown. This leads to consistent results when parsing unknown
566 ;; types. Previously it was indeterminate whether a condition would
567 ;; be signaled for (OR UNKNOWN KNOWN) depending on whether that expression
568 ;; had ever been parsed and whether it had been evicted from the cache.
569 (assert-signal (progn (sb-kernel:specifier-type
'(or weeble ratio
))
570 (sb-kernel:specifier-type
'(or weeble ratio
)))
571 sb-kernel
:parse-unknown-type
2) ; expect 2 signals
572 (assert-signal (progn (sb-kernel:specifier-type
'(and potrzebie real
))
573 (sb-kernel:specifier-type
'(and potrzebie real
)))
574 sb-kernel
:parse-unknown-type
2) ; expect 2 signals
575 (assert-signal (progn (sb-kernel:specifier-type
'(array strudel
))
576 (sb-kernel:specifier-type
'(array strudel
)))
577 sb-kernel
:parse-unknown-type
2) ; expect 2 signals
578 (assert-signal (progn (sb-kernel:specifier-type
'(not bad
))
579 (sb-kernel:specifier-type
'(not bad
)))
580 sb-kernel
:parse-unknown-type
2)) ; expect 2 signals
582 (with-test (:name
(typep :complex-integer
))
583 (assert (not (eval '(typep #c
(0 1/2) '(complex integer
))))))
585 (with-test (:name
:typep-satisfies-boolean
)
586 (assert (eq (eval '(typep 1 '(satisfies eval
))) t
)))
588 (import '(sb-kernel:specifier-type
589 sb-kernel
:type-specifier
590 sb-kernel
:type-intersection
591 #+sb-unicode sb-kernel
::character-string
592 sb-kernel
:simple-character-string
594 sb-kernel
:find-classoid
595 sb-kernel
:make-numeric-type
596 sb-kernel
::numeric-types-adjacent
597 sb-kernel
::numeric-types-intersect
598 sb-kernel
:*empty-type
*))
600 (with-test (:name
:partition-array-into-simple
/hairy
)
601 ;; Some tests that (simple-array | hairy-array) = array
602 ;; At present this works only for wild element-type.
604 t t
(type= (specifier-type '(not (and array
(not simple-array
))))
605 (specifier-type '(or (not array
) simple-array
))))
607 ;; if X is neither simple-array nor hairy-array, it is not an array
608 (assert (type= (specifier-type '(and (not simple-array
)
609 (not (and array
(not simple-array
)))))
610 (specifier-type '(not array
))))
612 ;; (simple-array * (*)) = (AND (NOT <hairy-array>) VECTOR) etc
613 (flet ((try (unrestricted simple
)
614 (assert (type= (specifier-type simple
)
617 '(not (and array
(not simple-array
))))
618 (specifier-type unrestricted
))))))
619 (try 'vector
'(simple-array * (*)))
620 (try '(vector t
) 'simple-vector
)
621 (try 'bit-vector
'simple-bit-vector
)
622 (try 'string
'simple-string
)
623 #+sb-unicode
(try 'character-string
'simple-character-string
)
624 (try 'base-string
'simple-base-string
))
626 ;; if X is a known string and not an array-header
627 ;; it must be a SIMPLE-STRING
628 (assert (type= (type-intersection
629 (specifier-type 'string
)
631 '(not (or (and simple-array
(not vector
))
632 (and array
(not simple-array
))))))
633 (specifier-type 'simple-string
))))
635 (with-test (:name
:values-
*-illegal
)
636 (dolist (x '((values *)
640 (values bit
&optional
*)
642 (values bit
&rest
*)))
643 (assert-signal (sb-kernel:values-specifier-type x
) warning
)))
645 (with-test (:name
:classoids-as-type-specifiers
)
646 (dolist (classoid (list (find-classoid 'integer
)
647 (find-class 'integer
)))
648 ;; Classoids and classes should work as type specifiers
649 ;; in the atom form, not as lists.
650 ;; Their legality or lack thereof is equivalent in all cases.
651 (checked-compile `(lambda (x) (declare (,classoid x
)) x
))
652 (checked-compile `(lambda (x) (declare (type ,classoid x
)) x
))
653 ;; Negative tests come in two flavors:
654 ;; In the case of (DECLARE (TYPE ...)), parsing the following thing
655 ;; as a type should fail. But when 'TYPE is implied, "canonization"
656 ;; should do nothing, because the following form is not a type,
657 ;; so we get an error about an unrecognized declaration instead.
658 (flet ((expect-lose (type)
659 (assert (nth-value 1 (checked-compile
660 `(lambda (x) (declare (,type x
)) x
)
662 (assert (nth-value 1 (checked-compile
663 `(lambda (x) (declare (,type x
)) x
)
664 :allow-warnings t
)))))
665 (expect-lose `(,classoid
))
666 (expect-lose `(,classoid
1 100)))))
668 (with-test (:name
:classoid-type-kind
)
670 (let ((c (sb-kernel:find-classoid s nil
)))
671 ;; No classoid can have a :TYPE :KIND that is :DEFINED.
673 (if (typep c
'sb-kernel
:built-in-classoid
)
674 (assert (eq (sb-int:info
:type
:kind s
) :primitive
))
675 (assert (eq (sb-int:info
:type
:kind s
) :instance
)))))))
677 (with-test (:name
(make-numeric-type :smoke
))
678 (assert (eq (make-numeric-type :class
'integer
:low
'(4) :high
'(5))
681 (with-test (:name
(make-numeric-type :union
))
682 (assert (equal (type-specifier (make-numeric-type :low
'(-79106810381456307)))
683 `(or (rational (-79106810381456307))
684 (single-float (-7.910681e16
))
685 (double-float (-7.91068103814563d16
))))))
687 (with-test (:name
(make-numeric-type :infinities
))
689 (assert (equal (type-specifier
690 (make-numeric-type :low sb-ext
:single-float-negative-infinity
691 :high sb-ext
:single-float-negative-infinity
))
692 `(or (single-float ,sb-ext
:single-float-negative-infinity
693 ,sb-ext
:single-float-negative-infinity
)
694 (double-float ,sb-ext
:double-float-negative-infinity
695 ,sb-ext
:double-float-negative-infinity
))))
696 (assert (equal (type-specifier
697 (make-numeric-type :low sb-ext
:single-float-negative-infinity
))
700 (assert (equal (type-specifier
701 (make-numeric-type :class
'float
702 :low sb-ext
:single-float-negative-infinity
703 :high sb-ext
:single-float-negative-infinity
))
704 `(or (single-float ,sb-ext
:single-float-negative-infinity
705 ,sb-ext
:single-float-negative-infinity
)
706 (double-float ,sb-ext
:double-float-negative-infinity
707 ,sb-ext
:double-float-negative-infinity
))))
708 (assert (equal (type-specifier
709 (make-numeric-type :class
'float
710 :low sb-ext
:single-float-negative-infinity
))
713 (with-test (:name
:prettier-union-types
:skipped-on
(not :sb-unicode
))
714 ;; (OR STRING BIGNUM) used to unparse as
715 ;; (OR (VECTOR CHARACTER) BASE-STRING (INTEGER * -4611686018427387905)
716 ;; (INTEGER 4611686018427387904)) etc
717 (dolist (other '(float real bignum
))
718 (let* ((spec `(or string
,other
))
719 (parse (sb-kernel:specifier-type spec
))
720 (unparse (sb-kernel:type-specifier parse
)))
721 (assert (or (equal unparse
`(or string
,other
))
722 (equal unparse
`(or ,other string
)))))))
724 (with-test (:name
:unparse-string
)
725 (assert (equal (type-specifier (specifier-type '(string 10)))
726 '(#+sb-unicode string
#-sb-unicode base-string
10)))
727 (assert (equal (type-specifier (specifier-type '(simple-string 10)))
728 '(#+sb-unicode simple-string
#-sb-unicode simple-base-string
10))))
730 (with-test (:name
:numeric-types-adjacent
)
731 (dolist (x '(-0s0 0s0
))
732 (dolist (y '(-0s0 0s0
))
733 (let ((a (specifier-type `(single-float -
10s0
,x
)))
734 (b (specifier-type `(single-float ,y
20s0
))))
735 (assert (numeric-types-intersect a b
)))
736 (let ((a (specifier-type `(single-float -
10s0
(,x
))))
737 (b (specifier-type `(single-float ,y
20s0
))))
738 (assert (not (numeric-types-intersect a b
)))
739 (assert (numeric-types-adjacent a b
)))
740 (let ((a (specifier-type `(single-float -
10s0
,x
)))
741 (b (specifier-type `(single-float (,y
) 20s0
))))
742 (assert (not (numeric-types-intersect a b
)))
743 (assert (numeric-types-adjacent a b
))))))
745 (with-test (:name
:ctypep-function
)
746 (assert (not (sb-kernel:ctypep
#'+ (eval '(sb-kernel:specifier-type
'(function (list))))))))
748 (with-test (:name
:cons-union-loop
)
749 (checked-compile-and-assert
752 (typep x
'(or (cons (or fixnum vector
(member a
"b")))
753 (cons (or (and (not vector
) array
) (and (not integer
) number
)) number
))))
757 (with-test (:name
:pathnamep-flag-bit
)
758 (let ((f (compile nil
'(lambda (x) (pathnamep x
)))))
759 (assert (not (ctu:find-code-constants f
)))))
761 (with-test (:name
:structure-is-a
)
762 (dolist (what '(sb-int:sset-element sb-c
::leaf sb-c
::functional
763 sb-c
::optional-dispatch
))
764 (assert (eval `(sb-c::%structure-is-a
,(sb-kernel:find-layout
'sb-c
::optional-dispatch
)
765 ,(sb-kernel:find-layout what
))))))
767 (with-test (:name
:type-of-empty-instance
)
768 (assert (eq (type-of (test-util::make-funcallable-instance
6))
769 'sb-kernel
:funcallable-instance
))
770 (assert (eq (type-of (eval '(sb-kernel:%make-instance
12)))
771 'sb-kernel
:instance
)))
773 (with-test (:name
(:cons-union
:lp1912863
))
774 (let ((c (cons 2 4)))
775 (assert (not (typep c
'(or (cons (integer 0 8) (integer 5 15))
776 (cons (integer 3 15) (integer 4 14))))))))
778 (with-test (:name
(:rational-union
:equivalent-to-t
))
779 (let ((type '(or (integer * -
1) (rational -
1/2 1/2) (integer 1) (not integer
))))
780 (assert-tri-eq t t
(subtypep t type
))))
782 (with-test (:name
(:rational-union
:wider-equivalent-to-t
))
783 (let ((type '(or (integer * -
2) (rational -
3/2 3/2) (integer 2) (not integer
))))
784 (assert-tri-eq t t
(subtypep t type
))))
786 (with-test (:name
(:rational-union
:no-integers-in-rational
))
787 (let ((type '(or (integer 1 1) (rational 1/2 1/2))))
788 (assert-tri-eq t t
(subtypep type
'rational
))
789 (assert-tri-eq nil t
(subtypep 'rational type
))
790 (assert-tri-eq nil t
(subtypep type
'integer
))
791 (assert-tri-eq nil t
(subtypep 'integer type
))
792 (assert (typep 1 type
))
793 (assert (typep 1/2 type
))
794 (assert (not (typep 3/4 type
)))))
796 (with-test (:name
(:rational-union
:open-bounds-closed
))
797 (let ((t1 '(rational -
1 1))
798 (t2 '(or (integer -
1 1) (rational (-1) (1)))))
799 (assert-tri-eq t t
(subtypep t1 t2
))
800 (assert-tri-eq t t
(subtypep t2 t1
))))
802 (with-test (:name
(:rational-union
:lp1912863
:bug039
))
805 (t2 '(or (not (cons t
(real -
1 1)))
806 (not (cons sequence
(eql 2))))))
807 (assert-tri-eq t t
(subtypep t1 t2
))
808 (assert-tri-eq t t
(subtypep `(not ,t2
) `(not ,t1
))))))
811 (with-test (:name
(:rational-union
:lp1912863
:bug041
))
813 (let ((t1 '(not (cons t integer
)))
814 (t2 '(not (cons (array nil
) (eql 0))))
815 (t3 '(cons simple-array t
)))
816 (assert-tri-eq t t
(subtypep t1 t2
))
817 (assert-tri-eq t t
(subtypep `(not (or ,t2
,t3
)) `(not ,t1
)))
818 (assert-tri-eq t t
(subtypep `(and (not ,t2
) (not ,t3
)) `(not ,t1
))))))
821 (with-test (:name
(:lp1916040
:answer
))
822 (let* ((t1 '(cons sequence short-float
))
823 (t2 '(or (cons t atom
) (cons function t
)))
824 (answer (multiple-value-list (subtypep t1 t2
))))
825 (assert (member answer
'((nil nil
) (t t
)) :test
'equal
))))
827 (with-test (:name
(:lp1916233
))
828 (assert-tri-eq t t
(subtypep '(cons (or (simple-array ratio
) simple-array
) nil
) nil
))
829 (assert-tri-eq t t
(subtypep '(or (array ratio
) sequence
) t
)))
831 (defun my-widetag-of (x)
832 (sb-sys:sap-ref-8
(sb-sys:int-sap
(sb-kernel:get-lisp-obj-address x
))
833 (- sb-vm
:other-pointer-lowtag
)))
834 ;;; I'll bet that nothing anywhere tests this
835 (with-test (:name
:nil-has-symbol-widetag
836 :skipped-on
(:or
:ppc64
:big-endian
))
837 (assert (= (my-widetag-of nil
) (my-widetag-of t
))))
839 (with-test (:name
:array-rank-deriver-negation
)
842 (sb-kernel:%simple-fun-type
844 `(lambda (a) (array-rank (the (not (array t
)) a
))))))
845 `(values (mod 129) &optional
))))
847 (with-test (:name
(:rational-intersection
:lp1998008
))
849 (let ((t1 '(or (not (real 1 3)) (eql 2))))
850 (assert-tri-eq t t
(subtypep `(not (not ,t1
)) t1
))
851 (assert-tri-eq t t
(subtypep t1
`(not (not ,t1
)))))))
854 (with-test (:name
(:rational-intersection
:integer-bounds
))
855 (let ((t1 '(and (not integer
) (rational 3 5)))
856 (t2 '(and (not integer
) (rational (3) (5)))))
857 (assert-tri-eq t t
(subtypep t1 t2
))
858 (assert-tri-eq t t
(subtypep t2 t1
))
859 (assert-tri-eq t t
(subtypep `(not ,t1
) `(not ,t2
)))
860 (assert-tri-eq t t
(subtypep `(not ,t2
) `(not ,t1
)))))
862 (with-test (:name
(:cons-union
:lp1999352
))
864 (type1 `(cons (or atom
(eql ,v
))))
865 (type2 `(cons (or (member :a
2) cons
) list
)))
866 (let ((bug103 (compile nil
868 (declare (type ,type1 val
))
870 (assert (equal (funcall bug103
(list v
)) '((:a
)))))))
872 (with-test (:name
:union-type-checks
)
873 (assert (not (find 'integerp
874 (ctu:ir1-named-calls
`(lambda (x)
875 (declare ((or list fixnum
) x
))
879 (with-test (:name
:union-intersection-simplification
)
880 (checked-compile-and-assert
884 (and symbol
(not null
))
885 (and array
(not string
)))))
891 (with-test (:name
:union-integer-complex
)
892 (checked-compile-and-assert
895 (typep x
'(or (integer 36757953510256822604)
898 ((36757953510256822603) nil
)
899 ((36757953510256822604) t
)
900 ((36757953510256822605) t
)
903 ((#C
(1 #.
(expt 2 300))) nil
)))
906 (with-test (:name
:structure-typep-fold
)
909 (declare (character a
))
910 (sb-c::structure-typep a b
))
914 (declare (hash-table a
))
915 (sb-c::structure-typep a
#.
(sb-kernel:find-layout
'condition
)))
919 (declare (pathname a
))
920 (sb-c::structure-typep a
#.
(sb-kernel:find-layout
'pathname
)))
923 (with-test (:name
:typep-vector-folding
)
926 (declare (integer p
))
927 (typep p
'(vector t
1)))