[COMMITTED 070/141] gccrs: add discriminant value intrinsic

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This is pretty nasty piece of rust in my opinion the return type of this
intrinsic results into a lang item associated type:

  ::Discriminant

This is a special case which needs to support mapping onto the repr type
of the associated ADT that is passed in, but defaults to iszie otherwise.

This patch assumes we only come accross this case in a HIR::CALL_EXPR, so
and makes assumutions that its always of this function signiture. I will
do some checking in libcore to verify that assumption. More work is needed
to parse the repr type on enums but the code is there to support this when
its in to change the types etc.

Addresses Rust-GCC#3348

gcc/rust/ChangeLog:

* backend/rust-compile-intrinsic.cc (discriminant_value_handler): new 
handler
* typecheck/rust-hir-trait-resolve.cc 
(TraitItemReference::resolve_item): track the defid
* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::parse_repr_options): default isize
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): special 
case CallExpr
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): parse 
repr options enum
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): remove 
bad diagnostic
* typecheck/rust-tyty.cc (PlaceholderType::PlaceholderType): track defid
(PlaceholderType::clone): likewise
(PlaceholderType::get_def_id): likeiwse
* typecheck/rust-tyty.h: placeholder track defid
* util/rust-lang-item.cc: add new lang items
* util/rust-lang-item.h: likewise

gcc/testsuite/ChangeLog:

* rust/execute/torture/enum_intrinsics1.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-intrinsic.cc| 149 --
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |   1 +
 .../typecheck/rust-hir-type-check-base.cc |   4 +
 .../typecheck/rust-hir-type-check-expr.cc |  46 ++
 .../typecheck/rust-hir-type-check-item.cc |   7 +-
 .../typecheck/rust-hir-type-check-type.cc |   8 -
 gcc/rust/typecheck/rust-tyty.cc   |  20 ++-
 gcc/rust/typecheck/rust-tyty.h|   8 +-
 gcc/rust/util/rust-lang-item.cc   |   3 +
 gcc/rust/util/rust-lang-item.h|   3 +
 .../rust/execute/torture/enum_intrinsics1.rs  |  48 ++
 11 files changed, 235 insertions(+), 62 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/enum_intrinsics1.rs

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 0f054588220..1f93e82a93a 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -17,7 +17,6 @@
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-context.h"
 #include "rust-compile-type.h"
-#include "rust-compile-expr.h"
 #include "rust-compile-fnparam.h"
 #include "rust-builtins.h"
 #include "rust-diagnostics.h"
@@ -27,14 +26,10 @@
 #include "rust-tree.h"
 #include "tree-core.h"
 #include "rust-gcc.h"
-#include "print-tree.h"
 #include "fold-const.h"
 #include "langhooks.h"
-#include "rust-gcc.h"
 #include "rust-constexpr.h"
 
-#include "print-tree.h"
-
 // declaration taken from "stringpool.h"
 // the get_identifier macro causes compilation issues
 extern tree
@@ -93,6 +88,8 @@ static tree
 move_val_init_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
 assume_handler (Context *ctx, TyTy::FnType *fntype);
+static tree
+discriminant_value_handler (Context *ctx, TyTy::FnType *fntype);
 
 enum class Prefetch
 {
@@ -217,45 +214,45 @@ sorry_handler (Context *ctx, TyTy::FnType *fntype)
 
 static const std::map>
-  generic_intrinsics = {
-{"offset", offset_handler},
-{"size_of", sizeof_handler},
-{"transmute", transmute_handler},
-{"rotate_left", rotate_left_handler},
-{"rotate_right", rotate_right_handler},
-{"wrapping_add", wrapping_op_handler (PLUS_EXPR)},
-{"wrapping_sub", wrapping_op_handler (MINUS_EXPR)},
-{"wrapping_mul", wrapping_op_handler (MULT_EXPR)},
-{"add_with_overflow", op_with_overflow (PLUS_EXPR)},
-{"sub_with_overflow", op_with_overflow (MINUS_EXPR)},
-{"mul_with_overflow", op_with_overflow (MULT_EXPR)},
-{"copy", copy_handler (true)},
-{"copy_nonoverlapping", copy_handler (false)},
-{"prefetch_read_data", prefetch_read_data},
-{"prefetch_write_data", prefetch_write_data},
-{"atomic_store_seqcst", atomic_store_handler (__ATOMIC_SEQ_CST)},
-{"atomic_store_release", atomic_store_handler (__ATOMIC_RELEASE)},
-{"atomic_store_relaxed", atomic_store_handler (__ATOMIC_RELAXED)},
-{"atomic_store_unordered", atomic_store_handler (__ATOMIC_RELAXED)},
-{"atomic_load_seqcst", atomic_load_handler (__ATOMIC_SEQ_CST)},
-{"atomic_load_acquire", atomic_load_handler (__ATOMIC_ACQUIRE)},
-{"atomic_load_relaxed", atomic_load_handler (__ATOMIC_RELAXED)},
-{"atomic_load_unordered", atomic_load_handler (__ATOMIC_RELAXED

[COMMITTED 073/141] gccrs: remove name resolution inserts from type-path

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We resolve path segments and inserted their resolution into the name
resolution space which was an old hack to use this as information in
code-gen/check-passes in order to help things move forward but this is
not nessecary

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): remove 
name resolution info
(TypeCheckType::resolve_root_path): likewise
* typecheck/rust-hir-type-check-type.h: likewise

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-type.cc | 142 ++
 gcc/rust/typecheck/rust-hir-type-check-type.h |   9 +-
 2 files changed, 16 insertions(+), 135 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 6afa7cf3af9..327cbb010a4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -136,9 +136,7 @@ TypeCheckType::visit (HIR::TypePath &path)
   // remaining segments if possible
   bool wasBigSelf = false;
   size_t offset = 0;
-  NodeId resolved_node_id = UNKNOWN_NODEID;
-  TyTy::BaseType *root
-= resolve_root_path (path, &offset, &resolved_node_id, &wasBigSelf);
+  TyTy::BaseType *root = resolve_root_path (path, &offset, &wasBigSelf);
   if (root->get_kind () == TyTy::TypeKind::ERROR)
 {
   rust_debug_loc (path.get_locus (), "failed to resolve type-path type");
@@ -159,9 +157,9 @@ TypeCheckType::visit (HIR::TypePath &path)
 }
 
   translated
-= resolve_segments (resolved_node_id, path.get_mappings ().get_hirid (),
-   path.get_segments (), offset, path_type,
-   path.get_mappings (), path.get_locus (), wasBigSelf);
+= resolve_segments (path.get_mappings ().get_hirid (), path.get_segments 
(),
+   offset, path_type, path.get_mappings (),
+   path.get_locus (), wasBigSelf);
 
   rust_debug_loc (path.get_locus (), "resolved type-path to: [%s]",
  translated->debug_str ().c_str ());
@@ -180,32 +178,8 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
 
   if (!qual_path_type.has_as_clause ())
 {
-  // then this is just a normal path-in-expression
-  NodeId root_resolved_node_id = UNKNOWN_NODEID;
-  bool ok = false;
-  if (flag_name_resolution_2_0)
-   {
- auto &nr_ctx
-   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
- if (auto id = nr_ctx.lookup (
-   qual_path_type.get_type ().get_mappings ().get_nodeid ()))
-   {
- root_resolved_node_id = *id;
- ok = true;
-   }
-   }
-  else
-   {
- ok = resolver->lookup_resolved_type (
-   qual_path_type.get_type ().get_mappings ().get_nodeid (),
-   &root_resolved_node_id);
-   }
-  rust_assert (ok);
-
   translated
-   = resolve_segments (root_resolved_node_id,
-   path.get_mappings ().get_hirid (),
+   = resolve_segments (path.get_mappings ().get_hirid (),
path.get_segments (), 0, translated,
path.get_mappings (), path.get_locus (), false);
 
@@ -278,7 +252,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
}
 }
 
-  NodeId root_resolved_node_id = UNKNOWN_NODEID;
   if (impl_item == nullptr)
 {
   // this may be valid as there could be a default trait implementation 
here
@@ -286,27 +259,19 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
   // not because this will have already been validated as part of the trait
   // impl block
   translated = item.get_tyty_for_receiver (root);
-  root_resolved_node_id
-   = item.get_raw_item ()->get_mappings ().get_nodeid ();
 }
   else
 {
   HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
   bool ok = query_type (impl_item_id, &translated);
   if (!ok)
-   {
- // FIXME
- // I think query_type should error if required here anyway
- return;
-   }
+   return;
 
   if (!args.is_error ())
{
  // apply the args
  translated = SubstMapperInternal::Resolve (translated, args);
}
-
-  root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
 }
 
   // turbo-fish segment path::
@@ -337,34 +302,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
   // continue on as a path-in-expression
   bool fully_resolved = path.get_segments ().empty ();
   if (fully_resolved)
-{
-  if (flag_name_resolution_2_0)
-   {
- auto &nr_ctx = const_cast (
-   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
-
- nr_ctx.map_usage (Resolver2_0::Usage (
- path.get_mappings ().get_nodeid ()),
-   Resolver2_0::Definition (root_resolved_nod

[COMMITTED 078/141] gccrs: improve error diagnostic for bad type-resolution in CallExpr

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We have the type information for the resolved call lets tell the user about
it in the diagnostic and apply the correct error code.

Fixes Rust-GCC#2035

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): improve 
error diag

gcc/testsuite/ChangeLog:

* rust/compile/generics4.rs: cleanup
* rust/compile/generics6.rs: likewise
* rust/compile/type-bindings1.rs: likewise
* rust/compile/unconstrained_type_param.rs: likewise
* rust/compile/issue-2035.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 13 +
 gcc/testsuite/rust/compile/generics4.rs |  1 -
 gcc/testsuite/rust/compile/generics6.rs |  1 -
 gcc/testsuite/rust/compile/issue-2035.rs| 10 ++
 gcc/testsuite/rust/compile/type-bindings1.rs|  1 -
 .../rust/compile/unconstrained_type_param.rs|  1 -
 6 files changed, 19 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2035.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 5c38cb42b39..85d717535ed 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -225,12 +225,17 @@ TypeCheckExpr::visit (HIR::CallExpr &expr)
   if (resolved_fn_trait_call)
 return;
 
-  bool valid_tyty = function_tyty->get_kind () == TyTy::TypeKind::FNDEF
-   || function_tyty->get_kind () == TyTy::TypeKind::FNPTR;
+  bool valid_tyty
+= function_tyty->is () || function_tyty->is ();
   if (!valid_tyty)
 {
-  rust_error_at (expr.get_locus (),
-"Failed to resolve expression of function call");
+  bool emit_error = !function_tyty->is ();
+  if (emit_error)
+   {
+ rich_location r (line_table, expr.get_locus ());
+ rust_error_at (r, ErrorCode::E0618, "expected function, found %<%s%>",
+function_tyty->get_name ().c_str ());
+   }
   return;
 }
 
diff --git a/gcc/testsuite/rust/compile/generics4.rs 
b/gcc/testsuite/rust/compile/generics4.rs
index 31b681abb10..c4dbc432c07 100644
--- a/gcc/testsuite/rust/compile/generics4.rs
+++ b/gcc/testsuite/rust/compile/generics4.rs
@@ -6,7 +6,6 @@ struct GenericStruct(T, usize);
 fn main() {
 let a2;
 a2 = GenericStruct::(1, 456); // { dg-error "generic item takes 
at most 1 type arguments but 2 were supplied" }
-   // { dg-error {Failed to resolve 
expression of function call} "" { target *-*-* } .-1 }
 
 let b2: i32 = a2.0;
 // { dg-error {Expected Tuple or ADT got: T\?} "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/generics6.rs 
b/gcc/testsuite/rust/compile/generics6.rs
index 33093cf706b..d77c559db21 100644
--- a/gcc/testsuite/rust/compile/generics6.rs
+++ b/gcc/testsuite/rust/compile/generics6.rs
@@ -27,6 +27,5 @@ impl Foo {
 
 fn main() {
 let a: i32 = Foo::test(); // { dg-error "multiple applicable items in 
scope for: .test." }
-// { dg-error {Failed to resolve expression of function call} "" { target 
*-*-* } .-1 }
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-2035.rs 
b/gcc/testsuite/rust/compile/issue-2035.rs
new file mode 100644
index 000..c0817d532cc
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2035.rs
@@ -0,0 +1,10 @@
+fn func(i: i32) {
+i();
+// { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } 
.-1 }
+}
+
+fn main() {
+let i = 0i32;
+i();
+// { dg-error "expected function, found .i32. .E0618." "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/type-bindings1.rs 
b/gcc/testsuite/rust/compile/type-bindings1.rs
index 358035bbc17..ef0b47128df 100644
--- a/gcc/testsuite/rust/compile/type-bindings1.rs
+++ b/gcc/testsuite/rust/compile/type-bindings1.rs
@@ -7,5 +7,4 @@ fn main() {
 let a;
 a = Foo::(123f32);
 // { dg-error "associated type bindings are not allowed here" "" { target 
*-*-* } .-1 }
-// { dg-error {Failed to resolve expression of function call} "" { target 
*-*-* } .-2 }
 }
diff --git a/gcc/testsuite/rust/compile/unconstrained_type_param.rs 
b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
index 1cef0b983b0..60554dac0e0 100644
--- a/gcc/testsuite/rust/compile/unconstrained_type_param.rs
+++ b/gcc/testsuite/rust/compile/unconstrained_type_param.rs
@@ -13,5 +13,4 @@ impl Foo {
 fn main() {
 let a = Foo::test();
 // { dg-error "expected" "" { target *-*-* } .-1 }
-// { dg-error "Failed to resolve expression of function call" "" { target 
*-*-* } .-2 }
 }
-- 
2.45.2



[COMMITTED 082/141] gccrs: Add type check on if-expr

2025-03-24 Thread arthur . cohen
From: Benjamin Thos 

Check if an if-expr returns void type or a coercible type like an early return.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Add check on if-expr.

gcc/testsuite/ChangeLog:

* rust/compile/implicit_returns_err3.rs: Change test to be valid.
* rust/compile/torture/if.rs: Likewise.
* rust/compile/if-without-else.rs: New test.

Signed-off-by: Benjamin Thos 
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc  | 13 +++--
 gcc/testsuite/rust/compile/if-without-else.rs   |  9 +
 gcc/testsuite/rust/compile/implicit_returns_err3.rs |  2 +-
 gcc/testsuite/rust/compile/torture/if.rs|  8 ++--
 4 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/if-without-else.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 85d717535ed..4e57d6a8ffb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -526,9 +526,18 @@ TypeCheckExpr::visit (HIR::IfExpr &expr)
expr.get_if_condition ().get_locus ()),
  expr.get_locus ());
 
-  TypeCheckExpr::Resolve (expr.get_if_block ());
+  TyTy::BaseType *block_type = TypeCheckExpr::Resolve (expr.get_if_block ());
 
-  infered = TyTy::TupleType::get_unit_type ();
+  TyTy::BaseType *unit_ty = nullptr;
+  ok = context->lookup_builtin ("()", &unit_ty);
+  rust_assert (ok);
+
+  infered
+= coercion_site (expr.get_mappings ().get_hirid (),
+TyTy::TyWithLocation (unit_ty),
+TyTy::TyWithLocation (block_type,
+  expr.get_if_block ().get_locus ()),
+expr.get_locus ());
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/if-without-else.rs 
b/gcc/testsuite/rust/compile/if-without-else.rs
new file mode 100644
index 000..1a0f6449d70
--- /dev/null
+++ b/gcc/testsuite/rust/compile/if-without-else.rs
@@ -0,0 +1,9 @@
+fn foo(pred: bool) -> u8 {
+if pred { // { dg-error "mismatched types" }
+1
+}
+3
+}
+
+fn main(){
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs 
b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
index ac982137798..f0330aca9c0 100644
--- a/gcc/testsuite/rust/compile/implicit_returns_err3.rs
+++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
@@ -1,6 +1,6 @@
 fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but 
got " }
 if x > 1 {
-1
+return 1;
 }
 }
 
diff --git a/gcc/testsuite/rust/compile/torture/if.rs 
b/gcc/testsuite/rust/compile/torture/if.rs
index bcd520f66a9..3b753a71eb2 100644
--- a/gcc/testsuite/rust/compile/torture/if.rs
+++ b/gcc/testsuite/rust/compile/torture/if.rs
@@ -4,6 +4,10 @@ fn foo() -> bool {
 
 fn bar() {}
 
+fn baz(a: i32) {
+a;
+}
+
 struct Foo1 {
 one: i32
 }
@@ -13,7 +17,7 @@ fn main() {
 if foo() {
 bar();
 let a = Foo1{one: 1};
-a.one
+baz (a.one);
 }
 
-}
\ No newline at end of file
+}
-- 
2.45.2



[COMMITTED 001/141] gccrs: typecheck: Separate assemble_builtin_candidate in two

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

This paves the way for adding trait bounds that aren't necessarily Sized.

gcc/rust/ChangeLog:

* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::add_trait_bound): New 
function.
* typecheck/rust-hir-type-bounds.h: Declare it.
(TypeBoundsProbe::assemble_builtin_candidate): Call into 
add_trait_bound.
---
 gcc/rust/typecheck/rust-hir-type-bounds.h |  1 +
 gcc/rust/typecheck/rust-tyty-bounds.cc| 12 +---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-bounds.h 
b/gcc/rust/typecheck/rust-hir-type-bounds.h
index 7fdba1c549b..82333f18685 100644
--- a/gcc/rust/typecheck/rust-hir-type-bounds.h
+++ b/gcc/rust/typecheck/rust-hir-type-bounds.h
@@ -38,6 +38,7 @@ public:
 private:
   void scan ();
   void assemble_sized_builtin ();
+  void add_trait_bound (HIR::Trait *trait);
   void assemble_builtin_candidate (LangItem::Kind item);
 
 private:
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 5db96cc7b41..73d686b7814 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -150,6 +150,14 @@ TypeBoundsProbe::assemble_sized_builtin ()
 }
 }
 
+void
+TypeBoundsProbe::add_trait_bound (HIR::Trait *trait)
+{
+  auto trait_ref = TraitResolver::Resolve (*trait);
+
+  trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
+}
+
 void
 TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind lang_item)
 {
@@ -167,9 +175,7 @@ TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind 
lang_item)
   HIR::Trait *trait = static_cast (item);
   const TyTy::BaseType *raw = receiver->destructure ();
 
-  // assemble the reference
-  TraitReference *trait_ref = TraitResolver::Resolve (*trait);
-  trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
+  add_trait_bound (trait);
 
   rust_debug ("Added builtin lang_item: %s for %s",
  LangItem::ToString (lang_item).c_str (),
-- 
2.45.2



[COMMITTED 034/141] gccrs: Compile unit struct with constructor

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (ResolvePathRef::resolve): Do
not use query system for unit struct but compile it's constructor
instead.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 5 +
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index a40f5542a68..103f0cb6fe8 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -180,6 +180,11 @@ ResolvePathRef::resolve_with_node_id (
}
 }
 
+  // Handle unit struct
+  if (lookup->get_kind () == TyTy::TypeKind::ADT)
+return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+
   // let the query system figure it out
   tree resolved_item = query_compile (ref, lookup, final_segment, mappings,
  expr_locus, is_qualified_path);
-- 
2.45.2



[COMMITTED 035/141] gccrs: Remove some passing test from exclude file

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Those tests are now passing.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove some tests.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/nr2/exclude | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 641222a8d7f..c5c7326500d 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -36,7 +36,6 @@ issue-1981.rs
 issue-2036.rs
 issue-2043.rs
 issue-2142.rs
-issue-2238.rs
 issue-2330.rs
 issue-2479.rs
 issue-2723-1.rs
@@ -50,6 +49,7 @@ issue-852.rs
 issue-855.rs
 iterators1.rs
 lookup_err1.rs
+macros/mbe/macro20.rs
 macros/mbe/macro23.rs
 macros/mbe/macro40.rs
 macros/mbe/macro43.rs
@@ -68,8 +68,6 @@ match9.rs
 method2.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
-name_resolution2.rs
-name_resolution4.rs
 nested_macro_use1.rs
 nested_macro_use2.rs
 nested_macro_use3.rs
@@ -93,6 +91,7 @@ pub_restricted_3.rs
 redef_error2.rs
 redef_error4.rs
 redef_error5.rs
+self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
@@ -103,7 +102,6 @@ type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
 use_1.rs
-use_2.rs
 v0-mangle1.rs
 v0-mangle2.rs
 while_break_expr.rs
@@ -128,7 +126,6 @@ issue-2907.rs
 issue-2423.rs
 issue-266.rs
 additional-trait-bounds2.rs
-auto_traits2.rs
 issue-3140.rs
 cmp1.rs
 derive_clone_enum1.rs
-- 
2.45.2



[COMMITTED 097/141] gccrs: Remove some member functions from SingleASTNode

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* ast/rust-ast.h
(SingleASTNode::take_trait_item): Remove.
(SingleASTNode::take_impl_item): Remove.
(SingleASTNode::take_trait_impl_item): Remove.
* expand/rust-expand-visitor.cc
(ExpandVisitor::visit): Replace calls to aforementioned
functions with calls to SingleASTNode::take_assoc_item.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast.h| 17 -
 gcc/rust/expand/rust-expand-visitor.cc |  7 ---
 2 files changed, 4 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 42be097f056..4d7d23d23cc 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1996,13 +1996,6 @@ public:
 return std::move (item);
   }
 
-  std::unique_ptr take_trait_item ()
-  {
-rust_assert (!is_error ());
-return std::unique_ptr (
-  static_cast (assoc_item.release ()));
-  }
-
   std::unique_ptr take_external_item ()
   {
 rust_assert (!is_error ());
@@ -2015,16 +2008,6 @@ public:
 return std::move (assoc_item);
   }
 
-  std::unique_ptr take_impl_item ()
-  {
-return take_assoc_item ();
-  }
-
-  std::unique_ptr take_trait_impl_item ()
-  {
-return take_assoc_item ();
-  }
-
   std::unique_ptr take_type ()
   {
 rust_assert (!is_error ());
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 2830d200f72..1d131b18180 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -865,7 +865,7 @@ ExpandVisitor::visit (AST::Trait &trait)
 
   std::function (AST::SingleASTNode)>
 extractor
-= [] (AST::SingleASTNode node) { return node.take_trait_item (); };
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::TRAIT,
 trait.get_trait_items (), extractor);
@@ -892,7 +892,8 @@ ExpandVisitor::visit (AST::InherentImpl &impl)
 expand_where_clause (impl.get_where_clause ());
 
   std::function (AST::SingleASTNode)>
-extractor = [] (AST::SingleASTNode node) { return node.take_impl_item (); 
};
+extractor
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::IMPL,
 impl.get_impl_items (), extractor);
@@ -920,7 +921,7 @@ ExpandVisitor::visit (AST::TraitImpl &impl)
 
   std::function (AST::SingleASTNode)>
 extractor
-= [] (AST::SingleASTNode node) { return node.take_trait_impl_item (); };
+= [] (AST::SingleASTNode node) { return node.take_assoc_item (); };
 
   expand_macro_children (MacroExpander::ContextType::TRAIT_IMPL,
 impl.get_impl_items (), extractor);
-- 
2.45.2



[COMMITTED 108/141] gccrs: Adjust unknown macro error message

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc
(Early::visit): Adjust error produced when macro resolution
fails.
* resolve/rust-early-name-resolver.cc
(EarlyNameResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro43.rs: Adjust expected errors.
* rust/compile/macros/mbe/macro44.rs: Likewise.
* rust/compile/nested_macro_use2.rs: Likewise.
* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 3 ++-
 gcc/rust/resolve/rust-early-name-resolver.cc | 3 ++-
 gcc/testsuite/rust/compile/macros/mbe/macro43.rs | 2 +-
 gcc/testsuite/rust/compile/macros/mbe/macro44.rs | 2 +-
 gcc/testsuite/rust/compile/nested_macro_use2.rs  | 2 +-
 gcc/testsuite/rust/compile/nr2/exclude   | 2 --
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 764be45e34c..b894d130ccf 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -280,7 +280,8 @@ Early::visit (AST::MacroInvocation &invoc)
   if (!definition.has_value ())
 {
   collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
-   "could not resolve macro invocation"));
+   "could not resolve macro invocation %qs",
+   path.as_string ().c_str ()));
   return;
 }
 
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index a8df631200c..fc9a26ccac0 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -477,7 +477,8 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
   bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node);
   if (!found)
 {
-  rust_error_at (invoc.get_locus (), "unknown macro: [%s]",
+  rust_error_at (invoc.get_locus (), ErrorCode::E0433,
+"could not resolve macro invocation %qs",
 seg.get ().c_str ());
   return;
 }
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
index 992bc77cedf..fbc36a9d6e5 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro43.rs
@@ -48,7 +48,7 @@ macro_rules! nonzero_integers {
 
 }
 
-impl_nonzero_fmt! { // { dg-error "unknown macro" }
+impl_nonzero_fmt! { // { dg-error "could not resolve macro 
invocation" }
 (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
 }
 )+
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
index dabac6f7844..0cfd98718b4 100644
--- a/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro44.rs
@@ -16,7 +16,7 @@ mod foo {
 }
 
 fn bar_f() {
-baz!(); // { dg-error "unknown macro" }
+baz!(); // { dg-error "could not resolve macro invocation" }
 }
 }
 
diff --git a/gcc/testsuite/rust/compile/nested_macro_use2.rs 
b/gcc/testsuite/rust/compile/nested_macro_use2.rs
index 46595008710..7bb6154c28c 100644
--- a/gcc/testsuite/rust/compile/nested_macro_use2.rs
+++ b/gcc/testsuite/rust/compile/nested_macro_use2.rs
@@ -8,5 +8,5 @@ mod foo {
 }
 
 fn main() {
-baz!(); // { dg-error "unknown macro: .baz." }
+baz!(); // { dg-error "could not resolve macro invocation .baz." }
 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6dba0f71705..02da99de52f 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -21,11 +21,9 @@ issue-855.rs
 iterators1.rs
 lookup_err1.rs
 macros/mbe/macro43.rs
-macros/mbe/macro44.rs
 macros/mbe/macro6.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
-nested_macro_use2.rs
 not_find_value_in_scope.rs
 privacy5.rs
 privacy8.rs
-- 
2.45.2



[COMMITTED 037/141] gccrs: lang-items: Add From::from

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* util/rust-lang-item.h: Declare it.
* util/rust-lang-item.cc: Use it.
---
 gcc/rust/util/rust-lang-item.cc | 2 ++
 gcc/rust/util/rust-lang-item.h  | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index b37a237c24e..145054ff9d7 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -110,6 +110,8 @@ const BiMap 
Rust::LangItem::lang_items = {{
   {"into_result", Kind::TRY_INTO_RESULT},
   {"from_error", Kind::TRY_FROM_ERROR},
   {"from_ok", Kind::TRY_FROM_OK},
+
+  {"from", Kind::FROM_FROM},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 851909d409c..f30b93609b5 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -141,6 +141,9 @@ public:
 TRY_INTO_RESULT,
 TRY_FROM_ERROR,
 TRY_FROM_OK,
+
+// NOTE: This is not a lang item in later versions of Rust
+FROM_FROM,
   };
 
   static const BiMap lang_items;
-- 
2.45.2



[COMMITTED 116/141] gccrs: Add rib kind debug representation

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Rib kind had no string representation, and thus were not used in the
debug string representation.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Output rib kind.
* resolve/rust-rib.h: Add function to get string representation from
a rib kind.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 10 ++---
 gcc/rust/resolve/rust-rib.h | 29 +
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index c1407344b52..9e66c802d5f 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -781,13 +781,17 @@ ForeverStack::stream_rib (std::stringstream &stream, 
const Rib &rib,
 const std::string &next,
 const std::string &next_next) const
 {
+  std::string rib_kind = Rib::kind_to_string (rib.kind);
+  stream << next << "rib [" << rib_kind << "]: {";
   if (rib.get_values ().empty ())
 {
-  stream << next << "rib: {},\n";
+  stream << "}\n";
   return;
 }
-
-  stream << next << "rib: {\n";
+  else
+{
+  stream << "\n";
+}
 
   for (const auto &kv : rib.get_values ())
 stream << next_next << kv.first << ": " << kv.second.to_string () << "\n";
diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h
index 2eb8de8f0ef..767547f985f 100644
--- a/gcc/rust/resolve/rust-rib.h
+++ b/gcc/rust/resolve/rust-rib.h
@@ -175,6 +175,35 @@ public:
 ConstParamType,
   } kind;
 
+  static std::string kind_to_string (Rib::Kind kind)
+  {
+switch (kind)
+  {
+  case Rib::Kind::Normal:
+   return "Normal";
+  case Rib::Kind::Module:
+   return "Module";
+  case Rib::Kind::Function:
+   return "Function";
+  case Rib::Kind::ConstantItem:
+   return "ConstantItem";
+  case Rib::Kind::TraitOrImpl:
+   return "TraitOrImpl";
+  case Rib::Kind::Item:
+   return "Item";
+  case Rib::Kind::Closure:
+   return "Closure";
+  case Rib::Kind::MacroDefinition:
+   return "Macro definition";
+  case Rib::Kind::ForwardTypeParamBan:
+   return "Forward type param ban";
+  case Rib::Kind::ConstParamType:
+   return "Const Param Type";
+  default:
+   rust_unreachable ();
+  }
+  }
+
   Rib (Kind kind);
   Rib (Kind kind, std::string identifier, NodeId id);
   Rib (Kind kind, std::unordered_map values);
-- 
2.45.2



[COMMITTED 080/141] gccrs: initial setup for new OpaqueType to represent Impl types

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This completes the initial setup and boilerplate for the new type in the
typesystem. This is not functional yet but its a big patch already.

gcc/rust/ChangeLog:

* backend/rust-compile-type.cc (TyTyResolveCompile::visit): new 
tyty::OpaqueType
* backend/rust-compile-type.h: likewise
* checks/errors/borrowck/rust-bir-fact-collector.h: likewise
* checks/errors/borrowck/rust-bir-place.h: likewise
* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::check_base_type_privacy):
likewise
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): likewise
* typecheck/rust-hir-type-check-type.h: likewise
* typecheck/rust-substitution-mapper.cc (SubstMapperInternal::visit): 
likewise
* typecheck/rust-substitution-mapper.h: likewise
* typecheck/rust-tyty-bounds.cc 
(TypeBoundsProbe::assemble_sized_builtin): likewise
* typecheck/rust-tyty-call.h: likewise
* typecheck/rust-tyty-cmp.h (class OpaqueCmp): likewise
* typecheck/rust-tyty-variance-analysis-private.h: likewise
* typecheck/rust-tyty-visitor.h: likewise
* typecheck/rust-tyty.cc (TypeKindFormat::to_string): likewise
(BaseType::is_unit): likewise
(BaseType::destructure): likewise
(BaseType::has_substitutions_defined): likewise
(BaseType::needs_generic_substitutions): likewise
(OpaqueType::OpaqueType): likewise
(OpaqueType::can_resolve): likewise
(OpaqueType::accept_vis): likewise
(OpaqueType::as_string): likewise
(OpaqueType::get_name): likewise
(OpaqueType::can_eq): likewise
(OpaqueType::clone): likewise
(OpaqueType::resolve): likewise
(OpaqueType::is_equal): likewise
(OpaqueType::handle_substitions): likewise
* typecheck/rust-tyty.h (enum TypeKind): likewise
(class OpaqueType): likewise
* typecheck/rust-unify.cc (UnifyRules::go): likewise
(UnifyRules::expect_inference_variable): likewise
(UnifyRules::expect_adt): likewise
(UnifyRules::expect_str): likewise
(UnifyRules::expect_reference): likewise
(UnifyRules::expect_pointer): likewise
(UnifyRules::expect_param): likewise
(UnifyRules::expect_array): likewise
(UnifyRules::expect_slice): likewise
(UnifyRules::expect_fndef): likewise
(UnifyRules::expect_fnptr): likewise
(UnifyRules::expect_tuple): likewise
(UnifyRules::expect_bool): likewise
(UnifyRules::expect_char): likewise
(UnifyRules::expect_int): likewise
(UnifyRules::expect_uint): likewise
(UnifyRules::expect_float): likewise
(UnifyRules::expect_isize): likewise
(UnifyRules::expect_usize): likewise
(UnifyRules::expect_placeholder): likewise
(UnifyRules::expect_projection): likewise
(UnifyRules::expect_dyn): likewise
(UnifyRules::expect_opaque): likewise
* typecheck/rust-unify.h: likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-type.cc |   6 +
 gcc/rust/backend/rust-compile-type.h  |   1 +
 .../errors/borrowck/rust-bir-fact-collector.h |   1 +
 .../checks/errors/borrowck/rust-bir-place.h   |   1 +
 .../errors/privacy/rust-privacy-reporter.cc   |   2 +
 .../typecheck/rust-hir-type-check-type.cc |  37 -
 gcc/rust/typecheck/rust-hir-type-check-type.h |  13 +-
 .../typecheck/rust-substitution-mapper.cc |   5 +
 gcc/rust/typecheck/rust-substitution-mapper.h |   4 +
 gcc/rust/typecheck/rust-tyty-bounds.cc|   1 +
 gcc/rust/typecheck/rust-tyty-call.h   |   1 +
 gcc/rust/typecheck/rust-tyty-cmp.h|  33 
 .../rust-tyty-variance-analysis-private.h |   2 +
 gcc/rust/typecheck/rust-tyty-visitor.h|   2 +
 gcc/rust/typecheck/rust-tyty.cc   | 152 +-
 gcc/rust/typecheck/rust-tyty.h|  34 
 gcc/rust/typecheck/rust-unify.cc  |  89 +-
 gcc/rust/typecheck/rust-unify.h   |   2 +
 18 files changed, 372 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 74368a29f49..d8af1d1af6b 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -731,6 +731,12 @@ TyTyResolveCompile::visit (const TyTy::DynamicObjectType 
&type)
type.get_ident ().locus);
 }
 
