diff --git a/src/implicit.c b/src/implicit.c
index b281a17..4223d0f 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -24,7 +24,8 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "commands.h" /* set_file_variables */
 
 static int pattern_search (struct file *file, int archive,
-                           unsigned int depth, unsigned int recursions);
+                           unsigned int depth, unsigned int recursions,
+                           unsigned int anydepth);
 
 /* For a FILE which has no commands specified, try to figure out some
    from the implicit pattern rules.
@@ -42,7 +43,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
      (the archive search omits the archive name), it is more specific and
      should come first.  */
 
-  if (pattern_search (file, 0, depth, 0))
+  if (pattern_search (file, 0, depth, 0, 0))
     return 1;
 
 #ifndef NO_ARCHIVES
@@ -52,7 +53,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
     {
       DBF (DB_IMPLICIT,
            _("Looking for archive-member implicit rule for '%s'.\n"));
-      if (pattern_search (file, 1, depth, 0))
+      if (pattern_search (file, 1, depth, 0, 0))
         return 1;
     }
 #endif
@@ -173,6 +174,9 @@ struct tryrule
 
     /* Nonzero if the LASTSLASH logic was used in matching this rule. */
     char checked_lastslash;
+
+    /* True if the rule would match anything. */
+    char anyrule;
   };
 
 int
@@ -200,7 +204,8 @@ stemlen_compare (const void *v1, const void *v2)
 
 static int
 pattern_search (struct file *file, int archive,
-                unsigned int depth, unsigned int recursions)
+                unsigned int depth, unsigned int recursions,
+                unsigned int anydepth)
 {
   /* Filename we are searching for a rule for.  */
   const char *filename = archive ? strchr (file->name, '(') : file->name;
@@ -317,12 +322,20 @@ pattern_search (struct file *file, int archive,
           const char *target = rule->targets[ti];
           const char *suffix = rule->suffixes[ti];
           char check_lastslash;
+          char anyrule = 0;
 
           /* Rules that can match any filename and are not terminal
-             are ignored if we're recursing, so that they cannot be
-             intermediate files.  */
-          if (recursions > 0 && target[1] == '\0' && !rule->terminal)
-            continue;
+             must not be allowed to nest very deeply.  Record whether
+             we have such a rule, so that if a further level of
+             recursion is required as a result of matching this rule,
+             we can increment the number of such rules we're nested
+             in.  */
+          if (target[1] == '\0' && !rule->terminal)
+            {
+              if (anydepth > 0)
+                continue;
+              anyrule = 1;
+            }
 
           if (rule->lens[ti] > namelen)
             /* It can't possibly match.  */
@@ -395,6 +408,7 @@ pattern_search (struct file *file, int archive,
              target in MATCHES.  If several targets of the same rule match,
              that rule will be in TRYRULES more than once.  */
           tryrules[nrules].rule = rule;
+          tryrules[nrules].anyrule = anyrule;
           tryrules[nrules].matches = ti;
           tryrules[nrules].stemlen = stemlen + (check_lastslash ? pathlen : 0);
           tryrules[nrules].order = nrules;
@@ -704,6 +718,7 @@ pattern_search (struct file *file, int archive,
               /* Go through the nameseq and handle each as a prereq name.  */
               for (d = dl; d != 0; d = d->next)
                 {
+                  struct file *f;
                   struct dep *expl_d;
                   int is_rule = d->name == dep_name (dep);
 
@@ -753,7 +768,7 @@ pattern_search (struct file *file, int archive,
                      FILENAME's directory), so it might actually exist.  */
 
                   /* @@ dep->changed check is disabled. */
-                  if (lookup_file (d->name) != 0
+                  if (((f = lookup_file (d->name)) != 0 && f->is_target)
                       /*|| ((!dep->changed || check_lastslash) && */
                       || file_exists_p (d->name))
                     {
@@ -794,7 +809,8 @@ pattern_search (struct file *file, int archive,
                       if (pattern_search (int_file,
                                           0,
                                           depth + 1,
-                                          recursions + 1))
+                                          recursions + 1,
+                                          anydepth + !!tryrules[ri].anyrule))
                         {
                           pat->pattern = int_file->name;
                           int_file->name = d->name;
