diff --git a/action.lisp b/action.lisp
index 431dc6c8dd617f5a0605f30bdeb772421b860de0..59810e77cadb444e0f183510f03cc14fccc054d1 100644
--- a/action.lisp
+++ b/action.lisp
@@ -122,12 +122,6 @@ You can put together sentences using this phrase."))
         a component name or a component object.  Also note that, the degenerate
         case of (<operation>) is a no-op.]
 
-      or
-
-      (FEATURE <feature>), which means that the component depends
-        on the <feature> expression satisfying FEATUREP.
-        (This is DEPRECATED -- use :IF-FEATURE instead.)
-
     Methods specialized on subclasses of existing component types
     should usually append the results of CALL-NEXT-METHOD to the list."))
   (define-convenience-action-methods component-depends-on (operation component))
diff --git a/backward-internals.lisp b/backward-internals.lisp
index 17070e33407bc895468296b821cb4ac177c741f8..b907b5492173d4b270f9d2adfc221cd997972389 100644
--- a/backward-internals.lisp
+++ b/backward-internals.lisp
@@ -9,7 +9,6 @@
   (:export ;; for internal use
    #:load-sysdef #:make-temporary-package
    #:%refresh-component-inline-methods
-   #:%resolve-if-component-dep-fails
    #:make-sub-operation
    #:load-sysdef #:make-temporary-package))
 (in-package :asdf/backward-internals)
@@ -49,27 +48,6 @@
     (%remove-component-inline-methods component)
     (%define-component-inline-methods component rest)))
 