+void
+TyTyResolveCompile::visit (const TyTy::OpaqueType &type)
+{
+  translated = error_mark_node;
+}
+
 tree
 TyTyResolveCompile::create_dyn_obj_record (const TyTy::DynamicObjectType &type)
 {
diff --git a/gcc/rust/backend/rust-compile-type.h 
b/gcc/rust/backend/rust-compile-type.h
index 398d7f8bda9..bc611cfbc73 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -56,6 +56,7 @@ public:
   v

[COMMITTED 076/141] gccrs: fix name resolution for generics where type param is declared later

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Rust allows you to use generics within type bounds when they are declared
later on. This changes the name resolution to walk the genric params
in two passes to ensure the type parameters are setup before drilling down
into the type parameters

This issue has exposed another type checking issue which needs fixed in
a subseqent patch.

Addresses Rust-GCC#3022

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit): use new 
api
(ResolveItem::visit): likewise
(ResolveExternItem::visit): likewise
* resolve/rust-ast-resolve-stmt.h: likewise
* resolve/rust-ast-resolve-type.h (class ResolveGenericParam): remove
(class ResolveGenericParams): added new api

Signed-off-by: Philip Herron 
---
 gcc/rust/resolve/rust-ast-resolve-item.cc | 48 ++---
 gcc/rust/resolve/rust-ast-resolve-stmt.h  | 26 +++
 gcc/rust/resolve/rust-ast-resolve-type.h  | 87 ++-
 3 files changed, 86 insertions(+), 75 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index cecc8ad6857..366716a22e2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -64,8 +64,8 @@ ResolveTraitItems::visit (AST::Function &function)
   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   if (function.has_generics ())
-for (auto &generic : function.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (function.has_return_type ())
 ResolveType::go (function.get_return_type ());
@@ -188,8 +188,8 @@ ResolveItem::visit (AST::TypeAlias &alias)
   resolver->get_type_scope ().push (scope_node_id);
 
   if (alias.has_generics ())
-for (auto &generic : alias.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (alias.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (alias.has_where_clause ())
 ResolveWhereClause::Resolve (alias.get_where_clause ());
@@ -250,8 +250,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl)
   resolver->get_type_scope ().push (scope_node_id);
 
   if (struct_decl.has_generics ())
-for (auto &generic : struct_decl.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (struct_decl.has_where_clause ())
 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -284,8 +284,8 @@ ResolveItem::visit (AST::Enum &enum_decl)
   resolver->get_type_scope ().push (scope_node_id);
 
   if (enum_decl.has_generics ())
-for (auto &generic : enum_decl.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, cpath);
+ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (enum_decl.has_where_clause ())
 ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
@@ -374,8 +374,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl)
   resolver->get_type_scope ().push (scope_node_id);
 
   if (struct_decl.has_generics ())
-for (auto &generic : struct_decl.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (struct_decl.has_where_clause ())
 ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
@@ -409,8 +409,8 @@ ResolveItem::visit (AST::Union &union_decl)
   resolver->get_type_scope ().push (scope_node_id);
 
   if (union_decl.has_generics ())
-for (auto &generic : union_decl.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
+ canonical_prefix);
 
   if (union_decl.has_where_clause ())
 ResolveWhereClause::Resolve (union_decl.get_where_clause ());
@@ -476,8 +476,8 @@ ResolveItem::visit (AST::Function &function)
   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
 
   if (function.has_generics ())
-for (auto &generic : function.get_generic_params ())
-  ResolveGenericParam::go (*generic, prefix, canonical_prefix);
+ResolveGenericParams::go (function.get_generic_params (), prefix,
+ canonical_prefix);
 
   // resolve any where clause items
   if (function.has_where_clause ())
@@ -567,8 +567,8 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
   resolve_visibility (impl_block.get_visibility ());
 
   if (impl_block.has_generics ())
-for (auto &g

[COMMITTED 124/141] gccrs: check for recursion trait cycle with bounds checks

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We need to be careful when doing bounds check as to not create a recusive
trait resolution. This patch checks for that case and fixes a bad type
is equal check on ADT Types which was caught with a regression here.

Fixes Rust-GCC#3126

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc (TraitResolver::ResolveHirItem): 
new helper
* typecheck/rust-hir-trait-resolve.h: add helper prototype
* typecheck/rust-type-util.cc (query_type): add debug
* typecheck/rust-tyty-bounds.cc (TypeBoundsProbe::scan): check for 
recursion
* typecheck/rust-tyty.cc (VariantDef::is_equal): fix is equal check

gcc/testsuite/ChangeLog:

* rust/execute/torture/issue-3126.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 10 
 gcc/rust/typecheck/rust-hir-trait-resolve.h   |  2 +
 gcc/rust/typecheck/rust-type-util.cc  |  7 ++-
 gcc/rust/typecheck/rust-tyty-bounds.cc|  9 
 gcc/rust/typecheck/rust-tyty.cc   |  3 --
 .../rust/execute/torture/issue-3126.rs| 52 +++
 6 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/issue-3126.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 98323f63132..58a0f014926 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -107,6 +107,16 @@ TraitResolver::Lookup (HIR::TypePath &path)
   return resolver.lookup_path (path);
 }
 
+HIR::Trait *
+TraitResolver::ResolveHirItem (const HIR::TypePath &path)
+{
+  TraitResolver resolver;
+
+  HIR::Trait *lookup = nullptr;
+  bool ok = resolver.resolve_path_to_trait (path, &lookup);
+  return ok ? lookup : nullptr;
+}
+
 TraitResolver::TraitResolver () : TypeCheckBase () {}
 
 bool
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h 
b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index 916abe6c9d0..b79fe17ee3e 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -58,6 +58,8 @@ public:
 
   static TraitReference *Lookup (HIR::TypePath &path);
 
+  static HIR::Trait *ResolveHirItem (const HIR::TypePath &path);
+
 private:
   TraitResolver ();
 
diff --git a/gcc/rust/typecheck/rust-type-util.cc 
b/gcc/rust/typecheck/rust-type-util.cc
index 7a39eb53710..4abfbae3665 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -87,8 +87,11 @@ query_type (HirId reference, TyTy::BaseType **result)
   // is it an impl_type?
   if (auto impl_block_by_type = mappings.lookup_impl_block_type (reference))
 {
-  *result
-   = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type.value ());
+  // found an impl item
+  HIR::ImplBlock *impl = impl_block_by_type.value ();
+  rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
+ reference);
+  *result = TypeCheckItem::ResolveImplBlockSelf (*impl);
   context->query_completed (reference);
   return true;
 }
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 9187fc63141..d7007879228 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -20,6 +20,7 @@
 #include "rust-hir-type-bounds.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-substitution-mapper.h"
+#include "rust-hir-trait-resolve.h"
 #include "rust-type-util.h"
 
 namespace Rust {
@@ -71,6 +72,14 @@ TypeBoundsProbe::scan ()
   if (!impl->has_trait_ref ())
return true;
 
+  // can be recursive trait resolution
+  HIR::Trait *t = TraitResolver::ResolveHirItem (impl->get_trait_ref ());
+  if (t == nullptr)
+   return true;
+  DefId trait_id = t->get_mappings ().get_defid ();
+  if (context->trait_query_in_progress (trait_id))
+   return true;
+
   HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
   TyTy::BaseType *impl_type = nullptr;
   if (!query_type (impl_ty_id, &impl_type))
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 3951fa88da8..efad5f61322 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -1566,9 +1566,6 @@ VariantDef::is_equal (const VariantDef &other) const
   if (identifier.compare (other.identifier) != 0)
 return false;
 
-  if (discriminant != other.discriminant)
-return false;
-
   if (fields.size () != other.fields.size ())
 return false;
 
diff --git a/gcc/testsuite/rust/execute/torture/issue-3126.rs 
b/gcc/testsuite/rust/execute/torture/issue-3126.rs
new file mode 100644
index 000..f5051467f02
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-3126.rs
@@ -0,0 +1,52 @@
+/* { dg-output "child\r*\n" }*/
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+#[lang = "size

[COMMITTED 121/141] gccrs: Fix some small issues

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* backend/rust-compile-intrinsic.cc
(assume_handler): Fix copy/paste error.
* typecheck/rust-hir-type-check-pattern.cc
(TypeCheckPattern::visit): Fix spelling mistake.

Signed-off-by: Owen Avery 
---
 gcc/rust/backend/rust-compile-intrinsic.cc| 2 +-
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 28c69d50b46..fb0c66101fa 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -1273,7 +1273,7 @@ assume_handler (Context *ctx, TyTy::FnType *fntype)
   TREE_SIDE_EFFECTS (assume_expr) = 1;
 
   ctx->add_statement (assume_expr);
-  // BUILTIN size_of FN BODY END
+  // BUILTIN assume FN BODY END
 
   finalize_intrinsic_block (ctx, fndecl);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index a00fa7dbd89..3f9557a5c3e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -109,7 +109,7 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
  rich_location rich_locus (
line_table, pattern.get_final_segment ().get_locus ());
  rich_locus.add_fixit_replace (
-   "not a unit struct, unit variant or constatnt");
+   "not a unit struct, unit variant or constant");
  rust_error_at (rich_locus, ErrorCode::E0532,
 "expected unit struct, unit variant or constant, "
 "found %s %<%s%>",
-- 
2.45.2



[COMMITTED 138/141] gccrs: Modify multiple definition error

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-expr.cc
(ResolveExpr::visit): Modify error message.
* resolve/rust-ast-resolve-implitem.h
(ResolveToplevelImplItem::visit): Likewise.
(ResolveTopLevelTraitItems::visit): Likewise.
(ResolveToplevelExternItem::visit): Likewise.
* resolve/rust-ast-resolve-stmt.cc
(ResolveStmt::visit): Likewise.
* resolve/rust-ast-resolve-stmt.h
(ResolveStmt::visit): Likewise.
* resolve/rust-ast-resolve-toplevel.h
(ResolveTopLevel::visit): Likewise.
* resolve/rust-ast-resolve-type.h
(ResolveGenericParams::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.
* rust/compile/redef_error2.rs: Modify expected error.
* rust/compile/redef_error5.rs: Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc|  8 ++---
 gcc/rust/resolve/rust-ast-resolve-implitem.h | 18 +--
 gcc/rust/resolve/rust-ast-resolve-stmt.cc|  2 +-
 gcc/rust/resolve/rust-ast-resolve-stmt.h | 20 ++--
 gcc/rust/resolve/rust-ast-resolve-toplevel.h | 32 ++--
 gcc/rust/resolve/rust-ast-resolve-type.h |  2 +-
 gcc/testsuite/rust/compile/nr2/exclude   |  2 --
 gcc/testsuite/rust/compile/redef_error2.rs   |  2 +-
 gcc/testsuite/rust/compile/redef_error5.rs   |  2 +-
 9 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc 
b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index be960beccd5..dc7f76d652d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -287,7 +287,7 @@ ResolveExpr::visit (AST::BlockExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
  rust_error_at (locus, "was defined here");
});
 }
@@ -459,7 +459,7 @@ ResolveExpr::visit (AST::LoopExpr &expr)
CanonicalPath::new_seg (expr.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
  rust_error_at (locus, "was defined here");
});
 }
@@ -535,7 +535,7 @@ ResolveExpr::visit (AST::WhileLoopExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
  rust_error_at (locus, "was defined here");
});
 }
@@ -564,7 +564,7 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
CanonicalPath::new_seg (label.get_node_id (), label_name),
label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label,
[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rust_error_at (label.get_locus (), "label redefined multiple times");
+ rust_error_at (label.get_locus (), "label defined multiple times");
  rust_error_at (locus, "was defined here");
});
 }
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h 
b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 2ca12965d9b..971bf8faee2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -51,7 +51,7 @@ public:
   [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, type.get_locus ());
r.add_range (locus);
-   rust_error_at (r, "redefined multiple times");
+   rust_error_at (r, "defined multiple times");
   });
   }
 
@@ -67,7 +67,7 @@ public:
   [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, constant.get_locus ());
r.add_range (locus);
-   rust_error_at (r, "redefined multiple times");
+   rust_error_at (r, "defined multiple times");
   });
   }
 
@@ -84,7 +84,7 @@ public:
   [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
rich_location r (line_table, function.get_locus ());
r.add_range (locus);
-   rust_error_at (r, "redefined multiple times");
+   rust_error_at (r, "defined multiple times");
   });
   }
 
@@ -124,7 +124,7 @@ public:
   [&] (co

[COMMITTED 140/141] gccrs: nr2.0: Fix StructExprFieldIdentifier handling

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Add visitor for StructExprFieldIdentifier.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 28 +++
 .../resolve/rust-late-name-resolver-2.0.h |  1 +
 gcc/testsuite/rust/compile/nr2/exclude|  8 --
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 09aa5fc44e6..cf7b7dcd03f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -259,6 +259,34 @@ Late::visit (AST::IdentifierExpr &expr)
   // toplevel instead insert a name in ctx.values? (like it currently does)
 }
 
+void
+Late::visit (AST::StructExprFieldIdentifier &expr)
+{
+  tl::optional resolved = tl::nullopt;
+
+  if (auto value = ctx.values.get (expr.get_field_name ()))
+{
+  resolved = value;
+}
+  // seems like we don't need a type namespace lookup
+  else
+{
+  rust_error_at (expr.get_locus (), "could not resolve struct field: %qs",
+expr.get_field_name ().as_string ().c_str ());
+  return;
+}
+
+  if (resolved->is_ambiguous ())
+{
+  rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+expr.as_string ().c_str ());
+  return;
+}
+
+  ctx.map_usage (Usage (expr.get_node_id ()),
+Definition (resolved->get_node_id ()));
+}
+
 void
 Late::visit (AST::PathInExpression &expr)
 {
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 31303eb4fb2..ac376b5cb6f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -46,6 +46,7 @@ public:
 
   // resolutions
   void visit (AST::IdentifierExpr &) override;
+  void visit (AST::StructExprFieldIdentifier &) override;
   void visit (AST::BreakExpr &) override;
   void visit (AST::PathInExpression &) override;
   void visit (AST::TypePath &) override;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 59964fc90e2..fed7bde6307 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -23,7 +23,6 @@ pub_restricted_1.rs
 pub_restricted_2.rs
 pub_restricted_3.rs
 sizeof-stray-infer-var-bug.rs
-struct-expr-parse.rs
 undeclared_label.rs
 use_1.rs
 while_break_expr.rs
@@ -40,15 +39,8 @@ derive-eq-invalid.rs
 derive-hash1.rs
 torture/alt_patterns1.rs
 torture/builtin_abort.rs
-torture/impl_block3.rs
-torture/issue-1434.rs
 torture/loop4.rs
 torture/loop8.rs
-torture/methods1.rs
-torture/methods2.rs
-torture/methods3.rs
 torture/name_resolve1.rs
-torture/nested_struct1.rs
-torture/struct_init_3.rs
 torture/uninit-intrinsic-1.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 136/141] gccrs: Prevent multiple resolution insertion

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc
(DeriveClone::clone_impl): Avoid using the same node id multiple
times.
(DeriveClone::clone_enum_identifier): Likewise.
(DeriveClone::clone_enum_tuple): Likewise.
* expand/rust-derive-copy.cc
(DeriveCopy::copy_impl): Likewise.
* resolve/rust-ast-resolve-item.cc
(flatten_list): Likewise.
* resolve/rust-ast-resolve-path.cc
(ResolvePath::resolve_path): Prevent reinsertion of resolutions.
* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Likewise.
* typecheck/rust-hir-type-check-expr.cc
(TypeCheckExpr::resolve_fn_trait_call): Likewise.
* resolve/rust-name-resolver.cc
(Resolver::insert_resolved_name): Catch multiple resolution
insertions.
(Resolver::insert_resolved_type): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/expand/rust-derive-clone.cc  |  43 ++--
 gcc/rust/expand/rust-derive-copy.cc   |  13 +-
 gcc/rust/resolve/rust-ast-resolve-item.cc |  13 +-
 gcc/rust/resolve/rust-ast-resolve-path.cc | 200 +++---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  82 +--
 gcc/rust/resolve/rust-name-resolver.cc|   5 +-
 .../typecheck/rust-hir-type-check-expr.cc |  21 +-
 gcc/testsuite/rust/compile/nr2/exclude|   6 -
 8 files changed, 302 insertions(+), 81 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index d0ffbbdafa7..074ea01b24a 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -91,14 +91,17 @@ DeriveClone::clone_impl (
   std::unique_ptr &&clone_fn, std::string name,
   const std::vector> &type_generics)
 {
-  auto clone = builder.type_path (LangItem::Kind::CLONE);
+  // we should have two of these, so we don't run into issues with
+  // two paths sharing a node id
+  auto clone_bound = builder.type_path (LangItem::Kind::CLONE);
+  auto clone_trait_path = builder.type_path (LangItem::Kind::CLONE);
 
   auto trait_items = vec (std::move (clone_fn));
 
-  auto generics
-= setup_impl_generics (name, type_generics, builder.trait_bound (clone));
+  auto generics = setup_impl_generics (name, type_generics,
+  builder.trait_bound (clone_bound));
 
-  return builder.trait_impl (clone, std::move (generics.self_type),
+  return builder.trait_impl (clone_trait_path, std::move (generics.self_type),
 std::move (trait_items),
 std::move (generics.impl));
 }
@@ -173,9 +176,14 @@ DeriveClone::clone_enum_identifier (PathInExpression 
variant_path,
const std::unique_ptr &variant)
 {
   auto pattern = std::unique_ptr (new ReferencePattern (
-std::unique_ptr (new PathInExpression (variant_path)), false,
-false, loc));
-  auto expr = std::unique_ptr (new PathInExpression (variant_path));
+std::unique_ptr (new PathInExpression (
+  variant_path.get_segments (), {}, variant_path.get_locus (),
+  variant_path.opening_scope_resolution ())),
+false, false, loc));
+  auto expr = std::unique_ptr (
+new PathInExpression (variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ()));
 
   return builder.match_case (std::move (pattern), std::move (expr));
 }
@@ -206,14 +214,19 @@ DeriveClone::clone_enum_tuple (PathInExpression 
variant_path,
   auto pattern_items = std::unique_ptr (
 new TupleStructItemsNoRange (std::move (patterns)));
 
-  auto pattern = std::unique_ptr (
-new ReferencePattern (std::unique_ptr (new TupleStructPattern (
-   variant_path, std::move (pattern_items))),
- false, false, loc));
-
-  auto expr
-= builder.call (std::unique_ptr (new PathInExpression 
(variant_path)),
-   std::move (cloned_patterns));
+  auto pattern = std::unique_ptr (new ReferencePattern (
+std::unique_ptr (new TupleStructPattern (
+  PathInExpression (variant_path.get_segments (), {},
+   variant_path.get_locus (),
+   variant_path.opening_scope_resolution ()),
+  std::move (pattern_items))),
+false, false, loc));
+
+  auto expr = builder.call (std::unique_ptr (new PathInExpression (
+ variant_path.get_segments (), {},
+ variant_path.get_locus (),
+ variant_path.opening_scope_resolution ())),
+   std::move (cloned_patterns));
 
   return builder.match_case (std::move (pattern), std::move (expr));
 }
diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
inde

