anchor.diff:                 :datum ,x
                  :expected-type ',type)))))
   
  -(defmacro ecase-of (type x &body body)
  +(defmacro ecase-of (type x &body body &environment env)
     "Like `ecase' but, given a TYPE (which should be defined as `(member
   ...)'), warn, at compile time, unless the keys in BODY are all of TYPE
   and, taken together, they form an exhaustive partition of TYPE."
  
positive.code:                (nand ,@(rest forms))
                 t))))
  
  (defun check-exhaustiveness (style type body)
    ;; Should we do redundancy checking? Is there any Lisp that doesn't
    ;; already warn about that?
    (check-type style (member case typecase))
    (labels ((check-subtypep (subtype)
               (unless (subtypep subtype type)
                 (warn "~s is not a subtype of ~s" subtype type)))
             (check-exhaustive (partition)
               ;; TODO It would be nice if we could list the types that
               ;; are not matched, or (per OCaml) given an example of a
               ;; value.
               (unless (type= partition type)
                 (warn "Non-exhaustive match: ~s is not the same as ~s"
                       partition type)))
             (check-subtypes (body)
  
negative.code:     (check-subtypes body)
      (check-exhaustive (merge-clause-types body))))
  
  (defmacro etypecase-of (type x &body body &environment env)
    "Like `etypecase' but, at compile time, warn unless each clause in
  BODY is a subtype of TYPE, and the clauses in BODY form an exhaustive
  partition of TYPE."
    (check-exhaustiveness 'typecase type body env)
    (once-only (x)
      `(typecase ,x
         ,@body
  