diff --git a/src/mapping.c b/src/mapping.c
index 07c35c8273c367b090f2883f8402be38d92aabca..5126ba9c39bfb1e1d877074161dcff24874761e9 100644
--- a/src/mapping.c
+++ b/src/mapping.c
@@ -1891,12 +1891,21 @@ void o_append_mapping( INT32 args )
     struct mapping *m = val->u.mapping;
     if( m->refs == 2 )
     {
-      int i;
-      /* fprintf( stderr, "map_refs==2\n" ); */
-      for( i=0; i<args; i+=2 )
-        low_mapping_insert( m, Pike_sp-(i+2), Pike_sp-(i+1), 2 );
-      stack_pop_n_elems_keep_top(2+args);
-      return;
+      if ((TYPEOF(*lval) == T_OBJECT) &&
+	  lval->u.object->prog &&
+	  ((FIND_LFUN(lval->u.object->prog, LFUN_ASSIGN_INDEX) >= 0) ||
+	   (FIND_LFUN(lval->u.object->prog, LFUN_ASSIGN_ARROW) >= 0))) {
+	/* There's a function controlling assignments in this object,
+	 * so we can't alter the mapping in place.
+	 */
+      } else {
+	int i;
+	/* fprintf( stderr, "map_refs==2\n" ); */
+	for( i=0; i<args; i+=2 )
+	  low_mapping_insert( m, Pike_sp-(i+2), Pike_sp-(i+1), 2 );
+	stack_pop_n_elems_keep_top(2+args);
+	return;
+      }
     }
   }
 
diff --git a/src/testsuite.in b/src/testsuite.in
index e8ac2a877435fa402da2ee55184b14ce985b6454..4e69fc128fa1c13d9545d772c4038ddc9c375371 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -4112,6 +4112,29 @@ test_any([[
   return has_index(a->_modified, "foo");
 ]], 1)
 
+test_any([[
+  // Since the addition of F_APPEND_MAPPING in set_bar below
+  // the setter is not being called anymore. Instead, the mapping
+  // _data->foo is modified in place.
+  class A(mapping foo) {
+    mapping _modified = ([]);
+
+    mixed `->=(string sym, mixed v) {
+      return _modified[sym] = v;
+    }
+
+    void set_bar(int v) {
+      this->foo += ([ "bar" : v ]);
+    }
+  };
+
+  object a = A(([ "foo" : ([]) ]));
+
+  a->set_bar(2);
+
+  return has_index(a->_modified, "foo");
+]], 1)
+
 test_any([[
   // Since the addition of F_APPEND_ARRAY the setter is not being
   // called anymore. Instead, the array _data is modified in place.