]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: typecheck: Add basic handling for applying auto trait bounds
authorArthur Cohen <arthur.cohen@embecosm.com>
Thu, 16 Jan 2025 16:10:02 +0000 (17:10 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 24 Mar 2025 12:06:51 +0000 (13:06 +0100)
gcc/rust/ChangeLog:

* hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Register auto traits in mappings.
* util/rust-hir-map.cc (Mappings::insert_auto_trait): New.
(Mappings::get_auto_traits): New.
* util/rust-hir-map.h: Declare them.
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): Add auto trait bounds when
scanning.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Some parts of nr2.0 can't handle auto traits yet.
* rust/compile/auto_traits3.rs: Removed in favor of...
* rust/compile/auto_traits2.rs: ...this one.
* rust/compile/auto_traits4.rs: New test.

gcc/rust/hir/rust-ast-lower-item.cc
gcc/rust/typecheck/rust-tyty-bounds.cc
gcc/rust/util/rust-hir-map.cc
gcc/rust/util/rust-hir-map.h
gcc/testsuite/rust/compile/auto_traits2.rs
gcc/testsuite/rust/compile/auto_traits3.rs [deleted file]
gcc/testsuite/rust/compile/auto_traits4.rs [new file with mode: 0644]
gcc/testsuite/rust/compile/nr2/exclude

index ae938d9865899868721e41d3f7aac482b6aec125..5dbcad59dfb5840a38d100b202122be65c89b211 100644 (file)
@@ -606,17 +606,18 @@ ASTLoweringItem::visit (AST::Trait &trait)
                                 mappings.get_next_hir_id (crate_num),
                                 mappings.get_next_localdef_id (crate_num));
 
-  auto trait_unsafety = Unsafety::Normal;
-  if (trait.is_unsafe ())
-    {
-      trait_unsafety = Unsafety::Unsafe;
-    }
+  auto trait_unsafety
+    = trait.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
 
   HIR::Trait *hir_trait
     = new HIR::Trait (mapping, trait.get_identifier (), trait_unsafety,
                      std::move (generic_params), std::move (type_param_bounds),
                      where_clause, std::move (trait_items), vis,
                      trait.get_outer_attrs (), trait.get_locus ());
+
+  if (trait.is_auto ())
+    mappings.insert_auto_trait (hir_trait);
+
   translated = hir_trait;
 
   for (auto trait_item_id : trait_item_ids)
index 73d686b7814207c295f826c788f901ae481dd35c..3e42427e2ec0c085238eaa08e149270278e4351d 100644 (file)
@@ -97,6 +97,10 @@ TypeBoundsProbe::scan ()
 
   // marker traits...
   assemble_sized_builtin ();
+
+  // add auto trait bounds
+  for (auto *auto_trait : mappings.get_auto_traits ())
+    add_trait_bound (auto_trait);
 }
 
 void
index b94591e014c4a0fcf371bc52e2661e0c982e4cec..ac18e575765aece35ea6c17bd8d71277e8d6b6f5 100644 (file)
@@ -1309,5 +1309,17 @@ Mappings::get_lang_item_node (LangItem::Kind item_type)
                    LangItem::ToString (item_type).c_str ());
 }
 
+void
+Mappings::insert_auto_trait (HIR::Trait *trait)
+{
+  auto_traits.emplace_back (trait);
+}
+
+std::vector<HIR::Trait *> &
+Mappings::get_auto_traits ()
+{
+  return auto_traits;
+}
+
 } // namespace Analysis
 } // namespace Rust
index 21e532812ff7cb41a5dfa95423aa7f86f3979907..8ea86466220ebd63975e2353d6711751e8615856 100644 (file)
@@ -342,6 +342,9 @@ public:
   tl::optional<HIR::TraitItem *>
   lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
 
+  void insert_auto_trait (HIR::Trait *trait);
+  std::vector<HIR::Trait *> &get_auto_traits ();
+
 private:
   Mappings ();
 
@@ -380,6 +383,9 @@ private:
   std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
   std::map<HirId, HIR::Pattern *> hirPatternMappings;
 
+  // FIXME: Add documentation
+  std::vector<HIR::Trait *> auto_traits;
+
   // We need to have two maps here, as lang-items need to be used for both AST
   // passes and HIR passes. Thus those two maps are created at different times.
   std::map<LangItem::Kind, DefId> lang_item_mappings;
index 7d0dcc11cd2a2eb16d68c5509eacb2ba5fb253d3..382d44608113556a3703d02126096475ba4141db 100644 (file)
@@ -15,12 +15,11 @@ fn foo(a: &(dyn A + Send + Sync)) {
 struct S;
 
 impl A for S {
-    fn a_method(&self) {}
+    fn a_method(&self) {} // { dg-warning "unused name" }
 }
 
 fn main() {
     let s = S;
 
-    foo(&s); // { dg-error "bounds not satisfied" }
-             // { dg-error "mismatched type" "" { target *-*-* } .-1 }
+    foo(&s);
 }
diff --git a/gcc/testsuite/rust/compile/auto_traits3.rs b/gcc/testsuite/rust/compile/auto_traits3.rs
deleted file mode 100644 (file)
index 81c39ec..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#![feature(optin_builtin_traits)]
-
-pub unsafe auto trait Send {}
-#[lang = "sync"]
-pub unsafe auto trait Sync {}
-
-trait A {
-    fn a_method(&self) {}
-}
-
-fn foo(a: &(dyn A + Send + Sync)) {
-    a.a_method();
-}
-
-struct S;
-
-impl A for S {
-    fn a_method(&self) {} // { dg-warning "unused" }
-}
-
-// These should not be necessary because they are both auto traits
-// They need to be removed once we figure out the proper implementation for each of them
-// However, it'd be silly to implement other traits in order to ensure the test is okay,
-// as these extra trait bounds are only allowed to use auto traits
-// FIXME: #3327
-// FIXME: #3326
-unsafe impl Send for S {}
-unsafe impl Sync for S {}
-
-fn main() {
-    let s = S;
-
-    foo(&s);
-}
diff --git a/gcc/testsuite/rust/compile/auto_traits4.rs b/gcc/testsuite/rust/compile/auto_traits4.rs
new file mode 100644 (file)
index 0000000..f1cd1e4
--- /dev/null
@@ -0,0 +1,14 @@
+#![feature(optin_builtin_traits)]
+
+unsafe auto trait Send {}
+unsafe auto trait Sync {}
+
+fn take_send(_: &dyn Send) {}
+fn take_sync(_: &dyn Sync) {}
+
+fn main() {
+    let a = i32;
+
+    take_send(&a);
+    take_sync(&a);
+}
index 60322f3276a95b894f3b674bdae38a6b2c1b612c..a8e3ba56e611c2c0fbe5d97f25c9d71e42ea3715 100644 (file)
@@ -140,7 +140,8 @@ issue-2907.rs
 issue-2423.rs
 issue-266.rs
 additional-trait-bounds2.rs
-auto_traits3.rs
+auto_traits2.rs
+auto_traits4.rs
 issue-3140.rs
 cmp1.rs
 derive_clone_enum1.rs