[gccrs COMMIT 3/3] Use canonical path for Clone trait within derive

[email protected] Mon, 3 Aug 2026 03:35:53 +0000
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Pierre-Emmanuel Patry <[email protected]>

Using the local path for the Clone trait cannot be used with the core
library. This broke most test that "emulate core" with a Clone trait
placed outside a "clone" module.

gcc/rust/ChangeLog:

	* expand/rust-derive-clone.cc (DeriveClone::clone_call): Use the
	canonical path to Clone.

gcc/testsuite/ChangeLog:

	* rust/compile/derive_clone_enum2.rs: Fix test with a clone module
	to mimic the core library.
	* rust/compile/derive_clone_enum3.rs: Likewise.
	* rust/compile/issue-3139-1.rs: Likewise.
	* rust/compile/issue-3144.rs: Likewise.
	* rust/execute/torture/derive_clone_enum1.rs: Likewise.
	* rust/execute/torture/derive_macro3.rs: Likewise.
	* rust/execute/torture/derive_macro4.rs: Likewise.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
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/a7cc9cf930c956a736e83bb236f0bcea3270d93a

The commit has NOT been mentioned in any issue.

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

 gcc/rust/expand/rust-derive-clone.cc          |  9 ++--
 .../rust/compile/derive_clone_enum2.rs        | 19 ++++----
 .../rust/compile/derive_clone_enum3.rs        | 19 ++++----
 gcc/testsuite/rust/compile/issue-3139-1.rs    | 47 +++++++++++--------
 gcc/testsuite/rust/compile/issue-3144.rs      | 17 +++----
 .../execute/torture/derive_clone_enum1.rs     | 23 ++++-----
 .../rust/execute/torture/derive_macro3.rs     | 17 +++----
 .../rust/execute/torture/derive_macro4.rs     | 24 ++++++----
 8 files changed, 96 insertions(+), 79 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 4fb2a8222..e21fe298f 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -30,10 +30,6 @@ namespace AST {
 std::unique_ptr<Expr>
 DeriveClone::clone_call (std::unique_ptr<Expr> &&to_clone)
 {
-  // $crate::core::clone::Clone::clone for the fully qualified path - we don't
-  // link with `core` yet so that might be an issue. Use `Clone::clone` for now?
-  // TODO: Factor this function inside the DeriveAccumulator
-
   // Interestingly, later versions of Rust have a `clone_fn` lang item which
   // corresponds to this. But because we are first targeting 1.49, we cannot use
   // it yet. Once we target a new, more recent version of the language, we'll
@@ -45,7 +41,10 @@ DeriveClone::clone_call (std::unique_ptr<Expr> &&to_clone)
   auto args = std::vector<std::unique_ptr<Expr>> ();
   args.emplace_back (std::move (to_clone));
 
-  return builder.qualified_call ({"Clone", "clone"}, std::move (args));
+  // FIXME: Misses :: prefix to avoid collision with potential core module
+  return builder.qualified_call ({builder.get_path_start (), "clone", "Clone",
+				  "clone"},
+				 std::move (args));
 }
 
 /**
diff --git a/gcc/testsuite/rust/compile/derive_clone_enum2.rs b/gcc/testsuite/rust/compile/derive_clone_enum2.rs
index d48dd56ce..09e0404fb 100644
--- a/gcc/testsuite/rust/compile/derive_clone_enum2.rs
+++ b/gcc/testsuite/rust/compile/derive_clone_enum2.rs
@@ -1,21 +1,22 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 
-#[lang = "clone"]
-trait Clone {
-    pub fn clone(&self) -> Self;
-}
+mod clone {
+    #[lang = "clone"]
+    trait Clone {
+        pub fn clone(&self) -> Self;
+    }
 
-impl Clone for i32 {
-    fn clone(&self) -> Self {
-        *self
+    impl Clone for i32 {
+        fn clone(&self) -> Self {
+            *self
+        }
     }
 }
 
 #[derive(Clone)]
 enum TupleEnum {
     A(i32),
-    B(i32, i32, i32)
+    B(i32, i32, i32),
 }
diff --git a/gcc/testsuite/rust/compile/derive_clone_enum3.rs b/gcc/testsuite/rust/compile/derive_clone_enum3.rs
index 8e4406212..a82bffbe1 100644
--- a/gcc/testsuite/rust/compile/derive_clone_enum3.rs
+++ b/gcc/testsuite/rust/compile/derive_clone_enum3.rs
@@ -1,21 +1,22 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 
-#[lang = "clone"]
-trait Clone {
-    pub fn clone(&self) -> Self;
-}
+mod clone {
+    #[lang = "clone"]
+    trait Clone {
+        pub fn clone(&self) -> Self;
+    }
 
-impl Clone for i32 {
-    fn clone(&self) -> Self {
-        *self
+    impl Clone for i32 {
+        fn clone(&self) -> Self {
+            *self
+        }
     }
 }
 
 #[derive(Clone)]
 enum StructEnum {
     A { i0: i32 },
-    B { i0: i32, i1: i32, i2: i32 }
+    B { i0: i32, i1: i32, i2: i32 },
 }
diff --git a/gcc/testsuite/rust/compile/issue-3139-1.rs b/gcc/testsuite/rust/compile/issue-3139-1.rs
index 25140b589..a39b00f3c 100644
--- a/gcc/testsuite/rust/compile/issue-3139-1.rs
+++ b/gcc/testsuite/rust/compile/issue-3139-1.rs
@@ -1,11 +1,24 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 
-#[lang = "clone"]
-trait Clone {
-    fn clone(&self) -> Self;
+mod clone {
+    #[lang = "clone"]
+    trait Clone {
+        fn clone(&self) -> Self;
+    }
+
+    impl Clone for u32 {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    impl Clone for usize {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
 }
 
 #[lang = "sized"]
@@ -19,30 +32,24 @@ struct Abound {
 }
 
 #[derive(Clone)]
-struct Be<T:Clone> {
+struct Be<T: clone::Clone> {
     a: T,
     b: Abound,
 }
 
-impl Clone for u32 {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl Clone for usize {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl Clone for Abound {
+impl clone::Clone for Abound {
     fn clone(&self) -> Self {
-        return Abound { a: self.a.clone(), b: self.b.clone() };
+        return Abound {
+            a: self.a.clone(),
+            b: self.b.clone(),
+        };
     }
 }
 
 fn main() {
-    let b: Be<usize> = Be {a:1,b:Abound { a:0,b:1 }};
+    let b: Be<usize> = Be {
+        a: 1,
+        b: Abound { a: 0, b: 1 },
+    };
     let _: Be<usize> = b.clone();
 }
diff --git a/gcc/testsuite/rust/compile/issue-3144.rs b/gcc/testsuite/rust/compile/issue-3144.rs
index 6ab17882c..d564b2c7e 100644
--- a/gcc/testsuite/rust/compile/issue-3144.rs
+++ b/gcc/testsuite/rust/compile/issue-3144.rs
@@ -1,6 +1,5 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 #[lang = "sized"]
 pub trait Sized {}
@@ -8,14 +7,16 @@ pub trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
-#[lang = "clone"]
-pub trait Clone {
-    fn clone(&self) -> Self;
-}
+mod clone {
+    #[lang = "clone"]
+    pub trait Clone {
+        fn clone(&self) -> Self;
+    }
 
-impl Clone for i32 {
-    fn clone(&self) -> i32 {
-        *self
+    impl Clone for i32 {
+        fn clone(&self) -> i32 {
+            *self
+        }
     }
 }
 
diff --git a/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs b/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs
index b29d81913..fa2b7d799 100644
--- a/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_clone_enum1.rs
@@ -1,16 +1,17 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 
-#[lang = "clone"]
-trait Clone {
-    pub fn clone(&self) -> Self;
-}
+mod clone {
+    #[lang = "clone"]
+    trait Clone {
+        pub fn clone(&self) -> Self;
+    }
 
-impl Clone for i32 {
-    fn clone(&self) -> Self {
-        *self
+    impl Clone for i32 {
+        fn clone(&self) -> Self {
+            *self
+        }
     }
 }
 
@@ -18,7 +19,7 @@ impl Clone for i32 {
 enum MixAndMatch {
     A,
     B(i32),
-    C { inner: i32 }
+    C { inner: i32 },
 }
 
 fn main() -> i32 {
@@ -36,7 +37,7 @@ fn main() -> i32 {
     let a_copy = a.clone();
 
     match a_copy {
-        MixAndMatch::B(15) => {},
+        MixAndMatch::B(15) => {}
         _ => res += 1,
     };
 
@@ -48,7 +49,7 @@ fn main() -> i32 {
             if inner != 15 {
                 res += 1;
             }
-        },
+        }
         _ => res += 1,
     };
 
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro3.rs b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
index ffdf2219a..d68f9983a 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro3.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
@@ -1,18 +1,19 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 #[lang = "sized"]
 pub trait Sized {}
 
-#[lang = "clone"]
-pub trait Clone {
-    fn clone(&self) -> Self;
-}
+mod clone {
+    #[lang = "clone"]
+    pub trait Clone {
+        fn clone(&self) -> Self;
+    }
 
-impl Clone for i32 {
-    fn clone(&self) -> i32 {
-        *self
+    impl Clone for i32 {
+        fn clone(&self) -> i32 {
+            *self
+        }
     }
 }
 
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro4.rs b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
index 12f714741..f1ec202a2 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro4.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro4.rs
@@ -1,13 +1,20 @@
 #![feature(no_core)]
 #![no_core]
-
 #![feature(lang_items)]
 #[lang = "sized"]
 pub trait Sized {}
 
-#[lang = "clone"]
-pub trait Clone {
-    fn clone(&self) -> Self;
+mod clone {
+    #[lang = "clone"]
+    pub trait Clone {
+        fn clone(&self) -> Self;
+    }
+
+    impl Clone for i32 {
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
 }
 
 #[derive(Clone)]
@@ -21,12 +28,11 @@ struct S {
     b: Foo,
 }
 
-impl Clone for i32 {
-    fn clone(&self) -> Self { *self }
-}
-
 fn main() -> i32 {
-    let s1 = S { a: 15, b: Foo { a: 14 }};
+    let s1 = S {
+        a: 15,
+        b: Foo { a: 14 },
+    };
     let s2 = s1.clone();
 
     let l = s1.a - s2.a;
-- 
2.54.0