- "Arrange for FORM to be evaluated at load-time and use the value produced
- as if it were a constant. If READ-ONLY-P is non-NIL, then the resultant
- object is guaranteed to never be modified, so it can be put in read-only
- storage."
- (let ((*allow-instrumenting* nil))
+ "Arrange for FORM to be evaluated at load-time and use the value produced as
+if it were a constant. If READ-ONLY-P is non-NIL, then the resultant object is
+guaranteed to never be modified, so it can be put in read-only storage."
+ (let ((*allow-instrumenting* nil)
+ ;; First derive an approximate type from the source form, because it allows
+ ;; us to use READ-ONLY-P implicitly.
+ ;;
+ ;; We also use this type to augment whatever COMPILE-LOAD-TIME-VALUE
+ ;; returns -- in practice it returns *WILD-TYPE* all the time, but
+ ;; theoretically it could return something useful for the READ-ONLY-P case.
+ (source-type (single-value-type
+ (cond ((consp form)
+ (let ((op (car form)))
+ (cond ((member op '(the truly-the))
+ (values-specifier-type (second form)))
+ ((eq 'function op)
+ (specifier-type 'function))
+ ((and (legal-fun-name-p op)
+ (eq :declared (info :function :where-from op)))
+ (let ((ftype (info :function :type op)))
+ (if (fun-type-p ftype)
+ (fun-type-returns ftype)
+ *wild-type*)))
+ (t
+ *wild-type*))))
+ ((and (symbolp form)
+ (eq :declared (info :variable :where-from form)))
+ (info :variable :type form))
+ ((constantp form)
+ (ctype-of (eval form)))
+ (t
+ *universal-type*)))))
+ ;; Implictly READ-ONLY-P for immutable objects.
+ (when (and (not read-only-p)
+ (csubtypep source-type (specifier-type '(or character number))))
+ (setf read-only-p t))