diff -r 561942122df7 go/expressions.cc
--- a/go/expressions.cc	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/expressions.cc	Fri Sep 21 18:10:51 2012 -0700
@@ -293,19 +293,25 @@
       // object type: a list of function pointers for each interface
       // method.
       Named_type* rhs_named_type = rhs_type->named_type();
+      Struct_type* rhs_struct_type = rhs_type->struct_type();
       bool is_pointer = false;
-      if (rhs_named_type == NULL)
+      if (rhs_named_type == NULL && rhs_struct_type == NULL)
 	{
 	  rhs_named_type = rhs_type->deref()->named_type();
+	  rhs_struct_type = rhs_type->deref()->struct_type();
 	  is_pointer = true;
 	}
       tree method_table;
-      if (rhs_named_type == NULL)
-	method_table = null_pointer_node;
-      else
+      if (rhs_named_type != NULL)
 	method_table =
 	  rhs_named_type->interface_method_table(gogo, lhs_interface_type,
 						 is_pointer);
+      else if (rhs_struct_type != NULL)
+	method_table =
+	  rhs_struct_type->interface_method_table(gogo, lhs_interface_type,
+						  is_pointer);
+      else
+	method_table = null_pointer_node;
       first_field_value = fold_convert_loc(location.gcc_location(),
                                            const_ptr_type_node, method_table);
     }
diff -r 561942122df7 go/gogo-tree.cc
--- a/go/gogo-tree.cc	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/gogo-tree.cc	Fri Sep 21 18:10:51 2012 -0700
@@ -2128,8 +2128,7 @@
 
 tree
 Gogo::interface_method_table_for_type(const Interface_type* interface,
-				      Named_type* type,
-				      bool is_pointer)
+				      Type* type, bool is_pointer)
 {
   const Typed_identifier_list* interface_methods = interface->methods();
   go_assert(!interface_methods->empty());
@@ -2158,7 +2157,9 @@
   // interface.  If the interface has hidden methods, and the named
   // type is defined in a different package, then the interface
   // conversion table will be defined by that other package.
-  if (has_hidden_methods && type->named_object()->package() != NULL)
+  if (has_hidden_methods
+      && type->named_type() != NULL
+      && type->named_type()->named_object()->package() != NULL)
     {
       tree array_type = build_array_type(const_ptr_type_node, NULL);
       tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL, id, array_type);
@@ -2187,13 +2188,20 @@
                                               Linemap::predeclared_location());
   elt->value = fold_convert(const_ptr_type_node, tdp);
 
