0.7.7.24:
[sbcl.git] / src / compiler / ir1-translators.lisp
index 3053069..cb8e3a3 100644 (file)
@@ -12,7 +12,7 @@
 
 (in-package "SB!C")
 \f
-;;;; control special forms
+;;;; special forms for control
 
 (def-ir1-translator progn ((&rest forms) start cont)
   #!+sb-doc
@@ -84,7 +84,6 @@
       (push env-entry (continuation-lexenv-uses cont))
       (ir1-convert-progn-body dummy cont forms))))
 
-
 (def-ir1-translator return-from ((name &optional value) start cont)
   #!+sb-doc
   "Return-From Block-Name Value-Form
          (compiler-error
           "The local symbol macro name ~S is not a symbol."
           name))
+       (let ((kind (info :variable :kind name)))
+        (when (member kind '(:special :constant))
+          (compiler-error "Attempt to bind a ~(~A~) variable with SYMBOL-MACROLET: ~S" kind name)))
        `(,name . (MACRO . ,expansion))))
    :vars
    definitions
 ;;; FUNCALL is implemented on %FUNCALL, which can only call functions
 ;;; (not symbols). %FUNCALL is used directly in some places where the
 ;;; call should always be open-coded even if FUNCALL is :NOTINLINE.
-(deftransform funcall ((function &rest args) * * :when :both)
+(deftransform funcall ((function &rest args) * *)
   (let ((arg-names (make-gensym-list (length args))))
     `(lambda (function ,@arg-names)
        (%funcall ,(if (csubtypep (continuation-type function)
       (values nil t)))
 
 (deftransform %coerce-callable-to-fun ((thing) (function) *
-                                      :when :both
                                       :important t)
   "optimize away possible call to FDEFINITION at runtime"
   'thing)
   During evaluation of the Forms, bind the Vars to the result of evaluating the
   Value forms. The variables are bound in parallel after all of the Values are
   evaluated."
-  (multiple-value-bind (forms decls) (sb!sys:parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body nil)
     (multiple-value-bind (vars values) (extract-let-vars bindings 'let)
       (let ((fun-cont (make-continuation)))
         (let* ((*lexenv* (process-decls decls vars nil cont))
   "LET* ({(Var [Value]) | Var}*) Declaration* Form*
   Similar to LET, but the variables are bound sequentially, allowing each Value
   form to reference any of the previous Vars."
-  (multiple-value-bind (forms decls) (sb!sys:parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body nil)
     (multiple-value-bind (vars values) (extract-let-vars bindings 'let*)
       (let ((*lexenv* (process-decls decls vars nil cont)))
        (ir1-convert-aux-bindings start cont forms vars values)))))
 ;;; forms before we hit the IR1 transform level.
 (defun ir1-translate-locally (body start cont)
   (declare (type list body) (type continuation start cont))
-  (multiple-value-bind (forms decls) (sb!sys:parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body nil)
     (let ((*lexenv* (process-decls decls nil nil cont)))
       (ir1-convert-aux-bindings start cont forms nil nil))))
 
       (let ((name (first def)))
        (check-fun-name name)
        (names name)
-       (multiple-value-bind (forms decls) (sb!sys:parse-body (cddr def))
+       (multiple-value-bind (forms decls) (parse-body (cddr def))
          (defs `(lambda ,(second def)
                   ,@decls
                   (block ,(fun-name-block-name name)
   Evaluate the Body-Forms with some local function definitions. The bindings
   do not enclose the definitions; any use of Name in the Forms will refer to
   the lexically apparent function definition in the enclosing environment."
-  (multiple-value-bind (forms decls) (sb!sys:parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body nil)
     (multiple-value-bind (names defs)
        (extract-flet-vars definitions 'flet)
       (let* ((fvars (mapcar (lambda (n d)
   Evaluate the Body-Forms with some local function definitions. The bindings
   enclose the new definitions, so the defined functions can call themselves or
   each other."
-  (multiple-value-bind (forms decls) (sb!sys:parse-body body nil)
+  (multiple-value-bind (forms decls) (parse-body body nil)
     (multiple-value-bind (names defs)
        (extract-flet-vars definitions 'labels)
       (let* (;; dummy LABELS functions, to be used as placeholders
 ;;; We make this work by getting USE-CONTINUATION to do the unioning
 ;;; across COND branches. We can't do it here, since we don't know how
 ;;; many branches there are going to be.
-(defun ir1ize-the-or-values (type cont lexenv name)
+(defun ir1ize-the-or-values (type cont lexenv place)
   (declare (type continuation cont) (type lexenv lexenv))
-  (let* ((ctype (values-specifier-type type))
+  (let* ((ctype (if (typep type 'ctype) type (values-specifier-type type)))
         (old-type (or (lexenv-find cont type-restrictions)
                       *wild-type*))
         (intersects (values-types-equal-or-intersect old-type ctype))
     (when (null (find-uses cont))
       (setf (continuation-asserted-type cont) new))
     (when (and (not intersects)
+              ;; FIXME: Is it really right to look at *LEXENV* here,
+              ;; instead of looking at the LEXENV argument? Why?
               (not (policy *lexenv*
                            (= inhibit-warnings 3)))) ;FIXME: really OK to suppress?
       (compiler-warn
-       "The type ~S in ~S declaration conflicts with an ~
+       "The type ~S ~A conflicts with an ~
         enclosing assertion:~%   ~S"
        (type-specifier ctype)
-       name
+       place
        (type-specifier old-type)))
     (make-lexenv :type-restrictions `((,cont . ,new))
                 :default lexenv)))
 ;;; this didn't seem to expand into an assertion, at least for ALIEN
 ;;; values. Check that SBCL doesn't have this problem.
 (def-ir1-translator the ((type value) start cont)
-  (let ((*lexenv* (ir1ize-the-or-values type cont *lexenv* 'the)))
+  (with-continuation-type-assertion (cont (values-specifier-type type)
+                                          "in THE declaration")
     (ir1-convert start cont value)))
 
 ;;; This is like the THE special form, except that it believes
     (continuation-starts-block dummy-start)
     (ir1-convert start dummy-start result)
 
-    (substitute-continuation-uses cont dummy-start)
+    (with-continuation-type-assertion
+        (cont (continuation-asserted-type dummy-start)
+              "of the first form")
+      (substitute-continuation-uses cont dummy-start))
 
     (continuation-starts-block dummy-result)
     (ir1-convert-progn-body dummy-start dummy-result forms)