[gccrs COMMIT] gccrs: Handle generic args to traits in paths

gerris.rs@gmail.com gerris.rs@gmail.com
Mon Sep 7 11:51:53 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

Fixes Rust-GCC/gccrs#4853

gcc/rust/ChangeLog:

	* typecheck/rust-substitution-mapper.cc (SubstMapper::valid_type): check for dyn object
	(SubstMapper::visit): substitution on it
	* typecheck/rust-substitution-mapper.h: add impl

gcc/testsuite/ChangeLog:

	* rust/compile/issue-4853.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: https://github.com/Rust-GCC/gccrs/commit/8a8099e11efb2dd86191a9e80320e36acc48ca7a

The commit has been mentioned in the following issue(s):
 - Rust-GCC/gccrs#4853: https://github.com/Rust-GCC/gccrs/issues/4853

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4854

 .../typecheck/rust-substitution-mapper.cc     | 24 ++++++++++++++++++
 gcc/rust/typecheck/rust-substitution-mapper.h |  2 +-
 gcc/testsuite/rust/compile/issue-4853.rs      | 25 +++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4853.rs

diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index 579c88c4d..e08356c2b 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -63,6 +63,14 @@ SubstMapper::valid_type (TyTy::BaseType *base)
   bool is_placeholder = base->is<TyTy::PlaceholderType> ();
   bool is_projection = base->is<TyTy::ProjectionType> ();
 
+  // see gcc/testsuite/rust/compile/issue-4853.rs
+  if (auto *dyn = base->try_as<TyTy::DynamicObjectType> ())
+    {
+      auto &bounds = dyn->get_specified_bounds ();
+      if (bounds.size () == 1)
+	return bounds.at (0).requires_generic_args ();
+    }
+
   return is_fn || is_adt || is_placeholder || is_projection;
 }
 
@@ -120,6 +128,22 @@ SubstMapper::visit (TyTy::ADTType &type)
     resolved = concrete;
 }
 
+void
+SubstMapper::visit (TyTy::DynamicObjectType &type)
+{
+  rust_assert (have_generic_args ());
+  rust_assert (type.get_specified_bounds ().size () == 1);
+  rust_assert (type.get_specified_bounds ().at (0).requires_generic_args ());
+
+  TyTy::TypeBoundPredicate predicate = type.get_specified_bounds ().at (0);
+  predicate.apply_generic_arguments (generics, false, false);
+  if (predicate.is_error ())
+    return;
+
+  resolved = new TyTy::DynamicObjectType (type.get_ref (), type.get_ident (),
+					  {predicate});
+}
+
 void
 SubstMapper::visit (TyTy::PlaceholderType &type)
 {
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 73632ddf2..fefab0c57 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -43,6 +43,7 @@ public:
   void visit (TyTy::ADTType &type) override;
   void visit (TyTy::PlaceholderType &type) override;
   void visit (TyTy::ProjectionType &type) override;
+  void visit (TyTy::DynamicObjectType &type) override;
 
   // nothing to do for these
   void visit (TyTy::InferType &) override { rust_unreachable (); }
@@ -67,7 +68,6 @@ public:
   void visit (TyTy::ConstErrorType &) override { rust_unreachable (); }
   void visit (TyTy::StrType &) override { rust_unreachable (); }
   void visit (TyTy::NeverType &) override { rust_unreachable (); }
-  void visit (TyTy::DynamicObjectType &) override { rust_unreachable (); }
   void visit (TyTy::ClosureType &) override { rust_unreachable (); }
   void visit (TyTy::OpaqueType &) override { rust_unreachable (); }
 
diff --git a/gcc/testsuite/rust/compile/issue-4853.rs b/gcc/testsuite/rust/compile/issue-4853.rs
new file mode 100644
index 000000000..45de755ed
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4853.rs
@@ -0,0 +1,25 @@
+// { dg-additional-options "-frust-edition=2018" }
+#![feature(lang_items, no_core)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+trait FloatToInt<Int>: Sized {
+    unsafe fn to_int_unchecked(self) -> Int;
+}
+
+impl FloatToInt<u32> for f32 {
+    unsafe fn to_int_unchecked(self) -> u32 {
+        0
+    }
+}
+
+impl f32 {
+    pub unsafe fn to_int_unchecked<Int>(self) -> Int
+    where
+        Self: FloatToInt<Int>,
+    {
+        unsafe { FloatToInt::<Int>::to_int_unchecked(self) }
+    }
+}

base-commit: 24b6c4053316da1414ddd21ae64ef980fe6752fa
-- 
2.55.0



More information about the Gcc-rust mailing list