+  Named_type* nt = type->named_type();
+  Struct_type* st = type->struct_type();
+  go_assert(nt != NULL || st != NULL);
   size_t i = 1;
   for (Typed_identifier_list::const_iterator p = interface_methods->begin();
        p != interface_methods->end();
        ++p, ++i)
     {
       bool is_ambiguous;
-      Method* m = type->method_function(p->name(), &is_ambiguous);
+      Method* m;
+      if (nt != NULL)
+	m = nt->method_function(p->name(), &is_ambiguous);
+      else
+	m = st->method_function(p->name(), &is_ambiguous);
       go_assert(m != NULL);
 
       Named_object* no = m->named_object();
diff -r 561942122df7 go/gogo.cc
--- a/go/gogo.cc	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/gogo.cc	Fri Sep 21 18:10:51 2012 -0700
@@ -2872,7 +2872,8 @@
 Build_method_tables::type(Type* type)
 {
   Named_type* nt = type->named_type();
-  if (nt != NULL)
+  Struct_type* st = type->struct_type();
+  if (nt != NULL || st != NULL)
     {
       for (std::vector<Interface_type*>::const_iterator p =
 	     this->interfaces_.begin();
@@ -2882,10 +2883,23 @@
 	  // We ask whether a pointer to the named type implements the
 	  // interface, because a pointer can implement more methods
 	  // than a value.
-	  if ((*p)->implements_interface(Type::make_pointer_type(nt), NULL))
+	  if (nt != NULL)
 	    {
-	      nt->interface_method_table(this->gogo_, *p, false);
-	      nt->interface_method_table(this->gogo_, *p, true);
+	      if ((*p)->implements_interface(Type::make_pointer_type(nt),
+					     NULL))
+		{
+		  nt->interface_method_table(this->gogo_, *p, false);
+		  nt->interface_method_table(this->gogo_, *p, true);
+		}
+	    }
+	  else
+	    {
+	      if ((*p)->implements_interface(Type::make_pointer_type(st),
+					     NULL))
+		{
+		  st->interface_method_table(this->gogo_, *p, false);
+		  st->interface_method_table(this->gogo_, *p, true);
+		}
 	    }
 	}
     }
diff -r 561942122df7 go/gogo.h
--- a/go/gogo.h	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/gogo.h	Fri Sep 21 18:10:51 2012 -0700
@@ -574,7 +574,7 @@
   // Build an interface method table for a type: a list of function
   // pointers, one for each interface method.  This returns a decl.
   tree
-  interface_method_table_for_type(const Interface_type*, Named_type*,
+  interface_method_table_for_type(const Interface_type*, Type*,
 				  bool is_pointer);
 
   // Return a tree which allocate SIZE bytes to hold values of type
diff -r 561942122df7 go/types.cc
--- a/go/types.cc	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/types.cc	Fri Sep 21 18:10:51 2012 -0700
@@ -4554,6 +4554,20 @@
   return Type::method_function(this->all_methods_, name, is_ambiguous);
 }
 
+// Return a pointer to the interface method table for this type for
+// the interface INTERFACE.  IS_POINTER is true if this is for a
+// pointer to THIS.
+
+tree
+Struct_type::interface_method_table(Gogo* gogo,
+				    const Interface_type* interface,
+				    bool is_pointer)
+{
+  return Type::interface_method_table(gogo, this, interface, is_pointer,
+				      &this->interface_method_tables_,
+				      &this->pointer_interface_method_tables_);
+}
+
 // Convert struct fields to the backend representation.  This is not
 // declared in types.h so that types.h doesn't have to #include
 // backend.h.
@@ -7182,7 +7196,17 @@
 	{
 	  if (!p->name().empty())
 	    {
-	      std::string n = Gogo::unpack_hidden_name(p->name());
+	      std::string n;
+	      if (!Gogo::is_hidden_name(p->name()))
+		n = p->name();
+	      else
+		{
+		  n = ".";
+		  std::string pkgpath = Gogo::hidden_name_pkgpath(p->name());
+		  n.append(Gogo::pkgpath_for_symbol(pkgpath));
+		  n.append(1, '.');
+		  n.append(Gogo::unpack_hidden_name(p->name()));
+		}
 	      char buf[20];
 	      snprintf(buf, sizeof buf, "%u_",
 		       static_cast<unsigned int>(n.length()));
@@ -7735,32 +7759,9 @@
 Named_type::interface_method_table(Gogo* gogo, const Interface_type* interface,
 				   bool is_pointer)
 {
-  go_assert(!interface->is_empty());
-
-  Interface_method_tables** pimt = (is_pointer
-				    ? &this->interface_method_tables_
-				    : &this->pointer_interface_method_tables_);
-
-  if (*pimt == NULL)
-    *pimt = new Interface_method_tables(5);
-
-  std::pair<const Interface_type*, tree> val(interface, NULL_TREE);
-  std::pair<Interface_method_tables::iterator, bool> ins = (*pimt)->insert(val);
-
-  if (ins.second)
-    {
-      // This is a new entry in the hash table.
-      go_assert(ins.first->second == NULL_TREE);
-      ins.first->second = gogo->interface_method_table_for_type(interface,
-								this,
-								is_pointer);
-    }
-
-  tree decl = ins.first->second;
-  if (decl == error_mark_node)
-    return error_mark_node;
-  go_assert(decl != NULL_TREE && TREE_CODE(decl) == VAR_DECL);
-  return build_fold_addr_expr(decl);
+  return Type::interface_method_table(gogo, this, interface, is_pointer,
+				      &this->interface_method_tables_,
+				      &this->pointer_interface_method_tables_);
 }
 
 // Return whether a named type has any hidden fields.
@@ -8944,6 +8945,42 @@
   return m;
 }
 
+// Return a pointer to the interface method table for TYPE for the
+// interface INTERFACE.
+
+tree
+Type::interface_method_table(Gogo* gogo, Type* type,
+			     const Interface_type *interface,
+			     bool is_pointer,
+			     Interface_method_tables** method_tables,
+			     Interface_method_tables** pointer_tables)
+{
+  go_assert(!interface->is_empty());
+
+  Interface_method_tables** pimt = is_pointer ? method_tables : pointer_tables;
+
+  if (*pimt == NULL)
+    *pimt = new Interface_method_tables(5);
+
+  std::pair<const Interface_type*, tree> val(interface, NULL_TREE);
+  std::pair<Interface_method_tables::iterator, bool> ins = (*pimt)->insert(val);
+
+  if (ins.second)
+    {
+      // This is a new entry in the hash table.
+      go_assert(ins.first->second == NULL_TREE);
+      ins.first->second = gogo->interface_method_table_for_type(interface,
+								type,
+								is_pointer);
+    }
+
+  tree decl = ins.first->second;
+  if (decl == error_mark_node)
+    return error_mark_node;
+  go_assert(decl != NULL_TREE && TREE_CODE(decl) == VAR_DECL);
+  return build_fold_addr_expr(decl);
+}
+
 // Look for field or method NAME for TYPE.  Return an Expression for
 // the field or method bound to EXPR.  If there is no such field or
 // method, give an appropriate error and return an error expression.
diff -r 561942122df7 go/types.h
--- a/go/types.h	Fri Sep 21 15:10:32 2012 -0700
+++ b/go/types.h	Fri Sep 21 18:10:51 2012 -0700
@@ -983,6 +983,19 @@
   method_function(const Methods*, const std::string& name,
 		  bool* is_ambiguous);
 
+  // A mapping from interfaces to the associated interface method
+  // tables for this type.  This maps to a decl.
+  typedef Unordered_map_hash(const Interface_type*, tree, Type_hash_identical,
+			     Type_identical) Interface_method_tables;
+
+  // Return a pointer to the interface method table for TYPE for the
+  // interface INTERFACE.
+  static tree
+  interface_method_table(Gogo* gogo, Type* type,
+			 const Interface_type *interface, bool is_pointer,
+			 Interface_method_tables** method_tables,
+			 Interface_method_tables** pointer_tables);
+
   // Return a composite literal for the type descriptor entry for a
   // type.
   static Expression*
@@ -1994,7 +2007,8 @@
  public:
   Struct_type(Struct_field_list* fields, Location location)
     : Type(TYPE_STRUCT),
-      fields_(fields), location_(location), all_methods_(NULL)
+      fields_(fields), location_(location), all_methods_(NULL),
+      interface_method_tables_(NULL), pointer_interface_method_tables_(NULL)
   { }
 
   // Return the field NAME.  This only looks at local fields, not at
@@ -2076,6 +2090,14 @@
   Method*
   method_function(const std::string& name, bool* is_ambiguous) const;
 
+  // Return a pointer to the interface method table for this type for
+  // the interface INTERFACE.  If IS_POINTER is true, set the type
+  // descriptor to a pointer to this type, otherwise set it to this
+  // type.
+  tree
+  interface_method_table(Gogo*, const Interface_type* interface,
+			 bool is_pointer);
+
   // Traverse just the field types of a struct type.
   int
   traverse_field_types(Traverse* traverse)
@@ -2156,6 +2178,13 @@
   Location location_;
   // If this struct is unnamed, a list of methods.
   Methods* all_methods_;
+  // A mapping from interfaces to the associated interface method
+  // tables for this type.  Only used if this struct is unnamed.
+  Interface_method_tables* interface_method_tables_;
+  // A mapping from interfaces to the associated interface method
+  // tables for pointers to this type.  Only used if this struct is
+  // unnamed.
+  Interface_method_tables* pointer_interface_method_tables_;
 };
 
 // The type of an array.
@@ -2861,11 +2890,6 @@
   void
   create_placeholder(Gogo*);
 
-  // A mapping from interfaces to the associated interface method
-  // tables for this type.  This maps to a decl.
-  typedef Unordered_map_hash(const Interface_type*, tree, Type_hash_identical,
-			     Type_identical) Interface_method_tables;
-
   // A pointer back to the Named_object for this type.
   Named_object* named_object_;
   // If this type is defined in a function, a pointer back to the