[COMMITTED 081/141] gccrs: nr2.0: Resolve paths which start with Self

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Be more careful about
applying ForeverStack::find_closest_module.
(ForeverStack::resolve_segments): Allow traversal into parent
nodes when not in a module node or root node, which
ForeverStack::find_starting_point previously made moot through
use of ForeverStack::find_closest_module. Also, when a child
node lookup fails when resolving in the type namespace, attempt
a rib lookup as a fallback.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Avoid throwing a resolution error for type paths
when the typechecker may be able to finish the resolution. Also,
throw an error when a resolution is ambiguous.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.hxx   | 60 ---
 .../resolve/rust-late-name-resolver-2.0.cc| 25 +---
 gcc/testsuite/rust/compile/nr2/exclude| 35 ---
 3 files changed, 56 insertions(+), 64 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index b51da51948f..d2020554f74 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -381,13 +381,6 @@ ForeverStack::find_starting_point (
 {
   auto iterator = segments.begin ();
 
-  // If we need to do path segment resolution, then we start
-  // at the closest module. In order to resolve something like `foo::bar!()`, 
we
-  // need to get back to the surrounding module, and look for a child module
-  // named `foo`.
-  if (segments.size () > 1)
-starting_point = find_closest_module (starting_point);
-
   for (; !is_last (iterator, segments); iterator++)
 {
   auto &outer_seg = *iterator;
@@ -416,12 +409,14 @@ ForeverStack::find_starting_point (
   if (seg.is_lower_self_seg ())
{
  // insert segment resolution and exit
+ starting_point = find_closest_module (starting_point);
  insert_segment_resolution (outer_seg, starting_point.get ().id);
  iterator++;
  break;
}
   if (seg.is_super_path_seg ())
{
+ starting_point = find_closest_module (starting_point);
  if (starting_point.get ().is_root ())
{
  rust_error_at (seg.get_locus (), ErrorCode::E0433,
@@ -469,27 +464,48 @@ ForeverStack::resolve_segments (
 
   tl::optional::Node &> child = tl::nullopt;
 
-  for (auto &kv : current_node->children)
+  while (true)
{
- auto &link = kv.first;
+ for (auto &kv : current_node->children)
+   {
+ auto &link = kv.first;
+
+ if (link.path.map_or (
+   [&str] (Identifier path) {
+ auto &path_str = path.as_string ();
+ return str == path_str;
+   },
+   false))
+   {
+ child = kv.second;
+ break;
+   }
+   }
 
- if (link.path.map_or (
-   [&str] (Identifier path) {
- auto &path_str = path.as_string ();
- return str == path_str;
-   },
-   false))
+ if (child.has_value ())
{
- child = kv.second;
  break;
}
-   }
 
-  if (!child.has_value ())
-   {
- rust_error_at (seg.get_locus (), ErrorCode::E0433,
-"failed to resolve path segment %qs", str.c_str ());
- return tl::nullopt;
+ if (N == Namespace::Types)
+   {
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
+   {
+ insert_segment_resolution (outer_seg,
+rib_lookup->get_node_id ());
+ return tl::nullopt;
+   }
+   }
+
+ if (!is_start (iterator, segments)
+ || current_node->rib.kind == Rib::Kind::Module
+ || current_node->is_root ())
+   {
+ return tl::nullopt;
+   }
+
+ current_node = ¤t_node->parent.value ();
}
 
   current_node = &child.value ();
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index c134ca03336..7253deb42d9 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -294,6 +294,8 @@ Late::visit (AST::TypePath &type)
   // maybe we can overload `resolve_path` to only do
   // typepath-like path resolution? that sounds good
 
+  DefaultResolver::visit (type);
+
   // take care of only simple cases
   // TODO: remove this?
   r

[COMMITTED 027/146] gccrs: typecheck: Remove unused parameter in TyTyCheckCallExpr

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* typecheck/rust-tyty-call.h: Remove unused context member.
---
 gcc/rust/typecheck/rust-tyty-call.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty-call.h 
b/gcc/rust/typecheck/rust-tyty-call.h
index 67cfe30057a..00ac655e5e4 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -73,14 +73,12 @@ private:
   TypeCheckCallExpr (HIR::CallExpr &c, TyTy::VariantDef &variant,
 Resolver::TypeCheckContext *context)
 : resolved (new TyTy::ErrorType (c.get_mappings ().get_hirid ())), call 
(c),
-  variant (variant), context (context),
-  mappings (Analysis::Mappings::get ())
+  variant (variant), mappings (Analysis::Mappings::get ())
   {}
 
   BaseType *resolved;
   HIR::CallExpr &call;
   TyTy::VariantDef &variant;
-  Resolver::TypeCheckContext *context;
   Analysis::Mappings &mappings;
 };
 
-- 
2.45.2



[COMMITTED 022/141] gccrs: hir: Adapt visitors to lang item PathInExpressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Adapt 
visitor to lang item
HIR::PathInExpressions.
* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): 
Likewise.
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 22 +-
 .../typecheck/rust-hir-type-check-path.cc | 78 ---
 2 files changed, 85 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index d248ee282a6..eb897b7ee20 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -35,15 +35,29 @@ namespace Compile {
 void
 ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
 {
-  resolved = resolve (expr.get_final_segment ().get_segment (),
- expr.get_mappings (), expr.get_locus (), true);
+  auto final_segment = HIR::PathIdentSegment::create_error ();
+  if (expr.is_lang_item ())
+final_segment
+  = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
+  else
+final_segment = expr.get_final_segment ().get_segment ();
+
+  resolved
+= resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
 }
 
 void
 ResolvePathRef::visit (HIR::PathInExpression &expr)
 {
-  resolved = resolve (expr.get_final_segment ().get_segment (),
- expr.get_mappings (), expr.get_locus (), false);
+  auto final_segment = HIR::PathIdentSegment::create_error ();
+  if (expr.is_lang_item ())
+final_segment
+  = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
+  else
+final_segment = expr.get_final_segment ().get_segment ();
+
+  resolved
+= resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
 }
 
 tree
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 4c7dec1dea3..68b33d1a05d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -16,6 +16,9 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-type.h"
 #include "rust-hir-type-check-item.h"
@@ -24,6 +27,7 @@
 #include "rust-hir-path-probe.h"
 #include "rust-type-util.h"
 #include "rust-hir-type-bounds.h"
+#include "rust-hir-item.h"
 #include "rust-session-manager.h"
 #include "rust-immutable-name-resolution-context.h"
 
@@ -179,20 +183,72 @@ void
 TypeCheckExpr::visit (HIR::PathInExpression &expr)
 {
   NodeId resolved_node_id = UNKNOWN_NODEID;
-  size_t offset = -1;
-  TyTy::BaseType *tyseg = resolve_root_path (expr, &offset, &resolved_node_id);
-  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
-return;
-
-  bool fully_resolved = offset == expr.get_segments ().size ();
-  if (fully_resolved)
+  if (expr.is_lang_item ())
 {
-  infered = tyseg;
-  return;
+  auto lookup
+   = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+  auto hir_id = mappings.lookup_node_to_hir (lookup);
+
+  // We can type resolve the path in expression easily as it is a lang
+  // item path, but we still need to setup the various generics and
+  // substitutions
+
+  // FIXME: We probably need to check *if* the type needs substitutions
+  // or not
+  if (LangItem::IsEnumVariant (expr.get_lang_item ()))
+   {
+ std::pair enum_item_lookup
+   = mappings.lookup_hir_enumitem (*hir_id);
+ bool enum_item_ok = enum_item_lookup.first != nullptr
+ && enum_item_lookup.second != nullptr;
+ rust_assert (enum_item_ok);
+
+ HirId variant_id
+   = enum_item_lookup.second->get_mappings ().get_hirid ();
+
+ HIR::EnumItem *enum_item = enum_item_lookup.second;
+ resolved_node_id = enum_item->get_mappings ().get_nodeid ();
+
+ // insert the id of the variant we are resolved to
+ context->insert_variant_definition (expr.get_mappings ().get_hirid (),
+ variant_id);
+
+ query_type (variant_id, &infered);
+ infered = SubstMapper::InferSubst (infered, expr.get_locus ());
+   }
+  else
+   {
+ TyTy::BaseType *resolved = nullptr;
+ context->lookup_type (*hir_id, &resolved);
+
+ rust_assert (resolved);
+
+ query_type (*hir_id, &infered);
+
+ infered = SubstMapper::InferSubst (resolved, expr.get_locus ());
+   }
+
+  // FIXME: also we probably need to insert resolved types in the name
+  // resolver here
 }
+  else
+{
+  size_t offset = -1;
+  TyTy::BaseType *tyseg
+   = resolve_root_path (expr, &offset, &resolved_node_id);
+  if (tys

[COMMITTED 023/141] gccrs: marklive: Fix handling for lang item PathInExpressions.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* checks/lints/rust-lint-marklive.cc (MarkLive::visit): Adapt to lang 
items.
---
 gcc/rust/checks/lints/rust-lint-marklive.cc | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 4b524d710c9..6e2e2e4e447 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -22,6 +22,8 @@
 #include "rust-lint-marklive.h"
 #include "options.h"
 #include "rust-hir-full.h"
+#include "rust-hir-map.h"
+#include "rust-hir-path.h"
 #include "rust-name-resolver.h"
 #include "rust-immutable-name-resolution-context.h"
 #include "rust-system.h"
@@ -99,15 +101,21 @@ MarkLive::visit (HIR::PathInExpression &expr)
 {
   // We should iterate every path segment in order to mark the struct which
   // is used in expression like Foo::bar(), we should mark the Foo alive.
-  expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
-return visit_path_segment (seg);
-  });
+  if (!expr.is_lang_item ())
+expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
+  return visit_path_segment (seg);
+});
 
   // after iterate the path segments, we should mark functions and associated
   // functions alive.
   NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
   NodeId ref_node_id = UNKNOWN_NODEID;
-  find_ref_node_id (ast_node_id, ref_node_id);
+
+  if (expr.is_lang_item ())
+ref_node_id
+  = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+  else
+find_ref_node_id (ast_node_id, ref_node_id);
 
   // node back to HIR
   tl::optional hid = mappings.lookup_node_to_hir (ref_node_id);
-- 
2.45.2



[COMMITTED 025/141] gccrs: backend: Improve handling of lang-item PathInExpressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Call 
into
resolve_path_like instead.
(ResolvePathRef::resolve_path_like): New.
(ResolvePathRef::resolve): Call into resolve_with_node_id.
* backend/rust-compile-resolve-path.h: Declare new functions and 
document them.
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 116 ++
 gcc/rust/backend/rust-compile-resolve-path.h  |  16 +++
 2 files changed, 84 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index eb897b7ee20..6ede1bea22f 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -32,32 +32,37 @@
 namespace Rust {
 namespace Compile {
 
-void
-ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
+template 
+tree
+ResolvePathRef::resolve_path_like (T &expr)
 {
-  auto final_segment = HIR::PathIdentSegment::create_error ();
   if (expr.is_lang_item ())
-final_segment
-  = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
-  else
-final_segment = expr.get_final_segment ().get_segment ();
+{
+  auto lang_item
+   = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
+
+  // FIXME: Is that correct? :/
+  auto final_segment
+   = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
 
-  resolved
-= resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
+  return resolve_with_node_id (final_segment, expr.get_mappings (),
+  expr.get_locus (), true, lang_item);
+}
+
+  return resolve (expr.get_final_segment ().get_segment (),
+ expr.get_mappings (), expr.get_locus (), true);
 }
 
 void
-ResolvePathRef::visit (HIR::PathInExpression &expr)
+ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
 {
-  auto final_segment = HIR::PathIdentSegment::create_error ();
-  if (expr.is_lang_item ())
-final_segment
-  = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ()));
-  else
-final_segment = expr.get_final_segment ().get_segment ();
+  resolved = resolve_path_like (expr);
+}
 
-  resolved
-= resolve (final_segment, expr.get_mappings (), expr.get_locus (), true);
+void
+ResolvePathRef::visit (HIR::PathInExpression &expr)
+{
+  resolved = resolve_path_like (expr);
 }
 
 tree
@@ -106,42 +111,17 @@ ResolvePathRef::attempt_constructor_expression_lookup (
 }
 
 tree
-ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
-const Analysis::NodeMapping &mappings,
-location_t expr_locus, bool is_qualified_path)
+ResolvePathRef::resolve_with_node_id (
+  const HIR::PathIdentSegment &final_segment,
+  const Analysis::NodeMapping &mappings, location_t expr_locus,
+  bool is_qualified_path, NodeId resolved_node_id)
 {
   TyTy::BaseType *lookup = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup);
   rust_assert (ok);
 
-  // need to look up the reference for this identifier
-
-  // this can fail because it might be a Constructor for something
-  // in that case the caller should attempt ResolvePathType::Compile
-  NodeId ref_node_id = UNKNOWN_NODEID;
-  if (flag_name_resolution_2_0)
-{
-  auto nr_ctx
-   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
-
-  auto resolved = nr_ctx.lookup (mappings.get_nodeid ());
-
-  if (!resolved)
-   return attempt_constructor_expression_lookup (lookup, ctx, mappings,
- expr_locus);
-
-  ref_node_id = *resolved;
-}
-  else
-{
-  if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
-  &ref_node_id))
-   return attempt_constructor_expression_lookup (lookup, ctx, mappings,
- expr_locus);
-}
-
   tl::optional hid
-= ctx->get_mappings ().lookup_node_to_hir (ref_node_id);
+= ctx->get_mappings ().lookup_node_to_hir (resolved_node_id);
   if (!hid.has_value ())
 {
   rust_error_at (expr_locus, "reverse call path lookup failure");
@@ -207,9 +187,49 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment 
&final_segment,
 {
   TREE_USED (resolved_item) = 1;
 }
+
   return resolved_item;
 }
 
+tree
+ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
+const Analysis::NodeMapping &mappings,
+location_t expr_locus, bool is_qualified_path)
+{
+  TyTy::BaseType *lookup = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup);
+  rust_assert (ok);
+
+  // need to look up the reference for this identifier
+
+  // this can fail because it might 

[COMMITTED 067/141] gccrs: session manager: Call into DesugarForLoops

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Call the visitor.
---
 gcc/rust/rust-session-manager.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 3adde297a4e..fabb3d426cd 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -18,6 +18,7 @@
 
 #include "rust-session-manager.h"
 #include "rust-collect-lang-items.h"
+#include "rust-desugar-for-loops.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-pattern-analysis.h"
 #include "rust-immutable-name-resolution-context.h"
@@ -614,6 +615,9 @@ Session::compile_crate (const char *filename)
   // expansion pipeline stage
 
   expansion (parsed_crate, name_resolution_ctx);
+
+  AST::DesugarForLoops ().go (parsed_crate);
+
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
   if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
 {
-- 
2.45.2



[COMMITTED 065/141] gccrs: ast: builder: Fix arguments of Builder::let

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Mark all arguments as &&.
* ast/rust-ast-builder.cc (Builder::let): Likewise.
---
 gcc/rust/ast/rust-ast-builder.cc | 4 ++--
 gcc/rust/ast/rust-ast-builder.h  | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 4c42b5bddae..369f5a44630 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -306,8 +306,8 @@ Builder::return_expr (std::unique_ptr &&to_return)
 }
 
 std::unique_ptr
-Builder::let (std::unique_ptr pattern, std::unique_ptr type,
- std::unique_ptr init) const
+Builder::let (std::unique_ptr &&pattern, std::unique_ptr &&type,
+ std::unique_ptr &&init) const
 {
   return std::unique_ptr (new LetStmt (std::move (pattern),
 std::move (init), std::move (type),
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 21da13f14c8..99ab1610ce7 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -95,9 +95,9 @@ public:
 
   /* Create a let binding with an optional type and initializer (`let  :
*  = `) */
-  std::unique_ptr let (std::unique_ptr pattern,
-std::unique_ptr type = nullptr,
-std::unique_ptr init = nullptr) const;
+  std::unique_ptr let (std::unique_ptr &&pattern,
+std::unique_ptr &&type = nullptr,
+std::unique_ptr &&init = nullptr) const;
 
   /**
* Create a call expression to a function, struct or enum variant, given its
-- 
2.45.2



[COMMITTED 086/141] gccrs: derive(Eq): Add implementation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveEq.
* expand/rust-derive-eq.cc: New file.
* expand/rust-derive-eq.h: New file.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/derive-eq-invalid.rs: New test.
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/expand/rust-derive-eq.cc | 207 ++
 gcc/rust/expand/rust-derive-eq.h  |  82 +++
 gcc/rust/expand/rust-derive.cc|   2 +
 .../rust/compile/derive-eq-invalid.rs |  45 
 5 files changed, 337 insertions(+)
 create mode 100644 gcc/rust/expand/rust-derive-eq.cc
 create mode 100644 gcc/rust/expand/rust-derive-eq.h
 create mode 100644 gcc/testsuite/rust/compile/derive-eq-invalid.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 5ddad257805..83ffc47ce28 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -98,6 +98,7 @@ GRS_OBJS = \
 rust/rust-derive-copy.o \
 rust/rust-derive-debug.o \
 rust/rust-derive-default.o \
+rust/rust-derive-eq.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
 rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-eq.cc 
b/gcc/rust/expand/rust-derive-eq.cc
new file mode 100644
index 000..a2a7a769065
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-eq.cc
@@ -0,0 +1,207 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+std::unique_ptr
+DeriveEq::assert_receiver_is_total_eq_fn (
+  std::vector> &&types)
+{
+  auto stmts = std::vector> ();
+
+  stmts.emplace_back (assert_param_is_eq ());
+
+  for (auto &&type : types)
+stmts.emplace_back (assert_type_is_eq (std::move (type)));
+
+  auto block = std::unique_ptr (
+new BlockExpr (std::move (stmts), nullptr, {}, {}, AST::LoopLabel::error 
(),
+  loc, loc));
+
+  auto self = builder.self_ref_param ();
+
+  return builder.function ("assert_receiver_is_total_eq",
+  vec (std::move (self)), {}, std::move (block));
+}
+
+std::unique_ptr
+DeriveEq::assert_param_is_eq ()
+{
+  auto eq_bound = std::unique_ptr (
+new TraitBound (builder.type_path ({"core", "cmp", "Eq"}, true), loc));
+
+  auto sized_bound = std::unique_ptr (
+new TraitBound (builder.type_path (LangItem::Kind::SIZED), loc, false,
+   true /* opening_question_mark */));
+
+  auto bounds = vec (std::move (eq_bound), std::move (sized_bound));
+
+  auto assert_param_is_eq = "AssertParamIsEq";
+
+  auto t = std::unique_ptr (
+new TypeParam (Identifier ("T"), loc, std::move (bounds)));
+
+  return builder.struct_struct (
+assert_param_is_eq, vec (std::move (t)),
+{StructField (
+  Identifier ("_t"),
+  builder.single_generic_type_path (
+   LangItem::Kind::PHANTOM_DATA,
+   GenericArgs (
+ {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
+  Visibility::create_private (), loc)});
+}
+
+std::unique_ptr
+DeriveEq::assert_type_is_eq (std::unique_ptr &&type)
+{
+  auto assert_param_is_eq = "AssertParamIsEq";
+
+  // AssertParamIsCopy::
+  auto assert_param_is_eq_ty
+= std::unique_ptr (new TypePathSegmentGeneric (
+  PathIdentSegment (assert_param_is_eq, loc), false,
+  GenericArgs ({}, {GenericArg::create_type (std::move (type))}, {}, loc),
+  loc));
+
+  // TODO: Improve this, it's really ugly
+  auto type_paths = std::vector> ();
+  type_paths.emplace_back (std::move (assert_param_is_eq_ty));
+
+  auto full_path
+= std::unique_ptr (new TypePath ({std::move (type_paths)}, loc));
+
+  return builder.let (builder.wildcard (), std::move (full_path));
+}
+
+std::unique_ptr
+DeriveEq::eq_impl (
+  std::unique_ptr &&fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto eq = builder.type_path ({"core", "cmp", "Eq"}, true);
+
+  auto trait_items = vec (std::move (fn));
+
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+
+  return builder.trait_impl (eq, 

[COMMITTED 141/141] gccrs: support generic super traits recursively

2025-03-24 Thread arthur . cohen
From: Philip Herron 

In order to handle generic super traits on any trait bound we need to ensure
we track the TypeBoundPredicate as part of the TraitReference instead of just
the raw TraitReferences because these will have any applied generics enplace.

Then for any TypeBoundPredicate it takes a copy of the super traits because
this is the usage of a TraitBound and we can apply generics which then need
to be recursively applied up the chain of super predicates.

The main tweak is around TypeBoundPredicate::lookup_associated_item because
we need to associate the predicate with the item we are looking up so the caller
can respect the generics correctly as well.

Fixes Rust-GCC#3502

gcc/rust/ChangeLog:

* typecheck/rust-hir-path-probe.cc: update call
* typecheck/rust-hir-trait-reference.cc 
(TraitReference::lookup_trait_item): track predicate
(TraitReference::is_equal): likewise
(TraitReference::is_object_safe): likewise
(TraitReference::satisfies_bound): likewise
* typecheck/rust-hir-trait-reference.h: likewise
* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): 
likewise
* typecheck/rust-tyty-bounds.cc 
(TypeBoundPredicate::TypeBoundPredicate): track super traits
(TypeBoundPredicate::operator=): likewise
(TypeBoundPredicate::apply_generic_arguments): ensure we apply to super 
predicates
(TypeBoundPredicateItem::operator=): take copy of parent predicate
(TypeBoundPredicateItem::error): pass error instead of nullptr
(TypeBoundPredicateItem::is_error): update to no longer check for 
nullptr
(TypeBoundPredicateItem::get_parent): updated
(TypeBoundPredicateItem::get_tyty_for_receiver): likewise
(TypeBoundPredicate::get_associated_type_items): likewise
* typecheck/rust-tyty-bounds.h (class TypeBoundPredicateItem): move
* typecheck/rust-tyty-subst.cc: flag to handle placeholder Self on 
traits
* typecheck/rust-tyty-subst.h (class TypeBoundPredicateItem): likewise
* typecheck/rust-tyty.h (class TypeBoundPredicateItem): refactored

gcc/testsuite/ChangeLog:

* rust/execute/torture/issue-3502.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-path-probe.cc |  2 +-
 .../typecheck/rust-hir-trait-reference.cc | 24 ---
 gcc/rust/typecheck/rust-hir-trait-reference.h |  9 +--
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  7 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc| 67 +++
 gcc/rust/typecheck/rust-tyty-bounds.h | 25 ---
 gcc/rust/typecheck/rust-tyty-subst.cc |  4 +-
 gcc/rust/typecheck/rust-tyty-subst.h  |  4 +-
 gcc/rust/typecheck/rust-tyty.h| 32 +
 .../rust/execute/torture/issue-3502.rs| 52 ++
 10 files changed, 166 insertions(+), 60 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/issue-3502.rs

diff --git a/gcc/rust/typecheck/rust-hir-path-probe.cc 
b/gcc/rust/typecheck/rust-hir-path-probe.cc
index 0465d2f5786..32e23997cb7 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.cc
+++ b/gcc/rust/typecheck/rust-hir-path-probe.cc
@@ -346,7 +346,7 @@ PathProbeType::process_associated_trait_for_candidates (
 
   const TyTy::TypeBoundPredicate p (*trait_ref, BoundPolarity::RegularBound,
UNDEF_LOCATION);
-  TyTy::TypeBoundPredicateItem item (&p, trait_item_ref);
+  TyTy::TypeBoundPredicateItem item (p, trait_item_ref);
 
   TyTy::BaseType *trait_item_tyty = item.get_raw_item ()->get_tyty ();
   if (receiver->get_kind () != TyTy::DYNAMIC)
diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.cc 
b/gcc/rust/typecheck/rust-hir-trait-reference.cc
index 2ac086cf931..83985f00989 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.cc
@@ -106,7 +106,7 @@ TraitItemReference::get_error () const
 
 TraitReference::TraitReference (
   const HIR::Trait *hir_trait_ref, std::vector item_refs,
-  std::vector super_traits,
+  std::vector super_traits,
   std::vector substs)
   : hir_trait_ref (hir_trait_ref), item_refs (item_refs),
 super_traits (super_traits)
@@ -263,7 +263,8 @@ TraitReference::lookup_hir_trait_item (const HIR::TraitItem 
&item,
 
 bool
 TraitReference::lookup_trait_item (const std::string &ident,
-  const TraitItemReference **ref) const
+  const TraitItemReference **ref,
+  bool lookup_supers) const
 {
   for (auto &item : item_refs)
 {
@@ -274,10 +275,13 @@ TraitReference::lookup_trait_item (const std::string 
&ident,
}
 }
 
+  if (!lookup_supers)
+return false;
+
   // lookup super traits
   for (const auto &super_trait : super_traits)
 {
-  bool found = super_trait->lookup_trait_item (ident, ref);
+  bool found = super_trait.get ()->lookup_trait_item (ident, r

[COMMITTED 084/141] gccrs: nr2.0: Fix issue with external crates

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): When visiting an external crate declaration,
handle failed crate name lookups. This can happen when
Session::load_extern_crate fails to load a crate during the
CfgStrip phase.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 11 ++-
 gcc/testsuite/rust/compile/nr2/exclude  |  3 ---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 305286970c7..572d5956c0a 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -163,7 +163,16 @@ void
 TopLevel::visit (AST::ExternCrate &crate)
 {
   auto &mappings = Analysis::Mappings::get ();
-  CrateNum num = *mappings.lookup_crate_name (crate.get_referenced_crate ());
+  auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
+
+  if (!num_opt)
+{
+  rust_error_at (crate.get_locus (), "unknown crate %qs",
+crate.get_referenced_crate ().c_str ());
+  return;
+}
+
+  CrateNum num = *num_opt;
 
   auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
 
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index a400378f071..2186a1106d9 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -46,9 +46,6 @@ not_find_value_in_scope.rs
 privacy4.rs
 privacy5.rs
 privacy8.rs
-macros/proc/attribute_non_function.rs
-macros/proc/derive_non_function.rs
-macros/proc/non_function.rs
 pub_restricted_1.rs
 pub_restricted_2.rs
 pub_restricted_3.rs
-- 
2.45.2



[COMMITTED 090/141] gccrs: derive(PartialEq): Add partial implementation

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

We are still missing some deriving for enums, as part of our codegen and 
nameres for rebinding struct
field patterns is missing.

gcc/rust/ChangeLog:

* expand/rust-derive-partial-eq.cc: New file.
* expand/rust-derive-partial-eq.h: New file.
* expand/rust-derive.cc (DeriveVisitor::derive): Call them.
* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

* rust/compile/derive-eq-invalid.rs: Mark PartialEq def as a lang item.
* rust/compile/derive-partialeq1.rs: New test.
* rust/execute/torture/derive-partialeq1.rs: New test.
* rust/compile/nr2/exclude: Exclude all of them.
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/expand/rust-derive-partial-eq.cc | 308 ++
 gcc/rust/expand/rust-derive-partial-eq.h  |  81 +
 gcc/rust/expand/rust-derive.cc|   2 +
 .../rust/compile/derive-eq-invalid.rs |   9 +-
 .../rust/compile/derive-partialeq1.rs |  59 
 gcc/testsuite/rust/compile/nr2/exclude|   2 +
 .../rust/execute/torture/derive-partialeq1.rs |  61 
 8 files changed, 519 insertions(+), 4 deletions(-)
 create mode 100644 gcc/rust/expand/rust-derive-partial-eq.cc
 create mode 100644 gcc/rust/expand/rust-derive-partial-eq.h
 create mode 100644 gcc/testsuite/rust/compile/derive-partialeq1.rs
 create mode 100644 gcc/testsuite/rust/execute/torture/derive-partialeq1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 83ffc47ce28..5e13c6cfc3f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -98,6 +98,7 @@ GRS_OBJS = \
 rust/rust-derive-copy.o \
 rust/rust-derive-debug.o \
 rust/rust-derive-default.o \
+rust/rust-derive-partial-eq.o \
 rust/rust-derive-eq.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc 
b/gcc/rust/expand/rust-derive-partial-eq.cc
new file mode 100644
index 000..6f7ef7d8780
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -0,0 +1,308 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-partial-eq.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-operators.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+DerivePartialEq::DerivePartialEq (location_t loc)
+  : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr
+DerivePartialEq::go (Item &item)
+{
+  item.accept_vis (*this);
+
+  rust_assert (expanded);
+
+  return std::move (expanded);
+}
+
+std::unique_ptr
+DerivePartialEq::partial_eq_impl (
+  std::unique_ptr &&eq_fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto eq = builder.type_path (LangItem::Kind::EQ);
+
+  auto trait_items = vec (std::move (eq_fn));
+
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+
+  return builder.trait_impl (eq, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
+}
+
+std::unique_ptr
+DerivePartialEq::eq_fn (std::unique_ptr &&cmp_expression,
+   std::string type_name)
+{
+  auto block = builder.block (tl::nullopt, std::move (cmp_expression));
+
+  auto self_type
+= std::unique_ptr (new TypePath (builder.type_path 
("Self")));
+
+  auto params
+= vec (builder.self_ref_param (),
+  builder.function_param (builder.identifier_pattern ("other"),
+  builder.reference_type (
+std::move (self_type;
+
+  return builder.function ("eq", std::move (params),
+  builder.single_type_path ("bool"),
+  std::move (block));
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::tuple_indexes (int idx)
+{
+  return SelfOther{
+builder.tuple_idx ("self", idx),
+builder.tuple_idx ("other", idx),
+  };
+}
+
+DerivePartialEq::SelfOther
+DerivePartialEq::field_acccesses (const std::string &field_name)
+{
+  return SelfOther{
+builder.field_access (builder.identifier ("self"), field_name),
+builder.field_access (builder.identifier ("other"), 

[COMMITTED 089/141] gccrs: derive(Clone): chore: Cleanup

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc: Cleanup implementation, avoid 
repetitions.
* expand/rust-derive-clone.h: Likewise.
---
 gcc/rust/expand/rust-derive-clone.cc | 34 ++--
 gcc/rust/expand/rust-derive-clone.h  |  8 ---
 2 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index b1b39668f51..d0ffbbdafa7 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -18,7 +18,6 @@
 
 #include "rust-derive-clone.h"
 #include "rust-ast.h"
-#include "rust-ast-dump.h"
 #include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-path.h"
@@ -169,21 +168,10 @@ DeriveClone::visit_struct (StructStruct &item)
 item.get_generic_params ());
 }
 
-PathInExpression
-DeriveClone::variant_match_path (Enum &item, const Identifier &variant)
-{
-  return PathInExpression ({builder.path_segment (
- item.get_identifier ().as_string ()),
-   builder.path_segment (variant.as_string ())},
-  {}, loc, false);
-}
-
 MatchCase
-DeriveClone::clone_enum_identifier (Enum &item,
+DeriveClone::clone_enum_identifier (PathInExpression variant_path,
const std::unique_ptr &variant)
 {
-  auto variant_path = variant_match_path (item, variant->get_identifier ());
-
   auto pattern = std::unique_ptr (new ReferencePattern (
 std::unique_ptr (new PathInExpression (variant_path)), false,
 false, loc));
@@ -193,10 +181,9 @@ DeriveClone::clone_enum_identifier (Enum &item,
 }
 
 MatchCase
-DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant)
+DeriveClone::clone_enum_tuple (PathInExpression variant_path,
+  const EnumItemTuple &variant)
 {
-  auto variant_path = variant_match_path (item, variant.get_identifier ());
-
   auto patterns = std::vector> ();
   auto cloned_patterns = std::vector> ();
 
@@ -232,10 +219,9 @@ DeriveClone::clone_enum_tuple (Enum &item, const 
EnumItemTuple &variant)
 }
 
 MatchCase
-DeriveClone::clone_enum_struct (Enum &item, const EnumItemStruct &variant)
+DeriveClone::clone_enum_struct (PathInExpression variant_path,
+   const EnumItemStruct &variant)
 {
-  auto variant_path = variant_match_path (item, variant.get_identifier ());
-
   auto field_patterns = std::vector> ();
   auto cloned_fields = std::vector> ();
 
@@ -314,21 +300,25 @@ DeriveClone::visit_enum (Enum &item)
 
   for (const auto &variant : item.get_variants ())
 {
+  auto path
+   = builder.variant_path (item.get_identifier ().as_string (),
+   variant->get_identifier ().as_string ());
+
   switch (variant->get_enum_item_kind ())
{
// Identifiers and discriminated variants are the same for a clone - we
// just return the same variant
case EnumItem::Kind::Identifier:
case EnumItem::Kind::Discriminant:
- cases.emplace_back (clone_enum_identifier (item, variant));
+ cases.emplace_back (clone_enum_identifier (path, variant));
  break;
case EnumItem::Kind::Tuple:
  cases.emplace_back (
-   clone_enum_tuple (item, static_cast (*variant)));
+   clone_enum_tuple (path, static_cast (*variant)));
  break;
case EnumItem::Kind::Struct:
  cases.emplace_back (
-   clone_enum_struct (item, static_cast (*variant)));
+   clone_enum_struct (path, static_cast (*variant)));
  break;
}
 }
diff --git a/gcc/rust/expand/rust-derive-clone.h 
b/gcc/rust/expand/rust-derive-clone.h
index d48ec5d2889..61224ba527b 100644
--- a/gcc/rust/expand/rust-derive-clone.h
+++ b/gcc/rust/expand/rust-derive-clone.h
@@ -73,10 +73,12 @@ private:
   /**
* Implementation of clone for all possible variants of an enum
*/
-  MatchCase clone_enum_identifier (Enum &item,
+  MatchCase clone_enum_identifier (PathInExpression variant_path,
   const std::unique_ptr &variant);
-  MatchCase clone_enum_tuple (Enum &item, const EnumItemTuple &variant);
-  MatchCase clone_enum_struct (Enum &item, const EnumItemStruct &variant);
+  MatchCase clone_enum_tuple (PathInExpression variant_path,
+ const EnumItemTuple &variant);
+  MatchCase clone_enum_struct (PathInExpression variant_path,
+  const EnumItemStruct &variant);
 
   virtual void visit_struct (StructStruct &item);
   virtual void visit_tuple (TupleStruct &item);
-- 
2.45.2



[COMMITTED 130/141] gccrs: Fix canonical path parent resolution

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

The algorithm was comparing using the wrong id, this lead to some
mangling errors as an erroneous parent was selected.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Fix the id comparison.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 59142a4094c..90e0ceb9f81 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -686,7 +686,7 @@ ForeverStack::to_canonical_path (NodeId id) const
  auto &link = kv.first;
  auto &child = kv.second;
 
- if (link.id == child.id)
+ if (current.id == child.id)
{
  outer_link = &link;
  break;
-- 
2.45.2



[COMMITTED 085/141] gccrs: nr2.0: Run DefaultResolver::visit on PathInExpression

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): When visiting a PathInExpression instance, call
into DefaultResolver::visit, ensuring generic arguments are
visited.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  2 ++
 gcc/testsuite/rust/compile/nr2/exclude  | 11 ---
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 7253deb42d9..8dd1088d65d 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -284,6 +284,8 @@ Late::visit (AST::PathInExpression &expr)
 
   ctx.map_usage (Usage (expr.get_node_id ()),
 Definition (resolved->get_node_id ()));
+
+  DefaultResolver::visit (expr);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 2186a1106d9..6eff293f0aa 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -2,20 +2,14 @@ break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
 complex-path1.rs
-const-issue1440.rs
 const_generics_3.rs
 const_generics_4.rs
 const_generics_7.rs
 derive_macro1.rs
-expected_type_args2.rs
 feature_rust_attri0.rs
 generic-default1.rs
-generics3.rs
-generics4.rs
 generics5.rs
 generics9.rs
-issue-1130.rs
-issue-1173.rs
 issue-1483.rs
 issue-1786.rs
 issue-1901.rs
@@ -24,14 +18,12 @@ issue-2043.rs
 issue-2330.rs
 issue-2723-1.rs
 issue-2723-2.rs
-issue-2775.rs
 issue-2782.rs
 issue-2812.rs
 issue-850.rs
 issue-855.rs
 iterators1.rs
 lookup_err1.rs
-macros/mbe/macro40.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
 macros/mbe/macro6.rs
@@ -43,7 +35,6 @@ nested_macro_use1.rs
 nested_macro_use2.rs
 nested_macro_use3.rs
 not_find_value_in_scope.rs
-privacy4.rs
 privacy5.rs
 privacy8.rs
 pub_restricted_1.rs
@@ -56,8 +47,6 @@ self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
 traits3.rs
-traits6.rs
-traits7.rs
 undeclared_label.rs
 use_1.rs
 v0-mangle1.rs
-- 
2.45.2



[COMMITTED 087/141] gccrs: ast-builder: Improve function generation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::block): Change return type.
(Builder::loop): Use new APIs.
* ast/rust-ast-builder.h: Change return type of block functions.
---
 gcc/rust/ast/rust-ast-builder.cc | 22 +++---
 gcc/rust/ast/rust-ast-builder.h  | 12 ++--
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 369f5a44630..f59ff19d621 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -279,23 +279,25 @@ Builder::path_in_expression (LangItem::Kind lang_item) 
const
   return PathInExpression (lang_item, {}, loc);
 }
 
-std::unique_ptr
-Builder::block (std::unique_ptr &&stmt,
+std::unique_ptr
+Builder::block (tl::optional> &&stmt,
std::unique_ptr &&tail_expr) const
 {
   auto stmts = std::vector> ();
-  stmts.emplace_back (std::move (stmt));
+
+  if (stmt)
+stmts.emplace_back (std::move (*stmt));
 
   return block (std::move (stmts), std::move (tail_expr));
 }
 
-std::unique_ptr
+std::unique_ptr
 Builder::block (std::vector> &&stmts,
std::unique_ptr &&tail_expr) const
 {
-  return std::unique_ptr (new BlockExpr (std::move (stmts),
-  std::move (tail_expr), {}, {},
-  LoopLabel::error (), loc, loc));
+  return std::unique_ptr (
+new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {},
+  LoopLabel::error (), loc, loc));
 }
 
 std::unique_ptr
@@ -421,11 +423,9 @@ Builder::match_case (std::unique_ptr &&pattern,
 std::unique_ptr
 Builder::loop (std::vector> &&stmts)
 {
-  auto block = std::unique_ptr (
-new BlockExpr (std::move (stmts), nullptr, {}, {}, LoopLabel::error (), 
loc,
-  loc));
+  auto block_expr = block (std::move (stmts), nullptr);
 
-  return std::unique_ptr (new LoopExpr (std::move (block), loc));
+  return std::unique_ptr (new LoopExpr (std::move (block_expr), loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 99ab1610ce7..9fbcea182be 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -82,12 +82,12 @@ public:
   std::unique_ptr deref (std::unique_ptr &&of) const;
 
   /* Create a block with an optional tail expression */
-  std::unique_ptr block (std::vector> &&stmts,
-  std::unique_ptr &&tail_expr
-  = nullptr) const;
-  std::unique_ptr block (std::unique_ptr &&stmt,
-  std::unique_ptr &&tail_expr
-  = nullptr) const;
+  std::unique_ptr block (std::vector> &&stmts,
+   std::unique_ptr &&tail_expr
+   = nullptr) const;
+  std::unique_ptr block (tl::optional> &&stmt,
+   std::unique_ptr &&tail_expr
+   = nullptr) const;
 
   /* Create an early return expression with an optional expression */
   std::unique_ptr return_expr (std::unique_ptr &&to_return
-- 
2.45.2



[COMMITTED 098/141] gccrs: ast: builder: Add new builder methods

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::statementify): New.
(Builder::function): Add generic params optional argument.
(Builder::path_in_expression): Add opening_scope_resolution optional 
argument.
(Builder::block): Add function for creating empty blocks.
(Builder::generic_type_param):  New.
* ast/rust-ast-builder.h (ptrify): New.
---
 gcc/rust/ast/rust-ast-builder.cc | 39 
 gcc/rust/ast/rust-ast-builder.h  | 24 ++--
 2 files changed, 56 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 82e6a5abe24..86290e199c6 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -33,6 +33,14 @@
 namespace Rust {
 namespace AST {
 
+std::unique_ptr
+Builder::statementify (std::unique_ptr &&value,
+  bool semicolon_followed) const
+{
+  return std::make_unique (std::move (value), loc,
+semicolon_followed);
+}
+
 std::unique_ptr
 Builder::literal_string (std::string &&content) const
 {
@@ -150,13 +158,14 @@ Builder::function (std::string function_name,
   std::vector> params,
   std::unique_ptr return_type,
   std::unique_ptr block,
+  std::vector> generic_params,
   FunctionQualifiers qualifiers, WhereClause where_clause,
   Visibility visibility) const
 {
   return std::unique_ptr (
-new Function (function_name, qualifiers, {}, std::move (params),
- std::move (return_type), where_clause, std::move (block),
- visibility, {}, loc));
+new Function (function_name, qualifiers, std::move (generic_params),
+ std::move (params), std::move (return_type), where_clause,
+ std::move (block), visibility, {}, loc));
 }
 
 PathExprSegment
@@ -277,13 +286,14 @@ Builder::reference_type (std::unique_ptr 
&&inner_type,
 }
 
 PathInExpression
-Builder::path_in_expression (std::vector &&segments) const
+Builder::path_in_expression (std::vector &&segments,
+bool opening_scope) const
 {
   auto path_segments = std::vector ();
   for (auto &seg : segments)
 path_segments.emplace_back (path_segment (seg));
 
-  return PathInExpression (std::move (path_segments), {}, loc);
+  return PathInExpression (std::move (path_segments), {}, loc, opening_scope);
 }
 
 PathInExpression
@@ -312,6 +322,14 @@ Builder::block (tl::optional> &&stmt,
   return block (std::move (stmts), std::move (tail_expr));
 }
 
+std::unique_ptr
+Builder::block () const
+{
+  auto stmts = std::vector> ();
+
+  return block (std::move (stmts));
+}
+
 std::unique_ptr
 Builder::block (std::vector> &&stmts,
std::unique_ptr &&tail_expr) const
@@ -493,6 +511,17 @@ Builder::trait_impl (TypePath trait_path, 
std::unique_ptr target,
   visibility, {}, {}, loc));
 }
 
+std::unique_ptr
+Builder::generic_type_param (
+  std::string type_representation,
+  std::vector> &&bounds,
+  std::unique_ptr &&type)
+{
+  return std::make_unique (type_representation, loc,
+ std::move (bounds), std::move (type),
+ std::vector ());
+}
+
 std::unique_ptr
 Builder::new_type (Type &type)
 {
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index faf3cf74df9..41ce118e771 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -51,6 +51,14 @@ vec (std::unique_ptr &&t1, std::unique_ptr &&t2)
   return v;
 }
 
+/* Pointer-ify something */
+template 
+static std::unique_ptr
+ptrify (T value)
+{
+  return std::unique_ptr (new T (value));
+}
+
 // TODO: Use this builder when expanding regular macros
 /* Builder class with helper methods to create AST nodes. This builder is
  * tailored towards generating multiple AST nodes from a single location, and
@@ -60,6 +68,10 @@ class Builder
 public:
   Builder (location_t loc) : loc (loc) {}
 
+  /* Create an expression statement from an expression */
+  std::unique_ptr statementify (std::unique_ptr &&value,
+ bool semicolon_followed = true) const;
+
   /* Create a string literal expression ("content") */
   std::unique_ptr literal_string (std::string &&content) const;
 
@@ -102,6 +114,8 @@ public:
   std::unique_ptr block (tl::optional> &&stmt,
std::unique_ptr &&tail_expr
= nullptr) const;
+  /* Create an empty block */
+  std::unique_ptr block () const;
 
   /* Create an early return expression with an optional expression */
   std::unique_ptr return_expr (std::unique_ptr &&to_return
@@ -151,6 +165,7 @@ public:
   function (std::string function_name,
std::vector> params,
std::unique_ptr return_type,

[COMMITTED 030/141] gccrs: Remove some tests from nr2 exclusion file

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Those test are now passing.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove passing tests.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/nr2/exclude | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 8bcc8aed030..641222a8d7f 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -2,17 +2,12 @@ bounds1.rs
 break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
-cfg3.rs
-cfg4.rs
-cfg5.rs
 closure_no_type_anno.rs
 complex-path1.rs
 const-issue1440.rs
 const_generics_3.rs
 const_generics_4.rs
-const_generics_5.rs
 const_generics_7.rs
-derive_empty.rs
 derive_macro1.rs
 expected_type_args2.rs
 feature_rust_attri0.rs
@@ -40,7 +35,6 @@ issue-1901.rs
 issue-1981.rs
 issue-2036.rs
 issue-2043.rs
-issue-2136-2.rs
 issue-2142.rs
 issue-2238.rs
 issue-2330.rs
@@ -56,16 +50,12 @@ issue-852.rs
 issue-855.rs
 iterators1.rs
 lookup_err1.rs
-macros/mbe/macro13.rs
-macros/mbe/macro15.rs
-macros/mbe/macro20.rs
 macros/mbe/macro23.rs
 macros/mbe/macro40.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
 macros/mbe/macro54.rs
 macros/mbe/macro6.rs
-macros/mbe/macro_rules_macro_rules.rs
 macros/mbe/macro_use1.rs
 match-never-ltype.rs
 match-never-rtype.rs
@@ -103,7 +93,6 @@ pub_restricted_3.rs
 redef_error2.rs
 redef_error4.rs
 redef_error5.rs
-self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
-- 
2.45.2



[COMMITTED 036/141] gccrs: add new -frust-overflow-checks flag to control overflow checks

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This will be crucial for more complex gimple debugging to make it easier
to follow the code vs the original rust code.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): disable overflow 
checks
* lang.opt: new flag

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc | 33 ++-
 gcc/rust/lang.opt |  4 
 2 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 887e476f234..29cc8835c33 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -159,27 +159,28 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
   return;
 }
 
-  if (ctx->in_fn () && !ctx->const_context_p ())
-{
-  auto receiver_tmp = NULL_TREE;
-  auto receiver
-   = Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
-  TREE_TYPE (lhs), lhs, true,
-  expr.get_locus (), &receiver_tmp);
-  auto check
-   = Backend::arithmetic_or_logical_expression_checked (op, lhs, rhs,
-expr.get_locus (),
-receiver);
-
-  ctx->add_statement (check);
-  translated = receiver->get_tree (expr.get_locus ());
-}
-  else
+  bool can_generate_overflow_checks
+= (ctx->in_fn () && !ctx->const_context_p ()) && flag_overflow_checks;
+  if (!can_generate_overflow_checks)
 {
   translated
= Backend::arithmetic_or_logical_expression (op, lhs, rhs,
 expr.get_locus ());
+  return;
 }
+
+  auto receiver_tmp = NULL_TREE;
+  auto receiver
+= Backend::temporary_variable (ctx->peek_fn ().fndecl, NULL_TREE,
+  TREE_TYPE (lhs), lhs, true,
+  expr.get_locus (), &receiver_tmp);
+  auto check
+= Backend::arithmetic_or_logical_expression_checked (op, lhs, rhs,
+expr.get_locus (),
+receiver);
+
+  ctx->add_statement (check);
+  translated = receiver->get_tree (expr.get_locus ());
 }
 
 void
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 0e9aab48dfb..9cdbce2bc0a 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -225,4 +225,8 @@ Enum(frust_panic) String(unwind) Value(0)
 EnumValue
 Enum(frust_panic) String(abort) Value(1)
 
+frust-overflow-checks
+Rust Var(flag_overflow_checks) Init(1)
+Enable the overflow checks in code generation
+
 ; This comment is to ensure we retain the blank line above.
-- 
2.45.2



[COMMITTED 020/141] gccrs: ast: More visitors to allow lang item paths in expressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Adapt visitor to 
lang item
PathInExpressions.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* expand/rust-cfg-strip.cc (CfgStrip::visit): Likewise.
* expand/rust-expand-visitor.cc (ExpandVisitor::visit): Likewise.
* hir/rust-ast-lower.cc (ASTLoweringExprWithBlock::visit): Likewise.
(ASTLowerPathInExpression::visit): Likewise.
* resolve/rust-ast-resolve-path.cc (ResolvePath::resolve_path): 
Likewise.
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit): 
Likewise.
---
 gcc/rust/ast/rust-ast-collector.cc   | 18 --
 gcc/rust/ast/rust-ast-visitor.cc |  6 ++--
 gcc/rust/expand/rust-cfg-strip.cc| 10 --
 gcc/rust/expand/rust-expand-visitor.cc   |  7 ++--
 gcc/rust/hir/rust-ast-lower.cc   | 35 
 gcc/rust/resolve/rust-ast-resolve-path.cc|  5 +++
 gcc/rust/resolve/rust-early-name-resolver.cc |  7 ++--
 7 files changed, 53 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 978de648a58..073fa728dcf 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -15,12 +15,14 @@
 // You should have received a copy of the GNU General Public License
 // along with GCC; see the file COPYING3.  If not see
 // .
+
 #include "rust-ast-collector.h"
 #include "rust-ast.h"
 #include "rust-diagnostics.h"
 #include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
+#include "rust-path.h"
 #include "rust-system.h"
 #include "rust-token.h"
 
@@ -530,11 +532,23 @@ TokenCollector::visit (PathExprSegment &segment)
 void
 TokenCollector::visit (PathInExpression &path)
 {
-  if (path.opening_scope_resolution ())
+  if (path.is_lang_item ())
 {
-  push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
+  push (Rust::Token::make (TokenId::HASH, path.get_locus ()));
+  push (Rust::Token::make (TokenId::LEFT_SQUARE, path.get_locus ()));
+  push (Rust::Token::make_identifier (path.get_locus (), "lang"));
+  push (Rust::Token::make (TokenId::EQUAL, path.get_locus ()));
+  push (
+   Rust::Token::make_string (path.get_locus (),
+ LangItem::ToString (path.get_lang_item (;
+  push (Rust::Token::make (TokenId::RIGHT_SQUARE, path.get_locus ()));
+
+  return;
 }
 
+  if (path.opening_scope_resolution ())
+push (Rust::Token::make (SCOPE_RESOLUTION, path.get_locus ()));
+
   visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
 }
 
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index e2e2d9dda37..077b41b5cac 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -89,8 +89,10 @@ void
 DefaultASTVisitor::visit (AST::PathInExpression &path)
 {
   visit_outer_attrs (path);
-  for (auto &segment : path.get_segments ())
-visit (segment);
+
+  if (!path.is_lang_item ())
+for (auto &segment : path.get_segments ())
+  visit (segment);
 }
 
 void
diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index 4e6a8ac2b5f..a8c3ca5bfc9 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -19,6 +19,7 @@
 #include "rust-cfg-strip.h"
 #include "rust-ast-full.h"
 #include "rust-ast-visitor.h"
+#include "rust-path.h"
 #include "rust-session-manager.h"
 #include "rust-attribute-values.h"
 
@@ -434,10 +435,13 @@ CfgStrip::visit (AST::PathInExpression &path)
   return;
 }
 
-  for (auto &segment : path.get_segments ())
+  if (!path.is_lang_item ())
 {
-  if (segment.has_generic_args ())
-   maybe_strip_generic_args (segment.get_generic_args ());
+  for (auto &segment : path.get_segments ())
+   {
+ if (segment.has_generic_args ())
+   maybe_strip_generic_args (segment.get_generic_args ());
+   }
 }
 }
 
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 38399d0d74b..6e06fa51609 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -477,9 +477,10 @@ ExpandVisitor::visit (AST::MacroInvocation ¯o_invoc)
 void
 ExpandVisitor::visit (AST::PathInExpression &path)
 {
-  for (auto &segment : path.get_segments ())
-if (segment.has_generic_args ())
-  expand_generic_args (segment.get_generic_args ());
+  if (!path.is_lang_item ())
+for (auto &segment : path.get_segments ())
+  if (segment.has_generic_args ())
+   expand_generic_args (segment.get_generic_args ());
 }
 
 void
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index a94a8432273..ebdf9810b34 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/

[COMMITTED 018/141] gccrs: mappings: Improve error message for get_lang_item_node

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* util/rust-hir-map.cc (Mappings::get_lang_item_node): Better 
formatting when a lang
item does not exist when it should.
---
 gcc/rust/util/rust-hir-map.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 39c3a98f16b..e58f1a2a715 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1305,8 +1305,8 @@ Mappings::get_lang_item_node (LangItem::Kind item_type)
   if (auto lookup = lookup_lang_item_node (item_type))
 return *lookup;
 
-  rust_fatal_error (UNKNOWN_LOCATION, "failed to find lang item %qs",
-   LangItem::ToString (item_type).c_str ());
+  rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs",
+   LangItem::PrettyString (item_type).c_str ());
 }
 
 void
-- 
2.45.2



[COMMITTED 015/141] gccrs: Infer crate name after file opening

2025-03-24 Thread arthur . cohen
From: Dylan Gardner 

Fixes #3129.

gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::handle_crate_name): Remove
crate name inference
(Session::compile_crate): Add crate name inference and error if
inferred name is empty. Remove CompileOptions::get_instance ()
that returned a local copy of the options. Rename
crate_name_changed to crate_name_found to match semantics.
(rust_crate_name_validation_test): Test inferring ".rs" name
* rust-session-manager.h: Modify handle_crate_name definition to
include filename.
---
 gcc/rust/rust-session-manager.cc | 61 +---
 gcc/rust/rust-session-manager.h  |  2 +-
 2 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 1039fdfb5b9..3adde297a4e 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -401,31 +401,16 @@ Session::handle_input_files (int num_files, const char 
**files)
 
   const auto &file = files[0];
 
-  if (options.crate_name.empty ())
-{
-  auto filename = "-";
-  if (num_files > 0)
-   filename = files[0];
-
-  auto crate_name = infer_crate_name (filename);
-  rust_debug ("inferred crate name: %s", crate_name.c_str ());
-  // set the preliminary crate name here
-  // we will figure out the real crate name in `handle_crate_name`
-  options.set_crate_name (crate_name);
-}
-
-  CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
-  mappings.set_current_crate (crate_num);
-
   rust_debug ("Attempting to parse file: %s", file);
   compile_crate (file);
 }
 
 void
-Session::handle_crate_name (const AST::Crate &parsed_crate)
+Session::handle_crate_name (const char *filename,
+   const AST::Crate &parsed_crate)
 {
   auto &mappings = Analysis::Mappings::get ();
-  auto crate_name_changed = false;
+  auto crate_name_found = false;
   auto error = Error (UNDEF_LOCATION, std::string ());
 
   for (const auto &attr : parsed_crate.inner_attrs)
@@ -449,7 +434,6 @@ Session::handle_crate_name (const AST::Crate &parsed_crate)
  continue;
}
 
-  auto options = Session::get_instance ().options;
   if (options.crate_name_set_manually && (options.crate_name != msg_str))
{
  rust_error_at (attr.get_locus (),
@@ -457,19 +441,39 @@ Session::handle_crate_name (const AST::Crate 
&parsed_crate)
 "required to match, but %qs does not match %qs",
 options.crate_name.c_str (), msg_str.c_str ());
}
-  crate_name_changed = true;
+  crate_name_found = true;
   options.set_crate_name (msg_str);
-  mappings.set_crate_name (mappings.get_current_crate (), msg_str);
 }
 
-  options.crate_name_set_manually |= crate_name_changed;
-  if (!options.crate_name_set_manually
-  && !validate_crate_name (options.crate_name, error))
+  options.crate_name_set_manually |= crate_name_found;
+  if (!options.crate_name_set_manually)
 {
-  error.emit ();
-  rust_inform (linemap_position_for_column (line_table, 0),
-  "crate name inferred from this file");
+  auto crate_name = infer_crate_name (filename);
+  if (crate_name.empty ())
+   {
+ rust_error_at (UNDEF_LOCATION, "crate name is empty");
+ rust_inform (linemap_position_for_column (line_table, 0),
+  "crate name inferred from this file");
+ return;
+   }
+
+  rust_debug ("inferred crate name: %s", crate_name.c_str ());
+  options.set_crate_name (crate_name);
+
+  if (!validate_crate_name (options.get_crate_name (), error))
+   {
+ error.emit ();
+ rust_inform (linemap_position_for_column (line_table, 0),
+  "crate name inferred from this file");
+ return;
+   }
 }
+
+  if (saw_errors ())
+return;
+
+  CrateNum crate_num = mappings.get_next_crate_num (options.get_crate_name ());
+  mappings.set_current_crate (crate_num);
 }
 
 // Parses a single file with filename filename.
@@ -539,7 +543,7 @@ Session::compile_crate (const char *filename)
   std::unique_ptr ast_crate = parser.parse_crate ();
 
   // handle crate name
-  handle_crate_name (*ast_crate.get ());
+  handle_crate_name (filename, *ast_crate.get ());
 
   // dump options except lexer dump
   if (options.dump_option_enabled (CompileOptions::AST_DUMP_PRETTY))
@@ -1400,6 +1404,7 @@ rust_crate_name_validation_test (void)
   ASSERT_FALSE (Rust::validate_crate_name ("∀", error));
 
   /* Tests for crate name inference */
+  ASSERT_EQ (Rust::infer_crate_name (".rs"), "");
   ASSERT_EQ (Rust::infer_crate_name ("c.rs"), "c");
   // NOTE: ... but - is allowed when in the filename
   ASSERT_EQ (Rust::infer_crate_name ("a-b.rs"), "a_b");
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 73a85b3

[COMMITTED 016/141] gccrs: catch missing guard for optional result

2025-03-24 Thread arthur . cohen
From: Philip Herron 

When we lookup here it returns an optional which can lead to a crash
because it needs a guard if it has a value.

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (HIRCompileBase::query_compile): 
add guard

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: these tests now work it seems

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 7 ++-
 gcc/testsuite/rust/compile/nr2/exclude| 2 --
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index 69599cc6185..d248ee282a6 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -248,12 +248,9 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType 
*lookup,
return CompileInherentImplItem::Compile (resolved_item->first, ctx,
 lookup, true, expr_locus);
}
-  else
+  else if (auto trait_item
+  = ctx->get_mappings ().lookup_hir_trait_item (ref))
{
- // it might be resolved to a trait item
- tl::optional trait_item
-   = ctx->get_mappings ().lookup_hir_trait_item (ref);
-
  HIR::Trait *trait = ctx->get_mappings ().lookup_trait_item_mapping (
trait_item.value ()->get_mappings ().get_hirid ());
 
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 5cc7cf7d64c..8bcc8aed030 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -63,7 +63,6 @@ macros/mbe/macro23.rs
 macros/mbe/macro40.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
-macros/mbe/macro50.rs
 macros/mbe/macro54.rs
 macros/mbe/macro6.rs
 macros/mbe/macro_rules_macro_rules.rs
@@ -141,7 +140,6 @@ issue-2423.rs
 issue-266.rs
 additional-trait-bounds2.rs
 auto_traits2.rs
-auto_traits4.rs
 issue-3140.rs
 cmp1.rs
 derive_clone_enum1.rs
-- 
2.45.2



[COMMITTED 009/141] gccrs: Fix rust breakage with nr2

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Nr2 did not emit the correct error message for break identifier "rust".

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add "rust"
identifier detection akin to nr1.
(funny_ice_finalizer): Copy ICE finalizer from nr1.
* resolve/rust-late-name-resolver-2.0.h: Add funny_error member
context state.
* Make-lang.in: Add new translation unit for new ice finalizer.
* resolve/rust-ast-resolve-expr.cc: Move ice
finalizer to it's own file.
* resolve/rust-ice-finalizer.cc: New file.
* resolve/rust-ice-finalizer.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove break-rust3.rs from exclude list.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/Make-lang.in |  1 +
 gcc/rust/resolve/rust-ast-resolve-expr.cc | 42 +---
 gcc/rust/resolve/rust-ice-finalizer.cc| 36 ++
 gcc/rust/resolve/rust-ice-finalizer.h | 65 +++
 .../resolve/rust-late-name-resolver-2.0.cc| 37 +++
 .../resolve/rust-late-name-resolver-2.0.h |  3 +
 gcc/testsuite/rust/compile/nr2/exclude|  1 -
 7 files changed, 143 insertions(+), 42 deletions(-)
 create mode 100644 gcc/rust/resolve/rust-ice-finalizer.cc
 create mode 100644 gcc/rust/resolve/rust-ice-finalizer.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index b6f3a35e4e6..f317c678359 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -133,6 +133,7 @@ GRS_OBJS = \
 rust/rust-toplevel-name-resolver-2.0.o \
 rust/rust-early-name-resolver-2.0.o \
rust/rust-finalize-imports-2.0.o \
+   rust/rust-ice-finalizer.o \
 rust/rust-late-name-resolver-2.0.o \
rust/rust-immutable-name-resolution-context.o \
 rust/rust-early-name-resolver.o \
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc 
b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 6524376a011..9d5d00fa6a2 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -22,8 +22,8 @@
 #include "rust-ast-resolve-type.h"
 #include "rust-ast-resolve-pattern.h"
 #include "rust-ast-resolve-path.h"
-#include "diagnostic.h"
 #include "rust-expr.h"
+#include "rust-ice-finalizer.h"
 
 namespace Rust {
 namespace Resolver {
@@ -108,46 +108,6 @@ ResolveExpr::visit (AST::AssignmentExpr &expr)
   ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix);
 }
 
-/* The "break rust" Easter egg.
-
-   Backstory: once upon a time, there used to be a bug in rustc: it would ICE
-   during typechecking on a 'break' with an expression outside of a loop.  The
-   issue has been reported [0] and fixed [1], but in recognition of this, as a
-   special Easter egg, "break rust" was made to intentionally cause an ICE.
-
-   [0]: https://github.com/rust-lang/rust/issues/43162
-   [1]: https://github.com/rust-lang/rust/pull/43745
-
-   This was made in a way that does not break valid programs: namely, it only
-   happens when the 'break' is outside of a loop (so invalid anyway).
-
-   GCC Rust supports this essential feature as well, but in a slightly
-   different way.  Instead of delaying the error until type checking, we emit
-   it here in the resolution phase.  We, too, only do this to programs that
-   are already invalid: we only emit our funny ICE if the name "rust" (which
-   must be immediately inside a break-with-a-value expression) fails to
-   resolve.  Note that "break (rust)" does not trigger our ICE, only using
-   "break rust" directly does, and only if there's no "rust" in scope.  We do
-   this in the same way regardless of whether the "break" is outside of a loop
-   or inside one.
-
-   As a GNU extension, we also support "break gcc", much to the same effect,
-   subject to the same rules.  */
-
-/* The finalizer for our funny ICE.  This prints a custom message instead of
-   the default bug reporting instructions, as there is no bug to report.  */
-
-static void ATTRIBUTE_NORETURN
-funny_ice_text_finalizer (diagnostic_text_output_format &text_output,
- const diagnostic_info *diagnostic,
- diagnostic_t diag_kind)
-{
-  gcc_assert (diag_kind == DK_ICE_NOBT);
-  default_diagnostic_text_finalizer (text_output, diagnostic, diag_kind);
-  fnotice (stderr, "You have broken GCC Rust. This is a feature.\n");
-  exit (ICE_EXIT_CODE);
-}
-
 void
 ResolveExpr::visit (AST::IdentifierExpr &expr)
 {
diff --git a/gcc/rust/resolve/rust-ice-finalizer.cc 
b/gcc/rust/resolve/rust-ice-finalizer.cc
new file mode 100644
index 000..bd4763f8c76
--- /dev/null
+++ b/gcc/rust/resolve/rust-ice-finalizer.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Fr

[COMMITTED 049/141] gccrs: derive(Debug): Add stub implementation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-debug.cc: New file.
* expand/rust-derive-debug.h: New file.
* Make-lang.in: Compile them.
* expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveDebug.

gcc/testsuite/ChangeLog:

* rust/compile/derive-debug1.rs: New test.
* rust/compile/nr2/exclude: Exclude it.
---
 gcc/rust/Make-lang.in   |   1 +
 gcc/rust/expand/rust-derive-debug.cc| 130 
 gcc/rust/expand/rust-derive-debug.h |  55 +
 gcc/rust/expand/rust-derive.cc  |   6 +
 gcc/testsuite/rust/compile/derive-debug1.rs |  41 ++
 gcc/testsuite/rust/compile/nr2/exclude  |   1 +
 6 files changed, 234 insertions(+)
 create mode 100644 gcc/rust/expand/rust-derive-debug.cc
 create mode 100644 gcc/rust/expand/rust-derive-debug.h
 create mode 100644 gcc/testsuite/rust/compile/derive-debug1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index f317c678359..bc58a341131 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -96,6 +96,7 @@ GRS_OBJS = \
 rust/rust-derive.o \
 rust/rust-derive-clone.o \
 rust/rust-derive-copy.o \
+rust/rust-derive-debug.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
 rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-debug.cc 
b/gcc/rust/expand/rust-derive-debug.cc
new file mode 100644
index 000..910f27c67b2
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -0,0 +1,130 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-debug.h"
+#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveDebug::DeriveDebug (location_t loc)
+  : DeriveVisitor (loc), expanded (nullptr)
+{}
+
+std::unique_ptr
+DeriveDebug::go (Item &item)
+{
+  item.accept_vis (*this);
+
+  rust_assert (expanded);
+
+  return std::move (expanded);
+}
+
+/* Pointer-ify something */
+template 
+static std::unique_ptr
+ptrify (T value)
+{
+  return std::unique_ptr (new T (value));
+}
+
+std::unique_ptr
+DeriveDebug::stub_debug_fn ()
+{
+  auto unit_expr = builder.tuple ();
+  auto ok_expr
+= ptrify (builder.path_in_expression (LangItem::Kind::RESULT_OK));
+
+  auto stub_return = builder.call (std::move (ok_expr), std::move (unit_expr));
+
+  // we can't use builder.block() here as it returns a unique_ptr and
+  // Function's constructor expects a unique_ptr
+  auto block = std::unique_ptr (
+new BlockExpr ({}, std::move (stub_return), {}, {},
+  AST::LoopLabel::error (), loc, loc));
+
+  auto self = builder.self_ref_param ();
+
+  auto return_type
+= ptrify (builder.type_path ({"core", "fmt", "Result"}, true));
+
+  auto mut_fmt_type_inner
+= ptrify (builder.type_path ({"core", "fmt", "Formatter"}, true));
+
+  auto mut_fmt_type
+= builder.reference_type (std::move (mut_fmt_type_inner), true);
+
+  auto fmt = builder.function_param (builder.identifier_pattern ("_fmt"),
+std::move (mut_fmt_type));
+
+  auto params = vec (std::move (self), std::move (fmt));
+
+  auto function = builder.function ({"fmt"}, std::move (params),
+   std::move (return_type), std::move (block));
+
+  return ptrify (function);
+}
+
+std::unique_ptr
+DeriveDebug::stub_derive_impl (
+  std::string name,
+  const std::vector> &type_generics)
+{
+  auto trait_items = vec (stub_debug_fn ());
+
+  auto debug = builder.type_path ({"core", "fmt", "Debug"}, true);
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (debug));
+
+  return builder.trait_impl (debug, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
+}
+
+void
+DeriveDebug::visit_struct (StructStruct &struct_item)
+{
+  expanded = stub_derive_impl (struct_item.get_identifier ().as_string (),
+  struct_item.get_generic_params ());
+}
+
+void
+DeriveDebug::visit_tuple (TupleStruct &tuple_item)
+{
+  expanded = stub_derive_impl (tuple_item.get_identifier ().as_string (),
+  tuple_item.get_generic_params ())

[COMMITTED 008/141] gccrs: derive(Copy): Improve bounds when deriving Copy

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-copy.cc: Always add an extra Copy bound on generic 
Copy impls.
---
 gcc/rust/expand/rust-derive-copy.cc | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
index 31b4819c042..1d5f72bd656 100644
--- a/gcc/rust/expand/rust-derive-copy.cc
+++ b/gcc/rust/expand/rust-derive-copy.cc
@@ -52,7 +52,7 @@ DeriveCopy::copy_impl (
   // for example:
   //
   // #[derive(Copy)]
-  // struct Be { ... }
+  // struct Be { ... }
   //
   // we need to generate the impl block:
   //
@@ -87,7 +87,12 @@ DeriveCopy::copy_impl (
  = GenericArg::create_type (std::move (associated_type));
generic_args.push_back (std::move (type_arg));
 
-   auto impl_type_param = builder.new_type_param (type_param);
+   std::vector> extra_bounds;
+   extra_bounds.emplace_back (std::unique_ptr (
+ new TraitBound (builder.type_path (LangItem::Kind::COPY), loc)));
+
+   auto impl_type_param
+ = builder.new_type_param (type_param, std::move (extra_bounds));
impl_generics.push_back (std::move (impl_type_param));
  }
  break;
-- 
2.45.2



[COMMITTED 012/141] gccrs: Check for type paths nr2.0 can't handle yet

2025-03-24 Thread arthur . cohen
From: Owen Avery 

Some of our tests only work with name resolution 2.0 because the latter
misinterprets type paths. This change should cause the compiler to error out
if it would otherwise misinterpret a type path. A fix for type path
resolution isn't included in this comment, since doing so would make it
harder to track the meaningfulness of test regressions.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Error out if a type path has multiple segments,
as we currently ignore every segment except the last.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Add entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  8 
 gcc/testsuite/rust/compile/nr2/exclude  | 15 +++
 2 files changed, 23 insertions(+)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 802f6a4d2ab..e3d95e5dd7b 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -287,6 +287,14 @@ Late::visit (AST::TypePath &type)
   // maybe we can overload `resolve_path` to only do
   // typepath-like path resolution? that sounds good
 
+  if (type.get_segments ().size () != 1)
+{
+  rust_sorry_at (
+   type.get_locus (),
+   "name resolution 2.0 cannot resolve multi-segment type paths");
+  return;
+}
+
   auto str = type.get_segments ().back ()->get_ident_segment ().as_string ();
   auto values = ctx.types.peek ().get_values ();
 
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index d53c1487173..5cc7cf7d64c 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -58,6 +58,7 @@ iterators1.rs
 lookup_err1.rs
 macros/mbe/macro13.rs
 macros/mbe/macro15.rs
+macros/mbe/macro20.rs
 macros/mbe/macro23.rs
 macros/mbe/macro40.rs
 macros/mbe/macro43.rs
@@ -151,4 +152,18 @@ derive_macro6.rs
 issue-2987.rs
 issue-3139-1.rs
 issue-3139-3.rs
+issue-1019.rs
+issue-1034.rs
+issue-2019-1.rs
+issue-2019-2.rs
+issue-2019-3.rs
+issue-2105.rs
+issue-2190-1.rs
+issue-2190-2.rs
+issue-2304.rs
+issue-2747.rs
+issue-2953-1.rs
+issue-3030.rs
+traits12.rs
+try-trait.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 053/141] gccrs: Fix ICE when fn_once and fn_once_output lang item is not defined

2025-03-24 Thread arthur . cohen
From: Philip Herron 

We needed to check for the optional has a value here or not it leads to an
ICE.

gcc/rust/ChangeLog:

* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): add 
checks for lang items

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-tyty.cc | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index f0c967e0949..02d91b1f195 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2226,12 +2226,24 @@ void
 ClosureType::setup_fn_once_output () const
 {
   // lookup the lang items
-  auto fn_once_lang_item = LangItem::Kind::FN_ONCE;
-  auto fn_once_output_lang_item = LangItem::Kind::FN_ONCE_OUTPUT;
+  auto fn_once_lookup = mappings.lookup_lang_item (LangItem::Kind::FN_ONCE);
+  auto fn_once_output_lookup
+= mappings.lookup_lang_item (LangItem::Kind::FN_ONCE_OUTPUT);
+  if (!fn_once_lookup)
+{
+  rust_fatal_error (UNKNOWN_LOCATION,
+   "Missing required % lang item");
+  return;
+}
+  if (!fn_once_output_lookup)
+{
+  rust_fatal_error (UNKNOWN_LOCATION,
+   "Missing required % lang item");
+  return;
+}
 
-  DefId &trait_id = mappings.lookup_lang_item (fn_once_lang_item).value ();
-  DefId &trait_item_id
-= mappings.lookup_lang_item (fn_once_output_lang_item).value ();
+  DefId &trait_id = fn_once_lookup.value ();
+  DefId &trait_item_id = fn_once_output_lookup.value ();
 
   // resolve to the trait
   HIR::Item *item = mappings.lookup_defid (trait_id).value ();
-- 
2.45.2



[COMMITTED 056/141] gccrs: Fix crash in privay reporter for placeholder types

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This guards against a crash but i think this should actually be treated
as if its a generic type like below. But for now this addresses a crash which 
can occur.

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::check_base_type_privacy):
Add guard for placeholder

Signed-off-by: Philip Herron 
---
 .../checks/errors/privacy/rust-privacy-reporter.cc | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index dcc7681..896c1c449ab 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -243,10 +243,12 @@ PrivacyReporter::check_base_type_privacy 
(Analysis::NodeMapping &node_mappings,
   static_cast (ty)->get_fields ())
recursive_check (param.get_tyty ());
   return;
-case TyTy::PLACEHOLDER:
-  return recursive_check (
-   // FIXME: Can we use `resolve` here? Is that what we should do?
-   static_cast (ty)->resolve ());
+  case TyTy::PLACEHOLDER: {
+   const auto p = static_cast (ty);
+   if (!p->can_resolve ())
+ return;
+   return recursive_check (p->resolve ());
+  }
 case TyTy::PROJECTION:
   return recursive_check (
static_cast (ty)->get ());
-- 
2.45.2



[COMMITTED 061/141] gccrs: Add test case to show issue is fixed

2025-03-24 Thread arthur . cohen
From: Philip Herron 

This was fixed as part of: "gccrs: Fix compilation of trait-items which map to 
impl items"

Fixes Rust-GCC#3402

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3402-1.rs: New test.
* rust/compile/issue-3402-2.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/testsuite/rust/compile/issue-3402-1.rs | 29 ++
 gcc/testsuite/rust/compile/issue-3402-2.rs | 18 ++
 gcc/testsuite/rust/compile/nr2/exclude |  1 +
 3 files changed, 48 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3402-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3402-2.rs

diff --git a/gcc/testsuite/rust/compile/issue-3402-1.rs 
b/gcc/testsuite/rust/compile/issue-3402-1.rs
new file mode 100644
index 000..ed603cecaad
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3402-1.rs
@@ -0,0 +1,29 @@
+pub struct Foo {
+a: i32,
+// { dg-warning "field is never read" "" { target *-*-* } .-1 }
+}
+pub struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+pub mod default {
+pub trait Default: Sized {
+fn default() -> Self;
+}
+
+impl Default for i32 {
+fn default() -> Self {
+0
+}
+}
+}
+}
+
+impl ::core::default::Default for Bar {
+#[inline]
+fn default() -> Bar {
+Bar(core::default::Default::default())
+}
+}
diff --git a/gcc/testsuite/rust/compile/issue-3402-2.rs 
b/gcc/testsuite/rust/compile/issue-3402-2.rs
new file mode 100644
index 000..b665af25b51
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3402-2.rs
@@ -0,0 +1,18 @@
+pub struct Bar(i32);
+
+#[lang = "sized"]
+trait Sized {}
+
+pub trait A: Sized {
+fn foo() -> Self;
+}
+
+impl A for i32 {
+fn foo() -> Self {
+0
+}
+}
+
+pub fn bar() {
+let _ = Bar(A::foo());
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index f8e280e341c..1b34e9fe20e 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -125,4 +125,5 @@ try-trait.rs
 derive-debug1.rs
 issue-3382.rs
 derive-default1.rs
+issue-3402-1.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 110/141] gccrs: lower: Error out when lowering ErrorPropagationExpr

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

Adapt functions for lowering nodes that should never reach the lowering phase 
to cause an
unreachable, and mark them as final so as it not possible to override them in 
other visitors.

gcc/rust/ChangeLog:

* hir/rust-ast-lower-base.cc: Adapt functions for ErrorPropagationExpr 
and MacroInvocation.
* hir/rust-ast-lower-base.h: Mark them as final.
* hir/rust-ast-lower-expr.cc: Remove previous definition for those 
overrides.
* hir/rust-ast-lower-expr.h: Likewise.
---
 gcc/rust/hir/rust-ast-lower-base.cc |  13 +-
 gcc/rust/hir/rust-ast-lower-base.h  | 356 ++--
 gcc/rust/hir/rust-ast-lower-expr.cc |  15 --
 gcc/rust/hir/rust-ast-lower-expr.h  |   1 -
 4 files changed, 188 insertions(+), 197 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index f38697cf316..c1fef3d7a20 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -23,6 +23,7 @@
 #include "rust-ast.h"
 #include "rust-attribute-values.h"
 #include "rust-diagnostics.h"
+#include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-system.h"
 #include "rust-attributes.h"
@@ -30,7 +31,6 @@
 namespace Rust {
 namespace HIR {
 
-// We special case lowering macro invocations as that should NEVER happen
 void
 ASTLoweringBase::visit (AST::MacroInvocation &invoc)
 {
@@ -38,6 +38,14 @@ ASTLoweringBase::visit (AST::MacroInvocation &invoc)
   rust_unreachable ();
 }
 
+void
+ASTLoweringBase::visit (AST::ErrorPropagationExpr &expr)
+{
+  rust_fatal_error (expr.get_locus (),
+   "missing desugar for question mark operator");
+  rust_unreachable ();
+}
+
 void
 ASTLoweringBase::visit (AST::Token &)
 {}
@@ -116,9 +124,6 @@ void
 ASTLoweringBase::visit (AST::DereferenceExpr &)
 {}
 void
-ASTLoweringBase::visit (AST::ErrorPropagationExpr &)
-{}
-void
 ASTLoweringBase::visit (AST::NegationExpr &)
 {}
 void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index 1bd1343bd16..b3bb174babf 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -60,202 +60,204 @@ class ASTLoweringBase : public AST::ASTVisitor
 public:
   virtual ~ASTLoweringBase () {}
 
+  // Special casing nodes that should never reach the HIR lowering stage
+  virtual void visit (AST::MacroInvocation &) override final;
+  virtual void visit (AST::ErrorPropagationExpr &) override final;
+
   // visitor impl
   // rust-ast.h
   //  virtual void visit(AttrInput& attr_input);
   //  virtual void visit(TokenTree& token_tree);
   //  virtual void visit(MacroMatch& macro_match);
-  virtual void visit (AST::Token &tok);
-  virtual void visit (AST::DelimTokenTree &delim_tok_tree);
-  virtual void visit (AST::AttrInputMetaItemContainer &input);
-  //  virtual void visit(MetaItem& meta_item);
-  //  void vsit(Stmt& stmt);
-  //  virtual void visit(Expr& expr);
-  virtual void visit (AST::IdentifierExpr &ident_expr);
-  //  virtual void visit(Pattern& pattern);
-  //  virtual void visit(Type& type);
-  //  virtual void visit(TypeParamBound& type_param_bound);
-  virtual void visit (AST::Lifetime &lifetime);
-  //  virtual void visit(GenericParam& generic_param);
-  virtual void visit (AST::LifetimeParam &lifetime_param);
-  virtual void visit (AST::ConstGenericParam &const_param);
-  //  virtual void visit(TraitItem& trait_item);
-  //  virtual void visit(InherentImplItem& inherent_impl_item);
-  //  virtual void visit(TraitImplItem& trait_impl_item);
+  virtual void visit (AST::Token &tok) override;
+  virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
+  virtual void visit (AST::AttrInputMetaItemContainer &input) override;
+  //  virtual void visit(MetaItem& meta_item) override;
+  //  void vsit(Stmt& stmt) override;
+  //  virtual void visit(Expr& expr) override;
+  virtual void visit (AST::IdentifierExpr &ident_expr) override;
+  //  virtual void visit(Pattern& pattern) override;
+  //  virtual void visit(Type& type) override;
+  //  virtual void visit(TypeParamBound& type_param_bound) override;
+  virtual void visit (AST::Lifetime &lifetime) override;
+  //  virtual void visit(GenericParam& generic_param) override;
+  virtual void visit (AST::LifetimeParam &lifetime_param) override;
+  virtual void visit (AST::ConstGenericParam &const_param) override;
+  //  virtual void visit(TraitItem& trait_item) override;
+  //  virtual void visit(InherentImplItem& inherent_impl_item) override;
+  //  virtual void visit(TraitImplItem& trait_impl_item) override;
 
   // rust-path.h
-  virtual void visit (AST::PathInExpression &path);
-  virtual void visit (AST::TypePathSegment &segment);
-  virtual void visit (AST::TypePathSegmentGeneric &segment);
-  virtual void visit (AST::TypePathSegmentFunction &segment);
-  virtual void visit (AST::TypePath &path);
-  virtual void visit (AST::QualifiedPathInExpression &path);
-  virtual void visit (AST::QualifiedPat

[COMMITTED 115/141] gccrs: nr2.0: Set the node id of the root node

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::ForeverStack): Set the node id of the root node
to that of the current crate.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Use the node id of the root
node during resolution of crate segments.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h   | 7 +--
 gcc/rust/resolve/rust-forever-stack.hxx | 7 +--
 gcc/testsuite/rust/compile/nr2/exclude  | 2 --
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index f1e5e8d2f2d..64e8a0f0f2c 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -547,13 +547,16 @@ template  class ForeverStack
 {
 public:
   ForeverStack ()
-// FIXME: Is that valid? Do we use the root? If yes, we should give the
-// crate's node id to ForeverStack's constructor
 : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
   cursor_reference (root)
   {
 rust_assert (root.is_root ());
 rust_assert (root.is_leaf ());
+
+// TODO: Should we be using the forever stack root as the crate scope?
+// TODO: Is this how we should be getting the crate node id?
+auto &mappings = Analysis::Mappings::get ();
+root.id = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
   }
 
   /**
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 9ca8db2c09d..c1407344b52 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -401,12 +401,7 @@ ForeverStack::find_starting_point (
   if (seg.is_crate_path_seg ())
{
  starting_point = root;
- // TODO: is this how we should be getting the crate node id?
- auto &mappings = Analysis::Mappings::get ();
- NodeId current_crate
-   = *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
-
- insert_segment_resolution (outer_seg, current_crate);
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
  iterator++;
  break;
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 763387f3548..e179dc30004 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,7 +1,6 @@
 break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
-complex-path1.rs
 const_generics_3.rs
 const_generics_4.rs
 feature_rust_attri0.rs
@@ -29,7 +28,6 @@ pub_restricted_2.rs
 pub_restricted_3.rs
 redef_error2.rs
 redef_error5.rs
-self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
-- 
2.45.2



[COMMITTED 122/141] gccrs: remove visitor which is not needed here

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Just a small refactor to remove a visitor which is not needed.

gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc (ResolvePathRef::Compile): 
remove visitor
(ResolvePathRef::ResolvePathRef): likewise
(ResolvePathRef::visit): likewise
* backend/rust-compile-resolve-path.h (class ResolvePathRef): likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 28 --
 gcc/rust/backend/rust-compile-resolve-path.h  | 38 ++-
 2 files changed, 20 insertions(+), 46 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index c54cc09b67b..2b6880c9b1a 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -32,6 +32,22 @@
 namespace Rust {
 namespace Compile {
 
+tree
+ResolvePathRef::Compile (HIR::QualifiedPathInExpression &expr, Context *ctx)
+{
+  ResolvePathRef resolver (ctx);
+  return resolver.resolve_path_like (expr);
+}
+
+tree
+ResolvePathRef::Compile (HIR::PathInExpression &expr, Context *ctx)
+{
+  ResolvePathRef resolver (ctx);
+  return resolver.resolve_path_like (expr);
+}
+
+ResolvePathRef::ResolvePathRef (Context *ctx) : HIRCompileBase (ctx) {}
+
 template 
 tree
 ResolvePathRef::resolve_path_like (T &expr)
@@ -53,18 +69,6 @@ ResolvePathRef::resolve_path_like (T &expr)
  expr.get_mappings (), expr.get_locus (), true);
 }
 
-void
-ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr)
-{
-  resolved = resolve_path_like (expr);
-}
-
-void
-ResolvePathRef::visit (HIR::PathInExpression &expr)
-{
-  resolved = resolve_path_like (expr);
-}
-
 tree
 ResolvePathRef::attempt_constructor_expression_lookup (
   TyTy::BaseType *lookup, Context *ctx, const Analysis::NodeMapping &mappings,
diff --git a/gcc/rust/backend/rust-compile-resolve-path.h 
b/gcc/rust/backend/rust-compile-resolve-path.h
index 12cdc19caba..79bfb86d6d2 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.h
+++ b/gcc/rust/backend/rust-compile-resolve-path.h
@@ -20,46 +20,18 @@
 #define RUST_COMPILE_RESOLVE_PATH
 
 #include "rust-compile-base.h"
-#include "rust-hir-visitor.h"
 
 namespace Rust {
 namespace Compile {
 
-class ResolvePathRef : public HIRCompileBase, public HIR::HIRPatternVisitor
+class ResolvePathRef : public HIRCompileBase
 {
 public:
-  static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx)
-  {
-ResolvePathRef resolver (ctx);
-expr.accept_vis (resolver);
-return resolver.resolved;
-  }
+  static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx);
 
-  static tree Compile (HIR::PathInExpression &expr, Context *ctx)
-  {
-ResolvePathRef resolver (ctx);
-expr.accept_vis (resolver);
-return resolver.resolved;
-  }
+  static tree Compile (HIR::PathInExpression &expr, Context *ctx);
 
-  void visit (HIR::PathInExpression &expr) override;
-  void visit (HIR::QualifiedPathInExpression &expr) override;
-
-  // Empty visit for unused Pattern HIR nodes.
-  void visit (HIR::IdentifierPattern &) override {}
-  void visit (HIR::LiteralPattern &) override {}
-  void visit (HIR::RangePattern &) override {}
-  void visit (HIR::ReferencePattern &) override {}
-  void visit (HIR::SlicePattern &) override {}
-  void visit (HIR::AltPattern &) override {}
-  void visit (HIR::StructPattern &) override {}
-  void visit (HIR::TuplePattern &) override {}
-  void visit (HIR::TupleStructPattern &) override {}
-  void visit (HIR::WildcardPattern &) override {}
-
-  ResolvePathRef (Context *ctx)
-: HIRCompileBase (ctx), resolved (error_mark_node)
-  {}
+  ResolvePathRef (Context *ctx);
 
   /**
* Generic visitor for both PathInExpression and QualifiedPathInExpression
@@ -81,8 +53,6 @@ public:
const Analysis::NodeMapping &mappings, location_t locus,
bool is_qualified_path);
 
-  tree resolved;
-
 private:
   tree
   attempt_constructor_expression_lookup (TyTy::BaseType *lookup, Context *ctx,
-- 
2.45.2



[COMMITTED 123/141] gccrs: track DefId on ADT Types this could be useful information

2025-03-24 Thread arthur . cohen
From: Philip Herron 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): track 
DefId of origin
* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): likewise
(ADTType::ADTType): likewise
(ADTType::get_id): likewise
(ADTType::clone): likewise
* typecheck/rust-tyty.h: likewise

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-item.cc |  8 +++-
 gcc/rust/typecheck/rust-tyty.cc   | 47 ++-
 gcc/rust/typecheck/rust-tyty.h| 39 ++-
 3 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 16c664fb595..a003848cce0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -232,6 +232,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
+struct_decl.get_mappings ().get_defid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
@@ -314,6 +315,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
+struct_decl.get_mappings ().get_defid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
@@ -376,7 +378,8 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
 
   // multi variant ADT
   auto *type
-= new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
+= new TyTy::ADTType (enum_decl.get_mappings ().get_defid (),
+enum_decl.get_mappings ().get_hirid (),
 enum_decl.get_mappings ().get_hirid (),
 enum_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::ENUM, std::move (variants),
@@ -447,7 +450,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
  std::move (fields)));
 
   auto *type
-= new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
+= new TyTy::ADTType (union_decl.get_mappings ().get_defid (),
+union_decl.get_mappings ().get_hirid (),
 union_decl.get_mappings ().get_hirid (),
 union_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::UNION, std::move (variants),
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 5d5da4d258c..3951fa88da8 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -638,7 +638,7 @@ BaseType::monomorphized_clone () const
   for (auto &variant : adt->get_variants ())
cloned_variants.push_back (variant->monomorphized_clone ());
 
-  return new ADTType (adt->get_ref (), adt->get_ty_ref (),
+  return new ADTType (adt->get_id (), adt->get_ref (), adt->get_ty_ref (),
  adt->get_identifier (), adt->ident,
  adt->get_adt_kind (), cloned_variants,
  adt->clone_substs (), adt->get_repr_options (),
@@ -1621,6 +1621,43 @@ VariantDef::get_ident () const
 
 // ADTType
 
+ADTType::ADTType (DefId id, HirId ref, std::string identifier, RustIdent ident,
+ ADTKind adt_kind, std::vector variants,
+ std::vector subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set refs)
+  : BaseType (ref, ref, TypeKind::ADT, ident, refs),
+SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+region_constraints),
+id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector variants,
+ std::vector subst_refs,
+ SubstitutionArgumentMappings generic_arguments,
+ RegionConstraints region_constraints, std::set refs)
+  : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
+SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+region_constraints),
+id (id), identifier (identifier), variants (variants), adt_kind (adt_kind)
+{}
+
+ADTType::ADTType (DefId id, HirId ref, HirId ty_ref, std::string identifier,
+ RustIdent ident, ADTKind adt_kind,
+ std::vector variants,
+ std::vector subst_refs,
+ ReprOptions repr,
+ SubstitutionArgumentMappings generic_arguments,

[Bug rust/116561] [15 regression] gcc/testsuite/rust/execute/torture/iter1.rs:350:5: internal compiler error: 'verify_gimple' failed since r15-3328-g673a448aa24efedd5ac140ebf7bfe652d7a6a846

2025-03-24 Thread pinskia at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116561

Andrew Pinski  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|NEW |RESOLVED

--- Comment #4 from Andrew Pinski  ---
(In reply to Sam James from comment #2)
> (In reply to Thomas Schwinge from comment #1)
> > This appears to be due to recent commit
> > r15-3328-g673a448aa24efedd5ac140ebf7bfe652d7a6a846 "Optimize initialization
> > of small padded objects".
> > 
> > Given this commit doesn't appear to be causing any other issues, chances are
> > that the Rust front end is doing "something funny"?
> 
> It seems to have started passing yesterday or so, probably after
> r15-5772-gf93059c82e61d6.

I reverted that patch and tried again. looks like the front-end is fixed.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

[COMMITTED 063/141] gccrs: inline-asm: Fix some warnings

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (strip_double_quotes): Special case 
empty
strings ("\"\"").
(parse_reg_operand): Remove use of the `struct` keyword.
(parse_reg_operand_in): Likewise.
(parse_reg_operand_out): Likewise.
* expand/rust-macro-builtins.cc: Add llvm_asm! built-in macro as an 
alias to asm!.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 24 +++---
 gcc/rust/expand/rust-macro-builtins.cc |  4 
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 78e308a6654..4d026044776 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -39,16 +39,28 @@ std::map 
InlineAsmOptionMap{
 std::set potentially_nonpromoted_keywords
   = {"in", "out", "lateout", "inout", "inlateout", "const", "sym", "label"};
 
+// Helper function strips the beginning and ending double quotes from a
+// string.
 std::string
 strip_double_quotes (const std::string &str)
 {
-  // Helper function strips the beginning and ending double quotes from a
-  // string.
   std::string result = str;
 
+  rust_assert (!str.empty ());
+
+  rust_assert (str.front () == '\"');
+  rust_assert (str.back () == '\"');
+
+  // we have to special case empty strings which just contain a set of quotes
+  // so, if the string is "\"\"", just return ""
+  if (result.size () == 2)
+return "";
+
   rust_assert (result.size () >= 3);
+
   result.erase (0, 1);
   result.erase (result.size () - 1, 1);
+
   return result;
 }
 
@@ -240,12 +252,10 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   // Loop over and execute the parsing functions, if the parser successfullly
   // parses or if the parser fails to parse while it has committed to a token,
   // we propogate the result.
-  int count = 0;
   tl::expected parsing_operand (
 inline_asm_ctx);
   for (auto &parse_func : parse_funcs)
 {
-  count++;
   auto result = parsing_operand.and_then (parse_func);
 
   // Per rust's asm.rs's structure
@@ -323,14 +333,14 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
  // We are sure to be failing a test here, based on asm.rs
  // 
https://github.com/rust-lang/rust/blob/a330e49593ee890f9197727a3a558b6e6b37f843/compiler/rustc_builtin_macros/src/asm.rs#L112
  rust_unreachable ();
- return tl::unexpected (COMMITTED);
+ // return tl::unexpected (COMMITTED);
}
 
   auto expr = parser.parse_expr ();
 
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
-  struct AST::InlineAsmOperand::In in (reg, std::move (expr));
+  AST::InlineAsmOperand::In in (reg, std::move (expr));
   inline_asm_ctx.inline_asm.operands.emplace_back (in, locus);
   return inline_asm_ctx;
 }
@@ -354,7 +364,7 @@ parse_reg_operand_out (InlineAsmContext inline_asm_ctx)
 
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
-  struct AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
+  AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
 
   inline_asm_ctx.inline_asm.operands.emplace_back (out, locus);
 
diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 804cfed521a..39c4c46b8e0 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -62,6 +62,8 @@ const BiMap MacroBuiltin::builtins 
= {{
   {"concat_idents", BuiltinMacro::ConcatIdents},
   {"module_path", BuiltinMacro::ModulePath},
   {"asm", BuiltinMacro::Asm},
+  // FIXME: Is that okay
+  {"llvm_asm", BuiltinMacro::Asm},
   {"global_asm", BuiltinMacro::GlobalAsm},
   {"log_syntax", BuiltinMacro::LogSyntax},
   {"trace_macros", BuiltinMacro::TraceMacros},
@@ -119,6 +121,8 @@ std::unordered_map
 {"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
 {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
 {"asm", inline_asm_maker (AST::AsmKind::Inline)},
+// FIXME: Is that okay?
+{"llvm_asm", inline_asm_maker (AST::AsmKind::Inline)},
 {"global_asm", inline_asm_maker (AST::AsmKind::Global)},
 {"option_env", MacroBuiltin::option_env_handler},
 /* Unimplemented macro builtins */
-- 
2.45.2



[COMMITTED 088/141] gccrs: ast-builder: Add new methods for creating operator expressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::literal_bool): New method.
(Builder::comparison_expr): Likewise.
(Builder::boolean_operation): Likewise.
* ast/rust-ast-builder.h: Declare them.
---
 gcc/rust/ast/rust-ast-builder.cc | 46 
 gcc/rust/ast/rust-ast-builder.h  | 20 ++
 2 files changed, 66 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index f59ff19d621..82e6a5abe24 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -21,9 +21,11 @@
 #include "rust-ast.h"
 #include "rust-common.h"
 #include "rust-expr.h"
+#include "rust-keyword-values.h"
 #include "rust-path.h"
 #include "rust-item.h"
 #include "rust-path.h"
+#include "rust-pattern.h"
 #include "rust-system.h"
 #include "rust-token.h"
 #include 
@@ -39,6 +41,17 @@ Builder::literal_string (std::string &&content) const
  PrimitiveCoreType::CORETYPE_STR, {}, loc));
 }
 
+std::unique_ptr
+Builder::literal_bool (bool b) const
+{
+  auto str
+= b ? Values::Keywords::TRUE_LITERAL : Values::Keywords::FALSE_LITERAL;
+
+  return std::unique_ptr (
+new AST::LiteralExpr (std::move (str), Literal::LitType::BOOL,
+ PrimitiveCoreType::CORETYPE_BOOL, {}, loc));
+}
+
 std::unique_ptr
 Builder::call (std::unique_ptr &&path,
   std::vector> &&args) const
@@ -279,6 +292,14 @@ Builder::path_in_expression (LangItem::Kind lang_item) 
const
   return PathInExpression (lang_item, {}, loc);
 }
 
+PathInExpression
+Builder::variant_path (const std::string &enum_path,
+  const std::string &variant) const
+{
+  return PathInExpression ({path_segment (enum_path), path_segment (variant)},
+  {}, loc, false);
+}
+
 std::unique_ptr
 Builder::block (tl::optional> &&stmt,
std::unique_ptr &&tail_expr) const
@@ -331,6 +352,24 @@ Builder::deref (std::unique_ptr &&of) const
   return std::unique_ptr (new DereferenceExpr (std::move (of), {}, loc));
 }
 
+std::unique_ptr
+Builder::comparison_expr (std::unique_ptr &&lhs,
+ std::unique_ptr &&rhs,
+ ComparisonOperator op) const
+{
+  return std::make_unique (std::move (lhs), std::move (rhs), 
op,
+  loc);
+}
+
+std::unique_ptr
+Builder::boolean_operation (std::unique_ptr &&lhs,
+   std::unique_ptr &&rhs,
+   LazyBooleanOperator op) const
+{
+  return std::make_unique (std::move (lhs), std::move (rhs),
+   op, loc);
+}
+
 std::unique_ptr
 Builder::struct_struct (std::string struct_name,
std::vector> &&generics,
@@ -390,6 +429,13 @@ Builder::wildcard () const
   return std::unique_ptr (new WildcardPattern (loc));
 }
 
+std::unique_ptr
+Builder::ref_pattern (std::unique_ptr &&inner) const
+{
+  return std::make_unique (std::move (inner), false, false,
+loc);
+}
+
 std::unique_ptr
 Builder::lang_item_path (LangItem::Kind kind) const
 {
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 9fbcea182be..faf3cf74df9 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -23,6 +23,7 @@
 #include "rust-expr.h"
 #include "rust-ast.h"
 #include "rust-item.h"
+#include "rust-operators.h"
 
 namespace Rust {
 namespace AST {
@@ -62,6 +63,9 @@ public:
   /* Create a string literal expression ("content") */
   std::unique_ptr literal_string (std::string &&content) const;
 
+  /* Create a boolean literal expression (true) */
+  std::unique_ptr literal_bool (bool b) const;
+
   /* Create an identifier expression (`variable`) */
   std::unique_ptr identifier (std::string name) const;
   std::unique_ptr identifier_pattern (std::string name,
@@ -81,6 +85,16 @@ public:
   /* Create a dereference of an expression (`*of`) */
   std::unique_ptr deref (std::unique_ptr &&of) const;
 
+  /* Build a comparison expression (`lhs == rhs`) */
+  std::unique_ptr comparison_expr (std::unique_ptr &&lhs,
+std::unique_ptr &&rhs,
+ComparisonOperator op) const;
+
+  /* Build a lazy boolean operator expression (`lhs && rhs`) */
+  std::unique_ptr boolean_operation (std::unique_ptr &&lhs,
+  std::unique_ptr &&rhs,
+  LazyBooleanOperator op) const;
+
   /* Create a block with an optional tail expression */
   std::unique_ptr block (std::vector> &&stmts,
std::unique_ptr &&tail_expr
@@ -191,6 +205,10 @@ public:
*/
   PathInExpression path_in_expression (LangItem::Kind lang_item) const;
 
+  /* Create the path to an enum's variant (`Result::Ok`) */
+  PathInExpression variant

[COMMITTED 109/141] gccrs: ast: Add base for desugaring try expressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* Make-lang.in: Compile it.
* ast/rust-desugar-question-mark.cc: New file.
* ast/rust-desugar-question-mark.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/try-expr1.rs: New test.
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/ast/rust-desugar-question-mark.cc | 167 +
 gcc/rust/ast/rust-desugar-question-mark.h  |  79 ++
 gcc/testsuite/rust/compile/try-expr1.rs|  84 +++
 4 files changed, 331 insertions(+)
 create mode 100644 gcc/rust/ast/rust-desugar-question-mark.cc
 create mode 100644 gcc/rust/ast/rust-desugar-question-mark.h
 create mode 100644 gcc/testsuite/rust/compile/try-expr1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 3e44b12c3d1..749c1123e05 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -239,6 +239,7 @@ GRS_OBJS = \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
rust/rust-desugar-for-loops.o \
+   rust/rust-desugar-question-mark.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc 
b/gcc/rust/ast/rust-desugar-question-mark.cc
new file mode 100644
index 000..4d2933b1bee
--- /dev/null
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -0,0 +1,167 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-desugar-question-mark.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+namespace AST {
+
+DesugarQuestionMark::DesugarQuestionMark () {}
+
+void
+DesugarQuestionMark::go (AST::Crate &crate)
+{
+  DesugarQuestionMark::visit (crate);
+}
+
+void
+DesugarQuestionMark::visit (ExprStmt &stmt)
+{
+  if (stmt.get_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
+desugar_and_replace (stmt.get_expr_ptr ());
+
+  DefaultASTVisitor::visit (stmt);
+}
+
+void
+DesugarQuestionMark::visit (CallExpr &call)
+{
+  if (call.get_function_expr ().get_expr_kind ()
+  == Expr::Kind::ErrorPropagation)
+desugar_and_replace (call.get_function_expr_ptr ());
+
+  for (auto &arg : call.get_params ())
+if (arg->get_expr_kind () == Expr::Kind::ErrorPropagation)
+  desugar_and_replace (arg);
+
+  DefaultASTVisitor::visit (call);
+}
+
+void
+DesugarQuestionMark::visit (LetStmt &stmt)
+{
+  if (stmt.has_init_expr ()
+  && stmt.get_init_expr ().get_expr_kind () == 
Expr::Kind::ErrorPropagation)
+desugar_and_replace (stmt.get_init_expr_ptr ());
+
+  DefaultASTVisitor::visit (stmt);
+}
+
+MatchArm
+make_match_arm (std::unique_ptr &&pattern)
+{
+  auto loc = pattern->get_locus ();
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (pattern));
+
+  return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+ok_case (Builder &builder)
+{
+  auto val = builder.identifier_pattern ("val");
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (val));
+
+  auto pattern_item = std::unique_ptr (
+new TupleStructItemsNoRange (std::move (patterns)));
+  auto pattern = std::unique_ptr (new TupleStructPattern (
+builder.path_in_expression (LangItem::Kind::RESULT_OK),
+std::move (pattern_item)));
+
+  auto arm = make_match_arm (std::move (pattern));
+
+  auto ret_val = builder.identifier ("val");
+
+  return MatchCase (std::move (arm), std::move (ret_val));
+}
+
+MatchCase
+err_case (Builder &builder)
+{
+  auto val = builder.identifier_pattern ("err");
+
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (val));
+
+  auto pattern_item = std::unique_ptr (
+new TupleStructItemsNoRange (std::move (patterns)));
+  auto pattern = std::unique_ptr (new TupleStructPattern (
+builder.path_in_expression (LangItem::Kind::RESULT_ERR),
+std::move (pattern_item)));
+
+  auto arm = make_match_arm (std::move (pattern));
+
+  auto try_from_err = std::make_unique (
+builder.path_in_expression (LangItem::Kind::TRY_FROM_ERROR));
+  auto from_from = std::make_unique (
+builder.path_in_expression (LangItem::Kind::FROM_FROM));
+
+  auto early_return = builder.return_expr (
+builder.call (std::move (try_from_err),
+ builder.call (std::move (from_from),
+   builder.identifier ("err";
+
+  return Ma

[COMMITTED 069/141] gccrs: Get rid of duplicate interface gccrs#3396

2025-03-24 Thread arthur . cohen
From: GS-GOAT <86884129+gs-g...@users.noreply.github.com>

gcc/rust/ChangeLog:

* typecheck/rust-autoderef.cc
(insert_implicit_type): Update single-parameter call to
pass explicit HirId.
* typecheck/rust-hir-type-check-expr.cc: Same.
* typecheck/rust-hir-type-check-pattern.cc: Same.
* typecheck/rust-hir-type-check.h: Removed call
to the duplicate interface.
* typecheck/rust-typecheck-context.cc
(TypeCheckContext::insert_implicit_type): Removed the
interface with no HirId field.

Signed-off-by: Guransh Singh 
---
 gcc/rust/typecheck/rust-autoderef.cc  | 2 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc| 2 +-
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 3 ++-
 gcc/rust/typecheck/rust-hir-type-check.h  | 1 -
 gcc/rust/typecheck/rust-typecheck-context.cc  | 7 ---
 5 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-autoderef.cc 
b/gcc/rust/typecheck/rust-autoderef.cc
index 75da3919ea4..6aa20a8c941 100644
--- a/gcc/rust/typecheck/rust-autoderef.cc
+++ b/gcc/rust/typecheck/rust-autoderef.cc
@@ -113,7 +113,7 @@ Adjuster::try_unsize_type (TyTy::BaseType *ty)
   auto slice
 = new TyTy::SliceType (mappings.get_next_hir_id (), ty->get_ident ().locus,
   TyTy::TyVar (slice_elem->get_ref ()));
-  context->insert_implicit_type (slice);
+  context->insert_implicit_type (slice->get_ref (), slice);
 
   return Adjustment (Adjustment::AdjustmentType::UNSIZE, ty, slice);
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 860975301a0..4b78ef32c9b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1576,7 +1576,7 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
   TyTy::TupleType *closure_args
 = new TyTy::TupleType (implicit_args_id, expr.get_locus (),
   parameter_types);
-  context->insert_implicit_type (closure_args);
+  context->insert_implicit_type (closure_args->get_ref (), closure_args);
 
   location_t result_type_locus = expr.has_return_type ()
   ? expr.get_return_type ().get_locus ()
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index ac43eaafacf..a00fa7dbd89 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -653,7 +653,8 @@ ClosureParamInfer::Resolve (HIR::Pattern &pattern)
 
   if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
 {
-  resolver.context->insert_implicit_type (resolver.infered);
+  resolver.context->insert_implicit_type (resolver.infered->get_ref (),
+ resolver.infered);
   resolver.mappings.insert_location (resolver.infered->get_ref (),
 pattern.get_locus ());
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index d8742939d95..18a65fec048 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -171,7 +171,6 @@ public:
 
   void insert_type (const Analysis::NodeMapping &mappings,
TyTy::BaseType *type);
-  void insert_implicit_type (TyTy::BaseType *type);
   bool lookup_type (HirId id, TyTy::BaseType **type) const;
   void clear_type (TyTy::BaseType *ty);
 
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index f6ef2688aaa..f02e4846731 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -90,13 +90,6 @@ TypeCheckContext::insert_type (const Analysis::NodeMapping 
&mappings,
   resolved[id] = type;
 }
 
-void
-TypeCheckContext::insert_implicit_type (TyTy::BaseType *type)
-{
-  rust_assert (type != nullptr);
-  resolved[type->get_ref ()] = type;
-}
-
 void
 TypeCheckContext::insert_implicit_type (HirId id, TyTy::BaseType *type)
 {
-- 
2.45.2



[COMMITTED 118/141] gccrs: Add enum variant string information to definition

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

New enum variant status now appears in the string representation of
the resolver's definition.

gcc/rust/ChangeLog:

* resolve/rust-rib.cc (Rib::Definition::to_string): Add enum variant
status.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-rib.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/resolve/rust-rib.cc b/gcc/rust/resolve/rust-rib.cc
index 1d53a741858..690bde91139 100644
--- a/gcc/rust/resolve/rust-rib.cc
+++ b/gcc/rust/resolve/rust-rib.cc
@@ -76,6 +76,8 @@ Rib::Definition::to_string () const
}
 }
   out << "]";
+  if (enum_variant)
+out << "(enum variant)";
   return out.str ();
 }
 
-- 
2.45.2



[COMMITTED 071/141] gccrs: add variant_count intrinsic

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Addresses Rust-GCC#3348

gcc/rust/ChangeLog:

* backend/rust-compile-intrinsic.cc (variant_count_handler): new 
intrinsic

gcc/testsuite/ChangeLog:

* rust/execute/torture/enum_intrinsics2.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-intrinsic.cc| 56 ++-
 .../rust/execute/torture/enum_intrinsics2.rs  | 25 +
 2 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs

diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index 1f93e82a93a..28c69d50b46 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -90,6 +90,8 @@ static tree
 assume_handler (Context *ctx, TyTy::FnType *fntype);
 static tree
 discriminant_value_handler (Context *ctx, TyTy::FnType *fntype);
+static tree
+variant_count_handler (Context *ctx, TyTy::FnType *fntype);
 
 enum class Prefetch
 {
@@ -252,7 +254,8 @@ static const std::mapget_num_type_params () == 1);
+  auto &mapping = fntype->get_substs ().at (0);
+  auto param_ty = mapping.get_param_ty ();
+  rust_assert (param_ty->can_resolve ());
+  auto resolved = param_ty->resolve ();
+
+  size_t variant_count = 0;
+  bool is_adt = resolved->is ();
+  if (is_adt)
+{
+  const auto &adt = *static_cast (resolved);
+  variant_count = adt.number_of_variants ();
+}
+
+  tree lookup = NULL_TREE;
+  if (check_for_cached_intrinsic (ctx, fntype, &lookup))
+return lookup;
+
+  auto fndecl = compile_intrinsic_function (ctx, fntype);
+
+  std::vector param_vars;
+  compile_fn_params (ctx, fntype, fndecl, ¶m_vars);
+
+  if (!Backend::function_set_parameters (fndecl, param_vars))
+return error_mark_node;
+
+  enter_intrinsic_block (ctx, fndecl);
+
+  // BUILTIN disriminant_value FN BODY BEGIN
+  tree result_decl = DECL_RESULT (fndecl);
+  tree type = TREE_TYPE (result_decl);
+
+  mpz_t ival;
+  mpz_init_set_ui (ival, variant_count);
+  tree result = wide_int_to_tree (type, wi::from_mpz (type, ival, true));
+  mpz_clear (ival);
+
+  auto return_statement
+= Backend::return_statement (fndecl, result, BUILTINS_LOCATION);
+  ctx->add_statement (return_statement);
+
+  // BUILTIN disriminant_value FN BODY END
+
+  finalize_intrinsic_block (ctx, fndecl);
+
+  return fndecl;
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs 
b/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs
new file mode 100644
index 000..c1bae35deb2
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/enum_intrinsics2.rs
@@ -0,0 +1,25 @@
+#![feature(intrinsics)]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+enum BookFormat {
+Paperback,
+Hardback,
+Ebook,
+}
+
+mod core {
+mod intrinsics {
+extern "rust-intrinsic" {
+#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
+pub fn variant_count() -> usize;
+}
+}
+}
+
+pub fn main() -> i32 {
+let count = core::intrinsics::variant_count::();
+
+(count as i32) - 3
+}
-- 
2.45.2



[COMMITTED 119/141] gccrs: Remove nr2 exhaustiveness test from exclusion list

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove test.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/nr2/exclude | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e179dc30004..11350099e74 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -36,7 +36,6 @@ use_1.rs
 v0-mangle1.rs
 v0-mangle2.rs
 while_break_expr.rs
-exhaustiveness2.rs
 issue-3139-2.rs
 issue-3033.rs
 issue-2953-2.rs
-- 
2.45.2



[COMMITTED 107/141] gccrs: nr2.0: Handle lang item type path segments

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Stop when hitting a lang
item segment.
(ForeverStack::resolve_segments): Resolve lang item segments.
(ForeverStacl::resolve_path): Handle single segment lang item
paths and add comment.
* util/rust-unwrap-segment.cc
(unwrap_segment_get_lang_item): Add.
* util/rust-unwrap-segment.h
(unwrap_segment_get_lang_item): Add.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 27 +
 gcc/rust/util/rust-unwrap-segment.cc| 20 ++
 gcc/rust/util/rust-unwrap-segment.h | 19 +
 gcc/testsuite/rust/compile/nr2/exclude  |  5 -
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 8abe8a61acb..9ca8db2c09d 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -384,6 +384,10 @@ ForeverStack::find_starting_point (
   for (; !is_last (iterator, segments); iterator++)
 {
   auto &outer_seg = *iterator;
+
+  if (unwrap_segment_get_lang_item (outer_seg).has_value ())
+   break;
+
   auto &seg = unwrap_type_segment (outer_seg);
   auto is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
@@ -452,6 +456,17 @@ ForeverStack::resolve_segments (
   for (; !is_last (iterator, segments); iterator++)
 {
   auto &outer_seg = *iterator;
+
+  if (auto lang_item = unwrap_segment_get_lang_item (outer_seg))
+   {
+ NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+   lang_item.value ());
+ current_node = &dfs_node (root, seg_id).value ();
+
+ insert_segment_resolution (outer_seg, seg_id);
+ continue;
+   }
+
   auto &seg = unwrap_type_segment (outer_seg);
   auto str = seg.as_string ();
   rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());
@@ -538,6 +553,17 @@ ForeverStack::resolve_path (
   // if there's only one segment, we just use `get`
   if (segments.size () == 1)
 {
+  auto &seg = segments.front ();
+  if (auto lang_item = unwrap_segment_get_lang_item (seg))
+   {
+ NodeId seg_id = Analysis::Mappings::get ().get_lang_item_node (
+   lang_item.value ());
+
+ insert_segment_resolution (seg, seg_id);
+ // TODO: does NonShadowable matter?
+ return Rib::Definition::NonShadowable (seg_id);
+   }
+
   auto res = get (unwrap_type_segment (segments.back ()).as_string ());
   if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
@@ -558,6 +584,7 @@ ForeverStack::resolve_path (
   // leave resolution within impl blocks to type checker
   if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;
+  // assuming this can't be a lang item segment
   auto res = final_node.rib.get (
unwrap_type_segment (segments.back ()).as_string ());
   if (res && !res->is_ambiguous ())
diff --git a/gcc/rust/util/rust-unwrap-segment.cc 
b/gcc/rust/util/rust-unwrap-segment.cc
index 38ff273fc06..083a0e54c91 100644
--- a/gcc/rust/util/rust-unwrap-segment.cc
+++ b/gcc/rust/util/rust-unwrap-segment.cc
@@ -38,4 +38,24 @@ unwrap_segment_node_id (const AST::PathExprSegment &seg)
   return seg.get_node_id ();
 }
 
+tl::optional
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg)
+{
+  if (seg.is_lang_item ())
+return seg.get_lang_item ();
+  return tl::nullopt;
+}
+
+tl::optional
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg)
+{
+  return tl::nullopt;
+}
+
+tl::optional
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg)
+{
+  return tl::nullopt;
+}
+
 } // namespace Rust
diff --git a/gcc/rust/util/rust-unwrap-segment.h 
b/gcc/rust/util/rust-unwrap-segment.h
index 4a3838a407a..bebdc3aadd4 100644
--- a/gcc/rust/util/rust-unwrap-segment.h
+++ b/gcc/rust/util/rust-unwrap-segment.h
@@ -99,4 +99,23 @@ unwrap_segment_node_id (const std::unique_ptr &ptr)
   return unwrap_segment_node_id (*ptr);
 }
 
+/**
+ * Used to check if a path segment is associated with a lang item
+ */
+tl::optional
+unwrap_segment_get_lang_item (const AST::TypePathSegment &seg);
+
+tl::optional
+unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg);
+
+tl::optional
+unwrap_segment_get_lang_item (const AST::PathExprSegment &seg);
+
+template 
+tl::optional
+unwrap_segment_get_lang_item (const std::unique_ptr &ptr)
+{
+  return unwrap_segment_get_lang_item (*ptr);
+}
+
 } // namespace Rust
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index f74c2ac6c66..6dba0f71705 100644
--- a/gcc/testsuite/ru

[COMMITTED 137/141] gccrs: nr2.0: Adjust visitors for struct expressions

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Make sure to always visit the struct
name.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Avoid visiting the struct name twice.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-visitor.cc  |  2 ++
 .../resolve/rust-late-name-resolver-2.0.cc| 20 ---
 gcc/testsuite/rust/compile/nr2/exclude|  5 -
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 077b41b5cac..ba5f87bc2eb 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -392,6 +392,7 @@ DefaultASTVisitor::visit (AST::StructExprStructFields &expr)
 {
   visit_outer_attrs (expr);
   visit_inner_attrs (expr);
+  visit (expr.get_struct_name ());
   if (expr.has_struct_base ())
 visit (expr.get_struct_base ());
   for (auto &field : expr.get_fields ())
@@ -403,6 +404,7 @@ DefaultASTVisitor::visit (AST::StructExprStructBase &expr)
 {
   visit_outer_attrs (expr);
   visit_inner_attrs (expr);
+  visit (expr.get_struct_name ());
   visit (expr.get_struct_base ());
 }
 
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index f4ad53a02ad..a8eb3b4fa12 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -351,6 +351,10 @@ Late::visit (AST::StructStruct &s)
 void
 Late::visit (AST::StructExprStruct &s)
 {
+  visit_outer_attrs (s);
+  visit_inner_attrs (s);
+  DefaultResolver::visit (s.get_struct_name ());
+
   auto resolved
 = ctx.resolve_path (s.get_struct_name ().get_segments (), 
Namespace::Types);
 
@@ -361,24 +365,34 @@ Late::visit (AST::StructExprStruct &s)
 void
 Late::visit (AST::StructExprStructBase &s)
 {
+  visit_outer_attrs (s);
+  visit_inner_attrs (s);
+  DefaultResolver::visit (s.get_struct_name ());
+  visit (s.get_struct_base ());
+
   auto resolved
 = ctx.resolve_path (s.get_struct_name ().get_segments (), 
Namespace::Types);
 
   ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
 Definition (resolved->get_node_id ()));
-  DefaultResolver::visit (s);
 }
 
 void
 Late::visit (AST::StructExprStructFields &s)
 {
+  visit_outer_attrs (s);
+  visit_inner_attrs (s);
+  DefaultResolver::visit (s.get_struct_name ());
+  if (s.has_struct_base ())
+visit (s.get_struct_base ());
+  for (auto &field : s.get_fields ())
+visit (field);
+
   auto resolved
 = ctx.resolve_path (s.get_struct_name ().get_segments (), 
Namespace::Types);
 
   ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
 Definition (resolved->get_node_id ()));
-
-  DefaultResolver::visit (s);
 }
 
 // needed because Late::visit (AST::GenericArg &) is non-virtual
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 0252028fb8f..6b8cf9801c5 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -32,7 +32,6 @@ struct-expr-parse.rs
 undeclared_label.rs
 use_1.rs
 while_break_expr.rs
-issue-3139-2.rs
 issue-2905-2.rs
 issue-266.rs
 derive_clone_enum3.rs
@@ -57,8 +56,4 @@ torture/name_resolve1.rs
 torture/nested_struct1.rs
 torture/struct_init_3.rs
 torture/uninit-intrinsic-1.rs
-torture/generics1.rs
-torture/generics10.rs
-torture/generics13.rs
-torture/generics6.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 024/141] gccrs: ast: Add Path::is_lang_item()

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-path.h: New function.
---
 gcc/rust/ast/rust-path.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 2a76acc48c3..c2537034b61 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -622,6 +622,8 @@ public:
 
   std::string as_string () const override;
 
+  bool is_lang_item () const { return kind == Kind::LangItem; }
+
   // TODO: this seems kinda dodgy
   std::vector &get_segments ()
   {
-- 
2.45.2



[COMMITTED 048/141] gccrs: derive(Clone, Copy): Cleanup using new method from DeriveVisitor

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc: Cleanup using 
DeriveVisitor::setup_impl_generics.
* expand/rust-derive-copy.cc: Likewise.
---
 gcc/rust/expand/rust-derive-clone.cc | 87 ++--
 gcc/rust/expand/rust-derive-copy.cc  | 87 ++--
 2 files changed, 11 insertions(+), 163 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 18f7723ddc2..b1b39668f51 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -94,89 +94,14 @@ DeriveClone::clone_impl (
 {
   auto clone = builder.type_path (LangItem::Kind::CLONE);
 
-  auto trait_items = std::vector> ();
-  trait_items.emplace_back (std::move (clone_fn));
-
-  // We need to build up the generics for this impl block which will be just a
-  // clone of the generics specified, with added `Clone` bounds
-  //
-  // For example with:
-  //
-  // #[derive(Clone)]
-  // struct Be { ... }
-  //
-  // We need to generate the following impl block:
-  //
-  // impl Clone for Be
-
-  std::vector lifetime_args;
-  std::vector generic_args;
-  std::vector> impl_generics;
-  for (const auto &generic : type_generics)
-{
-  switch (generic->get_kind ())
-   {
- case GenericParam::Kind::Lifetime: {
-   LifetimeParam &lifetime_param = (LifetimeParam &) *generic.get ();
-
-   Lifetime l = builder.new_lifetime (lifetime_param.get_lifetime ());
-   lifetime_args.push_back (std::move (l));
-
-   auto impl_lifetime_param
- = builder.new_lifetime_param (lifetime_param);
-   impl_generics.push_back (std::move (impl_lifetime_param));
- }
- break;
-
- case GenericParam::Kind::Type: {
-   TypeParam &type_param = (TypeParam &) *generic.get ();
-
-   std::unique_ptr associated_type = builder.single_type_path (
- type_param.get_type_representation ().as_string ());
-
-   GenericArg type_arg
- = GenericArg::create_type (std::move (associated_type));
-   generic_args.push_back (std::move (type_arg));
+  auto trait_items = vec (std::move (clone_fn));
 
-   std::vector> extra_bounds;
-   extra_bounds.emplace_back (std::unique_ptr (
- new TraitBound (builder.type_path (LangItem::Kind::CLONE), loc)));
-
-   auto impl_type_param
- = builder.new_type_param (type_param, std::move (extra_bounds));
-   impl_generics.push_back (std::move (impl_type_param));
- }
- break;
-
- case GenericParam::Kind::Const: {
-   rust_unreachable ();
-
-   // TODO
-   // const ConstGenericParam *const_param
-   //   = (const ConstGenericParam *) generic.get ();
-   // std::unique_ptr const_expr = nullptr;
-
-   // GenericArg type_arg
-   //   = GenericArg::create_const (std::move (const_expr));
-   // generic_args.push_back (std::move (type_arg));
- }
- break;
-   }
-}
+  auto generics
+= setup_impl_generics (name, type_generics, builder.trait_bound (clone));
 
-  GenericArgs generic_args_for_self (lifetime_args, generic_args,
-{} /*binding args*/, loc);
-  std::unique_ptr self_type_path
-= impl_generics.empty ()
-   ? builder.single_type_path (name)
-   : builder.single_generic_type_path (name, generic_args_for_self);
-
-  return std::unique_ptr (
-new TraitImpl (clone, /* unsafe */ false,
-  /* exclam */ false, std::move (trait_items),
-  std::move (impl_generics), std::move (self_type_path),
-  WhereClause::create_empty (), Visibility::create_private (),
-  {}, {}, loc));
+  return builder.trait_impl (clone, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
 }
 
 // TODO: Create new `make_qualified_call` helper function
diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
index 1d5f72bd656..e91a3508bde 100644
--- a/gcc/rust/expand/rust-derive-copy.cc
+++ b/gcc/rust/expand/rust-derive-copy.cc
@@ -17,9 +17,7 @@
 // .
 
 #include "rust-derive-copy.h"
-#include "rust-ast-full.h"
 #include "rust-hir-map.h"
-#include "rust-mapping-common.h"
 #include "rust-path.h"
 
 namespace Rust {
@@ -46,86 +44,11 @@ DeriveCopy::copy_impl (
 {
   auto copy = builder.type_path (LangItem::Kind::COPY);
 
-  // we need to build up the generics for this impl block which will be just a
-  // clone of the types specified ones
-  //
-  // for example:
-  //
-  // #[derive(Copy)]
-  // struct Be { ... }
-  //
-  // we need to generate the impl block:
-  //
-  // impl Clone for Be
-
-  std::vector lifetime_args;
-  std::vector generic_args;
-  std::vector> impl_generics;
-  for

[COMMITTED 021/141] gccrs: hir: Add LangItem paths to PathPattern class

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* hir/tree/rust-hir-path.h: Adapt PathPattern to accept lang-item paths.
* hir/tree/rust-hir-path.cc: Assert we are dealing with a segmented 
path, create lang-item
constructors.
* hir/tree/rust-hir.cc (PathPattern::convert_to_simple_path): Likewise.
---
 gcc/rust/hir/tree/rust-hir-path.cc | 20 +++
 gcc/rust/hir/tree/rust-hir-path.h  | 86 +++---
 gcc/rust/hir/tree/rust-hir.cc  |  6 +++
 3 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/hir/tree/rust-hir-path.cc 
b/gcc/rust/hir/tree/rust-hir-path.cc
index 7db2b25b5aa..ee4a57294db 100644
--- a/gcc/rust/hir/tree/rust-hir-path.cc
+++ b/gcc/rust/hir/tree/rust-hir-path.cc
@@ -133,6 +133,8 @@ PathExprSegment::operator= (PathExprSegment const &other)
 void
 PathPattern::iterate_path_segments (std::function cb)
 {
+  rust_assert (kind == Kind::Segmented);
+
   for (auto it = segments.begin (); it != segments.end (); it++)
 {
   if (!cb (*it))
@@ -150,6 +152,15 @@ PathInExpression::PathInExpression (Analysis::NodeMapping 
mappings,
 has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
 {}
 
+PathInExpression::PathInExpression (Analysis::NodeMapping mappings,
+   LangItem::Kind lang_item, location_t locus,
+   bool has_opening_scope_resolution,
+   std::vector outer_attrs)
+  : PathPattern (lang_item),
+PathExpr (std::move (mappings), std::move (outer_attrs)),
+has_opening_scope_resolution (has_opening_scope_resolution), locus (locus)
+{}
+
 bool
 PathInExpression::is_self () const
 
@@ -358,6 +369,15 @@ QualifiedPathInExpression::QualifiedPathInExpression (
 path_type (std::move (qual_path_type)), locus (locus)
 {}
 
+QualifiedPathInExpression::QualifiedPathInExpression (
+  Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
+  LangItem::Kind lang_item, location_t locus,
+  std::vector outer_attrs)
+  : PathPattern (lang_item),
+PathExpr (std::move (mappings), std::move (outer_attrs)),
+path_type (std::move (qual_path_type)), locus (locus)
+{}
+
 QualifiedPathInType::QualifiedPathInType (
   Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
   std::unique_ptr associated_segment,
diff --git a/gcc/rust/hir/tree/rust-hir-path.h 
b/gcc/rust/hir/tree/rust-hir-path.h
index bbb9c2d6077..c46f81e981c 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -19,6 +19,7 @@
 #ifndef RUST_HIR_PATH_H
 #define RUST_HIR_PATH_H
 
+#include "rust-hir-map.h"
 #include "rust-hir-simple-path.h"
 #include "rust-hir-type-no-bounds.h"
 #include "rust-hir-pattern-abstract.h"
@@ -230,15 +231,34 @@ public:
 // HIR node representing a pattern that involves a "path" - abstract base class
 class PathPattern : public Pattern
 {
+public:
+  enum class Kind
+  {
+Segmented,
+LangItem
+  };
+
+private:
   std::vector segments;
+  tl::optional lang_item;
+  Kind kind;
 
 protected:
   PathPattern (std::vector segments)
-: segments (std::move (segments))
+: segments (std::move (segments)), lang_item (tl::nullopt),
+  kind (Kind::Segmented)
+  {}
+
+  PathPattern (LangItem::Kind lang_item)
+: segments ({}), lang_item (lang_item), kind (Kind::LangItem)
   {}
 
   // Returns whether path has segments.
-  bool has_segments () const { return !segments.empty (); }
+  bool has_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return !segments.empty ();
+  }
 
   /* Converts path segments to their equivalent SimplePath segments if 
possible,
* and creates a SimplePath from them. */
@@ -248,26 +268,61 @@ protected:
 public:
   /* Returns whether the path is a single segment (excluding qualified path
* initial as segment). */
-  bool is_single_segment () const { return segments.size () == 1; }
+  bool is_single_segment () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.size () == 1;
+  }
 
   std::string as_string () const override;
 
   void iterate_path_segments (std::function cb);
 
-  size_t get_num_segments () const { return segments.size (); }
+  size_t get_num_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.size ();
+  }
 
-  std::vector &get_segments () { return segments; }
+  std::vector &get_segments ()
+  {
+rust_assert (kind == Kind::Segmented);
+return segments;
+  }
 
-  const std::vector &get_segments () const { return segments; 
}
+  const std::vector &get_segments () const
+  {
+rust_assert (kind == Kind::Segmented);
+return segments;
+  }
 
-  PathExprSegment &get_root_seg () { return segments.at (0); }
+  PathExprSegment &get_root_seg ()
+  {
+rust_assert (kind == Kind::Segmented);
+return segments.at (0);
+  }
+
+  const PathExprSegment &get_final_segment () const
+  {
+rust_assert (kind == Kind::Segmented)

[COMMITTED 043/141] gccrs: lang-items: Add structural_{peq, teq}

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

These lang items are used when deriving Eq and PartialEq, and will be checked 
when compiling pattern matching.

gcc/rust/ChangeLog:

* util/rust-lang-item.cc: New items.
* util/rust-lang-item.h: Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/structural-eq-peq.rs: New test.
---
 gcc/rust/util/rust-lang-item.cc | 3 +++
 gcc/rust/util/rust-lang-item.h  | 3 +++
 gcc/testsuite/rust/compile/structural-eq-peq.rs | 9 +
 3 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/structural-eq-peq.rs

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 145054ff9d7..92a76613b61 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -112,6 +112,9 @@ const BiMap 
Rust::LangItem::lang_items = {{
   {"from_ok", Kind::TRY_FROM_OK},
 
   {"from", Kind::FROM_FROM},
+
+  {"structural_peq", Kind::STRUCTURAL_PEQ},
+  {"structural_teq", Kind::STRUCTURAL_TEQ},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index f30b93609b5..29b972702bd 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -144,6 +144,9 @@ public:
 
 // NOTE: This is not a lang item in later versions of Rust
 FROM_FROM,
+
+STRUCTURAL_PEQ,
+STRUCTURAL_TEQ,
   };
 
   static const BiMap lang_items;
diff --git a/gcc/testsuite/rust/compile/structural-eq-peq.rs 
b/gcc/testsuite/rust/compile/structural-eq-peq.rs
new file mode 100644
index 000..d04c295037f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/structural-eq-peq.rs
@@ -0,0 +1,9 @@
+#[lang = "structural_peq"]
+pub trait StructuralPartialEq {
+// Empty.
+}
+
+#[lang = "structural_teq"]
+pub trait StructuralEq {
+// Empty.
+}
-- 
2.45.2



[COMMITTED 032/141] gccrs: Make foreverstack debug string const

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Those function should not change anything within the foreverstack, it
can therefore be made const.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h: Make debug functions const.
* resolve/rust-forever-stack.hxx: Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.h   | 6 +++---
 gcc/rust/resolve/rust-forever-stack.hxx | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 66e12668f71..661478bab9b 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -670,7 +670,7 @@ public:
   tl::optional to_rib (NodeId rib_id);
   tl::optional to_rib (NodeId rib_id) const;
 
-  std::string as_debug_string ();
+  std::string as_debug_string () const;
 
   /**
* Used to check if a module is a descendant of another module
@@ -752,9 +752,9 @@ private:
   std::reference_wrapper cursor_reference;
 
   void stream_rib (std::stringstream &stream, const Rib &rib,
-  const std::string &next, const std::string &next_next);
+  const std::string &next, const std::string &next_next) const;
   void stream_node (std::stringstream &stream, unsigned indentation,
-   const Node &node);
+   const Node &node) const;
 
   /* Helper types and functions for `resolve_path` */
 
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index d3d78894671..1c83f6bda61 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -699,7 +699,7 @@ template 
 void
 ForeverStack::stream_rib (std::stringstream &stream, const Rib &rib,
 const std::string &next,
-const std::string &next_next)
+const std::string &next_next) const
 {
   if (rib.get_values ().empty ())
 {
@@ -718,7 +718,7 @@ ForeverStack::stream_rib (std::stringstream &stream, 
const Rib &rib,
 template 
 void
 ForeverStack::stream_node (std::stringstream &stream, unsigned indentation,
- const ForeverStack::Node &node)
+ const ForeverStack::Node &node) const
 {
   auto indent = std::string (indentation, ' ');
   auto next = std::string (indentation + 4, ' ');
@@ -750,7 +750,7 @@ ForeverStack::stream_node (std::stringstream &stream, 
unsigned indentation,
 
 template 
 std::string
-ForeverStack::as_debug_string ()
+ForeverStack::as_debug_string () const
 {
   std::stringstream stream;
 
-- 
2.45.2



[COMMITTED 050/141] gccrs: ast: builder: Add Return expression builder

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Declare it.
* ast/rust-ast-builder.cc (Builder::return_expr): Define it.
---
 gcc/rust/ast/rust-ast-builder.cc | 7 +++
 gcc/rust/ast/rust-ast-builder.h  | 4 
 2 files changed, 11 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 3a3181f3752..aef0e110ce0 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -276,6 +276,13 @@ Builder::block (std::vector> &&stmts,
   LoopLabel::error (), loc, loc));
 }
 
+std::unique_ptr
+Builder::return_expr (std::unique_ptr &&to_return)
+{
+  return std::unique_ptr (
+new ReturnExpr (std::move (to_return), {}, loc));
+}
+
 std::unique_ptr
 Builder::let (std::unique_ptr pattern, std::unique_ptr type,
  std::unique_ptr init) const
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 9c5c1645eb9..90a878791df 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -89,6 +89,10 @@ public:
   std::unique_ptr &&tail_expr
   = nullptr) const;
 
+  /* Create an early return expression with an optional expression */
+  std::unique_ptr return_expr (std::unique_ptr &&to_return
+= nullptr);
+
   /* Create a let binding with an optional type and initializer (`let  :
*  = `) */
   std::unique_ptr let (std::unique_ptr pattern,
-- 
2.45.2



[COMMITTED 112/141] gccrs: Reduce usage of rust-session-manager.h

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* util/rust-edition.cc: New file.
* util/rust-edition.h: New file.
* Make-lang.in: Add rust-edition.o to the object list.

* ast/rust-pattern.cc: Remove inclusion of
rust-session-manager.h.
* expand/rust-macro-expand.cc: Likewise.
* expand/rust-macro-builtins-helpers.h: Likewise.

* expand/rust-macro-builtins-include.cc: Include
rust-session-manager.h.
* expand/rust-macro-builtins-utility.cc: Likewise.

* lex/rust-lex.cc: Include rust-edition.h instead of
rust-session-manager.h.
(Lexer::classify_keyword): Use get_rust_edition instead of
Session and CompileOptions.

* parse/rust-parse-impl.h: Include rust-edition.h instead of
rust-session-manager.h.
(Parser::parse_async_item): Use get_rust_edition instead of
Session and CompileOptions.

* checks/errors/rust-feature.h: Include rust-edition.h instead
of rust-session-manager.h.
(class Feature): Use Rust::Edition instead of
Rust::CompileOptions::Edition.

Signed-off-by: Owen Avery 
---
 gcc/rust/Make-lang.in |  1 +
 gcc/rust/ast/rust-pattern.cc  |  1 -
 gcc/rust/checks/errors/rust-feature.h |  6 +--
 gcc/rust/expand/rust-macro-builtins-helpers.h |  1 -
 .../expand/rust-macro-builtins-include.cc |  1 +
 .../expand/rust-macro-builtins-utility.cc |  1 +
 gcc/rust/expand/rust-macro-expand.cc  |  1 -
 gcc/rust/lex/rust-lex.cc  |  6 +--
 gcc/rust/parse/rust-parse-impl.h  |  5 +--
 gcc/rust/util/rust-edition.cc | 40 ++
 gcc/rust/util/rust-edition.h  | 41 +++
 11 files changed, 91 insertions(+), 13 deletions(-)
 create mode 100644 gcc/rust/util/rust-edition.cc
 create mode 100644 gcc/rust/util/rust-edition.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 749c1123e05..4028b47fa87 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -235,6 +235,7 @@ GRS_OBJS = \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
 rust/rust-unwrap-segment.o \
+rust/rust-edition.o \
rust/rust-expand-format-args.o \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index 98fd8e52f5f..fc7b6107be0 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -22,7 +22,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "rust-diagnostics.h"
 #include "rust-ast-visitor.h"
 #include "rust-macro.h"
-#include "rust-session-manager.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
 #include "rust-operators.h"
diff --git a/gcc/rust/checks/errors/rust-feature.h 
b/gcc/rust/checks/errors/rust-feature.h
index e2082c5efa5..9edae6d62c3 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/rust-feature.h
@@ -19,7 +19,7 @@
 #ifndef RUST_FEATURE_H
 #define RUST_FEATURE_H
 
-#include "rust-session-manager.h"
+#include "rust-edition.h"
 #include "optional.h"
 
 namespace Rust {
@@ -66,7 +66,7 @@ private:
   Feature (Name name, State state, const char *name_str,
   const char *rustc_since,
   tl::optional issue_number = tl::nullopt,
-  const tl::optional &edition = tl::nullopt,
+  const tl::optional &edition = tl::nullopt,
   const char *description = "")
 : m_state (state), m_name (name), m_name_str (name_str),
   m_rustc_since (rustc_since), m_issue (issue_number), edition (edition),
@@ -78,7 +78,7 @@ private:
   std::string m_name_str;
   std::string m_rustc_since;
   tl::optional m_issue;
-  tl::optional edition;
+  tl::optional edition;
   std::string m_description; // TODO: Switch to optional?
 
   static const std::map name_hash_map;
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h 
b/gcc/rust/expand/rust-macro-builtins-helpers.h
index ee5cae76764..429537e210a 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.h
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.h
@@ -29,7 +29,6 @@
 #include "rust-macro-invoc-lexer.h"
 #include "rust-macro.h"
 #include "rust-parse.h"
-#include "rust-session-manager.h"
 #include "rust-system.h"
 #include "rust-token.h"
 namespace Rust {
diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc 
b/gcc/rust/expand/rust-macro-builtins-include.cc
index 4719b0e268e..2ab2a3a1dbb 100644
--- a/gcc/rust/expand/rust-macro-builtins-include.cc
+++ b/gcc/rust/expand/rust-macro-builtins-include.cc
@@ -20,6 +20,7 @@
 #include "rust-common.h"
 #include "rust-macro-builtins.h"
 #include "rust-macro-builtins-helpers.h"
+#include "rust-session-manager.h"
 #include "optional.h"
 namespace Rust {
 /* Expand builtin macro include_bytes!("filename"), which includes the contents
diff --git a/gcc/rust/expand/rust-macro-builtins-utility.cc 
b/gcc/rust/expand/ru

[COMMITTED 062/141] gccrs: Add warning about default visitor usage

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

We already lost some time on this unusual pattern, a comment will
hopefully prevent this from happening again.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Add
warning about current code.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 4c6664f104b..305286970c7 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -110,6 +110,8 @@ TopLevel::visit (AST::InherentImpl &impl)
 insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
 impl.get_type (), Namespace::Types);
 
+// We do want to visit with the default visitor instead of default resolver
+// because we don't want to insert the scope twice.
 AST::DefaultASTVisitor::visit (impl);
   };
 
@@ -123,6 +125,8 @@ TopLevel::visit (AST::TraitImpl &impl)
 insert_or_error_out (Identifier ("Self", impl.get_type ().get_locus ()),
 impl.get_type (), Namespace::Types);
 
+// We do want to visit using the default visitor instead of default 
resolver
+// because we don't want to insert the scope twice.
 AST::DefaultASTVisitor::visit (impl);
   };
 
-- 
2.45.2



[COMMITTED 039/146] gccrs: Fix FnParam pattern location ternary logic

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Condition was inverted, we should retrieve the locus only if we have a
pattern.

gcc/rust/ChangeLog:

* typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Do not
get a reference if the pattern does not exist.
(TypeCheckMethodCallExpr::check): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/typecheck/rust-tyty-call.cc | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty-call.cc 
b/gcc/rust/typecheck/rust-tyty-call.cc
index 725b8414671..5fea34de40a 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -152,12 +152,11 @@ TypeCheckCallExpr::visit (FnType &type)
   if (i < type.num_params ())
{
  auto &fnparam = type.param_at (i);
- auto &fn_param_pattern = fnparam.get_pattern ();
  BaseType *param_ty = fnparam.get_type ();
  location_t param_locus
= fnparam.has_pattern ()
-   ? mappings.lookup_location (param_ty->get_ref ())
-   : fn_param_pattern.get_locus ();
+   ? fnparam.get_pattern ().get_locus ()
+   : mappings.lookup_location (param_ty->get_ref ());
 
  HirId coercion_side_id = argument->get_mappings ().get_hirid ();
  auto resolved_argument_type
@@ -375,12 +374,11 @@ TypeCheckMethodCallExpr::check (FnType &type)
   location_t arg_locus = argument.get_locus ();
 
   auto &fnparam = type.param_at (i);
-  HIR::Pattern &fn_param_pattern = fnparam.get_pattern ();
   BaseType *param_ty = fnparam.get_type ();
   location_t param_locus
= fnparam.has_pattern ()
-   ? mappings.lookup_location (param_ty->get_ref ())
-   : fn_param_pattern.get_locus ();
+   ? fnparam.get_pattern ().get_locus ()
+   : mappings.lookup_location (param_ty->get_ref ());
 
   auto argument_expr_tyty = argument.get_argument_type ();
   HirId coercion_side_id = argument.get_mappings ().get_hirid ();
-- 
2.45.2



[COMMITTED 139/141] gccrs: nr2.0: Adjust indentifier expression handling

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Make sure to return early after a resolution
error, improve the resolution error message, fix a typo, handle
ambiguous resolutions, and remove an old comment.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 26 ---
 gcc/testsuite/rust/compile/nr2/exclude|  3 ---
 2 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index a8eb3b4fa12..09aa5fc44e6 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -232,21 +232,29 @@ Late::visit (AST::IdentifierExpr &expr)
 }
   else
 {
-  if (auto typ = ctx.types.get_prelude (expr.get_ident ()))
-   resolved = typ;
+  if (auto type = ctx.types.get_prelude (expr.get_ident ()))
+   {
+ resolved = type;
+   }
   else
-   rust_error_at (expr.get_locus (),
-  "could not resolve identifier expression: %qs",
-  expr.get_ident ().as_string ().c_str ());
+   {
+ rust_error_at (expr.get_locus (), ErrorCode::E0425,
+"cannot find value %qs in this scope",
+expr.get_ident ().as_string ().c_str ());
+ return;
+   }
+}
+
+  if (resolved->is_ambiguous ())
+{
+  rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
+expr.as_string ().c_str ());
+  return;
 }
 
   ctx.map_usage (Usage (expr.get_node_id ()),
 Definition (resolved->get_node_id ()));
 
-  // in the old resolver, resolutions are kept in the resolver, not the 
mappings
-  // :/ how do we deal with that?
-  // ctx.mappings.insert_resolved_name(expr, resolved);
-
   // For empty types, do we perform a lookup in ctx.types or should the
   // toplevel instead insert a name in ctx.values? (like it currently does)
 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index de5824813b4..59964fc90e2 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,8 +1,6 @@
-break-rust2.rs
 canonical_paths1.rs
 cfg1.rs
 const_generics_3.rs
-const_generics_4.rs
 feature_rust_attri0.rs
 generics9.rs
 issue-1901.rs
@@ -19,7 +17,6 @@ macros/mbe/macro43.rs
 macros/mbe/macro6.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
-not_find_value_in_scope.rs
 privacy5.rs
 privacy8.rs
 pub_restricted_1.rs
-- 
2.45.2



[COMMITTED 133/141] gccrs: Fix modules with same name as builtins causing ICE (#3315)

2025-03-24 Thread arthur . cohen
From: Liam Naddell 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h (ForeverStack): Add a dedicated prelude 
node for
the Language prelude
* resolve/rust-forever-stack.hxx (ForeverStack): Add support code for 
the
prelude node
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Move
language prelude builtins to the prelude context
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::scoped): Add code for handling
the prelude corner case
* resolve/rust-rib.h (Rib::Kind): Add a special Prelude rib type

gcc/testsuite/ChangeLog:

* rust/compile/issue-3315-1.rs: Add test for module with same name
as builtin
* rust/compile/issue-3315-2.rs: Test with utilization of i32
type
* rust/compile/nr2/exclude: issue-3315-2.rs Does not work with
NR2.0

Signed-off-by: Liam Naddell 
---
 gcc/rust/resolve/rust-forever-stack.h | 12 +++
 gcc/rust/resolve/rust-forever-stack.hxx   | 82 ---
 .../resolve/rust-late-name-resolver-2.0.cc| 33 
 .../resolve/rust-name-resolution-context.cc   |  4 +
 gcc/rust/resolve/rust-rib.h   |  5 ++
 gcc/testsuite/rust/compile/issue-3315-1.rs|  8 ++
 gcc/testsuite/rust/compile/issue-3315-2.rs|  7 ++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 8 files changed, 127 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3315-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3315-2.rs

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 22efc973197..2a4c7348728 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -548,6 +548,7 @@ template  class ForeverStack
 public:
   ForeverStack ()
 : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)),
+  prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)),
   cursor_reference (root)
   {
 rust_assert (root.is_root ());
@@ -657,6 +658,8 @@ public:
* the current map, an empty one otherwise.
*/
   tl::optional get (const Identifier &name);
+  tl::optional get_prelude (const Identifier &name);
+  tl::optional get_prelude (const std::string &name);
 
   /**
* Resolve a path to its definition in the current `ForeverStack`
@@ -721,6 +724,7 @@ private:
 {}
 
 bool is_root () const;
+bool is_prelude () const;
 bool is_leaf () const;
 
 void insert_child (Link link, Node child);
@@ -756,7 +760,15 @@ private:
   const Node &cursor () const;
   void update_cursor (Node &new_cursor);
 
+  /* The forever stack's actual nodes */
   Node root;
+  /*
+   * A special prelude node used currently for resolving language builtins
+   * It has the root node as a parent, and acts as a "special case" for name
+   * resolution
+   */
+  Node prelude;
+
   std::reference_wrapper cursor_reference;
 
   void stream_rib (std::stringstream &stream, const Rib &rib,
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 90e0ceb9f81..a6e0b30a57b 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -34,6 +34,13 @@ ForeverStack::Node::is_root () const
   return !parent.has_value ();
 }
 
+template 
+bool
+ForeverStack::Node::is_prelude () const
+{
+  return rib.kind == Rib::Kind::Prelude;
+}
+
 template 
 bool
 ForeverStack::Node::is_leaf () const
@@ -63,6 +70,16 @@ template 
 void
 ForeverStack::push_inner (Rib rib, Link link)
 {
+  if (rib.kind == Rib::Kind::Prelude)
+{
+  // If you push_inner into the prelude from outside the root, you will pop
+  // back into the root, which could screw up a traversal.
+  rust_assert (&cursor_reference.get () == &root);
+  // Prelude doesn't have an access path
+  rust_assert (!link.path);
+  update_cursor (this->prelude);
+  return;
+}
   // If the link does not exist, we create it and emplace a new `Node` with the
   // current node as its parent. `unordered_map::emplace` returns a pair with
   // the iterator and a boolean. If the value already exists, the iterator
@@ -300,6 +317,20 @@ ForeverStack::get (const Identifier &name)
   return resolved_definition;
 }
 
+template 
+tl::optional
+ForeverStack::get_prelude (const Identifier &name)
+{
+  return prelude.rib.get (name.as_string ());
+}
+
+template 
+tl::optional
+ForeverStack::get_prelude (const std::string &name)
+{
+  return prelude.rib.get (name);
+}
+
 template <>
 tl::optional inline ForeverStack::get (
   const Identifier &name)
@@ -399,7 +430,7 @@ ForeverStack::find_starting_point (
break;
 
   auto &seg = unwrap_type_segment (outer_seg);
-  auto is_self_or_crate
+  bool is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
 
   // if we're after the first path segment and meet `self` or `crate`, it's
@@ -457,7

[COMMITTED 126/141] gccrs: Remove tests from exclusion list

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove issue-1786 and issue-3033 from
exclusion list.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/nr2/exclude | 2 --
 1 file changed, 2 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 11350099e74..e8e99da5801 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -6,7 +6,6 @@ const_generics_4.rs
 feature_rust_attri0.rs
 generics9.rs
 issue-1483.rs
-issue-1786.rs
 issue-1901.rs
 issue-1981.rs
 issue-2043.rs
@@ -37,7 +36,6 @@ v0-mangle1.rs
 v0-mangle2.rs
 while_break_expr.rs
 issue-3139-2.rs
-issue-3033.rs
 issue-2953-2.rs
 issue-2905-2.rs
 issue-266.rs
-- 
2.45.2



[COMMITTED 120/141] gccrs: Add a test for enum variant name resolution

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Highlight the fact that a value inside an enum definition refers to
a struct outside of the enum and not to the enum variant's name
directly.

gcc/testsuite/ChangeLog:

* rust/compile/enum_variant_name.rs: New test.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/enum_variant_name.rs | 12 
 1 file changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/enum_variant_name.rs

diff --git a/gcc/testsuite/rust/compile/enum_variant_name.rs 
b/gcc/testsuite/rust/compile/enum_variant_name.rs
new file mode 100644
index 000..671fced2bb8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/enum_variant_name.rs
@@ -0,0 +1,12 @@
+// { dg-additional-options "-w -frust-name-resolution-2.0" }
+struct E1;
+
+enum Test {
+E1 = {
+let x = E1;
+{
+let x = E1;
+}
+0
+},
+}
-- 
2.45.2



[COMMITTED 125/141] gccrs: Move import mapping resolution to in tree visit

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Import mapping was relying on resolve_path which in turn relies on
the cursor function. This means the mapping resolver should be called
from the correct scope instead of being called from the crate scope.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::Early): Move the
top level visitor from the function scope to attributes.
(Early::go): Remove top level visitor creation and adapt calling code.
Remove call to mapping resolution and import finalization.
(Early::finalize_simple_import): Move the finalization from it's
visitor.
(Early::finalize_glob_import): Likewise.
(Early::finalize_rebind_import): Likewise.
(Early::visit): Add mapping resolution and finalization in
UseDeclaration visitor function.
* resolve/rust-finalize-imports-2.0.cc (finalize_simple_import): Move
function.
(finalize_glob_import): Likewise.
(finalize_rebind_import): Likewise.
(FinalizeImports::visit): Remove call to finalizers.
* resolve/rust-early-name-resolver-2.0.h (class Early): Add top level
attribute.
* resolve/rust-finalize-imports-2.0.h: Add function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.h: Change getter return type
to reference.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 98 +--
 .../resolve/rust-early-name-resolver-2.0.h|  9 ++
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 79 +--
 gcc/rust/resolve/rust-finalize-imports-2.0.h  |  4 +-
 .../resolve/rust-toplevel-name-resolver-2.0.h |  5 +-
 5 files changed, 105 insertions(+), 90 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index b894d130ccf..492a665f43e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -27,7 +27,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty 
(false)
+Early::Early (NameResolutionContext &ctx)
+  : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
 {}
 
 void
@@ -52,16 +53,10 @@ void
 Early::go (AST::Crate &crate)
 {
   // First we go through TopLevel resolution to get all our declared items
-  auto toplevel = TopLevel (ctx);
   toplevel.go (crate);
 
   // We start with resolving the list of imports that `TopLevel` has built for
   // us
-  for (auto &&import : toplevel.get_imports_to_resolve ())
-build_import_mapping (std::move (import));
-
-  // Once this is done, we finalize their resolution
-  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   dirty = toplevel.is_dirty ();
   // We now proceed with resolving macros, which can be nested in almost any
@@ -375,5 +370,94 @@ Early::visit (AST::StructStruct &s)
   DefaultResolver::visit (s);
 }
 
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+  // FIXME: We probably need to store namespace information
+
+  auto locus = mapping.import_kind.to_resolve.get_locus ();
+  auto data = mapping.data;
+  auto identifier
+= mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+  for (auto &&definition : data.definitions ())
+toplevel
+  .insert_or_error_out (
+   identifier, locus, definition.first.get_node_id (), definition.second 
/* TODO: This isn't clear - it would be better if it was called .ns or 
something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+const Early::ImportPair &mapping)
+{
+  auto module = Analysis::Mappings::get ().lookup_ast_module (
+mapping.data.module ().get_node_id ());
+  rust_assert (module);
+
+  GlobbingVisitor glob_visitor (ctx);
+  glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (const Early::ImportPair &mapping)
+{
+  // We can fetch the value here as `resolve_rebind` will only be called on
+  // imports of the right kind
+  auto &path = mapping.import_kind.to_resolve;
+  auto &rebind = mapping.import_kind.rebind.value ();
+  auto data = mapping.data;
+
+  location_t locus = UNKNOWN_LOCATION;
+  std::string declared_name;
+
+  // FIXME: This needs to be done in `FinalizeImports`
+  switch (rebind.get_new_bind_type ())
+{
+case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+  declared_name = rebind.get_identifier ().as_string ();
+  locus = rebind.get_identifier ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::NONE:
+  declared_name = path.get_final_segment ().as_string ();
+  locus = path.get_final_segment ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::WILDCARD:
+  rust_unreachable ();
+  break;
+}
+
+  for (auto &&definition : data.definitions ())
+toplevel.insert_or_er

[COMMITTED 127/141] gccrs: Remove finalize import visitor

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

This visitor is not used anymore.

gcc/rust/ChangeLog:

* resolve/rust-finalize-imports-2.0.cc 
(FinalizeImports::FinalizeImports):
Remove constructor.
(FinalizeImports::go): Remove function.
(FinalizeImports::visit): Likewise.
* resolve/rust-finalize-imports-2.0.h (class FinalizeImports): Remove
FinalizeImports class.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 18 --
 gcc/rust/resolve/rust-finalize-imports-2.0.h  | 57 ---
 2 files changed, 75 deletions(-)

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index bd6002a09f4..b0e86512ac2 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -125,23 +125,5 @@ GlobbingVisitor::visit (AST::UseDeclaration &use)
   // Handle cycles ?
 }
 
-FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
- TopLevel &toplevel,
- NameResolutionContext &ctx)
-  : DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
-ctx (ctx)
-{}
-
-void
-FinalizeImports::go (AST::Crate &crate)
-{
-  for (auto &item : crate.items)
-item->accept_vis (*this);
-}
-
-void
-FinalizeImports::visit (AST::UseDeclaration &use)
-{}
-
 } // namespace Resolver2_0
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index a06fe538846..d587a5e5c46 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -49,62 +49,5 @@ private:
   NameResolutionContext &ctx;
 };
 
-// TODO: Fix documentation
-// How do we do that?
-//
-// We want to resolve in the EarlyNameResolver, but we want to declare in the
-// TopLevel Should the TopLevel declare stubs? How does rustc do it? How to do
-// that for globbing? Should we do globbing afterwards once we've declared all
-// the Uses*?
-//
-// Basically, for each use declare it in a separate map - in the
-// EarlyNameResolver resolve and fix the ForeverStack? Emptying the maps each
-// time?
-//
-// e.g. TopLevel builds a std::vector use_trees_to_resolve;
-// Early goes through and resolves the SimplePath, then replaces the NodeId 
with
-// the resolved one? Do we even need to do that?
-//
-// rustc just creates an empty definition for the use tree.
-//
-// What about globbing? std::vector globules;
-// Early goes through and visits the module's path and calls the
-// GlobbingVisitor?
-//
-// the file `imports.rs` goes through and *finalizes* imports. So we can
-// probably add a FinalizeImport pass after the TopLevel and the Early.
-// - TopLevel takes care of declaring these use trees
-// - Early takes care of resolving them to definition points
-// - Finalize takes care of mapping the use's definition point to the actual
-// definition point
-// - We need to work more on that last bit to know exactly what is being
-// inserted, but probably it's going to mutate the ForeverStack - is that okay?
-// - Oh actually maybe no!
-// - TopLevel creates a map of UseTrees with paths to resolve. This should
-// probably be an ImportKind enum or whatever
-// - Early resolves them, creates a map of SimplePath with the associated
-// definition: Map
-// - Finalizes visits all UseTrees and inserts the Definitions found for
-// each ImportKind - easy!
-// - yay!
-
-class FinalizeImports : DefaultResolver
-{
-public:
-  FinalizeImports (Early::ImportMappings &&data, TopLevel &toplevel,
-  NameResolutionContext &ctx);
-
-  void go (AST::Crate &crate);
-
-  void visit (AST::UseDeclaration &) override;
-
-private:
-  using AST::DefaultASTVisitor::visit;
-
-  Early::ImportMappings data;
-  TopLevel &toplevel;
-  NameResolutionContext &ctx;
-};
-
 } // namespace Resolver2_0
 } // namespace Rust
-- 
2.45.2



[COMMITTED 096/141] gccrs: Fix expansion of macros inside modules

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* expand/rust-expand-visitor.cc
(ExpandVisitor::visit): Override DefaultASTVisitor in order to
expand a module's items, rather than directly visit them.
* expand/rust-expand-visitor.h
(ExpandVisitor::visit): Add override.

gcc/testsuite/ChangeLog:

* rust/compile/macros/mbe/macro-expand-module.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/expand/rust-expand-visitor.cc|  6 ++
 gcc/rust/expand/rust-expand-visitor.h |  1 +
 .../rust/compile/macros/mbe/macro-expand-module.rs| 11 +++
 3 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 8ba9a15fddf..2830d200f72 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -721,6 +721,12 @@ ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
 visit (bound);
 }
 
+void
+ExpandVisitor::visit (AST::Module &module)
+{
+  expand_inner_items (module.get_items ());
+}
+
 void
 ExpandVisitor::visit (AST::ExternCrate &crate)
 {}
diff --git a/gcc/rust/expand/rust-expand-visitor.h 
b/gcc/rust/expand/rust-expand-visitor.h
index 5fc1011e001..ad237c07c2f 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -237,6 +237,7 @@ public:
   void visit (AST::TypeParam ¶m) override;
   void visit (AST::LifetimeWhereClauseItem &) override;
   void visit (AST::TypeBoundWhereClauseItem &item) override;
+  void visit (AST::Module &module) override;
   void visit (AST::ExternCrate &crate) override;
   void visit (AST::UseTreeGlob &) override;
   void visit (AST::UseTreeList &) override;
diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs 
b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
new file mode 100644
index 000..e3e702eac84
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macros/mbe/macro-expand-module.rs
@@ -0,0 +1,11 @@
+mod foo {
+macro_rules! bar {
+() => ()
+}
+
+bar! ();
+
+pub struct S;
+}
+
+pub fn buzz(_: foo::S) {}
-- 
2.45.2



[COMMITTED 064/141] gccrs: nr2.0: Resolve instances of TypePath more accurately

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* util/rust-unwrap-segment.cc: New file.
* util/rust-unwrap-segment.h: New file.
* Make-lang.in: Add rust-unwrap-segment.o to the object list.
* resolve/rust-forever-stack.hxx: Include rust-unwrap-segment.h.
(ForeverStack::find_starting_point): Use unwrap_type_segment.
(ForeverStack::resolve_segments): Likewise.
(ForeverStack::resolve_path): Likewise.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Resolve type paths using
NameResolutionContext::resolve_path.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::resolve_path): Use
unwrap_segment_node_id.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/resolve/rust-forever-stack.hxx   |  20 ++--
 .../resolve/rust-late-name-resolver-2.0.cc|  31 ++
 .../resolve/rust-name-resolution-context.h|   6 +-
 gcc/rust/util/rust-unwrap-segment.cc  |  41 +++
 gcc/rust/util/rust-unwrap-segment.h   | 102 ++
 gcc/testsuite/rust/compile/nr2/exclude|   5 -
 7 files changed, 170 insertions(+), 36 deletions(-)
 create mode 100644 gcc/rust/util/rust-unwrap-segment.cc
 create mode 100644 gcc/rust/util/rust-unwrap-segment.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 24054531d9e..dc03a72ec78 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -231,6 +231,7 @@ GRS_OBJS = \
 rust/rust-dir-owner.o \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
+rust/rust-unwrap-segment.o \
rust/rust-expand-format-args.o \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index f5f0b15c00b..b51da51948f 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -21,6 +21,7 @@
 #include "rust-diagnostics.h"
 #include "rust-forever-stack.h"
 #include "rust-rib.h"
+#include "rust-unwrap-segment.h"
 #include "optional.h"
 
 namespace Rust {
@@ -389,7 +390,8 @@ ForeverStack::find_starting_point (
 
   for (; !is_last (iterator, segments); iterator++)
 {
-  auto &seg = *iterator;
+  auto &outer_seg = *iterator;
+  auto &seg = unwrap_type_segment (outer_seg);
   auto is_self_or_crate
= seg.is_crate_path_seg () || seg.is_lower_self_seg ();
 
@@ -407,14 +409,14 @@ ForeverStack::find_starting_point (
  NodeId current_crate
= *mappings.crate_num_to_nodeid (mappings.get_current_crate ());
 
- insert_segment_resolution (seg, current_crate);
+ insert_segment_resolution (outer_seg, current_crate);
  iterator++;
  break;
}
   if (seg.is_lower_self_seg ())
{
  // insert segment resolution and exit
- insert_segment_resolution (seg, starting_point.get ().id);
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
  iterator++;
  break;
}
@@ -430,7 +432,7 @@ ForeverStack::find_starting_point (
  starting_point
= find_closest_module (starting_point.get ().parent.value ());
 
- insert_segment_resolution (seg, starting_point.get ().id);
+ insert_segment_resolution (outer_seg, starting_point.get ().id);
  continue;
}
 
@@ -454,7 +456,8 @@ ForeverStack::resolve_segments (
   auto *current_node = &starting_point;
   for (; !is_last (iterator, segments); iterator++)
 {
-  auto &seg = *iterator;
+  auto &outer_seg = *iterator;
+  auto &seg = unwrap_type_segment (outer_seg);
   auto str = seg.as_string ();
   rust_debug ("[ARTHUR]: resolving segment part: %s", str.c_str ());
 
@@ -490,7 +493,7 @@ ForeverStack::resolve_segments (
}
 
   current_node = &child.value ();
-  insert_segment_resolution (seg, current_node->id);
+  insert_segment_resolution (outer_seg, current_node->id);
 }
 
   return *current_node;
@@ -508,7 +511,7 @@ ForeverStack::resolve_path (
   // if there's only one segment, we just use `get`
   if (segments.size () == 1)
 {
-  auto res = get (segments.back ().as_string ());
+  auto res = get (unwrap_type_segment (segments.back ()).as_string ());
   if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
   return res;
@@ -528,7 +531,8 @@ ForeverStack::resolve_path (
   // leave resolution within impl blocks to type checker
   if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;
-  auto res = final_node.rib.get (segments.back ().as_string ());
+  auto res = final_node.rib.get (
+   unwrap_type_segment (segments.back ()).as_string ());
   if (res && !res->is_ambiguous ())
   

[COMMITTED 100/141] gccrs: derive(Hash): Add implementation.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* Make-lang.in: Compile it.
* expand/rust-derive.cc (DeriveVisitor::derive): Call it.
* expand/rust-derive-hash.cc: New file.
* expand/rust-derive-hash.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/derive-hash1.rs: New test.
* rust/compile/nr2/exclude: Add testcase to exclusion list.
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/expand/rust-derive-hash.cc| 293 +
 gcc/rust/expand/rust-derive-hash.h |  61 +
 gcc/rust/expand/rust-derive.cc |  22 +-
 gcc/testsuite/rust/compile/derive-hash1.rs |  91 +++
 gcc/testsuite/rust/compile/nr2/exclude |   1 +
 6 files changed, 460 insertions(+), 9 deletions(-)
 create mode 100644 gcc/rust/expand/rust-derive-hash.cc
 create mode 100644 gcc/rust/expand/rust-derive-hash.h
 create mode 100644 gcc/testsuite/rust/compile/derive-hash1.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 5e13c6cfc3f..3e44b12c3d1 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -100,6 +100,7 @@ GRS_OBJS = \
 rust/rust-derive-default.o \
 rust/rust-derive-partial-eq.o \
 rust/rust-derive-eq.o \
+rust/rust-derive-hash.o \
 rust/rust-proc-macro.o \
 rust/rust-macro-invoc-lexer.o \
 rust/rust-proc-macro-invoc-lexer.o \
diff --git a/gcc/rust/expand/rust-derive-hash.cc 
b/gcc/rust/expand/rust-derive-hash.cc
new file mode 100644
index 000..0c9b0f7b105
--- /dev/null
+++ b/gcc/rust/expand/rust-derive-hash.cc
@@ -0,0 +1,293 @@
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-derive-hash.h"
+#include "rust-ast.h"
+#include "rust-expr.h"
+#include "rust-item.h"
+#include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-stmt.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace AST {
+
+DeriveHash::DeriveHash (location_t loc) : DeriveVisitor (loc) {}
+
+std::unique_ptr
+DeriveHash::go (Item &item)
+{
+  item.accept_vis (*this);
+
+  return std::move (expanded);
+}
+
+std::unique_ptr
+DeriveHash::hash_call (std::unique_ptr &&value)
+{
+  auto hash
+= builder.path_in_expression ({"core", "hash", "Hash", "hash"}, true);
+
+  return builder.call (ptrify (hash),
+  vec (std::move (value),
+   builder.identifier (DeriveHash::state)));
+}
+
+std::unique_ptr
+DeriveHash::hash_fn (std::unique_ptr &&block)
+{
+  auto hash_calls = std::vector> ();
+
+  auto state_type = std::unique_ptr (
+new TypePath (builder.type_path (DeriveHash::state_type)));
+  auto state_param =
+
+builder.function_param (builder.identifier_pattern (DeriveHash::state),
+   builder.reference_type (std::move (state_type),
+   true));
+
+  auto params = vec (builder.self_ref_param (), std::move (state_param));
+  auto bounds = vec (
+builder.trait_bound (builder.type_path ({"core", "hash", "Hasher"}, 
true)));
+  auto generics = vec (
+builder.generic_type_param (DeriveHash::state_type, std::move (bounds)));
+
+  return builder.function ("hash", std::move (params), nullptr,
+  std::move (block), std::move (generics));
+}
+
+std::unique_ptr
+DeriveHash::hash_impl (
+  std::unique_ptr &&hash_fn, std::string name,
+  const std::vector> &type_generics)
+{
+  auto hash_path = builder.type_path ({"core", "hash", "Hash"}, true);
+
+  auto trait_items = vec (std::move (hash_fn));
+
+  auto generics = setup_impl_generics (name, type_generics,
+  builder.trait_bound (hash_path));
+
+  return builder.trait_impl (hash_path, std::move (generics.self_type),
+std::move (trait_items),
+std::move (generics.impl));
+}
+
+void
+DeriveHash::visit_struct (StructStruct &item)
+{
+  auto hash_calls = std::vector> ();
+
+  for (auto &field : item.get_fields ())
+{
+  auto value = builder.ref (
+   builder.field_access (builder.identifier ("self"),
+ field.get_field_name ().as_string ()));
+
+  auto stmt = builder.statementify (hash_call (std::move (value)));
+
+  hash_calls.emplace_back (std::move (stmt));
+}
+
+  auto block = builder.

[COMMITTED 099/141] gccrs: derive(Debug): Use builder's ptrify function instead

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-debug.cc (ptrify): Remove function.
---
 gcc/rust/expand/rust-derive-debug.cc | 8 
 1 file changed, 8 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-debug.cc 
b/gcc/rust/expand/rust-derive-debug.cc
index f37547459a0..7ad3908483a 100644
--- a/gcc/rust/expand/rust-derive-debug.cc
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -38,14 +38,6 @@ DeriveDebug::go (Item &item)
   return std::move (expanded);
 }
 
-/* Pointer-ify something */
-template 
-static std::unique_ptr
-ptrify (T value)
-{
-  return std::unique_ptr (new T (value));
-}
-
 std::unique_ptr
 DeriveDebug::stub_debug_fn ()
 {
-- 
2.45.2



[COMMITTED 132/141] gccrs: nr2.0: Check compile/torture/*.rs tests

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/testsuite/ChangeLog:

* rust/compile/nr2/compile.exp: Adjust to cover tests in the
torture subdirectory.
* rust/compile/nr2/exclude: Add entries.

Signed-off-by: Owen Avery 
---
 gcc/testsuite/rust/compile/nr2/compile.exp |  6 ++
 gcc/testsuite/rust/compile/nr2/exclude | 17 +
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp 
b/gcc/testsuite/rust/compile/nr2/compile.exp
index f2724f6c454..35637f11ee8 100644
--- a/gcc/testsuite/rust/compile/nr2/compile.exp
+++ b/gcc/testsuite/rust/compile/nr2/compile.exp
@@ -14,9 +14,7 @@
 # along with GCC; see the file COPYING3.  If not see
 # .
 
-# Compile tests, no torture testing, for name resolution 2.0
-#
-# These tests raise errors in the front end; torture testing doesn't apply.
+# Run compile tests with name resolution 2.0 enabled
 
 # Load support procs.
 load_lib rust-dg.exp
@@ -44,7 +42,7 @@ namespace eval rust-nr2-ns {
 # Run tests in directories
 # Manually specifying these, in case some other test file
 # does something weird
-set test_dirs {{} {macros builtin} {macros mbe} {macros proc}}
+set test_dirs {{} {macros builtin} {macros mbe} {macros proc} {torture}}
 
 set tests_expect_ok ""
 set tests_expect_err ""
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 8aaec5d3b22..d36c24b95e3 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -50,4 +50,21 @@ for-loop2.rs
 issue-3403.rs
 derive-eq-invalid.rs
 derive-hash1.rs
+torture/alt_patterns1.rs
+torture/builtin_abort.rs
+torture/impl_block3.rs
+torture/issue-1434.rs
+torture/loop4.rs
+torture/loop8.rs
+torture/methods1.rs
+torture/methods2.rs
+torture/methods3.rs
+torture/name_resolve1.rs
+torture/nested_struct1.rs
+torture/struct_init_3.rs
+torture/uninit-intrinsic-1.rs
+torture/generics1.rs
+torture/generics10.rs
+torture/generics13.rs
+torture/generics6.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 129/141] gccrs: Insert crate name in canonical path

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Insert a new segment with the crate's
name as canonical's path prefix.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.hxx | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 628b8c5b6fe..59142a4094c 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -704,7 +704,12 @@ ForeverStack::to_canonical_path (NodeId id) const
   return KeepGoing::Yes;
 });
 
-auto path = Resolver::CanonicalPath::create_empty ();
+auto &mappings = Analysis::Mappings::get ();
+CrateNum crate_num = mappings.lookup_crate_num (root.id).value ();
+auto path = Resolver::CanonicalPath::new_seg (
+  root.id, mappings.get_crate_name (crate_num).value ());
+path.set_crate_num (crate_num);
+
 for (const auto &segment : segments)
   path = path.append (segment);
 
-- 
2.45.2



[COMMITTED 135/141] gccrs: nr2.0: Fix test self-path2.rs

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-path.cc
(ResolvePath::resolve_path): Adjust the error message for a lower
self segment in the middle of a path.
* resolve/rust-ast-resolve-type.cc
(ResolveRelativeTypePath::go): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove self-path2.rs
* rust/compile/self-path2.rs: Adjust expected errors.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-ast-resolve-path.cc | 14 +++---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  4 ++--
 gcc/testsuite/rust/compile/nr2/exclude|  1 -
 gcc/testsuite/rust/compile/self-path2.rs  |  4 ++--
 4 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc 
b/gcc/rust/resolve/rust-ast-resolve-path.cc
index 256159bc5cc..656b7e64bb7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 Free Software Foundation, Inc.
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -68,8 +68,8 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
   if (in_middle_of_path && segment.is_lower_self_seg ())
{
  rust_error_at (segment.get_locus (), ErrorCode::E0433,
-"failed to resolve: %qs in paths can only be used "
-"in start position",
+"leading path segment %qs can only be used at the "
+"beginning of a path",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -192,7 +192,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
  else
{
  rust_error_at (segment.get_locus (),
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -212,7 +212,7 @@ ResolvePath::resolve_path (AST::PathInExpression &expr)
   else if (is_first_segment)
{
  rust_error_at (segment.get_locus (), ErrorCode::E0433,
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -331,7 +331,7 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
  else
{
  rust_error_at (segment.get_locus (),
-"Cannot find path %qs in this scope",
+"Cannot find path %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
@@ -379,7 +379,7 @@ ResolvePath::resolve_path (AST::SimplePath &expr)
   if (resolved_node_id == UNKNOWN_NODEID)
{
  rust_error_at (segment.get_locus (),
-"cannot find simple path segment %qs in this scope",
+"cannot find simple path segment %<%s%> in this scope",
 segment.as_string ().c_str ());
  return UNKNOWN_NODEID;
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index af63898a5d2..87643d775ff 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -176,8 +176,8 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId 
&resolved_node_id)
  if (in_middle_of_path && segment->is_lower_self_seg ())
{
  rust_error_at (segment->get_locus (), ErrorCode::E0433,
-"failed to resolve: %qs in paths can only be used "
-"in start position",
+"leading path segment %qs can only be used at the "
+"beginning of a path",
 segment->as_string ().c_str ());
  return false;
}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index a4bac9ac836..a2a833f9073 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -28,7 +28,6 @@ pub_restricted_2.rs
 pub_restricted_3.rs
 redef_error2.rs
 redef_error5.rs
-self-path2.rs
 sizeof-stray-infer-var-bug.rs
 struct-expr-parse.rs
 undeclared_label.rs
diff --git a/gcc/testsuite/rust/compile/self-path2.rs 
b/gcc/testsuite/rust/compile/self-path2.rs
index b9b82cae5a6..6441c3328f9 100644
--- a/gcc/testsuite/rust/compile/self-path2.rs
+++ b/gcc/testsuite/rust/compile/self-path2.rs
@@ -11,11 +11,11 @@ fn baz() {
 crate::bar();
 
 crate::self::foo();
-// { dg-error "failed to resolve: .self. in p

[COMMITTED 013/141] gccrs: Add environment capture to NR2

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

The compiler was still relying on NR1 for closure captures when using nr2
even though the resolver was not used and thus it's state empty.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add environment
collection.
* resolve/rust-late-name-resolver-2.0.h: Add function prototype.
* resolve/rust-name-resolver.cc (Resolver::get_captures): Add assertion
to prevent NR2 usage with nr1 capture functions.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Use
nr2 captures.
* util/rust-hir-map.cc (Mappings::add_capture): Add function to
register capture for a given closure.
(Mappings::lookup_captures):  Add a function to lookup all captures
available for a given closure.
* util/rust-hir-map.h: Add function prototypes.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 13 
 .../resolve/rust-late-name-resolver-2.0.h |  2 ++
 gcc/rust/resolve/rust-name-resolver.cc|  2 ++
 .../typecheck/rust-hir-type-check-expr.cc | 20 ++-
 gcc/rust/util/rust-hir-map.cc | 20 +++
 gcc/rust/util/rust-hir-map.h  |  5 +
 6 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index e3d95e5dd7b..0779736809e 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -390,5 +390,18 @@ Late::visit (AST::GenericArg &arg)
   DefaultResolver::visit (arg);
 }
 
+void
+Late::visit (AST::ClosureExprInner &closure)
+{
+  auto vals = ctx.values.peek ().get_values ();
+  for (auto &val : vals)
+{
+  ctx.mappings.add_capture (closure.get_node_id (),
+   val.second.get_node_id ());
+}
+
+  DefaultResolver::visit (closure);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 95ad338417c..bf6d1935d3d 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -21,6 +21,7 @@
 
 #include "rust-ast-full.h"
 #include "rust-default-resolver.h"
+#include "rust-expr.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -55,6 +56,7 @@ public:
   void visit (AST::StructStruct &) override;
   void visit (AST::GenericArgs &) override;
   void visit (AST::GenericArg &);
+  void visit (AST::ClosureExprInner &) override;
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
diff --git a/gcc/rust/resolve/rust-name-resolver.cc 
b/gcc/rust/resolve/rust-name-resolver.cc
index 0f5b1084774..97ee2d37ded 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -674,6 +674,8 @@ Resolver::decl_needs_capture (NodeId decl_rib_node_id,
 const std::set &
 Resolver::get_captures (NodeId id) const
 {
+  rust_assert (!flag_name_resolution_2_0);
+
   auto it = closures_capture_mappings.find (id);
   rust_assert (it != closures_capture_mappings.end ());
   return it->second;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 113f43f6c72..23773f13836 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "rust-system.h"
 #include "rust-tyty-call.h"
 #include "rust-hir-type-check-struct-field.h"
 #include "rust-hir-path-probe.h"
@@ -1599,7 +1600,24 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
 
   // generate the closure type
   NodeId closure_node_id = expr.get_mappings ().get_nodeid ();
-  const std::set &captures = resolver->get_captures (closure_node_id);
+
+  // Resolve closure captures
+
+  std::set captures;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx = const_cast (
+   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+  if (auto opt_cap = nr_ctx.mappings.lookup_captures (closure_node_id))
+   for (auto cap : opt_cap.value ())
+ captures.insert (cap);
+}
+  else
+{
+  captures = resolver->get_captures (closure_node_id);
+}
+
   infered = new TyTy::ClosureType (ref, id, ident, closure_args, result_type,
   subst_refs, captures);
 
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index ac18e575765..39c3a98f16b 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1321,5 +1321,25 @@ Mappings::get_auto_traits ()
   return auto_traits;
 }
 
+void
+Mappings::add_capture (NodeId closure, NodeId definition)
+{
+  auto cap = captures.find (closure);
+  if (c

[COMMITTED 002/141] gccrs: typecheck: Add basic handling for applying auto trait bounds

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

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| 11 +++
 gcc/rust/typecheck/rust-tyty-bounds.cc |  4 +++
 gcc/rust/util/rust-hir-map.cc  | 12 
 gcc/rust/util/rust-hir-map.h   |  6 
 gcc/testsuite/rust/compile/auto_traits2.rs |  5 ++--
 gcc/testsuite/rust/compile/auto_traits3.rs | 34 --
 gcc/testsuite/rust/compile/auto_traits4.rs | 14 +
 gcc/testsuite/rust/compile/nr2/exclude |  3 +-
 8 files changed, 46 insertions(+), 43 deletions(-)
 delete mode 100644 gcc/testsuite/rust/compile/auto_traits3.rs
 create mode 100644 gcc/testsuite/rust/compile/auto_traits4.rs

diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index ae938d98658..5dbcad59dfb 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -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)
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 73d686b7814..3e42427e2ec 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -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
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index b94591e014c..ac18e575765 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -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 &
+Mappings::get_auto_traits ()
+{
+  return auto_traits;
+}
+
 } // namespace Analysis
 } // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 21e532812ff..8ea86466220 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -342,6 +342,9 @@ public:
   tl::optional
   lookup_trait_item_lang_item (LangItem::Kind item, location_t locus);
 
+  void insert_auto_trait (HIR::Trait *trait);
+  std::vector &get_auto_traits ();
+
 private:
   Mappings ();
 
@@ -380,6 +383,9 @@ private:
   std::map hirTraitItemsToTraitMappings;
   std::map hirPatternMappings;
 
+  // FIXME: Add documentation
+  std::vector 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 lang_item_mappings;
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs 
b/gcc/testsuite/rust/compile/auto_traits2.rs
index 7d0dcc11cd2..382d4460811 100644
--- a/gcc/testsuite/rust/compile/auto_traits2.rs
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -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
index 81c39ecda7f..000
--- a/gcc/testsuite/rust/compile/auto_traits3.r

[COMMITTED 004/141] gccrs: hir-dump: Improve handling of typepathsegments that are lang items.

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::do_typepathsegment): Add handling for 
lang items.
---
 gcc/rust/hir/rust-hir-dump.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 798179d172e..0bfcc97afe7 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -388,7 +388,10 @@ void
 Dump::do_typepathsegment (TypePathSegment &e)
 {
   do_mappings (e.get_mappings ());
-  put_field ("ident_segment", e.get_ident_segment ().as_string ());
+  if (e.is_lang_item ())
+put_field ("ident_segment", LangItem::PrettyString (e.get_lang_item ()));
+  else
+put_field ("ident_segment", e.get_ident_segment ().as_string ());
 }
 
 void
-- 
2.45.2



[COMMITTED 005/141] gccrs: ast-builder: Add extra parameter for TypeParam builder

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::new_type_param): Add optional extra 
trait bounds.
* ast/rust-ast-builder.h: Likewise.
---
 gcc/rust/ast/rust-ast-builder.cc | 6 +-
 gcc/rust/ast/rust-ast-builder.h  | 4 +++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 47044df9171..567e6c43509 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -361,7 +361,8 @@ Builder::new_lifetime_param (LifetimeParam ¶m)
 }
 
 std::unique_ptr
-Builder::new_type_param (TypeParam ¶m)
+Builder::new_type_param (
+  TypeParam ¶m, std::vector> extra_bounds)
 {
   location_t locus = param.get_locus ();
   AST::AttrVec outer_attrs = param.get_outer_attrs ();
@@ -372,6 +373,9 @@ Builder::new_type_param (TypeParam ¶m)
   if (param.has_type ())
 type = new_type (param.get_type ());
 
+  for (auto &&extra_bound : extra_bounds)
+type_param_bounds.emplace_back (std::move (extra_bound));
+
   for (const auto &b : param.get_type_param_bounds ())
 {
   switch (b->get_bound_type ())
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index e5bae6ed6e9..3b9990a4969 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -200,7 +200,9 @@ public:
   static std::unique_ptr
   new_lifetime_param (LifetimeParam ¶m);
 
-  static std::unique_ptr new_type_param (TypeParam ¶m);
+  static std::unique_ptr new_type_param (
+TypeParam ¶m,
+std::vector> extra_trait_bounds = {});
 
   static Lifetime new_lifetime (const Lifetime &lifetime);
 
-- 
2.45.2



[COMMITTED 006/141] gccrs: derive(Clone): Add Clone bound on generated impl blocks

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc: Add extra bound when deriving generic 
Clone
---
 gcc/rust/expand/rust-derive-clone.cc | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 7620abe4e13..0081eb4cdaa 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -97,15 +97,15 @@ DeriveClone::clone_impl (
   auto trait_items = std::vector> ();
   trait_items.emplace_back (std::move (clone_fn));
 
-  // we need to build up the generics for this impl block which will be just a
-  // clone of the types specified ones
+  // We need to build up the generics for this impl block which will be just a
+  // clone of the generics specified, with added `Clone` bounds
   //
-  // for example:
+  // For example with:
   //
   // #[derive(Clone)]
-  // struct Be { ... }
+  // struct Be { ... }
   //
-  // we need to generate the impl block:
+  // We need to generate the following impl block:
   //
   // impl Clone for Be
 
@@ -138,7 +138,12 @@ DeriveClone::clone_impl (
  = GenericArg::create_type (std::move (associated_type));
generic_args.push_back (std::move (type_arg));
 
-   auto impl_type_param = builder.new_type_param (type_param);
+   std::vector> extra_bounds;
+   extra_bounds.emplace_back (std::unique_ptr (
+ new TraitBound (builder.type_path (LangItem::Kind::CLONE), loc)));
+
+   auto impl_type_param
+ = builder.new_type_param (type_param, std::move (extra_bounds));
impl_generics.push_back (std::move (impl_type_param));
  }
  break;
-- 
2.45.2



[COMMITTED 014/141] gccrs: Add captures for ClosureExprInnerTyped with nr2

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

Captures were only processed for regular ClosureExprInner.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add
ClosureExprInnerTyped visit implementation.
(add_captures): Add a function to avoid code duplication.
* resolve/rust-late-name-resolver-2.0.h: Add function prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 17 +++--
 gcc/rust/resolve/rust-late-name-resolver-2.0.h  |  1 +
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 0779736809e..bc973a009f0 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -390,8 +390,9 @@ Late::visit (AST::GenericArg &arg)
   DefaultResolver::visit (arg);
 }
 
-void
-Late::visit (AST::ClosureExprInner &closure)
+template 
+static void
+add_captures (Closure &closure, NameResolutionContext &ctx)
 {
   auto vals = ctx.values.peek ().get_values ();
   for (auto &val : vals)
@@ -399,7 +400,19 @@ Late::visit (AST::ClosureExprInner &closure)
   ctx.mappings.add_capture (closure.get_node_id (),
val.second.get_node_id ());
 }
+}
 
+void
+Late::visit (AST::ClosureExprInner &closure)
+{
+  add_captures (closure, ctx);
+  DefaultResolver::visit (closure);
+}
+
+void
+Late::visit (AST::ClosureExprInnerTyped &closure)
+{
+  add_captures (closure, ctx);
   DefaultResolver::visit (closure);
 }
 
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index bf6d1935d3d..31303eb4fb2 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -57,6 +57,7 @@ public:
   void visit (AST::GenericArgs &) override;
   void visit (AST::GenericArg &);
   void visit (AST::ClosureExprInner &) override;
+  void visit (AST::ClosureExprInnerTyped &) override;
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
-- 
2.45.2



[COMMITTED 011/141] gccrs: backend: Allow anything as a match scrutinee

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (check_match_scrutinee): Allow anything 
to be used as a
match scrutinee, not just ADTs.
---
 gcc/rust/backend/rust-compile-expr.cc | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 353a498dc4e..887e476f234 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -31,6 +31,7 @@
 #include "convert.h"
 #include "print-tree.h"
 #include "rust-system.h"
+#include "rust-tyty.h"
 
 namespace Rust {
 namespace Compile {
@@ -1035,11 +1036,6 @@ check_match_scrutinee (HIR::MatchExpr &expr, Context 
*ctx)
 }
 
   TyTy::TypeKind scrutinee_kind = scrutinee_expr_tyty->get_kind ();
-  rust_assert ((TyTy::is_primitive_type_kind (scrutinee_kind)
-   && scrutinee_kind != TyTy::TypeKind::NEVER)
-  || scrutinee_kind == TyTy::TypeKind::ADT
-  || scrutinee_kind == TyTy::TypeKind::TUPLE
-  || scrutinee_kind == TyTy::TypeKind::REF);
 
   if (scrutinee_kind == TyTy::TypeKind::FLOAT)
 {
-- 
2.45.2



[COMMITTED 028/141] gccrs: Add unit struct to name namespace in old resolver

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

We missed the name namespace for unit struct in the old resolver.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-toplevel.h: Add struct to name namespace.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-ast-resolve-toplevel.h | 23 +---
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h 
b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 565ca922e84..6828e573618 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -242,14 +242,21 @@ public:
 auto path = prefix.append (decl);
 auto cpath = canonical_prefix.append (decl);
 
-resolver->get_type_scope ().insert (
-  path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
-  Rib::ItemType::Type,
-  [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
-   rich_location r (line_table, struct_decl.get_locus ());
-   r.add_range (locus);
-   rust_error_at (r, "redefined multiple times");
-  });
+auto duplicate_item
+  = [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+  rich_location r (line_table, struct_decl.get_locus ());
+  r.add_range (locus);
+  rust_error_at (r, "redefined multiple times");
+};
+
+resolver->get_type_scope ().insert (path, struct_decl.get_node_id (),
+   struct_decl.get_locus (), false,
+   Rib::ItemType::Type, duplicate_item);
+
+if (struct_decl.is_unit_struct ())
+  resolver->get_name_scope ().insert (path, struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ Rib::ItemType::Type, duplicate_item);
 
 NodeId current_module = resolver->peek_current_module_scope ();
 mappings.insert_module_child_item (current_module, decl);
-- 
2.45.2



[COMMITTED 059/141] gccrs: ast-builder: Add methods for QualifiedPathInExpressions

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::qualified_path_in_expression): New.
(Builder::function): Change the return type.
* ast/rust-ast-builder.h: Declare qualified_path_in_expression 
functions.
* expand/rust-derive-debug.cc (DeriveDebug::stub_debug_fn): Adapt to 
new APIs.
---
 gcc/rust/ast/rust-ast-builder.cc | 32 +++-
 gcc/rust/ast/rust-ast-builder.h  | 16 +++---
 gcc/rust/expand/rust-derive-debug.cc |  4 ++--
 3 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index aef0e110ce0..4c42b5bddae 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -64,6 +64,27 @@ Builder::array (std::vector> 
&&members) const
   return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc));
 }
 
+std::unique_ptr
+Builder::qualified_path_in_expression (std::unique_ptr &&type,
+  TypePath trait,
+  PathExprSegment segment) const
+{
+  auto segments = {segment};
+
+  return qualified_path_in_expression (std::move (type), trait, segments);
+}
+
+std::unique_ptr
+Builder::qualified_path_in_expression (
+  std::unique_ptr &&type, TypePath trait,
+  std::vector &&segments) const
+{
+  auto qual_type = QualifiedPathType (std::move (type), loc, trait);
+
+  return std::unique_ptr (
+new QualifiedPathInExpression (qual_type, std::move (segments), {}, loc));
+}
+
 std::unique_ptr
 Builder::identifier (std::string name) const
 {
@@ -111,17 +132,18 @@ Builder::fn_qualifiers () const
   return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
 }
 
-Function
-Builder::function (Identifier function_name,
+std::unique_ptr
+Builder::function (std::string function_name,
   std::vector> params,
   std::unique_ptr return_type,
   std::unique_ptr block,
   FunctionQualifiers qualifiers, WhereClause where_clause,
   Visibility visibility) const
 {
-  return Function (function_name, qualifiers, {}, std::move (params),
-  std::move (return_type), where_clause, std::move (block),
-  visibility, {}, loc);
+  return std::unique_ptr (
+new Function (function_name, qualifiers, {}, std::move (params),
+ std::move (return_type), where_clause, std::move (block),
+ visibility, {}, loc));
 }
 
 PathExprSegment
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 90a878791df..21da13f14c8 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -104,7 +104,8 @@ public:
* arguments (`path(arg0, arg1, arg2)`)
*/
   std::unique_ptr call (std::unique_ptr &&path,
- std::vector> &&args) const;
+ std::vector> &&args
+ = {}) const;
   std::unique_ptr call (std::unique_ptr &&path,
  std::unique_ptr &&arg) const;
 
@@ -114,6 +115,15 @@ public:
   std::unique_ptr
   array (std::vector> &&members) const;
 
+  /* Create a qualified path in expression (`::seg::expr`) */
+  std::unique_ptr
+  qualified_path_in_expression (std::unique_ptr &&type, TypePath trait,
+   PathExprSegment segment) const;
+  std::unique_ptr
+  qualified_path_in_expression (std::unique_ptr &&type, TypePath trait,
+   std::vector &&segments
+   = {}) const;
+
   /* Self parameter for a function definition (`&self`) */
   std::unique_ptr self_ref_param (bool mutability = false) const;
   /* A regular named function parameter for a definition (`a: type`) */
@@ -123,8 +133,8 @@ public:
   /* Empty function qualifiers, with no specific qualifiers */
   FunctionQualifiers fn_qualifiers () const;
 
-  Function
-  function (Identifier function_name,
+  std::unique_ptr
+  function (std::string function_name,
std::vector> params,
std::unique_ptr return_type, std::unique_ptr block,
FunctionQualifiers qualifiers
diff --git a/gcc/rust/expand/rust-derive-debug.cc 
b/gcc/rust/expand/rust-derive-debug.cc
index 910f27c67b2..f37547459a0 100644
--- a/gcc/rust/expand/rust-derive-debug.cc
+++ b/gcc/rust/expand/rust-derive-debug.cc
@@ -77,10 +77,10 @@ DeriveDebug::stub_debug_fn ()
 
   auto params = vec (std::move (self), std::move (fmt));
 
-  auto function = builder.function ({"fmt"}, std::move (params),
+  auto function = builder.function ("fmt", std::move (params),
std::move (return_type), std::move (block));
 
-  return ptrify (function);
+  return function;
 }
 
 std::unique_ptr
-- 
2.45.2



[COMMITTED 055/141] gccrs: coercion sites allow for type inference as well.

2025-03-24 Thread arthur . cohen
From: Philip Herron 

Addresses Rust-GCC#3382 and Rust-GCC#3381

gcc/rust/ChangeLog:

* typecheck/rust-type-util.cc (coercion_site): allow inference vars

gcc/testsuite/ChangeLog:

* rust/compile/reference1.rs: fix error message

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-type-util.cc | 6 --
 gcc/testsuite/rust/compile/reference1.rs | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/typecheck/rust-type-util.cc 
b/gcc/rust/typecheck/rust-type-util.cc
index b7587526431..7a39eb53710 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -217,8 +217,10 @@ coercion_site (HirId id, TyTy::TyWithLocation lhs, 
TyTy::TyWithLocation rhs,
   rust_debug ("coerce_default_unify(a={%s}, b={%s})",
  receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
   TyTy::BaseType *coerced
-= unify_site (id, lhs, TyTy::TyWithLocation (receiver, rhs.get_locus ()),
- locus);
+= unify_site_and (id, lhs,
+ TyTy::TyWithLocation (receiver, rhs.get_locus ()), locus,
+ true /*emit_error*/, true /*commit*/, true /*infer*/,
+ true /*cleanup*/);
   context->insert_autoderef_mappings (id, std::move (result.adjustments));
   return coerced;
 }
diff --git a/gcc/testsuite/rust/compile/reference1.rs 
b/gcc/testsuite/rust/compile/reference1.rs
index 2f94754bcb0..28f7a262cc1 100644
--- a/gcc/testsuite/rust/compile/reference1.rs
+++ b/gcc/testsuite/rust/compile/reference1.rs
@@ -2,5 +2,5 @@ fn main() {
 let a = &123;
 let b: &mut i32 = a;
 // { dg-error "mismatched mutability" "" { target *-*-* } .-1 }
-// { dg-error "mismatched types, expected .&mut i32. but got .& i32." "" { 
target *-*-* } .-2 }
+// { dg-error "mismatched types, expected .&mut i32. but got .& 
." "" { target *-*-* } .-2 }
 }
-- 
2.45.2



[COMMITTED 051/141] gccrs: nr2.0: Remove accidental copies of resolver

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc
(CompileExpr::generate_closure_function): Take
NameResolutionContext by reference instead of by value.
* backend/rust-compile-item.cc
(CompileItem::visit): Likewise.
* backend/rust-compile-resolve-path.cc
(ResolvePathRef::resolve): Likewise.
* checks/lints/rust-lint-marklive.cc
(MarkLive::find_ref_node_id): Likewise.
* typecheck/rust-hir-type-check-enumitem.cc
(TypeCheckEnumItem::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.cc
(TypeCheckImplItem::visit): Likewise.
* typecheck/rust-hir-type-check-item.cc
(TypeCheckItem::visit): Likewise.
* typecheck/rust-hir-type-check-path.cc
(TypeCheckExpr::resolve_root_path): Likewise.
* typecheck/rust-hir-type-check-type.cc
(TypeCheckType::resolve_root_path): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/backend/rust-compile-expr.cc  |  2 +-
 gcc/rust/backend/rust-compile-item.cc  |  6 +++---
 gcc/rust/backend/rust-compile-resolve-path.cc  |  2 +-
 gcc/rust/checks/lints/rust-lint-marklive.cc|  2 +-
 gcc/rust/typecheck/rust-hir-type-check-enumitem.cc |  8 
 gcc/rust/typecheck/rust-hir-type-check-implitem.cc |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 10 +-
 gcc/rust/typecheck/rust-hir-type-check-path.cc |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-type.cc |  4 ++--
 9 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 29cc8835c33..48713e7b8b4 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2453,7 +2453,7 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr 
&expr,
   auto body_mappings = function_body.get_mappings ();
   if (flag_name_resolution_2_0)
{
- auto nr_ctx
+ auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
  auto candidate = nr_ctx.values.to_rib (body_mappings.get_nodeid ());
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index 52cd59f94e4..39d4b9eb4fa 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -52,7 +52,7 @@ CompileItem::visit (HIR::StaticItem &var)
 
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   canonical_path
@@ -119,7 +119,7 @@ CompileItem::visit (HIR::ConstantItem &constant)
 
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   canonical_path
@@ -192,7 +192,7 @@ CompileItem::visit (HIR::Function &function)
 
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   auto path = nr_ctx.values.to_canonical_path (
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index 103f0cb6fe8..fbf9a3dab59 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -212,7 +212,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment 
&final_segment,
   NodeId ref_node_id = UNKNOWN_NODEID;
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   auto resolved = nr_ctx.lookup (mappings.get_nodeid ());
diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 6e2e2e4e447..af7535a9826 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -287,7 +287,7 @@ MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId 
&ref_node_id)
 {
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index 7fa4b43d187..c80a12f8f84 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -83,7 +83,7 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
 
   if (flag_name_resolution_2_0)
 {
-  auto nr_ctx
+  auto &nr_ctx
= Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
 
   canonical_path
@@ -127,7 +127,7 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
 
   if (flag_name_resolution_2_0)
 {
- 

[COMMITTED 033/141] gccrs: Resolved item type shall be differentiated later

2025-03-24 Thread arthur . cohen
From: Pierre-Emmanuel Patry 

We need to query all namespaces and error out at a later stage if the
retrieved item is wrong.

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc 
(TraitResolver::resolve_path_to_trait):
Query all namespaces.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 82019328e16..04af5abf837 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -127,8 +127,10 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath 
&path,
 }
   else
 {
-  ok = resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
-  &ref);
+  auto path_nodeid = path.get_mappings ().get_nodeid ();
+  ok = resolver->lookup_resolved_type (path_nodeid, &ref)
+  || resolver->lookup_resolved_name (path_nodeid, &ref)
+  || resolver->lookup_resolved_macro (path_nodeid, &ref);
 }
 
   if (!ok)
-- 
2.45.2



[COMMITTED 105/141] gccrs: name-resolution: early: Remove overzealous overrides

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

Some empty overrides were incorrectly being set-up instead of using the correct 
behavior
from DefaultASTVisitor.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver.cc: Remove definitions.
* resolve/rust-early-name-resolver.h: Remove declarations.
---
 gcc/rust/resolve/rust-early-name-resolver.cc | 24 
 gcc/rust/resolve/rust-early-name-resolver.h  |  7 +-
 2 files changed, 1 insertion(+), 30 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index 42a4a17090f..a8df631200c 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -560,30 +560,6 @@ EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
   pattern.get_items ().accept_vis (*this);
 }
 
-void
-EarlyNameResolver::visit (AST::TraitBound &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ImplTraitType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::TraitObjectType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ParenthesisedType &)
-{}
-
-void
-EarlyNameResolver::visit (AST::ImplTraitTypeOneBound &)
-{}
-
-void
-EarlyNameResolver::visit (AST::TraitObjectTypeOneBound &)
-{}
-
 void
 EarlyNameResolver::visit (AST::TupleType &)
 {}
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h 
b/gcc/rust/resolve/rust-early-name-resolver.h
index 48562df2bcd..26fc84d52dc 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -36,6 +36,7 @@ public:
 
 private:
   using AST::DefaultASTVisitor::visit;
+
   /**
* Execute a lambda within a scope. This is equivalent to calling
* `enter_scope` before your code and `exit_scope` after. This ensures
@@ -181,12 +182,6 @@ private:
   virtual void visit (AST::StructPatternFieldIdent &field);
   virtual void visit (AST::StructPattern &pattern);
   virtual void visit (AST::TupleStructPattern &pattern);
-  virtual void visit (AST::TraitBound &bound);
-  virtual void visit (AST::ImplTraitType &type);
-  virtual void visit (AST::TraitObjectType &type);
-  virtual void visit (AST::ParenthesisedType &type);
-  virtual void visit (AST::ImplTraitTypeOneBound &type);
-  virtual void visit (AST::TraitObjectTypeOneBound &type);
   virtual void visit (AST::TupleType &type);
   virtual void visit (AST::RawPointerType &type);
   virtual void visit (AST::ReferenceType &type);
-- 
2.45.2



[COMMITTED 077/141] gccrs: self paths are patterns but we dont have mappings for it

2025-03-24 Thread arthur . cohen
From: Philip Herron 

With simple patterns we dont introduce any more inference varaibles as
they are already declared in a specific way. This would only lead to
more unconstrained inference varaibles than is required.

Fixes Rust-GCC#3022

gcc/rust/ChangeLog:

* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): add 
location mappings
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path): check for self

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-ast-lower-base.cc|  1 +
 gcc/rust/typecheck/rust-hir-type-check-path.cc |  5 -
 gcc/testsuite/rust/compile/issue-3022.rs   | 18 ++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3022.rs

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index 35a25093b73..add02747b0a 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -666,6 +666,7 @@ ASTLoweringBase::lower_self (AST::Param ¶m)
   Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
 mappings.get_next_hir_id (crate_num),
 mappings.get_next_localdef_id (crate_num));
+  mappings.insert_location (mapping.get_hirid (), param.get_locus ());
 
   if (self.has_type ())
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index a5243631fbd..33570ffa1c7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -312,6 +312,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
   auto seg_is_module = mappings.lookup_module (ref).has_value ();
   auto seg_is_crate = mappings.is_local_hirid_crate (ref);
   auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
+  auto seg_is_self = is_root && !have_more_segments
+&& seg.get_segment ().as_string () == "self";
   if (seg_is_module || seg_is_crate)
{
  // A::B::C::this_is_a_module::D::E::F
@@ -388,7 +390,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
-  else if (lookup->needs_generic_substitutions () && !seg_is_pattern)
+  else if (lookup->needs_generic_substitutions () && !seg_is_pattern
+  && !seg_is_self)
{
  lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
}
diff --git a/gcc/testsuite/rust/compile/issue-3022.rs 
b/gcc/testsuite/rust/compile/issue-3022.rs
new file mode 100644
index 000..b8b8e6fd5c7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3022.rs
@@ -0,0 +1,18 @@
+#[lang = "sized"]
+trait Sized {}
+
+trait Foo {
+fn foo(self) -> T;
+}
+
+struct Bar {
+// { dg-warning "struct is never constructed" "" { target *-*-* } .-1 }
+value: U,
+valte: T,
+}
+
+impl, U> Foo for Bar {
+fn foo(self) -> U {
+self.value
+}
+}
-- 
2.45.2



[COMMITTED 103/141] gccrs: nr2.0: Implement macro_use for modules

2025-03-24 Thread arthur . cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc:
Include rust-attribute-values.h.
(Early::visit): If a module has a macro_use attribute, avoid
pushing a new textual macro scope.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove entries.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-early-name-resolver-2.0.cc| 18 --
 gcc/testsuite/rust/compile/nr2/exclude |  3 ---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index d1e7ee0c9f8..764be45e34c 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -22,6 +22,7 @@
 #include "rust-toplevel-name-resolver-2.0.h"
 #include "rust-attributes.h"
 #include "rust-finalize-imports-2.0.h"
+#include "rust-attribute-values.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -227,11 +228,24 @@ Early::visit (AST::BlockExpr &block)
 void
 Early::visit (AST::Module &module)
 {
-  textual_scope.push ();
+  bool is_macro_use = false;
+
+  for (const auto &attr : module.get_outer_attrs ())
+{
+  if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE)
+   {
+ is_macro_use = true;
+ break;
+   }
+}
+
+  if (!is_macro_use)
+textual_scope.push ();
 
   DefaultResolver::visit (module);
 
-  textual_scope.pop ();
+  if (!is_macro_use)
+textual_scope.pop ();
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6e17eca1c20..f74c2ac6c66 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -24,12 +24,9 @@ lookup_err1.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
 macros/mbe/macro6.rs
-macros/mbe/macro_use1.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
-nested_macro_use1.rs
 nested_macro_use2.rs
-nested_macro_use3.rs
 not_find_value_in_scope.rs
 privacy5.rs
 privacy8.rs
-- 
2.45.2



[COMMITTED 106/141] gccrs: expansion: Expand generic args in generic type path segments

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* expand/rust-expand-visitor.cc (ExpandVisitor::visit): Correctly visit 
the generic args
of a generic type path segment.

gcc/testsuite/ChangeLog:

* rust/compile/issue-2015.rs: New test.
---
 gcc/rust/expand/rust-expand-visitor.cc   |  4 +++-
 gcc/testsuite/rust/compile/issue-2015.rs | 19 +++
 2 files changed, 22 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2015.rs

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 1d131b18180..d4db3137565 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -488,7 +488,9 @@ ExpandVisitor::visit (AST::PathInExpression &path)
 
 void
 ExpandVisitor::visit (AST::TypePathSegmentGeneric &segment)
-{}
+{
+  expand_generic_args (segment.get_generic_args ());
+}
 
 void
 ExpandVisitor::visit (AST::TypePathSegmentFunction &segment)
diff --git a/gcc/testsuite/rust/compile/issue-2015.rs 
b/gcc/testsuite/rust/compile/issue-2015.rs
new file mode 100644
index 000..7789ecda376
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2015.rs
@@ -0,0 +1,19 @@
+// { dg-additional-options "-frust-compile-until=lowering" }
+
+macro_rules! impl_foo {
+   () => { impl Foo }
+}
+
+pub trait Foo {}
+
+pub trait Bar {
+type Baz;
+}
+
+pub fn foo(_value: impl Bar) -> i32 {
+15
+}
+
+pub fn bar(_value: impl Bar) -> i32 {
+16
+}
-- 
2.45.2



[COMMITTED 044/141] gccrs: scan-deadcode: Do not warn unused fields if they start with '_'

2025-03-24 Thread arthur . cohen
From: Arthur Cohen 

gcc/rust/ChangeLog:

* checks/lints/rust-lint-scan-deadcode.h: Check if the field name 
starts with an
underscore before warning.
---
 gcc/rust/checks/lints/rust-lint-scan-deadcode.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h 
b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
index e6ef1392c89..0fc203b0318 100644
--- a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
+++ b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h
@@ -93,7 +93,8 @@ public:
  {
HirId field_hir_id = field.get_mappings ().get_hirid ();
if (should_warn (field_hir_id)
-   && !field.get_visibility ().is_public ())
+   && !field.get_visibility ().is_public ()
+   && field.get_field_name ().as_string ().at (0) != '_')
  {
rust_warning_at (field.get_locus (), 0,
 "field is never read: %qs",
-- 
2.45.2



  1   2   >