-;;;; PARTIAL SUPPORT ONLY for the :if-component-dep-fails component attribute
-;; and the companion asdf:feature pseudo-dependency.
-;; This won't recurse into dependencies to accumulate feature conditions.
-;; Therefore it will accept the SB-ROTATE-BYTE of an old SBCL
-;; (older than 1.1.2.20-fe6da9f) but won't suffice to load an old nibbles.
-(with-upgradability ()
-  (defun %resolve-if-component-dep-fails (if-component-dep-fails component)
-    (asdf-message "The system definition for ~S uses deprecated ~
-                  ASDF option :IF-COMPONENT-DEP-FAILS. ~
-                  Starting with ASDF 3, please use :IF-FEATURE instead"
-                  (coerce-name (component-system component)))
-    ;; This only supports the pattern of use of the "feature" seen in the wild
-    (check-type component parent-component)
-    (check-type if-component-dep-fails (member :fail :ignore :try-next))
-    (unless (eq if-component-dep-fails :fail)
-      (loop :with o = (make-operation 'compile-op)
-            :for c :in (component-children component) :do
-              (loop* :for (feature? feature) :in (component-depends-on o c)
-                     :when (eq feature? 'feature) :do
-                     (setf (component-if-feature c) feature))))))
-
 (when-upgrading (:when (fboundp 'make-sub-operation))
   (defun make-sub-operation (c o dep-c dep-o)
     (declare (ignore c o dep-c dep-o)) (asdf-upgrade-error)))
diff --git a/doc/asdf.texinfo b/doc/asdf.texinfo
index 0f66a0c033d29d62b948bffe0f76397110a211e5..97d6020c83fc42f332ac2ae831773f4e3bda1b95 100644
--- a/doc/asdf.texinfo
+++ b/doc/asdf.texinfo
@@ -999,14 +999,13 @@ other-component-type := symbol-by-name (@pxref{The defsystem grammar,,Component
 # This is used in :depends-on, as opposed to ``dependency,''
 # which is used in :in-order-to
 dependency-def := simple-component-name
-               | (feature @var{feature-name})
-               | ( :version simple-component-name version-specifier)
+               | ( :feature @var{feature-expression} dependency-def )
+               | ( :version simple-component-name version-specifier )
 
 # ``dependency'' is used in :in-order-to, as opposed to
 # ``dependency-def''
 dependency := (dependent-op @var{requirement}+)
 requirement := (required-op @var{required-component}+)
-             | (:feature @var{feature-name})
 dependent-op := operation-name
 required-op := operation-name
 
@@ -1337,14 +1336,22 @@ from within an editor without clobbering its source location)
 @end itemize
 
 @subsection if-feature option
+@cindex :if-feature component option
+@anchor{if-feature-option}      @c redo if this ever becomes a node in
+@c its own right...
+
 This option allows you to specify a feature expression to be evaluated
 as if by @code{#+} to conditionally include a component in your build.
 If the expression is false, the component is dropped
 as well as any dependency pointing to it.
 As compared to using @code{#+} which is expanded at read-time,
 this allows you to have an object in your component hierarchy
-that can be used for manipulations beside building your project.
-This option was added in ASDF 3.
+that can be used for manipulations beside building your project, and
+that is accessible to outside code that wishes to reason about system
+structure.
+
+This option was added in ASDF 3.  For more information,
+@xref{required-features, Required features}.
 
 @subsection if-component-dep-fails option
 This option was removed in ASDF 3.
@@ -1352,6 +1359,13 @@ Its semantics was limited in purpose and dubious to explain,
 and its implementation was breaking a hole into the ASDF object model.
 Please use the @code{if-feature} option instead.
 
+@subsection feature requirement
+This requirement was removed in ASDF 3.1.
+It used to ensure a chain of component dependencies will raise an error,
+which in conjunction with if-component-dep-fails would offer
+a roundabout way to express conditional compilation.
+
+
 @node Other code in .asd files, The package-system extension, The defsystem grammar, Defining systems with defsystem
 @section Other code in .asd files
 
@@ -2079,18 +2093,27 @@ Presumably it is much less useful within a given system,
 wherein the library author is responsible to keep the various files in synch.
 
 @subsubsection Required features
+@anchor{required-features}
 
 Traditionally defsystem users have used @code{#+} reader conditionals
 to include or exclude specific per-implementation files.
-This means that any single implementation cannot read the entire system,
-which becomes a problem if it doesn't wish to compile it,
-but instead for example to create an archive file containing all the sources,
-as it will omit to process the system-dependent sources for other systems.
-
-Each component in an asdf system may therefore specify using @code{:if-feature}
-a feature expression using the same syntax as @code{#+} does,
-such that any reference to the component will be ignored
-during compilation, loading and/or linking if the expression evaluates to false.
+For example, CFFI, the portable C foreign function interface contained
+lines like:
+@lisp
+     #+sbcl       (:file "cffi-sbcl")
+@end lisp
+An unfortunate side effect of this approach is tnoat no single
+implementation can read the entire system.
+This causes problems if, for example, one wished to design an @code{archive-op}
+that would create an archive file containing all the sources, since 
+for example the file @code{cffi-sbcl.lisp} above would be invisible when
+running the @code{archive-op} on any implementation other than SBCL.
+
+ASDF components may therefore have an @code{:if-feature} option.
+The value of this option should be
+a feature expression using the same syntax as @code{#+} does.
+If that feature expression evaluates to false, any reference to the component will be ignored
+during compilation, loading and/or linking.
 Since the expression is read by the normal reader,
 you must explicitly prefix your symbols with @code{:} so they be read as keywords;
 this is as contrasted with the @code{#+} syntax
@@ -2099,8 +2122,10 @@ that implicitly reads symbols in the keyword package by default.
 For instance, @code{:if-feature (:and :x86 (:or :sbcl :cmu :scl))} specifies that
 the given component is only to be compiled and loaded
 when the implementation is SBCL, CMUCL or Scieneer CL on an x86 machine.
-You can not write it as @code{:if-feature (and x86 (or sbcl cmu scl))}
-since the symbols would presumably fail to be read as keywords.
+You cannot write it as @code{:if-feature (and x86 (or sbcl cmu scl))}
+since the symbols would not be read as keywords.
+
+@xref{if-feature-option}
 
 @subsubsection Dependencies
 
@@ -2271,7 +2296,7 @@ are inferred to be of this type.
 @item
 @code{:if-component-dep-fails}
 This attribute was removed in ASDF 3. Do not use it.
-Use @code{:if-feature} instead.
+Use @code{:if-feature} instead (@pxref{required-features}, and @pxref{if-feature-option}).
 
 @item
 @code{:serial} When this attribute is set,
@@ -2907,7 +2932,7 @@ But so are good design ideas and elegant implementation tricks.
 @node Controlling where ASDF saves compiled files, Error handling, Controlling where ASDF searches for systems, Top
 @comment  node-name,  next,  previous,  up
 @chapter Controlling where ASDF saves compiled files
-@cindex asdf-output-translations
+@cindex asdf-output-translations   
 @vindex ASDF_OUTPUT_TRANSLATIONS
 
 Each Common Lisp implementation has its own format
diff --git a/operation.lisp b/operation.lisp
index 0c6dbb2606481a900ccb98fd9a2d7fda27f8a35d..9521bcc5b65cc687f95a30694c5db6927d849f68 100644
--- a/operation.lisp
+++ b/operation.lisp
@@ -7,7 +7,8 @@
   (:export
    #:operation
    #:operation-original-initargs #:original-initargs ;; backward-compatibility only. DO NOT USE.
-   #:*operations* #:make-operation #:find-operation #:feature))
+   #:*operations* #:make-operation #:find-operation
+   #:feature)) ;; TODO: stop exporting the deprecated FEATURE feature.
 (in-package :asdf/operation)
 
 ;;; Operation Classes
@@ -49,9 +50,7 @@
   (defmethod find-operation ((context t) (spec operation))
     spec)
   (defmethod find-operation (context (spec symbol))
-    (unless (member spec '(nil feature))
-      ;; NIL designates itself, i.e. absence of operation
-      ;; FEATURE is the ASDF1 misfeature that comes with IF-COMPONENT-DEP-FAILS
+    (when spec ;; NIL designates itself, i.e. absence of operation
       (apply 'make-operation spec (operation-original-initargs context))))
   (defmethod operation-original-initargs ((context symbol))
     (declare (ignorable context))
diff --git a/parse-defsystem.lisp b/parse-defsystem.lisp
index 80c11415e0a2c7f27998da33cd24e2c744101b32..a6f3d453032fa63dcd9b3674a18608d510b4aefb 100644
--- a/parse-defsystem.lisp
+++ b/parse-defsystem.lisp
@@ -202,7 +202,10 @@
         (setf (component-sideway-dependencies component) depends-on)
         (%refresh-component-inline-methods component rest)
         (when if-component-dep-fails
-          (%resolve-if-component-dep-fails if-component-dep-fails component))
+          (error "The system definition for ~S uses deprecated ~
+            ASDF option :IF-COMPONENT-DEP-FAILS. ~
+            Starting with ASDF 3, please use :IF-FEATURE instead"
+           (coerce-name (component-system component))))
         component)))
 
   (defun register-system-definition
diff --git a/test/test-asdf.asd b/test/test-asdf.asd
index fd99fc064eed1df18d94537008b8c15acb88b8d2..e07861d0f1c7657181286d9c4bebaab783baa0c7 100644
--- a/test/test-asdf.asd
+++ b/test/test-asdf.asd
@@ -45,11 +45,8 @@
      (:module "file3mod"
       :pathname ""
       :components
-      ((:file "file3"
-        :in-order-to ((compile-op (feature :common-lisp))))
-       (:file "does-not-exist"
-        :in-order-to ((compile-op (feature (:not :common-lisp))))))
-      :if-component-dep-fails :ignore)))))
+      ((:file "file3" :if-feature :common-lisp)
+       (:file "does-not-exist" :if-feature (:not :common-lisp))))))))
 
 
 (defsystem :test-asdf/test9-2