[gcc/devel/rust/master] Fix duplicated function generation on higher ranked trait bounds

Thomas Schwinge tschwinge@gcc.gnu.org
Tue Sep 27 15:49:53 GMT 2022


https://gcc.gnu.org/g:770a2449e8e3b7c9c8a9627ce5d57c3bcd99177c

commit 770a2449e8e3b7c9c8a9627ce5d57c3bcd99177c
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Tue Sep 27 12:19:43 2022 +0100

    Fix duplicated function generation on higher ranked trait bounds
    
    Deuplicate function elimination can fail when we compile helpers during
    higher ranked trait bound monomorphization. This because the
    TyTy::BaseType info can be lost/reset during the compilation process. This
    adds a second mechanism to match based on the manged names which is a bit
    more reliable. This patch is required since the query based refactor of
    the type system so this issue was likely hidden to to using duplicated type
    info for higher ranked trait bounds.

Diff:
---
 gcc/rust/backend/rust-compile-context.h | 21 ++++++++++++++++++++-
 gcc/rust/backend/rust-compile-item.cc   | 14 ++++++++------
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 096b65f8b39..415b13e5bd9 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -148,7 +148,8 @@ public:
   }
 
   bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
-			     const TyTy::BaseType *ref = nullptr)
+			     const TyTy::BaseType *ref = nullptr,
+			     const std::string &asm_name = std::string ())
   {
     // for for any monomorphized fns
     if (ref != nullptr)
@@ -163,11 +164,29 @@ public:
 	  {
 	    const TyTy::BaseType *r = e.first;
 	    tree f = e.second;
+
 	    if (ref->is_equal (*r))
 	      {
 		*fn = f;
 		return true;
 	      }
+
+	    if (DECL_ASSEMBLER_NAME_SET_P (f) && !asm_name.empty ())
+	      {
+		tree raw = DECL_ASSEMBLER_NAME_RAW (f);
+		const char *rptr = IDENTIFIER_POINTER (raw);
+
+		bool lengths_match_p
+		  = IDENTIFIER_LENGTH (raw) == asm_name.size ();
+		if (lengths_match_p
+		    && strncmp (rptr, asm_name.c_str (),
+				IDENTIFIER_LENGTH (raw))
+			 == 0)
+		  {
+		    *fn = f;
+		    return true;
+		  }
+	      }
 	  }
 	return false;
       }
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 8ba17c9ff0d..27f3e640e52 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -134,11 +134,18 @@ CompileItem::visit (HIR::Function &function)
 	}
     }
 
+  const Resolver::CanonicalPath *canonical_path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+    function.get_mappings ().get_nodeid (), &canonical_path);
+  rust_assert (ok);
+
+  const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
   tree lookup = NULL_TREE;
   if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
-				 fntype->get_id (), fntype))
+				 fntype->get_id (), fntype, asm_name))
     {
       // has this been added to the list then it must be finished
       if (ctx->function_completed (lookup))
@@ -160,11 +167,6 @@ CompileItem::visit (HIR::Function &function)
       fntype->override_context ();
     }
 
-  const Resolver::CanonicalPath *canonical_path = nullptr;
-  bool ok = ctx->get_mappings ()->lookup_canonical_path (
-    function.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
-
   if (function.get_qualifiers ().is_const ())
     ctx->push_const_context ();


More information about the Gcc-cvs mailing list