diff --git a/src/language.yacc b/src/language.yacc
index bc7d0790419f69b171a389081d7762f6f5b1fdbb..fe6ca29e81b6c8e8c835461cae1b978d42cc2c9f 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -3877,32 +3877,81 @@ string_or_identifier: TOK_IDENTIFIER
   | string
   ;
 
+/* Note that the result of this rule is passed both with
+ * the node value (inherit number) and with two global
+ * variables (inherit_state and inherit_depth).
+ *
+ * Note also that inherit number -1 indicates any inherit.
+ */
 inherit_specifier: string_or_identifier TOK_COLON_COLON
   {
     struct compilation *c = THIS_COMPILATION;
+    struct program_state *state = Pike_compiler;
+    int depth;
     int e = -1;
 
-    inherit_state = Pike_compiler;
-
-    for (inherit_depth = 0;; inherit_depth++, inherit_state = inherit_state->previous) {
-      int inh = find_inherit(inherit_state->new_program, $1->u.sval.u.string);
-      if (inh) {
+    inherit_state = NULL;
+    inherit_depth = 0;
+
+    /* NB: The heuristics here are a bit strange
+     *     (all to make it as backward compatible as possible).
+     *
+     *     The priority order is as follows:
+     *
+     *     1: Direct inherits in the current class.
+     *
+     *     2: The name of the current class.
+     *
+     *     3: 1 & 2 recursively for surrounding parent classes.
+     *
+     *     4: Indirect inherits in the current class.
+     *
+     *     5: 4 recursively for surrounding parent classes.
+     *
+     *     6: this_program.
+     *
+     * Note that a deep inherit in the current class trumphs
+     * a not so deep inherit in a parent class (but not a
+     * direct inherit in a parent class). To select the deep
+     * inherit in the parent class in this case, prefix it
+     * with the name of the parent class.
+     */
+    for (depth = 0;; depth++, state = state->previous) {
+      int inh = find_inherit(state->new_program, $1->u.sval.u.string);
+      if (inh &&
+	  (!inherit_state ||
+	   (state->new_program->inherits[inh].inherit_level == 1))) {
+	/* Found, and we've either not found anything earlier,
+	 * or this is a direct inherit (and the previous
+	 * wasn't since we didn't break out of the loop).
+	 */
 	e = inh;
-	break;
+	inherit_state = state;
+	inherit_depth = depth;
+	if (state->new_program->inherits[inh].inherit_level == 1) {
+	  /* Name of direct inherit ==> Done. */
+	  break;
+	}
       }
-      if (inherit_depth == c->compilation_depth) break;
+      /* The top-level class does not have a name, so break here. */
+      if (depth == c->compilation_depth) break;
       if (!TEST_COMPAT (7, 2) &&
-	  ID_FROM_INT (inherit_state->previous->new_program,
-		       inherit_state->parent_identifier)->name ==
+	  ID_FROM_INT (state->previous->new_program,
+		       state->parent_identifier)->name ==
 	  $1->u.sval.u.string) {
+	/* Name of surrounding class ==> Done. */
 	e = 0;
+	inherit_state = state;
+	inherit_depth = depth;
 	break;
       }
     }
     if (e == -1) {
-      if (TEST_COMPAT (7, 2))
+      inherit_state = state;
+      inherit_depth = depth;
+      if (TEST_COMPAT (7, 2)) {
 	my_yyerror("No such inherit %S.", $1->u.sval.u.string);
-      else {
+      } else {
 	if ($1->u.sval.u.string == this_program_string) {
 	  inherit_state = Pike_compiler;
 	  inherit_depth = 0;