aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2024-03-18 09:35:11 -0400
committerStefan Monnier2024-03-18 09:35:11 -0400
commitbe08372bf9b7ebe244ba6940f3e78fc754910d86 (patch)
treebb192d43d3e87a0945f0f05967da310aae29030a
parent1a8b34a503e5af32851c1aac27a3f09e2345673b (diff)
parent63e67916b01569da5bb24f6d9a354dc72897c468 (diff)
downloademacs-be08372bf9b7ebe244ba6940f3e78fc754910d86.tar.gz
emacs-be08372bf9b7ebe244ba6940f3e78fc754910d86.zip
Merge branch 'cl-type-of' (bug#69739)
-rw-r--r--doc/lispref/objects.texi27
-rw-r--r--etc/NEWS9
-rw-r--r--lisp/emacs-lisp/cl-generic.el6
-rw-r--r--lisp/emacs-lisp/cl-preloaded.el13
-rw-r--r--lisp/emacs-lisp/eieio-core.el2
-rw-r--r--lisp/emacs-lisp/seq.el3
-rw-r--r--lisp/subr.el11
-rw-r--r--src/comp.c2
-rw-r--r--src/data.c40
-rw-r--r--src/lisp.h6
-rw-r--r--src/puresize.h2
-rw-r--r--src/sqlite.c17
-rw-r--r--test/src/data-tests.el35
13 files changed, 134 insertions, 39 deletions
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 279f449a994..aa1e073042f 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -1485,8 +1485,8 @@ types that are not built into Emacs.
1485@subsection Type Descriptors 1485@subsection Type Descriptors
1486 1486
1487 A @dfn{type descriptor} is a @code{record} which holds information 1487 A @dfn{type descriptor} is a @code{record} which holds information
1488about a type. Slot 1 in the record must be a symbol naming the type, and 1488about a type. The first slot in the record must be a symbol naming the type,
1489@code{type-of} relies on this to return the type of @code{record} 1489and @code{type-of} relies on this to return the type of @code{record}
1490objects. No other type descriptor slot is used by Emacs; they are 1490objects. No other type descriptor slot is used by Emacs; they are
1491free for use by Lisp extensions. 1491free for use by Lisp extensions.
1492 1492
@@ -2175,7 +2175,7 @@ with references to further information.
2175function @code{type-of}. Recall that each object belongs to one and 2175function @code{type-of}. Recall that each object belongs to one and
2176only one primitive type; @code{type-of} tells you which one (@pxref{Lisp 2176only one primitive type; @code{type-of} tells you which one (@pxref{Lisp
2177Data Types}). But @code{type-of} knows nothing about non-primitive 2177Data Types}). But @code{type-of} knows nothing about non-primitive
2178types. In most cases, it is more convenient to use type predicates than 2178types. In most cases, it is preferable to use type predicates than
2179@code{type-of}. 2179@code{type-of}.
2180 2180
2181@defun type-of object 2181@defun type-of object
@@ -2207,6 +2207,27 @@ slot is returned; @ref{Records}.
2207@end example 2207@end example
2208@end defun 2208@end defun
2209 2209
2210@defun cl-type-of object
2211This function returns a symbol naming @emph{the} type of
2212@var{object}. It usually behaves like @code{type-of}, except
2213that it guarantees to return the most precise type possible, which also
2214implies that the specific type it returns may change depending on the
2215Emacs version. For this reason, as a rule you should never compare its
2216return value against some fixed set of types.
2217
2218@example
2219(cl-type-of 1)
2220 @result{} fixnum
2221@group
2222(cl-type-of 'nil)
2223 @result{} null
2224(cl-type-of (record 'foo))
2225 @result{} foo
2226@end group
2227@end example
2228@end defun
2229
2230
2210@node Equality Predicates 2231@node Equality Predicates
2211@section Equality Predicates 2232@section Equality Predicates
2212@cindex equality 2233@cindex equality
diff --git a/etc/NEWS b/etc/NEWS
index b02712dd21c..69e61d91b0e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1647,6 +1647,15 @@ values.
1647 1647
1648* Lisp Changes in Emacs 30.1 1648* Lisp Changes in Emacs 30.1
1649 1649
1650** New function 'cl-type-of'.
1651This function is like 'type-of' except that it sometimes returns
1652a more precise type. For example, for nil and t it returns 'null'
1653and 'boolean' respectively, instead of just 'symbol'.
1654
1655** New function `primitive-function-p`.
1656This is like `subr-primitive-p` except that it returns t only if the
1657argument is a function rather than a special-form.
1658
1650** Built-in types have now corresponding classes. 1659** Built-in types have now corresponding classes.
1651At the Lisp level, this means that things like (cl-find-class 'integer) 1660At the Lisp level, this means that things like (cl-find-class 'integer)
1652will now return a class object, and at the UI level it means that 1661will now return a class object, and at the UI level it means that
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 613ecf82a92..62abe8d1589 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -1334,8 +1334,7 @@ These match if the argument is `eql' to VAL."
1334 1334
1335(defconst cl--generic--unreachable-types 1335(defconst cl--generic--unreachable-types
1336 ;; FIXME: Try to make that list empty? 1336 ;; FIXME: Try to make that list empty?
1337 '(fixnum bignum boolean keyword 1337 '(keyword)
1338 special-form subr-primitive subr-native-elisp)
1339 "Built-in classes on which we cannot dispatch for technical reasons.") 1338 "Built-in classes on which we cannot dispatch for technical reasons.")
1340 1339
1341(defun cl--generic-type-specializers (tag &rest _) 1340(defun cl--generic-type-specializers (tag &rest _)
@@ -1345,8 +1344,7 @@ These match if the argument is `eql' to VAL."
1345 (cl--class-allparents class))))) 1344 (cl--class-allparents class)))))
1346 1345
1347(cl-generic-define-generalizer cl--generic-typeof-generalizer 1346(cl-generic-define-generalizer cl--generic-typeof-generalizer
1348 ;; FIXME: We could also change `type-of' to return `null' for nil. 1347 10 (lambda (name &rest _) `(cl-type-of ,name))
1349 10 (lambda (name &rest _) `(if ,name (type-of ,name) 'null))
1350 #'cl--generic-type-specializers) 1348 #'cl--generic-type-specializers)
1351 1349
1352(cl-defmethod cl-generic-generalizers :extra "typeof" (type) 1350(cl-defmethod cl-generic-generalizers :extra "typeof" (type)
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el
index 515aa99549d..cba56e0bbd4 100644
--- a/lisp/emacs-lisp/cl-preloaded.el
+++ b/lisp/emacs-lisp/cl-preloaded.el
@@ -339,8 +339,6 @@
339 ',parents)))))) 339 ',parents))))))
340 340
341;; FIXME: Our type DAG has various quirks: 341;; FIXME: Our type DAG has various quirks:
342;; - `subr' says it's a `compiled-function' but that's not true
343;; for those subrs that are special forms!
344;; - Some `keyword's are also `symbol-with-pos' but that's not reflected 342;; - Some `keyword's are also `symbol-with-pos' but that's not reflected
345;; in the DAG. 343;; in the DAG.
346;; - An OClosure can be an interpreted function or a `byte-code-function', 344;; - An OClosure can be an interpreted function or a `byte-code-function',
@@ -367,6 +365,7 @@
367(cl--define-built-in-type buffer atom) 365(cl--define-built-in-type buffer atom)
368(cl--define-built-in-type window atom) 366(cl--define-built-in-type window atom)
369(cl--define-built-in-type process atom) 367(cl--define-built-in-type process atom)
368(cl--define-built-in-type finalizer atom)
370(cl--define-built-in-type window-configuration atom) 369(cl--define-built-in-type window-configuration atom)
371(cl--define-built-in-type overlay atom) 370(cl--define-built-in-type overlay atom)
372(cl--define-built-in-type number-or-marker atom 371(cl--define-built-in-type number-or-marker atom
@@ -428,15 +427,17 @@ For this build of Emacs it's %dbit."
428 "Abstract type of functions that have been compiled.") 427 "Abstract type of functions that have been compiled.")
429(cl--define-built-in-type byte-code-function (compiled-function) 428(cl--define-built-in-type byte-code-function (compiled-function)
430 "Type of functions that have been byte-compiled.") 429 "Type of functions that have been byte-compiled.")
431(cl--define-built-in-type subr (compiled-function) 430(cl--define-built-in-type subr (atom)
432 "Abstract type of functions compiled to machine code.") 431 "Abstract type of functions compiled to machine code.")
433(cl--define-built-in-type module-function (function) 432(cl--define-built-in-type module-function (function)
434 "Type of functions provided via the module API.") 433 "Type of functions provided via the module API.")
435(cl--define-built-in-type interpreted-function (function) 434(cl--define-built-in-type interpreted-function (function)
436 "Type of functions that have not been compiled.") 435 "Type of functions that have not been compiled.")
437(cl--define-built-in-type subr-native-elisp (subr) 436(cl--define-built-in-type special-form (subr)
438 "Type of function that have been compiled by the native compiler.") 437 "Type of the core syntactic elements of the Emacs Lisp language.")
439(cl--define-built-in-type subr-primitive (subr) 438(cl--define-built-in-type subr-native-elisp (subr compiled-function)
439 "Type of functions that have been compiled by the native compiler.")
440(cl--define-built-in-type primitive-function (subr compiled-function)
440 "Type of functions hand written in C.") 441 "Type of functions hand written in C.")
441 442
442(unless (cl--class-parents (cl--find-class 'cl-structure-object)) 443(unless (cl--class-parents (cl--find-class 'cl-structure-object))
diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el
index a2f7c4172a3..cf8bd749f2a 100644
--- a/lisp/emacs-lisp/eieio-core.el
+++ b/lisp/emacs-lisp/eieio-core.el
@@ -1046,7 +1046,7 @@ method invocation orders of the involved classes."
1046 1046
1047(defun cl--generic-struct-tag (name &rest _) 1047(defun cl--generic-struct-tag (name &rest _)
1048 ;; Use exactly the same code as for `typeof'. 1048 ;; Use exactly the same code as for `typeof'.
1049 `(if ,name (type-of ,name) 'null)) 1049 `(cl-type-of ,name))
1050 1050
1051(cl-generic-define-generalizer eieio--generic-generalizer 1051(cl-generic-define-generalizer eieio--generic-generalizer
1052 ;; Use the exact same tagcode as for cl-struct, so that methods 1052 ;; Use the exact same tagcode as for cl-struct, so that methods
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 20077db9e60..a20cff16982 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -362,8 +362,7 @@ the result.
362 362
363The result is a sequence of the same type as SEQUENCE." 363The result is a sequence of the same type as SEQUENCE."
364 (seq-concatenate 364 (seq-concatenate
365 (let ((type (type-of sequence))) 365 (if (listp sequence) 'list (type-of sequence))
366 (if (eq type 'cons) 'list type))
367 (seq-subseq sequence 0 n) 366 (seq-subseq sequence 0 n)
368 (seq-subseq sequence (1+ n)))) 367 (seq-subseq sequence (1+ n))))
369 368
diff --git a/lisp/subr.el b/lisp/subr.el
index 38a3f6edb34..3de4412637f 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -312,11 +312,20 @@ value of last one, or nil if there are none."
312 cond '(empty-body unless) t))) 312 cond '(empty-body unless) t)))
313 313
314(defsubst subr-primitive-p (object) 314(defsubst subr-primitive-p (object)
315 "Return t if OBJECT is a built-in primitive function." 315 "Return t if OBJECT is a built-in primitive written in C.
316Such objects can be functions or special forms."
316 (declare (side-effect-free error-free)) 317 (declare (side-effect-free error-free))
317 (and (subrp object) 318 (and (subrp object)
318 (not (subr-native-elisp-p object)))) 319 (not (subr-native-elisp-p object))))
319 320
321(defsubst primitive-function-p (object)
322 "Return t if OBJECT is a built-in primitive function.
323This excludes special forms, since they are not functions."
324 (declare (side-effect-free error-free))
325 (and (subrp object)
326 (not (or (subr-native-elisp-p object)
327 (eq (cdr (subr-arity object)) 'unevalled)))))
328
320(defsubst xor (cond1 cond2) 329(defsubst xor (cond1 cond2)
321 "Return the boolean exclusive-or of COND1 and COND2. 330 "Return the boolean exclusive-or of COND1 and COND2.
322If only one of the arguments is non-nil, return it; otherwise 331If only one of the arguments is non-nil, return it; otherwise
diff --git a/src/comp.c b/src/comp.c
index 3f989c722d4..76cf1f3ab6e 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -2442,7 +2442,7 @@ emit_limple_insn (Lisp_Object insn)
2442 { 2442 {
2443 Lisp_Object arg1 = arg[1]; 2443 Lisp_Object arg1 = arg[1];
2444 2444
2445 if (EQ (Ftype_of (arg1), Qcomp_mvar)) 2445 if (EQ (Fcl_type_of (arg1), Qcomp_mvar))
2446 res = emit_mvar_rval (arg1); 2446 res = emit_mvar_rval (arg1);
2447 else if (EQ (FIRST (arg1), Qcall)) 2447 else if (EQ (FIRST (arg1), Qcall))
2448 res = emit_limple_call (XCDR (arg1)); 2448 res = emit_limple_call (XCDR (arg1));
diff --git a/src/data.c b/src/data.c
index 35f4c82c68f..69b990bed76 100644
--- a/src/data.c
+++ b/src/data.c
@@ -193,16 +193,37 @@ DEFUN ("null", Fnull, Snull, 1, 1, 0,
193DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0, 193DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0,
194 doc: /* Return a symbol representing the type of OBJECT. 194 doc: /* Return a symbol representing the type of OBJECT.
195The symbol returned names the object's basic type; 195The symbol returned names the object's basic type;
196for example, (type-of 1) returns `integer'. */) 196for example, (type-of 1) returns `integer'.
197Contrary to `cl-type-of', the returned type is not always the most
198precise type possible, because instead this function tries to preserve
199compatibility with the return value of previous Emacs versions. */)
200 (Lisp_Object object)
201{
202 return SYMBOLP (object) ? Qsymbol
203 : INTEGERP (object) ? Qinteger
204 : SUBRP (object) ? Qsubr
205 : Fcl_type_of (object);
206}
207
208DEFUN ("cl-type-of", Fcl_type_of, Scl_type_of, 1, 1, 0,
209 doc: /* Return a symbol representing the type of OBJECT.
210The returned symbol names the most specific possible type of the object.
211for example, (cl-type-of nil) returns `null'.
212The specific type returned may change depending on Emacs versions,
213so we recommend you use `cl-typep', `cl-typecase', or other predicates
214rather than compare the return value of this function against
215a fixed set of types. */)
197 (Lisp_Object object) 216 (Lisp_Object object)
198{ 217{
199 switch (XTYPE (object)) 218 switch (XTYPE (object))
200 { 219 {
201 case_Lisp_Int: 220 case_Lisp_Int:
202 return Qinteger; 221 return Qfixnum;
203 222
204 case Lisp_Symbol: 223 case Lisp_Symbol:
205 return Qsymbol; 224 return NILP (object) ? Qnull
225 : EQ (object, Qt) ? Qboolean
226 : Qsymbol;
206 227
207 case Lisp_String: 228 case Lisp_String:
208 return Qstring; 229 return Qstring;
@@ -215,7 +236,7 @@ for example, (type-of 1) returns `integer'. */)
215 switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) 236 switch (PSEUDOVECTOR_TYPE (XVECTOR (object)))
216 { 237 {
217 case PVEC_NORMAL_VECTOR: return Qvector; 238 case PVEC_NORMAL_VECTOR: return Qvector;
218 case PVEC_BIGNUM: return Qinteger; 239 case PVEC_BIGNUM: return Qbignum;
219 case PVEC_MARKER: return Qmarker; 240 case PVEC_MARKER: return Qmarker;
220 case PVEC_SYMBOL_WITH_POS: return Qsymbol_with_pos; 241 case PVEC_SYMBOL_WITH_POS: return Qsymbol_with_pos;
221 case PVEC_OVERLAY: return Qoverlay; 242 case PVEC_OVERLAY: return Qoverlay;
@@ -224,7 +245,10 @@ for example, (type-of 1) returns `integer'. */)
224 case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; 245 case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration;
225 case PVEC_PROCESS: return Qprocess; 246 case PVEC_PROCESS: return Qprocess;
226 case PVEC_WINDOW: return Qwindow; 247 case PVEC_WINDOW: return Qwindow;
227 case PVEC_SUBR: return Qsubr; 248 case PVEC_SUBR:
249 return XSUBR (object)->max_args == UNEVALLED ? Qspecial_form
250 : SUBR_NATIVE_COMPILEDP (object) ? Qsubr_native_elisp
251 : Qprimitive_function;
228 case PVEC_COMPILED: return Qcompiled_function; 252 case PVEC_COMPILED: return Qcompiled_function;
229 case PVEC_BUFFER: return Qbuffer; 253 case PVEC_BUFFER: return Qbuffer;
230 case PVEC_CHAR_TABLE: return Qchar_table; 254 case PVEC_CHAR_TABLE: return Qchar_table;
@@ -4202,7 +4226,9 @@ syms_of_data (void)
4202 "Variable binding depth exceeds max-specpdl-size"); 4226 "Variable binding depth exceeds max-specpdl-size");
4203 4227
4204 /* Types that type-of returns. */ 4228 /* Types that type-of returns. */
4229 DEFSYM (Qboolean, "boolean");
4205 DEFSYM (Qinteger, "integer"); 4230 DEFSYM (Qinteger, "integer");
4231 DEFSYM (Qbignum, "bignum");
4206 DEFSYM (Qsymbol, "symbol"); 4232 DEFSYM (Qsymbol, "symbol");
4207 DEFSYM (Qstring, "string"); 4233 DEFSYM (Qstring, "string");
4208 DEFSYM (Qcons, "cons"); 4234 DEFSYM (Qcons, "cons");
@@ -4218,6 +4244,9 @@ syms_of_data (void)
4218 DEFSYM (Qprocess, "process"); 4244 DEFSYM (Qprocess, "process");
4219 DEFSYM (Qwindow, "window"); 4245 DEFSYM (Qwindow, "window");
4220 DEFSYM (Qsubr, "subr"); 4246 DEFSYM (Qsubr, "subr");
4247 DEFSYM (Qspecial_form, "special-form");
4248 DEFSYM (Qprimitive_function, "primitive-function");
4249 DEFSYM (Qsubr_native_elisp, "subr-native-elisp");
4221 DEFSYM (Qcompiled_function, "compiled-function"); 4250 DEFSYM (Qcompiled_function, "compiled-function");
4222 DEFSYM (Qbuffer, "buffer"); 4251 DEFSYM (Qbuffer, "buffer");
4223 DEFSYM (Qframe, "frame"); 4252 DEFSYM (Qframe, "frame");
@@ -4255,6 +4284,7 @@ syms_of_data (void)
4255 defsubr (&Seq); 4284 defsubr (&Seq);
4256 defsubr (&Snull); 4285 defsubr (&Snull);
4257 defsubr (&Stype_of); 4286 defsubr (&Stype_of);
4287 defsubr (&Scl_type_of);
4258 defsubr (&Slistp); 4288 defsubr (&Slistp);
4259 defsubr (&Snlistp); 4289 defsubr (&Snlistp);
4260 defsubr (&Sconsp); 4290 defsubr (&Sconsp);
diff --git a/src/lisp.h b/src/lisp.h
index f353e4956eb..f86758c88fb 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -569,10 +569,8 @@ enum Lisp_Fwd_Type
569 your object -- this way, the same object could be used to represent 569 your object -- this way, the same object could be used to represent
570 several disparate C structures. 570 several disparate C structures.
571 571
572 In addition, you need to add switch branches in data.c for Ftype_of. 572 In addition, you need to add switch branches in data.c for Fcl_type_of
573 573 and `cl--define-builtin-type` in lisp/emacs-lisp/cl-preloaded.el. */
574 You also need to add the new type to the constant
575 `cl--typeof-types' in lisp/emacs-lisp/cl-preloaded.el. */
576 574
577 575
578/* A Lisp_Object is a tagged pointer or integer. Ordinarily it is a 576/* A Lisp_Object is a tagged pointer or integer. Ordinarily it is a
diff --git a/src/puresize.h b/src/puresize.h
index ac5d2da30dc..2a716872832 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -47,7 +47,7 @@ INLINE_HEADER_BEGIN
47#endif 47#endif
48 48
49#ifndef BASE_PURESIZE 49#ifndef BASE_PURESIZE
50#define BASE_PURESIZE (2750000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) 50#define BASE_PURESIZE (3000000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
51#endif 51#endif
52 52
53/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */ 53/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */
diff --git a/src/sqlite.c b/src/sqlite.c
index 7a018b28aa4..261080da673 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -349,9 +349,7 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
349 value = XCAR (values); 349 value = XCAR (values);
350 values = XCDR (values); 350 values = XCDR (values);
351 } 351 }
352 Lisp_Object type = Ftype_of (value); 352 if (STRINGP (value))
353
354 if (EQ (type, Qstring))
355 { 353 {
356 Lisp_Object encoded; 354 Lisp_Object encoded;
357 bool blob = false; 355 bool blob = false;
@@ -385,14 +383,11 @@ bind_values (sqlite3 *db, sqlite3_stmt *stmt, Lisp_Object values)
385 SSDATA (encoded), SBYTES (encoded), 383 SSDATA (encoded), SBYTES (encoded),
386 NULL); 384 NULL);
387 } 385 }
388 else if (EQ (type, Qinteger)) 386 else if (FIXNUMP (value))
389 { 387 ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value));
390 if (BIGNUMP (value)) 388 else if (BIGNUMP (value))
391 ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value)); 389 ret = sqlite3_bind_int64 (stmt, i + 1, bignum_to_intmax (value));
392 else 390 else if (FLOATP (value))
393 ret = sqlite3_bind_int64 (stmt, i + 1, XFIXNUM (value));
394 }
395 else if (EQ (type, Qfloat))
396 ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value)); 391 ret = sqlite3_bind_double (stmt, i + 1, XFLOAT_DATA (value));
397 else if (NILP (value)) 392 else if (NILP (value))
398 ret = sqlite3_bind_null (stmt, i + 1); 393 ret = sqlite3_bind_null (stmt, i + 1);
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index ad3b2071254..daa49e671b5 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -838,4 +838,39 @@ comparing the subr with a much slower Lisp implementation."
838 (dolist (sym (list nil t 'xyzzy (make-symbol ""))) 838 (dolist (sym (list nil t 'xyzzy (make-symbol "")))
839 (should (eq sym (bare-symbol (position-symbol sym 0))))))) 839 (should (eq sym (bare-symbol (position-symbol sym 0)))))))
840 840
841(require 'cl-extra) ;For `cl--class-children'.
842
843(ert-deftest data-tests--cl-type-of ()
844 ;; Make sure that `cl-type-of' returns the most precise type.
845 ;; Note: This doesn't work for list/vector structs since those types
846 ;; are too difficult/unreliable to detect (so `cl-type-of' only says
847 ;; it's a `cons' or a `vector').
848 (dolist (val (list -2 10 (expt 2 128) nil t 'car
849 (symbol-function 'car)
850 (symbol-function 'progn)
851 (position-symbol 'car 7)))
852 (let* ((type (cl-type-of val))
853 (class (cl-find-class type))
854 (alltypes (cl--class-allparents class))
855 ;; FIXME: Our type DAG is affected by `symbols-with-pos-enabled'.
856 ;; (e.g. `symbolp' returns nil on a sympos if that var is nil).
857 (symbols-with-pos-enabled t))
858 (dolist (parent alltypes)
859 (should (cl-typep val parent))
860 (dolist (subtype (cl--class-children (cl-find-class parent)))
861 (unless (memq subtype alltypes)
862 (unless (memq subtype
863 ;; FIXME: Some types don't have any associated
864 ;; predicate,
865 '( font-spec font-entity font-object
866 finalizer condvar terminal
867 native-comp-unit interpreted-function
868 tree-sitter-compiled-query
869 tree-sitter-node tree-sitter-parser
870 ;; `functionp' also matches things of type
871 ;; `symbol' and `cons'.
872 function))
873 (should-not (cl-typep val subtype)))))))))
874
875
841;;; data-tests.el ends here 876;;; data-tests.el ends here