diff --git a/src/array.c b/src/array.c
index a8d58f51b445b9516af39f7213c074b81041923a..db9d2e1acb1441ebb128f71ed58d15acba12a171 100644
--- a/src/array.c
+++ b/src/array.c
@@ -143,26 +143,31 @@ void array_index(struct svalue *s,struct array *v,INT32 index)
   free_array(v);
 }
 
-void simple_array_index(struct svalue *s,struct array *a,struct svalue *ind)
-{
-  INT32 i;
-  if(ind->type != T_INT)
-    error("Index is not an integer.\n");
-  i=ind->u.integer;
-  if(i<0) i+=a->size;
-  if(i<0 || i>=a->size) error("Index out of range.\n");
-  array_index(s,a,i);
-}
 
 void simple_array_index_no_free(struct svalue *s,struct array *a,struct svalue *ind)
 {
   INT32 i;
-  if(ind->type != T_INT)
-    error("Index is not an integer.\n");
-  i=ind->u.integer;
-  if(i<0) i+=a->size;
-  if(i<0 || i>=a->size) error("Index out of range.\n");
-  array_index_no_free(s,a,i);
+  switch(ind->type)
+  {
+    case T_INT:
+      i=ind->u.integer;
+      if(i<0) i+=a->size;
+      if(i<0 || i>=a->size) error("Index out of range.\n");
+      array_index_no_free(s,a,i);
+      break;
+
+    case T_STRING:
+      check_stack(4);
+      ref_push_array(a);
+      assign_svalue_no_free(sp++,ind);
+      f_column(2);
+      s[0]=sp[-1];
+      sp--;
+      break;
+
+    default:
+      error("Index is not an integer.\n");
+  }
 }
 
 /*
diff --git a/src/object.c b/src/object.c
index 3ce240db49ca22fd68bc5c3b0e52ccca4d907915..8eff02124040b6e74cd75aab4ca8bcce42b57662 100644
--- a/src/object.c
+++ b/src/object.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: object.c,v 1.23 1997/09/22 01:01:16 hubbe Exp $");
+RCSID("$Id: object.c,v 1.24 1997/09/29 00:57:53 hubbe Exp $");
 #include "object.h"
 #include "dynamic_buffer.h"
 #include "interpret.h"
@@ -419,7 +419,7 @@ void object_index_no_free(struct svalue *to,
   {
     push_svalue(index);
     apply_lfun(o,lfun,1);
-    to=sp;
+    *to=*sp;
     sp--;
   } else {
     object_index_no_free2(to,o,index);
diff --git a/src/opcodes.c b/src/opcodes.c
index f933786e0cc2e40f24b50c3f6beb3936e38ead96..6fb18a40e88f0347c0d22ed907b6db3ef90b0c63 100644
--- a/src/opcodes.c
+++ b/src/opcodes.c
@@ -68,12 +68,11 @@ void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind)
 
 void o_index(void)
 {
-  index_no_free(sp,sp-2,sp-1);
+  struct svalue s;
+  index_no_free(&s,sp-2,sp-1);
+  pop_n_elems(2);
+  *sp=s;
   sp++;
-  free_svalue(sp-3);
-  sp[-3]=sp[-1];
-  sp--;
-  pop_stack();
 }
 
 void cast(struct pike_string *s)
diff --git a/src/operators.c b/src/operators.c
index a634e4d7edd62d582781a65ac448ec2ec1f19c30..c528066fea6b4b4c4f9a710c1f5465b3cbfd32d8 100644
--- a/src/operators.c
+++ b/src/operators.c
@@ -5,7 +5,7 @@
 \*/
 #include <math.h>
 #include "global.h"
-RCSID("$Id: operators.c,v 1.17 1997/09/12 00:07:28 hubbe Exp $");
+RCSID("$Id: operators.c,v 1.18 1997/09/29 00:57:54 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "multiset.h"
@@ -1345,7 +1345,7 @@ void init_operators(void)
 	    "function(string,int:int)|function(object,string:mixed)|function(array,int:mixed)|function(mapping,mixed:mixed)|function(multiset,mixed:int)|function(string,int,int:string)|function(array,int,int:array)",OPT_TRY_OPTIMIZE,0,0);
 
   add_efun2("`->",f_arrow,
-	    "function(object|mapping|multiset,string:mixed)",OPT_TRY_OPTIMIZE,0,0);
+	    "function(array(object|mapping|multiset|array)|object|mapping|multiset,string:mixed)",OPT_TRY_OPTIMIZE,0,0);
 
   add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
   add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison);
diff --git a/src/pike_types.c b/src/pike_types.c
index 97ec88495455786999414db60b60de2b499204f5..c474489b4512a45add485efd24b6e1f2c26b3459 100644
--- a/src/pike_types.c
+++ b/src/pike_types.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: pike_types.c,v 1.25 1997/08/30 18:35:51 grubba Exp $");
+RCSID("$Id: pike_types.c,v 1.26 1997/09/29 00:57:55 hubbe Exp $");
 #include <ctype.h>
 #include "svalue.h"
 #include "pike_types.h"
@@ -983,9 +983,28 @@ static struct pike_string *low_index_type(char *t, node *n)
 
   case T_MAPPING:
     t+=type_length(t);
+    return make_shared_binary_string(t, type_length(t));
 
   case T_ARRAY:
-    return make_shared_binary_string(t, type_length(t));
+    if(low_match_types(string_type_string->str,CDR(n)->type->str,0))
+    {
+      struct pike_string *a=low_index_type(t,n);
+      if(!a)
+	return make_shared_binary_string(t, type_length(t));
+	
+      type_stack_mark();
+      push_finished_type(a);
+      free_string(a);
+      push_type(T_ARRAY);
+      if(low_match_types(int_type_string->str,CDR(n)->type->str,0))
+      {
+	push_unfinished_type(t);
+	  push_type(T_OR);
+      }
+      return pop_unfinished_type();
+    }else{
+      return make_shared_binary_string(t, type_length(t));
+    }
   }
 }
 
@@ -1012,8 +1031,12 @@ static int low_check_indexing(char *type, char *index_type, node *n)
   case T_NOT:
     return !low_check_indexing(type,index_type,n);
 
-  case T_STRING:
   case T_ARRAY:
+    if(low_match_types(string_type_string->str, index_type,0) &&
+       low_check_indexing(type, index_type,n))
+      return 1;
+
+  case T_STRING:
     return !!low_match_types(int_type_string->str, index_type,0);
 
   case T_OBJECT:
diff --git a/src/testsuite.in b/src/testsuite.in
index 019a56d744c211a5eb6d3cb4470a02c8b061b1c2..2b901081da4c8a23c48010e93239614da0dc9ab4 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.54 1997/09/16 00:33:09 hubbe Exp $"]])
+test_true([["$Id: testsuite.in,v 1.55 1997/09/29 00:57:55 hubbe Exp $"]])
 test_eq(1e1,10.0)
 test_eq(1E1,10.0)
 test_eq(1e+1,10.0)
@@ -9,6 +9,8 @@ test_eq("\x20","\040")
 
 test_eq(class { static int foo=17; }()->foo,0)
 test_eval_error(class { static int foo=17; }()->foo=18;)
+test_equal( [[ ({ (["foo":"bar"]), (<"foo">), ([]) })->foo ]], [[ ({"bar",1,0}) ]])
+test_eval_error([[mixed a=({([]),0}); a[1]=a; return a->foo;]])
 
 test_any([[
 class p1 { int foo() { return 1; }};