[Bug rust/116225] Rust test failures with -D_GLIBCXX_ASSERTIONS

2025-03-21 Thread sjames at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116225

Sam James  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|UNCONFIRMED |RESOLVED
   Target Milestone|--- |15.0

--- Comment #4 from Sam James  ---
Fixed between 15th and 19th March and there's a CI job for this in the gccrs
repo now too.

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

[PATCHSET] Update Rust frontend 21/03/2024 3/4

2025-03-21 Thread arthur . cohen
Hi everyone,

This is our the third patchset in the series for updating upstream GCC
with the latest changes in our development repository.

Most notably this contains handling for if-let statements by Marc
Poulhiès, changes to our name-resolution pass rewrite, and massive
changes to our AST and HIR representations to allow Rust lang-item paths
to be represented. This is different from how the official Rust compiler
handles lang-items, but allows us to refer to essential Rust items
easily while we are still in the process of compiling said core crate.

These lang-item changes also enabled us to continue our work on built-in
derive macros, with Clone and Copy being fully implemented in this
patchset. The remaining built-in derive macros will be upstreamed in the
next patchset. We are still missing on PartialOrd and PartialEq, which
will be upstreamed in time for 15.1.

There are also multiple type-system fixes, and testsuite fixes for
systems with different endianness.

Kindly,

Arthur



[COMMITTED 010/146] rust: Desugar IfLet* into MatchExpr

2025-03-21 Thread arthur . cohen
From: Marc Poulhiès 

Replace the "regular" AST->HIR lowering for IfLet* with a desugaring
into a MatchExpr.

Desugar a simple if let:

   if let Some(y) = some_value {
 bar();
   }

into:

   match some_value {
 Some(y) => {bar();},
 _ => ()
   }

Same applies for IfLetExprConseqElse (if let with an else block).

Desugar:

   if let Some(y) = some_value {
 bar();
   } else {
 baz();
   }

into:

   match some_value {
 Some(y) => {bar();},
 _ => {baz();}
   }

Fixes https://github.com/Rust-GCC/gccrs/issues/1177

gcc/rust/ChangeLog:

* backend/rust-compile-block.h: Adjust after removal of
HIR::IfLetExpr and HIR::IfLetExprConseqElse.
* backend/rust-compile-expr.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::visit): Likewise.
* checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
Likewise.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc
(PrivacyReporter::visit): Likewise.
* checks/errors/privacy/rust-privacy-reporter.h: Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit):
Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit):
Likewise.
* checks/errors/rust-unsafe-checker.h: Likewise.
* hir/rust-ast-lower-block.h (ASTLoweringIfLetBlock::translate):
Change return type.
* hir/rust-ast-lower.cc (ASTLoweringIfLetBlock::desugar_iflet):
New.
(ASTLoweringIfLetBlock::visit(AST::IfLetExpr &)): Adjust and use
desugar_iflet.
* hir/rust-ast-lower.h: Add comment.
* hir/rust-hir-dump.cc (Dump::do_ifletexpr): Remove.
(Dump::visit(IfLetExpr&)): Remove.
(Dump::visit(IfLetExprConseqElse&)): Remove.
* hir/rust-hir-dump.h (Dump::do_ifletexpr): Remove.
(Dump::visit(IfLetExpr&)): Remove.
(Dump::visit(IfLetExprConseqElse&)): Remove.
* hir/tree/rust-hir-expr.h (class IfLetExpr): Remove.
(class IfLetExprConseqElse): Remove.
* hir/tree/rust-hir-full-decls.h (class IfLetExpr): Remove.
(class IfLetExprConseqElse): Remove.
* hir/tree/rust-hir-visitor.h: Adjust after removal of
HIR::IfLetExpr and HIR::IfLetExprConseqElse.
* hir/tree/rust-hir.cc (IfLetExpr::as_string): Remove.
(IfLetExprConseqElse::as_string): Remove.
(IfLetExpr::accept_vis): Remove.
(IfLetExprConseqElse::accept_vis): Remove.
* hir/tree/rust-hir.h: Adjust after removal of HIR::IfLetExpr and
HIR::IfLetExprConseqElse.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise.
* typecheck/rust-hir-type-check-expr.h: Likewise.
* checks/errors/rust-hir-pattern-analysis.cc
(PatternChecker::visit (IfLetExpr &)): Remove.
(PatternChecker::visit (IfLetExprConseqElse &)): Remove.
* checks/errors/rust-hir-pattern-analysis.h (visit(IfLetExpr &)): 
Remove.
(visit(IfLetExprConseqElse &)): Remove.

gcc/testsuite/ChangeLog:

* rust/compile/if_let_expr.rs: Adjust.
* rust/compile/if_let_expr_simple.rs: New test.
* rust/compile/iflet.rs: New test.
* rust/execute/torture/iflet.rs: New test.
* rust/compile/nr2/exclude: Add iflet.rs and if_let_expr_simple.rs

Signed-off-by: Marc Poulhiès 
---
 gcc/rust/backend/rust-compile-block.h |   4 -
 gcc/rust/backend/rust-compile-expr.h  |   2 -
 .../borrowck/rust-bir-builder-expr-stmt.cc|  12 --
 .../borrowck/rust-bir-builder-expr-stmt.h |   2 -
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |   8 -
 .../errors/borrowck/rust-bir-builder-struct.h |   2 -
 .../errors/borrowck/rust-function-collector.h |   2 -
 .../errors/privacy/rust-privacy-reporter.cc   |  15 --
 .../errors/privacy/rust-privacy-reporter.h|   2 -
 gcc/rust/checks/errors/rust-const-checker.cc  |  16 --
 gcc/rust/checks/errors/rust-const-checker.h   |   2 -
 .../errors/rust-hir-pattern-analysis.cc   |  16 --
 .../checks/errors/rust-hir-pattern-analysis.h |   2 -
 gcc/rust/checks/errors/rust-unsafe-checker.cc |  16 --
 gcc/rust/checks/errors/rust-unsafe-checker.h  |   2 -
 gcc/rust/hir/rust-ast-lower-block.h   |  11 +-
 gcc/rust/hir/rust-ast-lower.cc| 144 +++---
 gcc/rust/hir/rust-ast-lower.h |   5 +
 gcc/rust/hir/rust-hir-dump.cc |  28 ---
 gcc/rust/hir/rust-hir-dump.h  |   3 -
 gcc/rust/hir/tree/rust-hir-expr.h | 176 +-
 gcc/rust/hir/tree/rust-hir-full-decls.h   |   2 -
 gcc/rust/hir/tree/rust-hir-visitor.h  |   6 -
 gcc/rust/hir/tree/rust-hir

[COMMITTED 002/146] gccrs: Insert trait names during toplevel resolution 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Insert trait names into the type namespace.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 3 +++
 1 file changed, 3 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 a0d8492b7eb..fff3769cd70 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -120,6 +120,9 @@ TopLevel::visit (AST::Trait &trait)
   trait.insert_implict_self (
 std::unique_ptr (implicit_self));
 
+  insert_or_error_out (trait.get_identifier ().as_string (), trait,
+  Namespace::Types);
+
   DefaultResolver::visit (trait);
 }
 
-- 
2.45.2



[COMMITTED 005/146] gccrs: Rename some PathIdentSegment functions

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

This makes PathIdentSegment more similar to other classes used to
represent path segments.

gcc/rust/ChangeLog:

* ast/rust-path.h
(PathIdentSegment::is_super_segment): Rename to...
(PathIdentSegment::is_super_path_seg): ...here.
(PathIdentSegment::is_crate_segment): Rename to...
(PathIdentSegment::is_crate_path_seg): ...here.
(PathIdentSegment::is_lower_self): Rename to...
(PathIdentSegment::is_lower_self_seg): ...here.
(PathIdentSegment::is_big_self): Rename to...
(PathIdentSegment::is_big_self_seg): ...here.

(PathExprSegment::is_super_path_seg): Handle renames.
(PathExprSegment::is_crate_path_seg): Likewise.
(PathExprSegment::is_lower_self_seg): Likewise.
(TypePathSegment::is_crate_path_seg): Likewise.
(TypePathSegment::is_super_path_seg): Likewise.
(TypePathSegment::is_big_self_seg): Likewise.
(TypePathSegment::is_lower_self_seg): Likewise.
* ast/rust-ast-collector.cc
(TokenCollector::visit): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-collector.cc |  8 
 gcc/rust/ast/rust-path.h   | 31 +++---
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 20226687846..bc76deb9a6d 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -711,19 +711,19 @@ TokenCollector::visit (TypePath &path)
 void
 TokenCollector::visit (PathIdentSegment &segment)
 {
-  if (segment.is_super_segment ())
+  if (segment.is_super_path_seg ())
 {
   push (Rust::Token::make (SUPER, segment.get_locus ()));
 }
-  else if (segment.is_crate_segment ())
+  else if (segment.is_crate_path_seg ())
 {
   push (Rust::Token::make (CRATE, segment.get_locus ()));
 }
-  else if (segment.is_lower_self ())
+  else if (segment.is_lower_self_seg ())
 {
   push (Rust::Token::make (SELF, segment.get_locus ()));
 }
-  else if (segment.is_big_self ())
+  else if (segment.is_big_self_seg ())
 {
   push (Rust::Token::make (SELF_ALIAS, segment.get_locus ()));
 }
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 98fde5a2606..2cad3955494 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -55,10 +55,16 @@ public:
 
   location_t get_locus () const { return locus; }
 
-  bool is_super_segment () const { return as_string ().compare ("super") == 0; 
}
-  bool is_crate_segment () const { return as_string ().compare ("crate") == 0; 
}
-  bool is_lower_self () const { return as_string ().compare ("self") == 0; }
-  bool is_big_self () const { return as_string ().compare ("Self") == 0; }
+  bool is_super_path_seg () const
+  {
+return as_string ().compare ("super") == 0;
+  }
+  bool is_crate_path_seg () const
+  {
+return as_string ().compare ("crate") == 0;
+  }
+  bool is_lower_self_seg () const { return as_string ().compare ("self") == 0; 
}
+  bool is_big_self_seg () const { return as_string ().compare ("Self") == 0; }
 };
 
 // A binding of an identifier to a type used in generic arguments in paths
@@ -560,17 +566,17 @@ public:
 
   bool is_super_path_seg () const
   {
-return !has_generic_args () && get_ident_segment ().is_super_segment ();
+return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
   }
 
   bool is_crate_path_seg () const
   {
-return !has_generic_args () && get_ident_segment ().is_crate_segment ();
+return !has_generic_args () && get_ident_segment ().is_crate_path_seg ();
   }
 
   bool is_lower_self_seg () const
   {
-return !has_generic_args () && get_ident_segment ().is_lower_self ();
+return !has_generic_args () && get_ident_segment ().is_lower_self_seg ();
   }
 };
 
@@ -950,16 +956,19 @@ public:
 
   bool is_crate_path_seg () const
   {
-return get_ident_segment ().is_crate_segment ();
+return get_ident_segment ().is_crate_path_seg ();
   }
   bool is_super_path_seg () const
   {
-return get_ident_segment ().is_super_segment ();
+return get_ident_segment ().is_super_path_seg ();
+  }
+  bool is_big_self_seg () const
+  {
+return get_ident_segment ().is_big_self_seg ();
   }
-  bool is_big_self_seg () const { return get_ident_segment ().is_big_self (); }
   bool is_lower_self_seg () const
   {
-return get_ident_segment ().is_lower_self ();
+return get_ident_segment ().is_lower_self_seg ();
   }
 };
 
-- 
2.45.2



[COMMITTED 009/146] gccrs: Fix name resolution 2.0 definition lookups in unsafe checker

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

gcc/rust/ChangeLog:

* checks/errors/rust-unsafe-checker.cc: Add includes.
(UnsafeChecker::visit): Use 2.0 version of resolver when name
resolution 2.0 is enabled.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 42 +--
 gcc/testsuite/rust/compile/nr2/exclude|  6 ---
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 4c8db3a554e..9ab18e2f656 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -23,6 +23,10 @@
 #include "rust-hir-item.h"
 #include "rust-attribute-values.h"
 #include "rust-system.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace HIR {
@@ -216,8 +220,23 @@ UnsafeChecker::visit (PathInExpression &path)
   NodeId ast_node_id = path.get_mappings ().get_nodeid ();
   NodeId ref_node_id;
 
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
-return;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto resolved = nr_ctx.lookup (ast_node_id);
+
+  if (!resolved.has_value ())
+   return;
+
+  ref_node_id = resolved.value ();
+}
+  else
+{
+  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+   return;
+}
 
   if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
 {
@@ -418,8 +437,23 @@ UnsafeChecker::visit (CallExpr &expr)
   // There are no unsafe types, and functions are defined in the name resolver.
   // If we can't find the name, then we're dealing with a type and should 
return
   // early.
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
-return;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto resolved = nr_ctx.lookup (ast_node_id);
+
+  if (!resolved.has_value ())
+   return;
+
+  ref_node_id = resolved.value ();
+}
+  else
+{
+  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+   return;
+}
 
   if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id))
 {
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 450fc254452..47d651b22bd 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -191,12 +191,6 @@ traits9.rs
 type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
-unsafe1.rs
-unsafe11.rs
-unsafe2.rs
-unsafe3.rs
-unsafe6.rs
-unsafe7.rs
 use_1.rs
 use_2.rs
 v0-mangle1.rs
-- 
2.45.2



[COMMITTED 012/146] gccrs: Resolve SelfParam in name resolution 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Handle SelfParam.
* 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 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 12 
 gcc/rust/resolve/rust-late-name-resolver-2.0.h  |  1 +
 gcc/testsuite/rust/compile/nr2/exclude  |  4 
 3 files changed, 13 insertions(+), 4 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 5fd49e7c2c9..5fc97a0922b 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -164,6 +164,18 @@ Late::visit (AST::IdentifierPattern &identifier)
  identifier.get_node_id ());
 }
 
+void
+Late::visit (AST::SelfParam ¶m)
+{
+  // handle similar to AST::IdentifierPattern
+
+  DefaultResolver::visit (param);
+  // FIXME: this location should be a bit off
+  // ex: would point to the begining of "mut self" instead of the "self"
+  std::ignore = ctx.values.insert (Identifier ("self", param.get_locus ()),
+  param.get_node_id ());
+}
+
 void
 Late::visit (AST::IdentifierExpr &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 7e33c965805..35fe400aeea 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -41,6 +41,7 @@ public:
   // TODO: Do we need this?
   // void visit (AST::Method &) override;
   void visit (AST::IdentifierPattern &) override;
+  void visit (AST::SelfParam &) override;
 
   // resolutions
   void visit (AST::IdentifierExpr &) override;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index f4304dae1d8..b4799edd4f5 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -34,7 +34,6 @@ derive_macro6.rs
 expected_type_args2.rs
 expected_type_args3.rs
 feature_rust_attri0.rs
-feature_rust_attri1.rs
 for_lifetimes.rs
 format_args_basic_expansion.rs
 generic-default1.rs
@@ -54,13 +53,11 @@ infer-crate-name.rs
 issue-1019.rs
 issue-1031.rs
 issue-1034.rs
-issue-1128.rs
 issue-1129-2.rs
 issue-1130.rs
 issue-1165.rs
 issue-1173.rs
 issue-1235.rs
-issue-1237.rs
 issue-1272.rs
 issue-1289.rs
 issue-1447.rs
@@ -167,7 +164,6 @@ redef_error2.rs
 redef_error4.rs
 redef_error5.rs
 redef_error6.rs
-rustc_attr1.rs
 self-path1.rs
 self-path2.rs
 sizeof-stray-infer-var-bug.rs
-- 
2.45.2



[COMMITTED 105/146] gccrs: cleanup our enum type layout to be closer to rustc

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

This changes our enum type layout so for example:

  enum Foo {
  A,
  B,
  C(char),
  D { x: i32, y: i32 },
  }

Used to get layed out like this in gccrs:

  union {
struct A { int RUST$ENUM$DISR; };
struct B { int RUST$ENUM$DISR; };
struct C { int RUST$ENUM$DISR; char __0; };
struct D { int RUST$ENUM$DISR; i64 x; i64 y; };
  }

This has some issues notably with the constexpr because this is just a
giant union it means its not simple to constify what enum variant we are
looking at because the discriminant is a mess.

This now gets layed out as:

  struct {
 int RUST$ENUM$DISR;
 union {
 struct A { };
 struct B { };
 struct C { char __0; };
 struct D { i64 x; i64 y; };
 } payload;
  }

This layout is much cleaner and allows for our constexpr to work properly.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): new layout
* backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): 
likewise
(CompilePatternBindings::visit): likewise
* backend/rust-compile-resolve-path.cc: likewise
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): implement 
new layout
* rust-gcc.cc (constructor_expression): get rid of useless assert

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc | 74 +++
 gcc/rust/backend/rust-compile-pattern.cc  | 64 
 gcc/rust/backend/rust-compile-resolve-path.cc |  5 +-
 gcc/rust/backend/rust-compile-type.cc | 62 
 gcc/rust/rust-gcc.cc  |  2 +-
 5 files changed, 128 insertions(+), 79 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 900e080ea0e..b40aa33866e 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -558,24 +558,32 @@ CompileExpr::visit (HIR::StructExprStructFields 
&struct_expr)
}
 }
 
-  // the constructor depends on whether this is actually an enum or not if
-  // its an enum we need to setup the discriminator
-  std::vector ctor_arguments;
-  if (adt->is_enum ())
+  if (!adt->is_enum ())
 {
-  HIR::Expr &discrim_expr = variant->get_discriminant ();
-  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
-  tree folded_discrim_expr = fold_expr (discrim_expr_node);
-  tree qualifier = folded_discrim_expr;
-
-  ctor_arguments.push_back (qualifier);
+  translated
+   = Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
+  arguments, union_disriminator,
+  struct_expr.get_locus ());
+  return;
 }
-  for (auto &arg : arguments)
-ctor_arguments.push_back (arg);
+
+  HIR::Expr &discrim_expr = variant->get_discriminant ();
+  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+  tree folded_discrim_expr = fold_expr (discrim_expr_node);
+  tree qualifier = folded_discrim_expr;
+
+  tree enum_root_files = TYPE_FIELDS (compiled_adt_type);
+  tree payload_root = DECL_CHAIN (enum_root_files);
+
+  tree payload = Backend::constructor_expression (TREE_TYPE (payload_root),
+ adt->is_enum (), arguments,
+ union_disriminator,
+ struct_expr.get_locus ());
+
+  std::vector ctor_arguments = {qualifier, payload};
 
   translated
-= Backend::constructor_expression (compiled_adt_type, adt->is_enum (),
-  ctor_arguments, union_disriminator,
+= Backend::constructor_expression (compiled_adt_type, 0, ctor_arguments, 
-1,
   struct_expr.get_locus ());
 }
 
@@ -1247,26 +1255,34 @@ CompileExpr::visit (HIR::CallExpr &expr)
  arguments.push_back (rvalue);
}
 
-  // the constructor depends on whether this is actually an enum or not if
-  // its an enum we need to setup the discriminator
-  std::vector ctor_arguments;
-  if (adt->is_enum ())
+  if (!adt->is_enum ())
{
- HIR::Expr &discrim_expr = variant->get_discriminant ();
- tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
- tree folded_discrim_expr = fold_expr (discrim_expr_node);
- tree qualifier = folded_discrim_expr;
-
- ctor_arguments.push_back (qualifier);
+ translated
+   = Backend::constructor_expression (compiled_adt_type,
+  adt->is_enum (), arguments,
+  union_disriminator,
+  expr.get_locus ());
+ return;
}
-  for (auto &arg : arguments)
-   ctor_arguments.push_back (arg);
 
-  transla

[COMMITTED 070/146] gccrs: ast: Add LangItemPath class

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

This commit adds a new kind of Path, changes the base Path class and turns 
TypePath
into a child of the base Path class.

gcc/rust/ChangeLog:

* ast/rust-path.h (class LangItemPath): New.
(class TypePath): Adapt to accomodate LangItemPath.
* ast/rust-ast.cc (TraitImpl::as_string): Use new checks for lang items.
(QualifiedPathType::as_string): Likewise.
(FormatArgs::set_outer_attrs): Likewise.
* ast/rust-item.h (class TraitImpl): Likewise.
---
 gcc/rust/ast/rust-ast.cc |  4 +--
 gcc/rust/ast/rust-item.h | 28 +++
 gcc/rust/ast/rust-path.h | 73 ++--
 3 files changed, 71 insertions(+), 34 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 1d52352daaa..f1298d0f3e9 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1299,7 +1299,7 @@ TraitImpl::as_string () const
   else
 str += "false";
 
-  str += "\n TypePath (to trait): " + trait_path.as_string ();
+  str += "\n TypePath (to trait): " + trait_path->as_string ();
 
   str += "\n Type (struct to impl on): " + trait_type->as_string ();
 
@@ -1561,7 +1561,7 @@ QualifiedPathType::as_string () const
   str += type_to_invoke_on->as_string ();
 
   if (has_as_clause ())
-str += " as " + trait_path.as_string ();
+str += " as " + trait_path->as_string ();
 
   return str + ">";
 }
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 6611707a9a6..a6276a72d8d 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3172,7 +3172,7 @@ class TraitImpl : public Impl
 {
   bool has_unsafe;
   bool has_exclam;
-  TypePath trait_path;
+  std::unique_ptr trait_path;
 
   // bool has_impl_items;
   std::vector> impl_items;
@@ -3184,7 +3184,7 @@ public:
   bool has_impl_items () const { return !impl_items.empty (); }
 
   // Mega-constructor
-  TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam,
+  TraitImpl (std::unique_ptr trait_path, bool is_unsafe, bool has_exclam,
 std::vector> impl_items,
 std::vector> generic_params,
 std::unique_ptr trait_type, WhereClause where_clause,
@@ -3197,10 +3197,26 @@ public:
   trait_path (std::move (trait_path)), impl_items (std::move (impl_items))
   {}
 
+  // Helper constructor with a typepath
+  TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam,
+std::vector> impl_items,
+std::vector> generic_params,
+std::unique_ptr trait_type, WhereClause where_clause,
+Visibility vis, std::vector inner_attrs,
+std::vector outer_attrs, location_t locus)
+: Impl (std::move (generic_params), std::move (trait_type),
+   std::move (where_clause), std::move (vis), std::move (inner_attrs),
+   std::move (outer_attrs), locus),
+  has_unsafe (is_unsafe), has_exclam (has_exclam),
+  trait_path (std::unique_ptr (new TypePath (trait_path))),
+  impl_items (std::move (impl_items))
+  {}
+
   // Copy constructor with vector clone
   TraitImpl (TraitImpl const &other)
 : Impl (other), has_unsafe (other.has_unsafe),
-  has_exclam (other.has_exclam), trait_path (other.trait_path)
+  has_exclam (other.has_exclam),
+  trait_path (other.trait_path->clone_path ())
   {
 impl_items.reserve (other.impl_items.size ());
 for (const auto &e : other.impl_items)
@@ -3211,7 +3227,7 @@ public:
   TraitImpl &operator= (TraitImpl const &other)
   {
 Impl::operator= (other);
-trait_path = other.trait_path;
+trait_path = other.trait_path->clone_path ();
 has_unsafe = other.has_unsafe;
 has_exclam = other.has_exclam;
 
@@ -3242,10 +3258,10 @@ public:
   }
 
   // TODO: is this better? Or is a "vis_block" better?
-  TypePath &get_trait_path ()
+  Path &get_trait_path ()
   {
 // TODO: assert that trait path is not empty?
-return trait_path;
+return *trait_path;
   }
 
 protected:
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 2cad3955494..bece60f95ed 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -589,6 +589,7 @@ public:
   {
 LangItem,
 Regular,
+Type,
   };
 
   virtual Kind get_path_kind () const = 0;
@@ -598,8 +599,8 @@ public:
 return Pattern::Kind::Path;
   }
 
-  location_t get_locus () const override final { return locus; }
-  NodeId get_node_id () const override final { return node_id; }
+  location_t get_locus () const override { return locus; }
+  NodeId get_node_id () const override { return node_id; }
 
   std::unique_ptr clone_path ()
   {
@@ -661,11 +662,12 @@ public:
 class LangItemPath : public Path
 {
   NodeId lang_item;
-  // TODO: Add LangItemKind or w/ever here as well
 
-  // TODO: This constructor is wrong
-  explicit LangItemPath (NodeId lang_item, location_t locus)
-: Path (locus, lang_item), lang_item (lang_item)
+  LangItem::Kind kind;
+
+public:
+  explicit LangItemPa

[COMMITTED 072/146] gccrs: hir: Start adapting visitors to accept multiple kinds of Paths

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

gcc/rust/ChangeLog:

* ast/rust-item.h: Add new method to specifically get a type-path.
* ast/rust-path.cc (LangItemPath::as_string): Implement properly.
* hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Adapt
visitor to use the new LangItemPath.
* hir/rust-ast-lower-type.h: Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise.
* resolve/rust-ast-resolve-type.h: Likewise.
---
 gcc/rust/ast/rust-item.h  |  7 ++
 gcc/rust/ast/rust-path.cc |  3 +--
 gcc/rust/hir/rust-ast-lower-type.cc   |  9 
 gcc/rust/hir/rust-ast-lower-type.h|  1 +
 gcc/rust/resolve/rust-ast-resolve-item.cc |  2 +-
 gcc/rust/resolve/rust-ast-resolve-type.h  | 28 +++
 6 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index a6276a72d8d..dca4aab45c8 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3264,6 +3264,13 @@ public:
 return *trait_path;
   }
 
+  Type &get_trait_path_type ()
+  {
+rust_assert (trait_path->get_path_kind () == Path::Kind::Type);
+
+return (AST::Type &) static_cast (*trait_path);
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc
index 06c98cdcc2d..94cf2bb1514 100644
--- a/gcc/rust/ast/rust-path.cc
+++ b/gcc/rust/ast/rust-path.cc
@@ -152,8 +152,7 @@ RegularPath::as_string () const
 std::string
 LangItemPath::as_string () const
 {
-  // FIXME: Handle #[lang] paths
-  rust_unreachable ();
+  return "#[lang = \"" + LangItem::ToString (kind) + "\"]";
 }
 
 SimplePath
diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index 58c93b9e25d..c09d60fafc6 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -19,10 +19,19 @@
 #include "rust-ast-lower-type.h"
 #include "optional.h"
 #include "rust-attribute-values.h"
+#include "rust-path.h"
 
 namespace Rust {
 namespace HIR {
 
+HIR::TypePath *
+ASTLowerTypePath::translate (AST::Path &type)
+{
+  rust_assert (type.get_path_kind () == AST::Path::Kind::Type);
+
+  return ASTLowerTypePath::translate (static_cast (type));
+}
+
 HIR::TypePath *
 ASTLowerTypePath::translate (AST::TypePath &type)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-type.h 
b/gcc/rust/hir/rust-ast-lower-type.h
index 5bb9a7e5f7c..72c6b29d7dd 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -31,6 +31,7 @@ protected:
   using Rust::HIR::ASTLoweringBase::visit;
 
 public:
+  static HIR::TypePath *translate (AST::Path &type);
   static HIR::TypePath *translate (AST::TypePath &type);
 
   void visit (AST::TypePathSegmentFunction &segment) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 245523ae5aa..a330541b682 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -680,7 +680,7 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
 
   // setup paths
   CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
-  bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (),
+  bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path_type (),
canonical_trait_type);
   if (!ok)
 {
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 561948e85b8..ed055a1f04e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -21,6 +21,8 @@
 
 #include "rust-ast-resolve-base.h"
 #include "rust-ast-resolve-expr.h"
+#include "rust-hir-map.h"
+#include "rust-path.h"
 
 namespace Rust {
 namespace Resolver {
@@ -56,6 +58,32 @@ class ResolveType : public ResolverBase
   using Rust::Resolver::ResolverBase::visit;
 
 public:
+  static NodeId go (AST::TypePath &type_path)
+  {
+return ResolveType::go ((AST::Type &) type_path);
+  }
+
+  static NodeId go (AST::Path &type_path)
+  {
+if (type_path.get_path_kind () == AST::Path::Kind::LangItem)
+  {
+   auto &type = static_cast (type_path);
+
+   Analysis::Mappings::get_lang_item (type);
+
+   type.get_node_id ();
+  }
+
+rust_assert (type_path.get_path_kind () == AST::Path::Kind::Type);
+
+// We have to do this dance to first downcast to a typepath, and then 
upcast
+// to a Type. The altnernative is to split `go` into `go` and `go_inner` or
+// something, but eventually this will need to change as we'll need
+// `ResolveType::` to resolve other kinds of `Path`s as well.
+return ResolveType::go (
+  (AST::Type &) static_cast (type_path));
+  }
+
   static NodeId go (AST::Type &type)
   {
 ResolveType resolver;
-- 
2.4

[COMMITTED 142/146] gccrs: ast-builder: Add new methods for building structs

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

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc: Add new methods for constructing struct 
exprs.
* ast/rust-ast-builder.h: Mention how to build tuple expressions.
---
 gcc/rust/ast/rust-ast-builder.cc | 12 ++--
 gcc/rust/ast/rust-ast-builder.h  |  5 +
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index fe80924fece..47044df9171 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -24,6 +24,7 @@
 #include "rust-path.h"
 #include "rust-item.h"
 #include "rust-path.h"
+#include "rust-system.h"
 #include "rust-token.h"
 
 namespace Rust {
@@ -261,10 +262,17 @@ std::unique_ptr
 Builder::struct_expr (
   std::string struct_name,
   std::vector> &&fields) const
+{
+  return struct_expr (path_in_expression ({struct_name}), std::move (fields));
+}
+
+std::unique_ptr
+Builder::struct_expr (
+  PathInExpression struct_name,
+  std::vector> &&fields) const
 {
   return std::unique_ptr (
-new StructExprStructFields (path_in_expression ({struct_name}),
-   std::move (fields), loc));
+new StructExprStructFields (struct_name, std::move (fields), loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 624cd715181..e5bae6ed6e9 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -160,10 +160,15 @@ public:
 
   /**
* Create an expression for struct instantiation with fields (`S { a, b: c 
}`)
+   * Tuple expressions are call expressions and can thus be constructed with
+   * `call`
*/
   std::unique_ptr
   struct_expr (std::string struct_name,
   std::vector> &&fields) const;
+  std::unique_ptr
+  struct_expr (PathInExpression struct_name,
+  std::vector> &&fields) const;
 
   /* Create a field expression for struct instantiation (`field_name: value`) 
*/
   std::unique_ptr
-- 
2.45.2



[COMMITTED 141/146] gccrs: derive(Clone): Add deriving of simple enum variants

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc: Clone enum identifier variants properly
* expand/rust-derive-clone.h: Declare new functions used.
---
 gcc/rust/expand/rust-derive-clone.cc | 52 ++--
 gcc/rust/expand/rust-derive-clone.h  |  3 ++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index b8c92dcc6fe..e4702d8a818 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -20,6 +20,7 @@
 #include "rust-ast.h"
 #include "rust-ast-dump.h"
 #include "rust-item.h"
+#include "rust-path.h"
 
 namespace Rust {
 namespace AST {
@@ -235,11 +236,58 @@ DeriveClone::visit_struct (StructStruct &item)
 item.get_generic_params ());
 }
 
+MatchCase
+DeriveClone::clone_enum_identifier (Enum &item,
+   const std::unique_ptr &variant)
+{
+  auto variant_path = PathInExpression (
+{builder.path_segment (item.get_identifier ().as_string ()),
+ builder.path_segment (variant->get_identifier ().as_string ())},
+{}, loc, false);
+
+  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));
+
+  return builder.match_case (std::move (pattern), std::move (expr));
+}
+
 void
 DeriveClone::visit_enum (Enum &item)
 {
-  rust_sorry_at (item.get_locus (), "cannot derive %qs for these items yet",
-"Clone");
+  // Create an arm for each variant of the enum
+  // For enum item variants, just create the same variant
+  // For struct and tuple variants, destructure the pattern and call clone for
+  // each field
+
+  auto cases = std::vector ();
+
+  for (const auto &variant : item.get_variants ())
+{
+  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));
+ break;
+   case EnumItem::Kind::Tuple:
+   case EnumItem::Kind::Struct:
+ rust_unreachable ();
+ break;
+   }
+}
+
+  // match self { ... }
+  auto match = builder.match (builder.identifier ("self"), std::move (cases));
+
+  expanded = clone_impl (clone_fn (std::move (match)),
+item.get_identifier ().as_string (),
+item.get_generic_params ());
+
+  AST::Dump::debug (*expanded);
 }
 
 void
diff --git a/gcc/rust/expand/rust-derive-clone.h 
b/gcc/rust/expand/rust-derive-clone.h
index 4a43b2ac1fc..339cf6357ae 100644
--- a/gcc/rust/expand/rust-derive-clone.h
+++ b/gcc/rust/expand/rust-derive-clone.h
@@ -63,6 +63,9 @@ private:
   clone_impl (std::unique_ptr &&clone_fn, std::string name,
  const std::vector> &type_generics);
 
+  MatchCase clone_enum_identifier (Enum &item,
+  const std::unique_ptr &variant);
+
   virtual void visit_struct (StructStruct &item);
   virtual void visit_tuple (TupleStruct &item);
   virtual void visit_enum (Enum &item);
-- 
2.45.2



[COMMITTED 133/146] gccrs: builder: Allow generating struct statements

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

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc (Builder::struct_struct): New function.
* ast/rust-ast-builder.h (vec): New function.
---
 gcc/rust/ast/rust-ast-builder.cc | 15 +++
 gcc/rust/ast/rust-ast-builder.h  | 31 +++
 2 files changed, 46 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index f6d0f0dc4ae..55d59c94b52 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -18,9 +18,11 @@
 
 #include "rust-ast-builder.h"
 #include "rust-ast-builder-type.h"
+#include "rust-ast.h"
 #include "rust-common.h"
 #include "rust-expr.h"
 #include "rust-path.h"
+#include "rust-item.h"
 #include "rust-token.h"
 
 namespace Rust {
@@ -182,6 +184,19 @@ Builder::deref (std::unique_ptr &&of) const
   return std::unique_ptr (new DereferenceExpr (std::move (of), {}, loc));
 }
 
+std::unique_ptr
+Builder::struct_struct (std::string struct_name,
+   std::vector> &&generics,
+   std::vector &&fields)
+{
+  auto is_unit = fields.empty ();
+
+  return std::unique_ptr (
+new StructStruct (std::move (fields), struct_name, std::move (generics),
+ WhereClause::create_empty (), is_unit,
+ Visibility::create_private (), {}, loc));
+}
+
 std::unique_ptr
 Builder::struct_expr_struct (std::string struct_name) const
 {
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index aaf05c6d1fb..36c0da2cff2 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -21,10 +21,35 @@
 
 #include "rust-ast-full.h"
 #include "rust-expr.h"
+#include "rust-ast.h"
+#include "rust-item.h"
 
 namespace Rust {
 namespace AST {
 
+template 
+std::vector>
+vec (std::unique_ptr &&t)
+{
+  auto v = std::vector> ();
+
+  v.emplace_back (std::move (t));
+
+  return v;
+}
+
+template 
+std::vector>
+vec (std::unique_ptr &&t1, std::unique_ptr &&t2)
+{
+  auto v = std::vector> ();
+
+  v.emplace_back (std::move (t1));
+  v.emplace_back (std::move (t2));
+
+  return v;
+}
+
 // 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
@@ -113,6 +138,12 @@ public:
*/
   PathInExpression path_in_expression (LangItem::Kind lang_item) const;
 
+  /* Create a new struct */
+  std::unique_ptr
+  struct_struct (std::string struct_name,
+std::vector> &&generics,
+std::vector &&fields);
+
   /* Create a struct expression for unit structs (`S`) */
   std::unique_ptr struct_expr_struct (std::string struct_name) const;
 
-- 
2.45.2



[COMMITTED 100/146] gccrs: nr2.0: Improve default, top-level, and late resolvers

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

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Make sure to scope visitation of the
children of type definition items.
* resolve/rust-default-resolver.h
(DefaultResolver::visit): Add overrides for TupleStruct, Union,
and TypeAlias.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Remove override for Enum.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Rely more on DefaultResolver::visit.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Remove override for BlockExpr.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-default-resolver.cc | 35 ++---
 gcc/rust/resolve/rust-default-resolver.h  |  3 ++
 .../resolve/rust-late-name-resolver-2.0.cc|  7 ---
 .../resolve/rust-late-name-resolver-2.0.h |  1 -
 .../rust-toplevel-name-resolver-2.0.cc| 50 ---
 .../resolve/rust-toplevel-name-resolver-2.0.h |  1 -
 gcc/testsuite/rust/compile/nr2/exclude|  9 
 7 files changed, 41 insertions(+), 65 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 57b1cc44815..7528e7950e6 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -88,27 +88,48 @@ DefaultResolver::visit (AST::TraitImpl &impl)
 void
 DefaultResolver::visit (AST::StructStruct &type)
 {
-  // do we need to scope anything here? no, right?
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
-  // we also can't visit `StructField`s by default, so there's nothing to do -
-  // correct? or should we do something like
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
+}
 
-  AST::DefaultASTVisitor::visit (type);
+void
+DefaultResolver::visit (AST::TupleStruct &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
-  // FIXME: ???
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_struct_name ());
 }
 
 void
 DefaultResolver::visit (AST::Enum &type)
 {
-  // FIXME: Do we need to scope anything by default?
-
   auto variant_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
  variant_fn, type.get_identifier ());
 }
 
+void
+DefaultResolver::visit (AST::Union &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_identifier ());
+}
+
+void
+DefaultResolver::visit (AST::TypeAlias &type)
+{
+  auto inner_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
+
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+ inner_fn, type.get_new_type_name ());
+}
+
 void
 DefaultResolver::visit (AST::ClosureExprInner &expr)
 {
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 9fcddd15851..587d7d45803 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -52,7 +52,10 @@ public:
 
   // type dec nodes, which visit their fields or variants by default
   void visit (AST::StructStruct &) override;
+  void visit (AST::TupleStruct &) override;
   void visit (AST::Enum &) override;
+  void visit (AST::Union &) override;
+  void visit (AST::TypeAlias &) override;
 
   // Visitors that visit their expression node(s)
   void visit (AST::ClosureExprInner &) override;
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 86fd5f12173..bb099ab68ae 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -308,13 +308,6 @@ Late::visit (AST::StructStruct &s)
   ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
 }
 
-void
-Late::visit (AST::Enum &s)
-{
-  auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
-  ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
-}
-
 void
 Late::visit (AST::StructExprStruct &s)
 {
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 803a5ec1c00..2af73c38286 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -53,7 +53,6 @@ public:
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
   void visit (AST::StructStruct &) override;
-  void visit (A

[COMMITTED 090/146] gccrs: Fix NR2.0 compiler ICE caused by Generics in Enums

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

gcc/rust/ChangeLog:
* resolve/rust-late-name-resolver-2.0.cc:
Change the late name resolver to enter proper lexical scope during 
typechecking
* resolve/rust-late-name-resolver-2.0.h:
Add needed prototype to header
* resolve/rust-toplevel-name-resolver-2.0.cc:
Add generic parameters to enum's scoped RIB to allow for proper name 
resolution on types.

gcc/testsuite/ChangeLog:
* rust/compile/issue-3304.rs:
Add small test for generics+enums combination for NR2.0

Signed-off-by: Liam Naddell 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc |  7 +++
 gcc/rust/resolve/rust-late-name-resolver-2.0.h  |  1 +
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc |  9 +
 gcc/testsuite/rust/compile/issue-3304.rs| 10 ++
 4 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3304.rs

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 40f067319b5..38515cdc0fd 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -295,6 +295,13 @@ Late::visit (AST::StructStruct &s)
   ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
 }
 
+void
+Late::visit (AST::Enum &s)
+{
+  auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
+  ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
+}
+
 void
 Late::visit (AST::StructExprStruct &s)
 {
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 6f1191662cc..1dbca3648da 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -52,6 +52,7 @@ public:
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
   void visit (AST::StructStruct &) override;
+  void visit (AST::Enum &) override;
   void visit (AST::GenericArgs &) override;
   void visit (AST::GenericArg &);
 
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 a2f695e54f6..a76c098f2df 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -332,6 +332,15 @@ TopLevel::visit (AST::EnumItemDiscriminant &variant)
 void
 TopLevel::visit (AST::Enum &enum_item)
 {
+  auto generic_vis = [this, &enum_item] () {
+for (auto &g : enum_item.get_generic_params ())
+  {
+   g->accept_vis (*this);
+  }
+  };
+
+  ctx.scoped (Rib::Kind::Item, enum_item.get_node_id (), generic_vis);
+
   insert_or_error_out (enum_item.get_identifier (), enum_item,
   Namespace::Types);
 
diff --git a/gcc/testsuite/rust/compile/issue-3304.rs 
b/gcc/testsuite/rust/compile/issue-3304.rs
new file mode 100644
index 000..6ab614fa2d5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3304.rs
@@ -0,0 +1,10 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+#[lang = "sized"]
+trait Sized {}
+
+pub enum ROption {
+RSome(T),
+RNone,
+}
+
+fn main() {}
-- 
2.45.2



[COMMITTED 077/146] gccrs: fix bad not expression in rust

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

Fixes Rust-GCC#3229

gcc/rust/ChangeLog:

* rust-gcc.cc (operator_to_tree_code): ! expressions are BIT_NOT_EXPR

Signed-off-by: Philip Herron 
---
 gcc/rust/rust-gcc.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 7da5e2c5637..37d51e58c08 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -942,7 +942,7 @@ operator_to_tree_code (NegationOperator op)
 case NegationOperator::NEGATE:
   return NEGATE_EXPR;
 case NegationOperator::NOT:
-  return TRUTH_NOT_EXPR;
+  return BIT_NOT_EXPR;
 default:
   rust_unreachable ();
 }
-- 
2.45.2



[COMMITTED 114/146] gccrs: Add ForeverStackStore

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

ForeverStackStore is meant to partially unify the internal states of
per-namespace ForeverStack instances. This commit does not contain
modifications to ForeverStack which would allow it to rely on a
ForeverStackStore to store nodes, but a future commit should address
this.

gcc/rust/ChangeLog:

* Make-lang.in: Handle rust-forever-stack.cc.
* resolve/rust-forever-stack.h
(class ForeverStackStore): Add.
* resolve/rust-forever-stack.cc: New file, based on
rust-forever-stack.hxx.

Signed-off-by: Owen Avery 
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/resolve/rust-forever-stack.cc | 318 +
 gcc/rust/resolve/rust-forever-stack.h  | 151 
 3 files changed, 470 insertions(+)
 create mode 100644 gcc/rust/resolve/rust-forever-stack.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 8771cdf91e1..b6f3a35e4e6 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -146,6 +146,7 @@ GRS_OBJS = \
 rust/rust-ast-resolve-path.o \
 rust/rust-ast-resolve-stmt.o \
 rust/rust-ast-resolve-struct-expr-field.o \
+rust/rust-forever-stack.o \
 rust/rust-hir-type-check.o \
 rust/rust-privacy-check.o \
 rust/rust-privacy-ctx.o \
diff --git a/gcc/rust/resolve/rust-forever-stack.cc 
b/gcc/rust/resolve/rust-forever-stack.cc
new file mode 100644
index 000..725ae0ea018
--- /dev/null
+++ b/gcc/rust/resolve/rust-forever-stack.cc
@@ -0,0 +1,318 @@
+// Copyright (C) 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 "expected.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
+#include "rust-forever-stack.h"
+#include "rust-rib.h"
+#include "optional.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+bool
+ForeverStackStore::Node::is_root () const
+{
+  return !parent.has_value ();
+}
+
+bool
+ForeverStackStore::Node::is_leaf () const
+{
+  return children.empty ();
+}
+
+NodeId
+ForeverStackStore::Node::get_id () const
+{
+  return id;
+}
+
+ForeverStackStore::Node &
+ForeverStackStore::Node::insert_child (NodeId id, tl::optional 
path,
+  Rib::Kind kind)
+{
+  auto res = children.insert ({Link (id, path), Node (kind, id, *this)});
+
+  rust_debug ("inserting link: Link(%d [%s]): existed? %s", id,
+ path.has_value () ? path.value ().as_string ().c_str ()
+   : "",
+ !res.second ? "yes" : "no");
+
+  // sanity check on rib kind
+  // pick the value rib, since all ribs should have the same kind anyways
+  rust_assert (res.second || res.first->second.value_rib.kind == kind);
+
+  // verify, if we're using an existing node, our paths don't contradict
+  if (!res.second && path.has_value ())
+{
+  auto other_path = res.first->first.path;
+  rust_assert (!other_path.has_value ()
+  || other_path.value ().as_string ()
+   == path.value ().as_string ());
+}
+
+  return res.first->second;
+}
+
+tl::optional
+ForeverStackStore::Node::get_child (const Identifier &path)
+{
+  for (auto &ent : children)
+{
+  if (ent.first.path.has_value ()
+ && ent.first.path->as_string () == path.as_string ())
+   return ent.second;
+}
+  return tl::nullopt;
+}
+
+tl::optional
+ForeverStackStore::Node::get_child (const Identifier &path) const
+{
+  for (auto &ent : children)
+{
+  if (ent.first.path.has_value ()
+ && ent.first.path->as_string () == path.as_string ())
+   return ent.second;
+}
+  return tl::nullopt;
+}
+
+tl::optional
+ForeverStackStore::Node::get_parent ()
+{
+  return parent;
+}
+
+tl::optional
+ForeverStackStore::Node::get_parent () const
+{
+  if (parent)
+return *parent;
+  return tl::nullopt;
+}
+
+tl::optional
+ForeverStackStore::Node::get_parent_path () const
+{
+  if (parent.has_value ())
+for (auto &ent : parent->children)
+  if (ent.first.id == id && ent.first.path.has_value ())
+   return ent.first.path.value ();
+  return tl::nullopt;
+}
+
+Rib &
+ForeverStackStore::Node::get_rib (Namespace ns)
+{
+  switch (ns)
+{
+case Namespace::Values:
+  return value_rib;
+case Namespace::Types:
+  return type_rib;
+case Namespace::Labels:
+  return label_rib;
+case Namespace::Macros:
+ 

[COMMITTED 096/146] gccrs: nr2.0: Resolve type aliases inside trait definitions

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Add visitor for TraitItemType.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h  | 1 +
 gcc/testsuite/rust/compile/nr2/exclude  | 5 -
 3 files changed, 10 insertions(+), 5 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 6d52fcaaac8..4833233e025 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -109,6 +109,15 @@ TopLevel::visit (AST::Trait &trait)
   DefaultResolver::visit (trait);
 }
 
+void
+TopLevel::visit (AST::TraitItemType &trait_item)
+{
+  insert_or_error_out (trait_item.get_identifier ().as_string (), trait_item,
+  Namespace::Types);
+
+  DefaultResolver::visit (trait_item);
+}
+
 template 
 static void
 insert_macros (std::vector ¯os, NameResolutionContext &ctx)
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 7f4e29585de..f540ab9ae61 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -148,6 +148,7 @@ private:
 
   void visit (AST::Module &module) override;
   void visit (AST::Trait &trait) override;
+  void visit (AST::TraitItemType &trait_item) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;
   void visit (AST::BlockExpr &expr) override;
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e23669f309b..da5880d9a57 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -74,8 +74,6 @@ issue-2139.rs
 issue-2142.rs
 issue-2165.rs
 issue-2166.rs
-issue-2190-1.rs
-issue-2190-2.rs
 issue-2238.rs
 issue-2304.rs
 issue-2330.rs
@@ -85,7 +83,6 @@ issue-2723-1.rs
 issue-2723-2.rs
 issue-2772-2.rs
 issue-2775.rs
-issue-2747.rs
 issue-2782.rs
 issue-2812.rs
 issue-850.rs
@@ -98,7 +95,6 @@ macros/mbe/macro-issue1233.rs
 macros/mbe/macro-issue1400.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
@@ -198,7 +194,6 @@ iflet.rs
 issue-3033.rs
 issue-3009.rs
 issue-2323.rs
-issue-2953-1.rs
 issue-2953-2.rs
 issue-1773.rs
 issue-2905-1.rs
-- 
2.45.2



[COMMITTED 087/146] gccrs: lang-items: Collect trait functions that are lang items

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

gcc/rust/ChangeLog:

* ast/rust-collect-lang-items.cc (CollectLangItems::visit): Add visitor 
for collecting
functions that might be lang items.
* ast/rust-collect-lang-items.h: Likewise.
---
 gcc/rust/ast/rust-collect-lang-items.cc | 8 
 gcc/rust/ast/rust-collect-lang-items.h  | 1 +
 2 files changed, 9 insertions(+)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index 308720ae69a..50d134a429f 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -82,5 +82,13 @@ CollectLangItems::visit (AST::TraitItemType &item)
   DefaultASTVisitor::visit (item);
 }
 
+void
+CollectLangItems::visit (AST::Function &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h 
b/gcc/rust/ast/rust-collect-lang-items.h
index 552648f04ed..1d021b1d9c5 100644
--- a/gcc/rust/ast/rust-collect-lang-items.h
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -47,6 +47,7 @@ public:
 
   void visit (AST::Trait &item) override;
   void visit (AST::TraitItemType &item) override;
+  void visit (AST::Function &item) override;
 
 private:
   template  void maybe_add_lang_item (const T &item);
-- 
2.45.2



[COMMITTED 020/146] gccrs: Use name resolver 2.0 for module descendance checks

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

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc:
Include rust-immutable-name-resolution-context.h.
(is_child_module): Use ForeverStack::is_module_descendant if name
resolution 2.0 is enabled.
* resolve/rust-forever-stack.h
(ForeverStack::is_module_descendant): Add.
(ForeverStack::dfs_node): Add.
* resolve/rust-forever-stack.hxx
(ForeverStack::dfs_rib): Use ForeverStack::dfs_node.
(ForeverStack::dfs_node): Add.
(ForeverStack::is_module_descendant): Add.

Signed-off-by: Owen Avery 
---
 .../errors/privacy/rust-privacy-reporter.cc   |  9 
 gcc/rust/resolve/rust-forever-stack.h | 10 +
 gcc/rust/resolve/rust-forever-stack.hxx   | 41 +++
 3 files changed, 53 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 1ee2097b383..fa2de9c3f40 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -22,6 +22,7 @@
 #include "rust-hir-stmt.h"
 #include "rust-hir-item.h"
 #include "rust-attribute-values.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Privacy {
@@ -93,6 +94,14 @@ static bool
 is_child_module (Analysis::Mappings &mappings, NodeId parent,
 NodeId possible_child)
 {
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  return nr_ctx.values.is_module_descendant (parent, possible_child);
+}
+
   auto children = mappings.lookup_module_children (parent);
 
   if (!children)
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 8c5e207a70d..28509259497 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -521,6 +521,12 @@ public:
 
   std::string as_debug_string ();
 
+  /**
+   * Used to check if a module is a descendant of another module
+   * Intended for use in the privacy checker
+   */
+  bool is_module_descendant (NodeId parent, NodeId child) const;
+
 private:
   /**
* A link between two Nodes in our trie data structure. This class represents
@@ -635,6 +641,10 @@ private:
   tl::optional dfs_rib (Node &starting_point, NodeId to_find);
   tl::optional dfs_rib (const Node &starting_point,
 NodeId to_find) const;
+  // FIXME: Documentation
+  tl::optional dfs_node (Node &starting_point, NodeId to_find);
+  tl::optional dfs_node (const Node &starting_point,
+  NodeId to_find) const;
 };
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 5a5a7c73f32..31f8ba498b3 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -625,13 +625,33 @@ ForeverStack::to_canonical_path (NodeId id) const
 template 
 tl::optional
 ForeverStack::dfs_rib (ForeverStack::Node &starting_point, NodeId 
to_find)
+{
+  return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
+return x.rib;
+  });
+}
+
+template 
+tl::optional
+ForeverStack::dfs_rib (const ForeverStack::Node &starting_point,
+ NodeId to_find) const
+{
+  return dfs_node (starting_point, to_find).map ([] (Node &x) -> Rib & {
+return x.rib;
+  });
+}
+
+template 
+tl::optional::Node &>
+ForeverStack::dfs_node (ForeverStack::Node &starting_point,
+  NodeId to_find)
 {
   if (starting_point.id == to_find)
-return starting_point.rib;
+return starting_point;
 
   for (auto &child : starting_point.children)
 {
-  auto candidate = dfs_rib (child.second, to_find);
+  auto candidate = dfs_node (child.second, to_find);
 
   if (candidate.has_value ())
return candidate;
@@ -641,16 +661,16 @@ ForeverStack::dfs_rib (ForeverStack::Node 
&starting_point, NodeId to_find)
 }
 
 template 
-tl::optional
-ForeverStack::dfs_rib (const ForeverStack::Node &starting_point,
- NodeId to_find) const
+tl::optional::Node &>
+ForeverStack::dfs_node (const ForeverStack::Node &starting_point,
+  NodeId to_find) const
 {
   if (starting_point.id == to_find)
-return starting_point.rib;
+return starting_point;
 
   for (auto &child : starting_point.children)
 {
-  auto candidate = dfs_rib (child.second, to_find);
+  auto candidate = dfs_node (child.second, to_find);
 
   if (candidate.has_value ())
return candidate;
@@ -737,6 +757,13 @@ ForeverStack::as_debug_string ()
   return stream.str ();
 }
 
+template 
+bool
+ForeverStack::is_module_descendant (NodeId parent, NodeId child) const
+{
+  return dfs_node (dfs_node (root, parent).value (), child).has

[COMMITTED 033/146] gccrs: Refactor HIR with optionals, references & newtypes

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

The HIR made heavy use of pair and other unamed types which can be
difficult to read.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Use FnParam getter.
* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
* backend/rust-compile-intrinsic.cc: Likewise.
* backend/rust-compile-type.cc: Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit):
Only visit childrens if not missing.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Use
a reference instead of a raw pointer.
* hir/tree/rust-hir-expr.h: Add presence function for return
expression.
* hir/tree/rust-hir-item.h: Remove take_param_name.
* hir/tree/rust-hir.h: Make mapping getter const.
* typecheck/rust-hir-dot-operator.cc (MethodResolver::Select): Use
getter.
* typecheck/rust-hir-type-check-expr.cc: Likewise.
* typecheck/rust-hir-type-check-implitem.cc: Use FnParam vector instead
of std::pair of Pattern and BaseType.
* typecheck/rust-hir-type-check-item.cc: Likewise.
* typecheck/rust-hir-type-check.cc: Likewise.
* typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Use getters.
(TypeCheckMethodCallExpr::check): Likewise.
* typecheck/rust-tyty-cmp.h: Likewise.
* typecheck/rust-tyty.cc: Use FnParam.
* typecheck/rust-tyty.h (class FnParam): Add FnParam to handle function
parameters instead of handling std::pairs.
* typecheck/rust-unify.cc (UnifyRules::expect_fndef): Use getters.
(UnifyRules::expect_fnptr): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-base.cc |  2 +-
 gcc/rust/backend/rust-compile-expr.cc |  4 +-
 gcc/rust/backend/rust-compile-intrinsic.cc| 17 ++---
 gcc/rust/backend/rust-compile-type.cc |  4 +-
 .../errors/privacy/rust-privacy-reporter.cc   | 11 +--
 gcc/rust/checks/errors/rust-unsafe-checker.cc |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.h |  2 +
 gcc/rust/hir/tree/rust-hir-item.h |  2 -
 gcc/rust/hir/tree/rust-hir.h  |  5 +-
 gcc/rust/typecheck/rust-hir-dot-operator.cc   |  2 +-
 .../typecheck/rust-hir-type-check-expr.cc |  4 +-
 .../typecheck/rust-hir-type-check-implitem.cc | 28 +++-
 .../typecheck/rust-hir-type-check-item.cc |  6 +-
 gcc/rust/typecheck/rust-hir-type-check.cc | 18 ++---
 gcc/rust/typecheck/rust-tyty-call.cc  | 16 ++---
 gcc/rust/typecheck/rust-tyty-cmp.h|  6 +-
 gcc/rust/typecheck/rust-tyty.cc   | 30 
 gcc/rust/typecheck/rust-tyty.h| 69 ---
 gcc/rust/typecheck/rust-unify.cc  |  6 +-
 19 files changed, 122 insertions(+), 112 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 598f2e2e451..80ea7a4ec95 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -711,7 +711,7 @@ HIRCompileBase::compile_function (
   for (auto &referenced_param : function_params)
 {
   auto &tyty_param = fntype->param_at (i++);
-  auto param_tyty = tyty_param.second;
+  auto param_tyty = tyty_param.get_type ();
   auto compiled_param_type = TyTyResolveCompile::compile (ctx, param_tyty);
 
   location_t param_locus = referenced_param.get_locus ();
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index c46bda954ad..107ca2eadf5 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1267,7 +1267,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
 
 const TyTy::FnType *fn = static_cast (base);
 auto ¶m = fn->param_at (index);
-*result = param.second;
+*result = param.get_type ();
 
 return true;
   };
@@ -1401,7 +1401,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
   // assignments are coercion sites so lets convert the rvalue if
   // necessary, offset from the already adjusted implicit self
   bool ok;
-  TyTy::BaseType *expected = fntype->param_at (i + 1).second;
+  TyTy::BaseType *expected = fntype->param_at (i + 1).get_type ();
 
   TyTy::BaseType *actual = nullptr;
   ok = ctx->get_tyctx ()->lookup_type (
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index bf595e4fb87..16447b29a51 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -315,13 +315,13 @@ compile_fn_params (Context *ctx, TyTy::FnType *fntype, 
tree fndecl,
 {
   for (auto &parm : fntype->get_params ())
 {
-  auto &referenced_param = parm.first;
-  auto ¶m_tyty = parm.second;
+  auto &referenced_param = parm.get_pattern ();
+  auto param_tyty = parm.get_type ();
   auto compiled_param_type = 

[COMMITTED 029/146] gccrs: Fix bad handling for recursive type query

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

When resolving a type like this which is generic it causes the argument
substitution to go through bounds checking which is expected. But this
can call a type bounds probe which again calls a type query which will be
on the Impl Type on an impl block which can result in a recursive type
query which does eventually get caught and errors correctly. But this then
triggers some old error diagnositcs which are not valid error codes but old
error messages we used to catch simple errors very early on which do not
apply for this senario.

Fixes Rust-GCC#2905

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc 
(TypeCheckItem::resolve_impl_block_substitutions):
dont check for unconstrained when the self is not resolved
* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path):
remove bad debug error diagnostic
* typecheck/rust-tyty-subst.cc: likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-item.cc |   8 ++
 .../typecheck/rust-hir-type-check-type.cc |   7 +-
 gcc/rust/typecheck/rust-tyty-subst.cc |   3 -
 gcc/testsuite/rust/compile/issue-2905-1.rs|  27 
 gcc/testsuite/rust/compile/issue-2905-2.rs| 136 ++
 gcc/testsuite/rust/compile/nr2/exclude|   2 +
 6 files changed, 175 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2905-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2905-2.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 28368d4730a..0652777c8c6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -724,6 +724,14 @@ TypeCheckItem::resolve_impl_block_substitutions 
(HIR::ImplBlock &impl_block,
 }
 
   TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get 
());
+  if (self->is ())
+{
+  // we cannot check for unconstrained type arguments when the Self type is
+  // not resolved it will just add extra errors that dont help as well as
+  // the case where this could just be a recursive type query that should
+  // fail and will work later on anyway
+  return {substitutions, region_constraints};
+}
 
   // inherit the bounds
   if (!specified_bound.is_error ())
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index ee17e53eb30..0ff4ac45247 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -426,11 +426,8 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, 
size_t *offset,
   if (!query_type (ref, &lookup))
{
  if (is_root)
-   {
- rust_error_at (seg->get_locus (),
-"failed to resolve root segment");
- return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
-   }
+   return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+
  return root_tyty;
}
 
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc 
b/gcc/rust/typecheck/rust-tyty-subst.cc
index a3ebf0aa8d5..575f04a3030 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -634,8 +634,6 @@ SubstitutionRef::get_mappings_from_generic_args (
  if (resolved == nullptr
  || resolved->get_kind () == TyTy::TypeKind::ERROR)
{
- rust_error_at (binding.get_locus (),
-"failed to resolve type arguments");
  return SubstitutionArgumentMappings::error ();
}
 
@@ -701,7 +699,6 @@ SubstitutionRef::get_mappings_from_generic_args (
   BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
   if (resolved == nullptr || resolved->get_kind () == 
TyTy::TypeKind::ERROR)
{
- rust_error_at (args.get_locus (), "failed to resolve type arguments");
  return SubstitutionArgumentMappings::error ();
}
 
diff --git a/gcc/testsuite/rust/compile/issue-2905-1.rs 
b/gcc/testsuite/rust/compile/issue-2905-1.rs
new file mode 100644
index 000..9b0c19da9bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2905-1.rs
@@ -0,0 +1,27 @@
+#![feature(lang_items)]
+
+#[lang = "sized"]
+trait Sized {}
+
+pub struct A(T);
+
+pub trait B {
+type C;
+}
+
+// --
+// swap these two items
+
+impl B for i32 {
+type C = Weird;
+}
+
+pub struct Weird(A<(T,)>);
+
+// --
+
+trait Foo {}
+
+impl Foo for Weird {}
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/issue-2905-2.rs 
b/gcc/testsuite/rust/compile/issue-2905-2.rs
new file mode 100644
index 0

[COMMITTED 036/146] gccrs: Fix Generic type retrieval

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

gcc/rust/ChangeLog:

* hir/rust-ast-lower-type.cc (ASTLowerGenericParam::visit): Forward
an optional to the constructor.
* hir/tree/rust-hir-item.cc (TypeParam::TypeParam): Use an optional
in the constructor.
(TypeParam::operator=): Ensure the TypeParam has a type properly.
(TypeParam::get_type_mappings): Likewise.
* hir/tree/rust-hir-item.h: Wrap the type smart pointer into an
optional.
* hir/tree/rust-hir.cc (TypeParam::as_string): Unwrap optional type
correctly.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/hir/rust-ast-lower-type.cc | 10 +-
 gcc/rust/hir/tree/rust-hir-item.cc  | 19 +++
 gcc/rust/hir/tree/rust-hir-item.h   | 14 --
 gcc/rust/hir/tree/rust-hir.cc   |  2 +-
 4 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index 7d6ac5ddffa..5836c1ac148 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-ast-lower-type.h"
+#include "optional.h"
 #include "rust-attribute-values.h"
 
 namespace Rust {
@@ -502,9 +503,9 @@ ASTLowerGenericParam::visit (AST::TypeParam ¶m)
}
 }
 
-  HIR::Type *type = param.has_type ()
- ? ASTLoweringType::translate (param.get_type ())
- : nullptr;
+  auto type = param.has_type () ? tl::optional (std::unique_ptr (
+   ASTLoweringType::translate (param.get_type (
+   : tl::nullopt;
 
   auto crate_num = mappings.get_current_crate ();
   Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
@@ -514,8 +515,7 @@ ASTLowerGenericParam::visit (AST::TypeParam ¶m)
   translated
 = new HIR::TypeParam (mapping, param.get_type_representation (),
  param.get_locus (), std::move (type_param_bounds),
- std::unique_ptr (type),
- param.get_outer_attrs ());
+ std::move (type), param.get_outer_attrs ());
 }
 
 HIR::TypeParamBound *
diff --git a/gcc/rust/hir/tree/rust-hir-item.cc 
b/gcc/rust/hir/tree/rust-hir-item.cc
index f81f1eae134..cff06d35269 100644
--- a/gcc/rust/hir/tree/rust-hir-item.cc
+++ b/gcc/rust/hir/tree/rust-hir-item.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-hir-item.h"
+#include "optional.h"
 
 namespace Rust {
 namespace HIR {
@@ -25,7 +26,7 @@ TypeParam::TypeParam (
   Analysis::NodeMapping mappings, Identifier type_representation,
   location_t locus,
   std::vector> type_param_bounds,
-  std::unique_ptr, AST::AttrVec outer_attrs)
+  tl::optional> type, AST::AttrVec outer_attrs)
   : GenericParam (mappings), outer_attrs (std::move (outer_attrs)),
 type_representation (std::move (type_representation)),
 type_param_bounds (std::move (type_param_bounds)), type (std::move (type)),
@@ -37,8 +38,10 @@ TypeParam::TypeParam (TypeParam const &other)
 type_representation (other.type_representation), locus (other.locus)
 {
   // guard to prevent null pointer dereference
-  if (other.type != nullptr)
-type = other.type->clone_type ();
+  if (other.has_type ())
+type = {other.type.value ()->clone_type ()};
+  else
+type = tl::nullopt;
 
   type_param_bounds.reserve (other.type_param_bounds.size ());
   for (const auto &e : other.type_param_bounds)
@@ -54,10 +57,10 @@ TypeParam::operator= (TypeParam const &other)
   mappings = other.mappings;
 
   // guard to prevent null pointer dereference
-  if (other.type != nullptr)
-type = other.type->clone_type ();
+  if (other.has_type ())
+type = {other.type.value ()->clone_type ()};
   else
-type = nullptr;
+type = tl::nullopt;
 
   type_param_bounds.reserve (other.type_param_bounds.size ());
   for (const auto &e : other.type_param_bounds)
@@ -69,8 +72,8 @@ TypeParam::operator= (TypeParam const &other)
 Analysis::NodeMapping
 TypeParam::get_type_mappings () const
 {
-  rust_assert (type != nullptr);
-  return type->get_mappings ();
+  rust_assert (type.has_value ());
+  return type.value ()->get_mappings ();
 }
 
 std::vector> &
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index bb300e9ed23..0fda1672b74 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -19,6 +19,7 @@
 #ifndef RUST_HIR_ITEM_H
 #define RUST_HIR_ITEM_H
 
+#include "optional.h"
 #include "rust-abi.h"
 #include "rust-hir-stmt.h"
 #include "rust-common.h"
@@ -102,14 +103,13 @@ class TypeParam : public GenericParam
   std::vector>
 type_param_bounds; // inlined form
 
-  // bool has_type;
-  std::unique_ptr type;
+  tl::optional> type;
 
   location_t locus;
 
 public:
   // Returns whether the type of the type param has been specified.
-  bool has_type () const { return type != nullp

[COMMITTED 016/146] gccrs: Remove usage of Resolver::get_builtin_types

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

gcc/rust/ChangeLog:

* backend/rust-compile-context.cc
(Context::setup_builtins): Use TypeCheckContext::get_builtins
instead of Resolver::get_builtin_types,
TypeCheckContext::lookup_type_by_node_id, and
TypeCheckContext::lookup_type.
* typecheck/rust-hir-type-check.h
(TypeCheckContext::get_builtins): Add.
* typecheck/rust-typecheck-context.cc
(TypeCheckContext::get_builtins): Add.

Signed-off-by: Owen Avery 
---
 gcc/rust/backend/rust-compile-context.cc | 15 ++-
 gcc/rust/typecheck/rust-hir-type-check.h |  1 +
 gcc/rust/typecheck/rust-typecheck-context.cc |  6 ++
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-context.cc 
b/gcc/rust/backend/rust-compile-context.cc
index c80f95649f1..86f089440ac 100644
--- a/gcc/rust/backend/rust-compile-context.cc
+++ b/gcc/rust/backend/rust-compile-context.cc
@@ -33,19 +33,8 @@ Context::Context ()
 void
 Context::setup_builtins ()
 {
-  auto builtins = resolver->get_builtin_types ();
-  for (auto it = builtins.begin (); it != builtins.end (); it++)
-{
-  HirId ref;
-  bool ok = tyctx->lookup_type_by_node_id ((*it)->get_node_id (), &ref);
-  rust_assert (ok);
-
-  TyTy::BaseType *lookup;
-  ok = tyctx->lookup_type (ref, &lookup);
-  rust_assert (ok);
-
-  TyTyResolveCompile::compile (this, lookup);
-}
+  for (auto &builtin : tyctx->get_builtins ())
+TyTyResolveCompile::compile (this, builtin.get ());
 }
 
 hashval_t
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index fa49e0689f3..5b1fe220890 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -135,6 +135,7 @@ public:
   bool lookup_builtin (NodeId id, TyTy::BaseType **type);
   bool lookup_builtin (std::string name, TyTy::BaseType **type);
   void insert_builtin (HirId id, NodeId ref, TyTy::BaseType *type);
+  const std::vector> &get_builtins () const;
 
   void insert_type (const Analysis::NodeMapping &mappings,
TyTy::BaseType *type);
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index 8f7a8a4f48f..0fb8224861e 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -73,6 +73,12 @@ TypeCheckContext::insert_builtin (HirId id, NodeId ref, 
TyTy::BaseType *type)
   builtins.push_back (std::unique_ptr (type));
 }
 
+const std::vector> &
+TypeCheckContext::get_builtins () const
+{
+  return builtins;
+}
+
 void
 TypeCheckContext::insert_type (const Analysis::NodeMapping &mappings,
   TyTy::BaseType *type)
-- 
2.45.2



[COMMITTED 019/146] gccrs: Use name resolver 2.0 in VisibilityResolver

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

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-visibility-resolver.cc:
Add includes.
(VisibilityResolver::resolve_module_path): Use name resolver 2.0
(when enabled) to lookup path resolutions.

Signed-off-by: Owen Avery 
---
 .../privacy/rust-visibility-resolver.cc   | 21 ++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc 
b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
index 464ce86e177..f0da7456076 100644
--- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc
@@ -20,6 +20,10 @@
 #include "rust-ast.h"
 #include "rust-hir.h"
 #include "rust-hir-item.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace Privacy {
@@ -61,7 +65,22 @@ VisibilityResolver::resolve_module_path (const 
HIR::SimplePath &restriction,
 "cannot use non-module path as privacy restrictor");
 
   NodeId ref_node_id = UNKNOWN_NODEID;
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  if (auto id = nr_ctx.lookup (ast_node_id))
+   {
+ ref_node_id = *id;
+   }
+  else
+   {
+ invalid_path.emit ();
+ return false;
+   }
+}
+  else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
 {
   invalid_path.emit ();
   return false;
-- 
2.45.2



[COMMITTED 021/146] gccrs: Reorganize the CPU feature detection

2025-03-21 Thread arthur . cohen
From: Antoni Boucher 

Move the code from i386-rust.cc to i386-rust-and-jit.inc so that it can
be reused by libgccjit.

gcc/ChangeLog:

* config/i386/i386-rust-and-jit.inc: New file.
* config/i386/i386-rust.cc: Move code to i386-rust-and-jit.inc.
---
 gcc/config/i386/i386-rust-and-jit.inc | 93 ++
 gcc/config/i386/i386-rust.cc  | 96 +--
 2 files changed, 96 insertions(+), 93 deletions(-)
 create mode 100644 gcc/config/i386/i386-rust-and-jit.inc

diff --git a/gcc/config/i386/i386-rust-and-jit.inc 
b/gcc/config/i386/i386-rust-and-jit.inc
new file mode 100644
index 000..998f44cfa3f
--- /dev/null
+++ b/gcc/config/i386/i386-rust-and-jit.inc
@@ -0,0 +1,93 @@
+if (TARGET_64BIT)
+  ADD_TARGET_INFO ("target_arch", "x86_64");
+else
+  ADD_TARGET_INFO ("target_arch", "x86");
+
+// features officially "stabilised" in rustc
+if (TARGET_MMX)
+  ADD_TARGET_INFO ("target_feature", "mmx");
+if (TARGET_SSE)
+  ADD_TARGET_INFO ("target_feature", "sse");
+if (TARGET_SSE2)
+  ADD_TARGET_INFO ("target_feature", "sse2");
+if (TARGET_SSE3)
+  ADD_TARGET_INFO ("target_feature", "sse3");
+if (TARGET_SSSE3)
+  ADD_TARGET_INFO ("target_feature", "ssse3");
+if (TARGET_SSE4_1)
+  ADD_TARGET_INFO ("target_feature", "sse4.1");
+if (TARGET_SSE4_2)
+  ADD_TARGET_INFO ("target_feature", "sse4.2");
+if (TARGET_AES)
+  ADD_TARGET_INFO ("target_feature", "aes");
+if (TARGET_SHA)
+  ADD_TARGET_INFO ("target_feature", "sha");
+if (TARGET_AVX)
+  ADD_TARGET_INFO ("target_feature", "avx");
+if (TARGET_AVX2)
+  ADD_TARGET_INFO ("target_feature", "avx2");
+if (TARGET_AVX512F)
+  ADD_TARGET_INFO ("target_feature", "avx512f");
+if (TARGET_AVX512CD)
+  ADD_TARGET_INFO ("target_feature", "avx512cd");
+if (TARGET_AVX512DQ)
+  ADD_TARGET_INFO ("target_feature", "avx512dq");
+if (TARGET_AVX512BW)
+  ADD_TARGET_INFO ("target_feature", "avx512bw");
+if (TARGET_AVX512VL)
+  ADD_TARGET_INFO ("target_feature", "avx512vl");
+if (TARGET_AVX512VBMI)
+  ADD_TARGET_INFO ("target_feature", "avx512vbmi");
+if (TARGET_AVX512IFMA)
+  ADD_TARGET_INFO ("target_feature", "avx512ifma");
+if (TARGET_AVX512VPOPCNTDQ)
+  ADD_TARGET_INFO ("target_feature", "avx512vpopcntdq");
+if (TARGET_FMA)
+  ADD_TARGET_INFO ("target_feature", "fma");
+if (TARGET_RTM)
+  ADD_TARGET_INFO ("target_feature", "rtm");
+if (TARGET_SSE4A)
+  ADD_TARGET_INFO ("target_feature", "sse4a");
+if (TARGET_BMI)
+  {
+ADD_TARGET_INFO ("target_feature", "bmi1");
+ADD_TARGET_INFO ("target_feature", "bmi");
+  }
+if (TARGET_BMI2)
+  ADD_TARGET_INFO ("target_feature", "bmi2");
+if (TARGET_LZCNT)
+  ADD_TARGET_INFO ("target_feature", "lzcnt");
+if (TARGET_TBM)
+  ADD_TARGET_INFO ("target_feature", "tbm");
+if (TARGET_POPCNT)
+  ADD_TARGET_INFO ("target_feature", "popcnt");
+if (TARGET_RDRND)
+  {
+ADD_TARGET_INFO ("target_feature", "rdrand");
+ADD_TARGET_INFO ("target_feature", "rdrnd");
+  }
+if (TARGET_F16C)
+  ADD_TARGET_INFO ("target_feature", "f16c");
+if (TARGET_RDSEED)
+  ADD_TARGET_INFO ("target_feature", "rdseed");
+if (TARGET_ADX)
+  ADD_TARGET_INFO ("target_feature", "adx");
+if (TARGET_FXSR)
+  ADD_TARGET_INFO ("target_feature", "fxsr");
+if (TARGET_XSAVE)
+  ADD_TARGET_INFO ("target_feature", "xsave");
+if (TARGET_XSAVEOPT)
+  ADD_TARGET_INFO ("target_feature", "xsaveopt");
+if (TARGET_XSAVEC)
+  ADD_TARGET_INFO ("target_feature", "xsavec");
+if (TARGET_XSAVES)
+  ADD_TARGET_INFO ("target_feature", "xsaves");
+if (TARGET_VPCLMULQDQ)
+  {
+ADD_TARGET_INFO ("target_feature", "pclmulqdq");
+ADD_TARGET_INFO ("target_feature", "vpclmulqdq");
+  }
+if (TARGET_CMPXCHG16B)
+  ADD_TARGET_INFO ("target_feature", "cmpxchg16b");
+if (TARGET_MOVBE)
+  ADD_TARGET_INFO ("target_feature", "movbe");
diff --git a/gcc/config/i386/i386-rust.cc b/gcc/config/i386/i386-rust.cc
index b9099d3dfaf..de00076bff5 100644
--- a/gcc/config/i386/i386-rust.cc
+++ b/gcc/config/i386/i386-rust.cc
@@ -29,97 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 void
 ix86_rust_target_cpu_info (void)
 {
-  if (TARGET_64BIT)
-rust_add_target_info ("target_arch", "x86_64");
-  else
-rust_add_target_info ("target_arch", "x86");
-
-  // features officially "stabilised" in rustc
-  if (TARGET_MMX)
-rust_add_target_info ("target_feature", "mmx");
-  if (TARGET_SSE)
-rust_add_target_info ("target_feature", "sse");
-  if (TARGET_SSE2)
-rust_add_target_info ("target_feature", "sse2");
-  if (TARGET_SSE3)
-rust_add_target_info ("target_feature", "sse3");
-  if (TARGET_SSSE3)
-rust_add_target_info ("target_feature", "ssse3");
-  if (TARGET_SSE4_1)
-rust_add_target_info ("target_feature", "sse4.1");
-  if (TARGET_SSE4_2)
-rust_add_target_info ("target_feature", "sse4.2");
-  if (TARGET_AES)
-rust_add_target_info ("target_feature", "aes");
-  if (TARGET_SHA)
-rust_add_target_info ("target_feature", "sha");
-  if (TARGET_AVX)
-rust_add_target_info ("target_feature", "avx");
-  if (TARGET_AVX2)
-   

[COMMITTED 018/146] gccrs: fix bad type inference on local patterns

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

We do not need to inject inference variables on generic patterns
with generic blocks. This will just cause unconstrained inference
variables as they may not unify against something.

Fixes Rust-GCC#2323

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path): dont infer here

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 3 ++-
 gcc/testsuite/rust/compile/issue-2323.rs   | 9 +
 gcc/testsuite/rust/compile/nr2/exclude | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2323.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 231ddd604db..7b934b38eb3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -245,6 +245,7 @@ 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 ();
   if (seg_is_module || seg_is_crate)
{
  // A::B::C::this_is_a_module::D::E::F
@@ -321,7 +322,7 @@ 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 ())
+  else if (lookup->needs_generic_substitutions () && !seg_is_pattern)
{
  lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
}
diff --git a/gcc/testsuite/rust/compile/issue-2323.rs 
b/gcc/testsuite/rust/compile/issue-2323.rs
new file mode 100644
index 000..02a3f90b4d8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2323.rs
@@ -0,0 +1,9 @@
+#[lang = "sized"]
+trait Sized {}
+
+pub struct S(T);
+
+pub fn foo(x: T) {
+let y = S(x);
+y.0;
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 4ba27d31f88..eaa2a1e0d0b 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -222,4 +222,5 @@ if_let_expr_simple.rs
 iflet.rs
 issue-3033.rs
 issue-3009.rs
+issue-2323.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 023/146] gccrs: fix typechecking of Fn trait calls using ADT types

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

Fixes RustGcc#2953

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): fix the 
ty_id

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-item.cc | 10 +++--
 gcc/testsuite/rust/compile/issue-2953-1.rs| 27 ++
 gcc/testsuite/rust/compile/issue-2953-2.rs| 37 +++
 gcc/testsuite/rust/compile/nr2/exclude|  2 +
 4 files changed, 72 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2953-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2953-2.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 81e2f25f73d..28368d4730a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -231,7 +231,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
-struct_decl.get_mappings ().get_hirid (), mappings.get_next_hir_id (),
+struct_decl.get_mappings ().get_hirid (),
+struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
 std::move (substitutions), repr,
@@ -312,7 +313,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
   auto *type = new TyTy::ADTType (
-struct_decl.get_mappings ().get_hirid (), mappings.get_next_hir_id (),
+struct_decl.get_mappings ().get_hirid (),
+struct_decl.get_mappings ().get_hirid (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
 std::move (substitutions), repr,
@@ -369,7 +371,7 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
   // multi variant ADT
   auto *type
 = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
-mappings.get_next_hir_id (),
+enum_decl.get_mappings ().get_hirid (),
 enum_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::ENUM, std::move (variants),
 std::move (substitutions));
@@ -440,7 +442,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
 
   auto *type
 = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
-mappings.get_next_hir_id (),
+union_decl.get_mappings ().get_hirid (),
 union_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::UNION, std::move (variants),
 std::move (substitutions));
diff --git a/gcc/testsuite/rust/compile/issue-2953-1.rs 
b/gcc/testsuite/rust/compile/issue-2953-1.rs
new file mode 100644
index 000..d07059e440e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2953-1.rs
@@ -0,0 +1,27 @@
+#[lang = "sized"]
+pub trait Sized {
+// Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce {
+/// The returned type after the call operator is used.
+#[lang = "fn_once_output"]
+type Output;
+
+/// Performs the call operation.
+extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub enum Ordering {
+/// An ordering where a compared value is less than another.
+Less = -1,
+/// An ordering where a compared value is equal to another.
+Equal = 0,
+/// An ordering where a compared value is greater than another.
+Greater = 1,
+}
+
+pub fn f Ordering>(g: F) -> Ordering {
+g(1)
+}
diff --git a/gcc/testsuite/rust/compile/issue-2953-2.rs 
b/gcc/testsuite/rust/compile/issue-2953-2.rs
new file mode 100644
index 000..59276246a1c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2953-2.rs
@@ -0,0 +1,37 @@
+#[lang = "sized"]
+pub trait Sized {
+// Empty.
+}
+
+#[lang = "fn_once"]
+pub trait FnOnce {
+/// The returned type after the call operator is used.
+#[lang = "fn_once_output"]
+type Output;
+
+/// Performs the call operation.
+extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub enum Ordering {
+/// An ordering where a compared value is less than another.
+Less = -1,
+/// An ordering where a compared value is equal to another.
+Equal = 0,
+/// An ordering where a compared value is greater than another.
+Greater = 1,
+}
+
+pub fn max_by Ordering>(v1: T, v2: T, compare: F) -> T 
{
+match compare(&v1, &v2) {
+Ordering::Less | Ordering::Equal => v2,
+Ordering::Greater => v1,
+}
+}
+
+pub fn min_by Ordering>(v1: T, v2: T, compare: F) -> T 
{
+ma

[COMMITTED 025/146] gccrs: add test case to show issue is fixed

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

The original test case 1773 has been moved to a new issue 3242 which
is still open and test-case is skipped. The original issue in 1773 is
fixed so this will close out that issue

Fixes Rust-Gcc#1773

gcc/testsuite/ChangeLog:

* rust/compile/issue-1773.rs: new test case
* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3242.rs: old test ranamed to match issue.

Signed-off-by: Philip Herron 
---
 gcc/testsuite/rust/compile/issue-1773.rs | 23 +++
 gcc/testsuite/rust/compile/issue-3242.rs | 24 
 gcc/testsuite/rust/compile/nr2/exclude   |  1 +
 3 files changed, 40 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3242.rs

diff --git a/gcc/testsuite/rust/compile/issue-1773.rs 
b/gcc/testsuite/rust/compile/issue-1773.rs
index 468497a4792..41c82f01b6d 100644
--- a/gcc/testsuite/rust/compile/issue-1773.rs
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -1,8 +1,4 @@
-#[lang = "sized"]
-// { dg-skip-if "" { *-*-* } }
-pub trait Sized {}
-
-trait Foo {
+trait Foo {
 type A;
 
 fn test(a: Self::A) -> Self::A {
@@ -10,9 +6,14 @@ trait Foo {
 }
 }
 
-struct Bar(T);
-impl Foo for Bar {
-type A = T;
+struct Bar(i32);
+impl Foo for Bar {
+type A = i32;
+}
+
+struct Baz(f32);
+impl Foo for Baz {
+type A = f32;
 }
 
 fn main() {
@@ -21,4 +22,10 @@ fn main() {
 
 let b;
 b = Bar::test(a.0);
+
+let c;
+c = Baz(123f32);
+
+let d;
+d = Baz::test(c.0);
 }
diff --git a/gcc/testsuite/rust/compile/issue-3242.rs 
b/gcc/testsuite/rust/compile/issue-3242.rs
new file mode 100644
index 000..468497a4792
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3242.rs
@@ -0,0 +1,24 @@
+#[lang = "sized"]
+// { dg-skip-if "" { *-*-* } }
+pub trait Sized {}
+
+trait Foo {
+type A;
+
+fn test(a: Self::A) -> Self::A {
+a
+}
+}
+
+struct Bar(T);
+impl Foo for Bar {
+type A = T;
+}
+
+fn main() {
+let a;
+a = Bar(123);
+
+let b;
+b = Bar::test(a.0);
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6f8187264aa..efee0fd1e2d 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -216,4 +216,5 @@ issue-3009.rs
 issue-2323.rs
 issue-2953-1.rs
 issue-2953-2.rs
+issue-1773.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 030/146] gccrs: Push ribs by kind rather than by value

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

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::push): Accept argument of type Rib::Kind rather
than Rib.
* resolve/rust-forever-stack.hxx
(ForeverStack::push): Likewise.
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::scoped): Likewise.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::scoped): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h|  2 +-
 gcc/rust/resolve/rust-forever-stack.hxx  |  5 +++--
 gcc/rust/resolve/rust-name-resolution-context.cc | 15 ---
 gcc/rust/resolve/rust-name-resolution-context.h  |  9 +
 4 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 28509259497..c548eeae087 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -416,7 +416,7 @@ public:
* @param path An optional path if the Rib was created due to a "named"
*lexical scope, like a module's.
*/
-  void push (Rib rib, NodeId id, tl::optional path = {});
+  void push (Rib::Kind rib_kind, NodeId id, tl::optional path = 
{});
 
   /**
* Pop the innermost Rib from the stack
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 31f8ba498b3..58164a4d328 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -52,9 +52,10 @@ ForeverStack::Node::insert_child (Link link, Node child)
 
 template 
 void
-ForeverStack::push (Rib rib, NodeId id, tl::optional path)
+ForeverStack::push (Rib::Kind rib_kind, NodeId id,
+  tl::optional path)
 {
-  push_inner (rib, Link (id, path));
+  push_inner (rib_kind, Link (id, path));
 }
 
 template 
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 9bfaa094abe..1b375213878 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -103,13 +103,13 @@ NameResolutionContext::lookup (NodeId usage) const
 }
 
 void
-NameResolutionContext::scoped (Rib rib, NodeId id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, NodeId id,
   std::function lambda,
   tl::optional path)
 {
-  values.push (rib, id, path);
-  types.push (rib, id, path);
-  macros.push (rib, id, path);
+  values.push (rib_kind, id, path);
+  types.push (rib_kind, id, path);
+  macros.push (rib_kind, id, path);
   // labels.push (rib, id);
 
   lambda ();
@@ -121,17 +121,18 @@ NameResolutionContext::scoped (Rib rib, NodeId id,
 }
 
 void
-NameResolutionContext::scoped (Rib rib, Namespace ns, NodeId scope_id,
+NameResolutionContext::scoped (Rib::Kind rib_kind, Namespace ns,
+  NodeId scope_id,
   std::function lambda,
   tl::optional path)
 {
   switch (ns)
 {
 case Namespace::Values:
-  values.push (rib, scope_id, path);
+  values.push (rib_kind, scope_id, path);
   break;
 case Namespace::Types:
-  types.push (rib, scope_id, path);
+  types.push (rib_kind, scope_id, path);
   break;
 case Namespace::Labels:
 case Namespace::Macros:
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index cd6fa931be5..183ce7f3c2e 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -185,8 +185,8 @@ public:
* function. This variant of the function enters a new scope in *all*
* namespaces, while the second variant enters a scope in *one* namespace.
*
-   * @param rib New `Rib` to create when entering this scope. A function `Rib`,
-   *or an item `Rib`... etc
+   * @param rib_kind New `Rib` to create when entering this scope. A function
+   *`Rib`, or an item `Rib`... etc
* @param scope_id node ID of the scope we are entering, e.g the block's
*`NodeId`.
* @param lambda Function to run within that scope
@@ -196,9 +196,10 @@ public:
*/
   // FIXME: Do we want to handle something in particular for expected within 
the
   // scoped lambda?
-  void scoped (Rib rib, NodeId scope_id, std::function lambda,
+  void scoped (Rib::Kind rib_kind, NodeId scope_id,
+  std::function lambda,
   tl::optional path = {});
-  void scoped (Rib rib, Namespace ns, NodeId scope_id,
+  void scoped (Rib::Kind rib_kind, Namespace ns, NodeId scope_id,
   std::function lambda,
   tl::optional path = {});
 
-- 
2.45.2



[COMMITTED 043/146] gccrs: Use nr2.0 in PrivacyReporter

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

gcc/rust/ChangeLog:

* checks/errors/privacy/rust-privacy-reporter.cc
(PrivacyReporter::check_for_privacy_violation): Use name
resolver 2.0.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 .../checks/errors/privacy/rust-privacy-reporter.cc | 10 +-
 gcc/testsuite/rust/compile/nr2/exclude |  2 --
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 3413e5ab3dd..dcc7681 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -127,8 +127,16 @@ PrivacyReporter::check_for_privacy_violation (const NodeId 
&use_id,
 {
   NodeId ref_node_id = UNKNOWN_NODEID;
 
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  if (auto id = nr_ctx.lookup (use_id))
+   ref_node_id = *id;
+}
   // FIXME: Don't assert here - we might be dealing with a type
-  if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
+  else if (!resolver.lookup_resolved_name (use_id, &ref_node_id))
 resolver.lookup_resolved_type (use_id, &ref_node_id);
 
   // FIXME: Assert here. For now, we return since this causes issues when
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index a73b1f027b1..2e956960dad 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -145,8 +145,6 @@ parse_complex_generic_application.rs
 parse_complex_generic_application2.rs
 path_as_generic_arg.rs
 pattern-struct.rs
-privacy1.rs
-privacy3.rs
 privacy4.rs
 privacy5.rs
 privacy8.rs
-- 
2.45.2



[COMMITTED 052/146] gccrs: improve handling of Self Type paths

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

TypePaths have special handling for Self where we can look at the current ctx
for more acurate TypeAlias information if required. We cant do this for Impl
contexts but not for Traits as we might as well fall back to the TypePathProbe.

The other issue was the dyn type comming in because Foo::foo and Foo is a trait
reference we represent this as a dyn type as the root resolved path but then 
find
the associated impl block for this but we cannot do this when we have resolved 
to
a Dyn because this is just a representation that we know we are talking about a
trait not because we are actually working with a real Dyn type.

Fixes Rust-GCC#2907

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): 
track trait
* typecheck/rust-hir-type-check-implitem.cc: trait block
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_segments): dont when dyn
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): look at 
Self contenxt
(TypeCheckType::resolve_root_path): track if Self
(TypeCheckType::resolve_associated_type): look at current context for 
associated types
* typecheck/rust-hir-type-check-type.h: change prototype
* typecheck/rust-hir-type-check.h (class TypeCheckBlockContextItem):
new context system to track current state
* typecheck/rust-typecheck-context.cc 
(TypeCheckContext::have_block_context): likewise
(TypeCheckContext::peek_block_context): likewise
(TypeCheckContext::push_block_context): likewise
(TypeCheckContext::pop_block_context): likewise
(TypeCheckBlockContextItem::Item::Item): likewise
(TypeCheckBlockContextItem::TypeCheckBlockContextItem): likewise
(TypeCheckBlockContextItem::is_impl_block): likewise
(TypeCheckBlockContextItem::is_trait_block): likewise
(TypeCheckBlockContextItem::get_impl_block): likewise
(TypeCheckBlockContextItem::get_trait): likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |   2 +
 .../typecheck/rust-hir-type-check-implitem.cc |   3 +
 .../typecheck/rust-hir-type-check-path.cc |   3 +-
 .../typecheck/rust-hir-type-check-type.cc | 195 --
 gcc/rust/typecheck/rust-hir-type-check-type.h |   9 +-
 gcc/rust/typecheck/rust-hir-type-check.h  |  38 
 gcc/rust/typecheck/rust-typecheck-context.cc  |  64 ++
 gcc/testsuite/rust/compile/issue-2907.rs  |  33 +++
 gcc/testsuite/rust/compile/nr2/exclude|   1 +
 9 files changed, 287 insertions(+), 61 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2907.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 6f2589a0d2b..2fbf123aa77 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -278,6 +278,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 }
   self->inherit_bounds (specified_bounds);
 
+  context->push_block_context (TypeCheckBlockContextItem (trait_reference));
   std::vector item_refs;
   for (auto &item : trait_reference->get_trait_items ())
 {
@@ -307,6 +308,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
   // resolve the blocks of functions etc because it can end up in a recursive
   // loop of trying to resolve traits as required by the types
   tref->on_resolved ();
+  context->pop_block_context ();
 
   return tref;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 602076811c3..5da88b890f3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -335,7 +335,10 @@ TypeCheckImplItem::Resolve (
 
   // resolve
   TypeCheckImplItem resolver (parent, self, substitutions);
+  resolver.context->push_block_context (TypeCheckBlockContextItem (&parent));
   item.accept_vis (resolver);
+  resolver.context->pop_block_context ();
+
   return resolver.result;
 }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cd0e941edd6..4746e7d730d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -355,6 +355,7 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_node_id,
   NodeId resolved_node_id = root_resolved_node_id;
   TyTy::BaseType *prev_segment = tyseg;
   bool reciever_is_generic = prev_segment->get_kind () == 
TyTy::TypeKind::PARAM;
+  bool reciever_is_dyn = prev_segment->get_kind () == TyTy::TypeKind::DYNAMIC;
 
   for (size_t i = offset; i < segments.size (); i++)
 {
@@ -434,7 +435,7 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_nod

[COMMITTED 045/146] gccrs: Use nr2.0 in typechecker

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

I probably missed a few spots, but this should cover most of the type
checker.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc: Add includes.
(TypeCheckExpr::visit): Use name resolver 2.0.
(TypeCheckExpr::resolve_operator_overload): Likewise.
(TypeCheckExpr::resolve_fn_trait_call): Likewise.
* typecheck/rust-hir-type-check-path.cc
(TypeCheckExpr::visit): Likewise.
(TypeCheckExpr::resolve_segments): Likewise.
* typecheck/rust-hir-type-check-type.cc
(TypeCheckType::resolve_segments): Likewise.
(ResolveWhereClauseItem::visit): Likewise.
(TypeCheckType::visit): Avoid usage of
Resolver::get_unit_type_node_id when handling TupleType, use
name resolver 2.0 when handling QualifiedPathInType.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 .../typecheck/rust-hir-type-check-expr.cc |  45 ++-
 .../typecheck/rust-hir-type-check-path.cc |  27 +++-
 .../typecheck/rust-hir-type-check-type.cc | 122 +-
 gcc/testsuite/rust/compile/nr2/exclude|   4 -
 4 files changed, 155 insertions(+), 43 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index d9f0361389f..03922bb554c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -27,6 +27,10 @@
 #include "rust-hir-type-check-stmt.h"
 #include "rust-hir-type-check-item.h"
 #include "rust-type-util.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace Resolver {
@@ -1238,8 +1242,17 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
   // store the expected fntype
   context->insert_type (expr.get_method_name ().get_mappings (), lookup);
 
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx = const_cast (
+   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+  nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid 
()),
+   Resolver2_0::Definition (resolved_node_id));
+}
   // set up the resolved name on the path
-  if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+  else if (resolver->get_name_scope ().decl_was_declared_here (
+resolved_node_id))
 {
   resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
  resolved_node_id);
@@ -1821,8 +1834,19 @@ TypeCheckExpr::resolve_operator_overload (LangItem::Kind 
lang_item_type,
   context->insert_operator_overload (expr.get_mappings ().get_hirid (), type);
 
   // set up the resolved name on the path
-  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- resolved_node_id);
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx = const_cast (
+   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+  nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid 
()),
+   Resolver2_0::Definition (resolved_node_id));
+}
+  else
+{
+  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ resolved_node_id);
+}
 
   // return the result of the function back
   infered = function_ret_tyty;
@@ -1991,8 +2015,19 @@ TypeCheckExpr::resolve_fn_trait_call (HIR::CallExpr 
&expr,
   context->insert_operator_overload (expr.get_mappings ().get_hirid (), fn);
 
   // set up the resolved name on the path
-  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- resolved_node_id);
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx = const_cast (
+   Resolver2_0::ImmutableNameResolutionContext::get ().resolver ());
+
+  nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid 
()),
+   Resolver2_0::Definition (resolved_node_id));
+}
+  else
+{
+  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ resolved_node_id);
+}
 
   // return the result of the function back
   *result = function_ret_tyty;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cc79e4d4995..cd0e941edd6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -153,8 +153,20 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
   bool fully_resolved = expr.get_segments ().size () <= 1;
   if (fully_resolved)
 {
-  resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
- root_resolved_node_id);
+  if (flag_name_resolution_2_0)
+   {
+  

[COMMITTED 054/146] gccrs: ensure packed and aligned is applied properly

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

We cannot apply aligned or packed after layout_type is called you need
to set this up first then call it.

Fixes Rust-GCC#3260

gcc/rust/ChangeLog:

* backend/rust-compile-type.cc (TyTyResolveCompile::visit): call lauout 
type directly
* rust-backend.h (struct_type): add optional layout parameter
(union_type): likewise
(fill_in_fields): likewise
* rust-gcc.cc (struct_type): likewise
(union_type): likewise
(fill_in_fields): only layout if we required

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-type.cc |  8 +---
 gcc/rust/rust-backend.h   |  6 +++---
 gcc/rust/rust-gcc.cc  | 15 +--
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 56d64e1405b..50b52fbd37f 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -22,6 +22,7 @@
 #include "rust-gcc.h"
 
 #include "tree.h"
+#include "stor-layout.h"
 
 namespace Rust {
 namespace Compile {
@@ -268,8 +269,8 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
  fields.push_back (std::move (f));
}
 
-  type_record = type.is_union () ? Backend::union_type (fields)
-: Backend::struct_type (fields);
+  type_record = type.is_union () ? Backend::union_type (fields, false)
+: Backend::struct_type (fields, false);
 }
   else
 {
@@ -359,7 +360,7 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
}
 
   // finally make the union or the enum
-  type_record = Backend::union_type (enum_fields);
+  type_record = Backend::union_type (enum_fields, false);
 }
 
   // Handle repr options
@@ -381,6 +382,7 @@ TyTyResolveCompile::visit (const TyTy::ADTType &type)
   SET_TYPE_ALIGN (type_record, repr.align * 8);
   TYPE_USER_ALIGN (type_record) = 1;
 }
+  layout_type (type_record);
 
   std::string named_struct_str
 = type.get_ident ().path.get () + type.subst_as_string ();
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 9d28cf6d393..414799edefe 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -133,11 +133,11 @@ function_ptr_type (tree result, const std::vector 
&praameters,
 
 // Get a struct type.
 tree
-struct_type (const std::vector &fields);
+struct_type (const std::vector &fields, bool layout = true);
 
 // Get a union type.
 tree
-union_type (const std::vector &fields);
+union_type (const std::vector &fields, bool layout = true);
 
 // Get an array type.
 tree
@@ -496,7 +496,7 @@ write_global_definitions (const std::vector 
&type_decls,
 // TODO: make static
 
 tree
-fill_in_fields (tree, const std::vector &);
+fill_in_fields (tree, const std::vector &, bool);
 
 tree fill_in_array (tree, tree, tree);
 
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab7889b0..59983ede97d 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -592,23 +592,24 @@ function_ptr_type (tree result_type, const 
std::vector ¶meters,
 // Make a struct type.
 
 tree
-struct_type (const std::vector &fields)
+struct_type (const std::vector &fields, bool layout)
 {
-  return fill_in_fields (make_node (RECORD_TYPE), fields);
+  return fill_in_fields (make_node (RECORD_TYPE), fields, layout);
 }
 
 // Make a union type.
 
 tree
-union_type (const std::vector &fields)
+union_type (const std::vector &fields, bool layout)
 {
-  return fill_in_fields (make_node (UNION_TYPE), fields);
+  return fill_in_fields (make_node (UNION_TYPE), fields, layout);
 }
 
 // Fill in the fields of a struct or union type.
 
 tree
-fill_in_fields (tree fill, const std::vector &fields)
+fill_in_fields (tree fill, const std::vector &fields,
+   bool layout)
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
@@ -625,7 +626,9 @@ fill_in_fields (tree fill, const 
std::vector &fields)
   pp = &DECL_CHAIN (field);
 }
   TYPE_FIELDS (fill) = field_trees;
-  layout_type (fill);
+
+  if (layout)
+layout_type (fill);
 
   // Because Rust permits converting between named struct types and
   // equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
-- 
2.45.2



[COMMITTED 055/146] gccrs: lang-items: Move comment about arithmetic lang items

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

gcc/rust/ChangeLog:

* util/rust-lang-item.h: Fix comment location to align with other 
comments.
---
 gcc/rust/util/rust-lang-item.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 951e4a3ceaf..92c70bbddf4 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -23,12 +23,12 @@
 
 namespace Rust {
 
-// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
 class LangItem
 {
 public:
   enum class Kind
   {
+// 
https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
 ADD,
 SUBTRACT,
 MULTIPLY,
-- 
2.45.2



[COMMITTED 064/146] gccrs: fix crash in hir dump

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

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): add missing check for no return 
value

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index be785b9ebec..2590eed19ae 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1365,7 +1365,8 @@ Dump::visit (ReturnExpr &e)
   begin ("ReturnExpr");
   do_mappings (e.get_mappings ());
 
-  visit_field ("return_expr", e.get_expr ());
+  if (e.has_return_expr ())
+visit_field ("return_expr", e.get_expr ());
 
   end ("ReturnExpr");
 }
-- 
2.45.2



[COMMITTED 062/146] gccrs: add checks for division by zero and left shift overflow

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

These are ported from the c-family code c-warn.cc and c/c-typchk.cc

Fixes Rust-GCC#2394

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_store_expression): check for null
(eval_call_expression): remove bad warning
* rust-gcc.cc (arithmetic_or_logical_expression): add warnings

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-constexpr.cc   |  8 +---
 gcc/rust/rust-gcc.cc | 11 +++
 gcc/testsuite/rust/compile/issue-2394.rs | 14 ++
 3 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2394.rs

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index bfd7d959aa8..2f2bbbd921d 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2929,8 +2929,13 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
}
 }
 
+  if (*non_constant_p)
+return t;
+
   /* Don't share a CONSTRUCTOR that might be changed later.  */
   init = unshare_constructor (init);
+  if (init == NULL_TREE)
+return t;
 
   if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
   && TREE_CODE (init) == CONSTRUCTOR)
@@ -3585,9 +3590,6 @@ eval_call_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
  result = *ctx->global->values.get (res);
  if (result == NULL_TREE && !*non_constant_p)
{
- if (!ctx->quiet)
-   error ("% call flows off the end "
-  "of the function");
  *non_constant_p = true;
}
}
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 59983ede97d..7da5e2c5637 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1106,6 +1106,17 @@ arithmetic_or_logical_expression 
(ArithmeticOrLogicalOperator op, tree left,
   if (floating_point && extended_type != NULL_TREE)
 ret = convert (original_type, ret);
 
+  if (op == ArithmeticOrLogicalOperator::DIVIDE
+  && (integer_zerop (right) || fixed_zerop (right)))
+{
+  rust_error_at (location, "division by zero");
+}
+  else if (op == ArithmeticOrLogicalOperator::LEFT_SHIFT
+  && (compare_tree_int (right, TYPE_PRECISION (TREE_TYPE (ret))) >= 0))
+{
+  rust_error_at (location, "left shift count >= width of type");
+}
+
   return ret;
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-2394.rs 
b/gcc/testsuite/rust/compile/issue-2394.rs
new file mode 100644
index 000..92f7afc6507
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2394.rs
@@ -0,0 +1,14 @@
+const A: i32 = (1 / 0);
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+fn main() {
+let a = 1 / 0;
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+let b = 3;
+let c = b / 0;
+// { dg-error "division by zero" "" { target *-*-* } .-1 }
+
+let a = 1 << 500;
+// { dg-error "left shift count >= width of type" "" { target *-*-* } .-1 }
+}
-- 
2.45.2



[COMMITTED 079/146] gccrs: Made changes to AST::TraitImpl constructor for TypePath

2025-03-21 Thread arthur . cohen
From: Sri Ganesh Thota 

gcc/rust/ChangeLog:

* ast/rust-item.h: I have changed helper constructor for typepath
to be a delegating constructor.

Signed-off-by: Sri Ganesh Thota 
---
 gcc/rust/ast/rust-item.h | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index dca4aab45c8..6b77449eb8d 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3197,19 +3197,18 @@ public:
   trait_path (std::move (trait_path)), impl_items (std::move (impl_items))
   {}
 
-  // Helper constructor with a typepath
+  // Delegating constructor for TypePath
   TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam,
 std::vector> impl_items,
 std::vector> generic_params,
 std::unique_ptr trait_type, WhereClause where_clause,
 Visibility vis, std::vector inner_attrs,
 std::vector outer_attrs, location_t locus)
-: Impl (std::move (generic_params), std::move (trait_type),
-   std::move (where_clause), std::move (vis), std::move (inner_attrs),
-   std::move (outer_attrs), locus),
-  has_unsafe (is_unsafe), has_exclam (has_exclam),
-  trait_path (std::unique_ptr (new TypePath (trait_path))),
-  impl_items (std::move (impl_items))
+: TraitImpl (std::unique_ptr (new TypePath (trait_path)), is_unsafe,
+has_exclam, std::move (impl_items), std::move (generic_params),
+std::move (trait_type), std::move (where_clause),
+std::move (vis), std::move (inner_attrs),
+std::move (outer_attrs), locus)
   {}
 
   // Copy constructor with vector clone
-- 
2.45.2



[COMMITTED 083/146] gccrs: resolve: Name resolve trait bounds properly

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

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): 
Resolve additional
trait bounds.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Error out 
properly on unresolved
type-path instead of crashing.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Exclude additional-trait-bounds2 for 
different error message.
* rust/compile/additional-trait-bounds1.rs: New test.
* rust/compile/additional-trait-bounds2.rs: New test.
* rust/compile/additional-trait-bounds2nr2.rs: New test.
---
 gcc/rust/resolve/rust-ast-resolve-type.cc | 57 ++-
 .../resolve/rust-late-name-resolver-2.0.cc|  3 +-
 .../rust/compile/additional-trait-bounds1.rs  | 10 
 .../rust/compile/additional-trait-bounds2.rs  |  9 +++
 .../compile/additional-trait-bounds2nr2.rs| 11 
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 6 files changed, 87 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds1.rs
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds2.rs
 create mode 100644 gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index ec5e8a762a7..cb5a18d5d47 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -18,6 +18,8 @@
 
 #include "rust-ast-resolve-type.h"
 #include "rust-ast-resolve-expr.h"
+#include "rust-canonical-path.h"
+#include "rust-type.h"
 
 namespace Rust {
 namespace Resolver {
@@ -495,10 +497,59 @@ ResolveTypeToCanonicalPath::visit 
(AST::TraitObjectTypeOneBound &type)
 }
 
 void
-ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
+ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type)
 {
-  // FIXME is this actually allowed? dyn A+B
-  rust_unreachable ();
+  rust_assert (!type.get_type_param_bounds ().empty ());
+
+  auto &first_bound = type.get_type_param_bounds ().front ();
+
+  // Is it allowed or even possible to have a lifetime bound as a first bound?
+  if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME)
+rust_unreachable ();
+
+  auto &trait = static_cast (*first_bound);
+
+  CanonicalPath path = CanonicalPath::create_empty ();
+  bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
+
+  // right?
+  rust_assert (ok);
+
+  auto slice_path = "get_bound_type ())
+   {
+ case AST::TypeParamBound::TRAIT: {
+   auto bound_path = CanonicalPath::create_empty ();
+
+   auto &bound_type_path
+ = static_cast (*additional_bound)
+ .get_type_path ();
+   bool ok
+ = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path);
+
+   if (!ok)
+ continue;
+
+   str = bound_path.get ();
+   break;
+ }
+   case AST::TypeParamBound::LIFETIME:
+ rust_unreachable ();
+ break;
+   }
+  slice_path += " + " + str;
+}
+
+  slice_path += ">";
+
+  result = CanonicalPath::new_seg (type.get_node_id (), slice_path);
 }
 
 void
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 ac5f1c57546..40f067319b5 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -282,7 +282,8 @@ Late::visit (AST::TypePath &type)
 ctx.map_usage (Usage (type.get_node_id ()),
   Definition (resolved->get_node_id ()));
   else
-rust_unreachable ();
+rust_error_at (type.get_locus (), "could not resolve type path %qs",
+  str.c_str ());
 
   DefaultResolver::visit (type);
 }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds1.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
new file mode 100644
index 000..449a72fe461
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds1.rs
@@ -0,0 +1,10 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send {}
+impl dyn A + Send + Sync {}
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
new file mode 100644
index 000..843228ae9a6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/additional-trait-bounds2.rs
@@ -0,0 +1,9 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {}
+
+impl dyn A + Send + Sync + NonExist {} // { dg-error "failed to resolve 
TypePath: NonExist in this scope" }
diff --git a/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs 
b/gcc/testsuite/rust/compile/additional-trait-bounds2nr2.rs
new file mode 100644
index 000..6764f6e8012
--- /de

[COMMITTED 089/146] gccrs: ast-builder: Add more methods

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

This commit adds new methods for building pattern nodes, match expressions and 
more precise call expressions.

gcc/rust/ChangeLog:

* ast/rust-ast-builder.cc: Add new functions.
* ast/rust-ast-builder.h: Declare them.
---
 gcc/rust/ast/rust-ast-builder.cc | 91 
 gcc/rust/ast/rust-ast-builder.h  | 30 +++
 2 files changed, 121 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 529c686db1b..2fb041abcc0 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -20,6 +20,7 @@
 #include "rust-ast-builder-type.h"
 #include "rust-common.h"
 #include "rust-expr.h"
+#include "rust-path.h"
 #include "rust-token.h"
 #include "rust-make-unique.h"
 
@@ -42,6 +43,33 @@ Builder::call (std::unique_ptr &&path,
 new CallExpr (std::move (path), std::move (args), {}, loc));
 }
 
+std::unique_ptr
+Builder::call (std::unique_ptr &&path,
+  std::vector> &&args) const
+{
+  return call (std::unique_ptr (
+new PathInExpression (std::move (path), {}, loc)),
+  std::move (args));
+}
+
+std::unique_ptr
+Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
+{
+  auto args = std::vector> ();
+  args.emplace_back (std::move (arg));
+
+  return call (std::move (path), std::move (args));
+}
+
+std::unique_ptr
+Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
+{
+  auto args = std::vector> ();
+  args.emplace_back (std::move (arg));
+
+  return call (std::move (path), std::move (args));
+}
+
 std::unique_ptr
 Builder::array (std::vector> &&members) const
 {
@@ -56,6 +84,13 @@ Builder::identifier (std::string name) const
   return std::unique_ptr (new IdentifierExpr (name, {}, loc));
 }
 
+std::unique_ptr
+Builder::identifier_pattern (std::string name, bool mut) const
+{
+  return std::unique_ptr (
+new IdentifierPattern (name, loc, false, mut));
+}
+
 std::unique_ptr
 Builder::tuple_idx (std::string receiver, int idx) const
 {
@@ -117,6 +152,22 @@ Builder::path_in_expression (std::vector 
&&segments) const
   return PathInExpression (std::move (path_segments), {}, loc);
 }
 
+PathInExpression
+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 &&tail_expr) const
+{
+  auto stmts = std::vector> ();
+  stmts.emplace_back (std::move (stmt));
+
+  return block (std::move (stmts), std::move (tail_expr));
+}
+
 std::unique_ptr
 Builder::block (std::vector> &&stmts,
std::unique_ptr &&tail_expr) const
@@ -189,6 +240,46 @@ Builder::wildcard () const
   return std::unique_ptr (new WildcardPattern (loc));
 }
 
+std::unique_ptr
+Builder::lang_item_path (LangItem::Kind kind) const
+{
+  return std::unique_ptr (new LangItemPath (kind, loc));
+}
+
+std::unique_ptr
+Builder::match (std::unique_ptr &&scrutinee,
+   std::vector &&cases)
+{
+  return std::unique_ptr (
+new MatchExpr (std::move (scrutinee), std::move (cases), {}, {}, loc));
+}
+
+MatchArm
+Builder::match_arm (std::unique_ptr &&pattern)
+{
+  auto patterns = std::vector> ();
+  patterns.emplace_back (std::move (pattern));
+
+  return MatchArm (std::move (patterns), loc);
+}
+
+MatchCase
+Builder::match_case (std::unique_ptr &&pattern,
+std::unique_ptr &&expr)
+{
+  return MatchCase (match_arm (std::move (pattern)), std::move (expr));
+}
+
+std::unique_ptr
+Builder::loop (std::vector> &&stmts)
+{
+  auto block = std::unique_ptr (
+new BlockExpr (std::move (stmts), nullptr, {}, {}, LoopLabel::error (), 
loc,
+  loc));
+
+  return std::unique_ptr (new LoopExpr (std::move (block), loc));
+}
+
 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 bad79d067ad..6e07df6e182 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -20,6 +20,7 @@
 #define AST_BUILDER_H
 
 #include "rust-ast-full.h"
+#include "rust-expr.h"
 
 namespace Rust {
 namespace AST {
@@ -38,6 +39,8 @@ public:
 
   /* Create an identifier expression (`variable`) */
   std::unique_ptr identifier (std::string name) const;
+  std::unique_ptr identifier_pattern (std::string name,
+  bool mut = false) const;
 
   /* Create a tuple index expression (`receiver.0`) */
   std::unique_ptr tuple_idx (std::string receiver, int idx) const;
@@ -53,6 +56,9 @@ public:
   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;
 
   /* Create a let binding with an optional type and in

[COMMITTED 059/146] gccrs: ast: Use StackedContexts class in ContextualASTVisitor

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

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.h: Replace context with StackedContexts.
* ast/rust-ast-visitor.cc (ContextualASTVisitor::visit): Use new APIs.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit): Likewise.
---
 gcc/rust/ast/rust-ast-visitor.cc  | 16 +++
 gcc/rust/ast/rust-ast-visitor.h   | 10 --
 gcc/rust/checks/errors/rust-ast-validation.cc | 20 ---
 3 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 8f53e528131..a390aa20bcb 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1453,33 +1453,33 @@ DefaultASTVisitor::visit (AST::VariadicParam ¶m)
 void
 ContextualASTVisitor::visit (AST::Crate &crate)
 {
-  push_context (Context::CRATE);
+  ctx.enter (Kind::CRATE);
   DefaultASTVisitor::visit (crate);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::InherentImpl &impl)
 {
-  push_context (Context::INHERENT_IMPL);
+  ctx.enter (Kind::INHERENT_IMPL);
   DefaultASTVisitor::visit (impl);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::TraitImpl &impl)
 {
-  push_context (Context::TRAIT_IMPL);
+  ctx.enter (Kind::TRAIT_IMPL);
   DefaultASTVisitor::visit (impl);
-  pop_context ();
+  ctx.exit ();
 }
 
 void
 ContextualASTVisitor::visit (AST::Trait &trait)
 {
-  push_context (Context::TRAIT);
+  ctx.enter (Kind::TRAIT);
   DefaultASTVisitor::visit (trait);
-  pop_context ();
+  ctx.exit ();
 }
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 50b93016d62..7e3423cd493 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -26,6 +26,7 @@
 #include "rust-item.h"
 #include "rust-path.h"
 #include "rust-system.h"
+#include "rust-stacked-contexts.h"
 
 namespace Rust {
 namespace AST {
@@ -452,7 +453,7 @@ public:
 class ContextualASTVisitor : public DefaultASTVisitor
 {
 protected:
-  enum class Context
+  enum class Kind
   {
 FUNCTION,
 INHERENT_IMPL,
@@ -461,6 +462,7 @@ protected:
 MODULE,
 CRATE,
   };
+
   using DefaultASTVisitor::visit;
 
   virtual void visit (AST::Crate &crate) override;
@@ -476,11 +478,7 @@ protected:
 DefaultASTVisitor::visit (item);
   }
 
-  std::vector context;
-
-  void push_context (Context ctx) { context.push_back (ctx); }
-
-  void pop_context () { context.pop_back (); }
+  StackedContexts ctx;
 };
 
 } // namespace AST
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index 7938286ffb5..59b28057bab 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -56,7 +56,7 @@ ASTValidation::visit (AST::LoopLabel &label)
 void
 ASTValidation::visit (AST::ConstantItem &const_item)
 {
-  if (!const_item.has_expr () && context.back () != Context::TRAIT_IMPL)
+  if (!const_item.has_expr () && ctx.peek () != Kind::TRAIT_IMPL)
 {
   rust_error_at (const_item.get_locus (),
 "associated constant in % without body");
@@ -82,23 +82,19 @@ ASTValidation::visit (AST::Function &function)
   "functions cannot be both % and %");
 
   if (qualifiers.is_const ()
-  && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+  && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
 rust_error_at (function.get_locus (), ErrorCode::E0379,
   "functions in traits cannot be declared %");
 
   // may change soon
   if (qualifiers.is_async ()
-  && (context.back () == Context::TRAIT_IMPL
- || context.back () == Context::TRAIT))
+  && (ctx.peek () == Kind::TRAIT_IMPL || ctx.peek () == Kind::TRAIT))
 rust_error_at (function.get_locus (), ErrorCode::E0706,
   "functions in traits cannot be declared %");
 
   // if not an associated function but has a self parameter
-  if (context.back () != Context::TRAIT
-  && context.back () != Context::TRAIT_IMPL
-  && context.back () != Context::INHERENT_IMPL
-  && function.has_self_param ())
+  if (ctx.peek () != Kind::TRAIT && ctx.peek () != Kind::TRAIT_IMPL
+  && ctx.peek () != Kind::INHERENT_IMPL && function.has_self_param ())
 rust_error_at (
   function.get_self_param ().get_locus (),
   "% parameter is only allowed in associated functions");
@@ -140,11 +136,11 @@ ASTValidation::visit (AST::Function &function)
 {
   if (!function.has_body ())
{
- if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+ if (ctx.peek () == Kind::INHERENT_IMPL
+ || ctx.peek () == Kind::TRAIT_IMPL)
rust_error_at (function.get_locus (),
   "associated function in % w

[COMMITTED 058/146] gccrs: stacked-contexts: Add peek() method

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

gcc/rust/ChangeLog:

* util/rust-stacked-contexts.h: Add new method to see what context we 
are currently in.
---
 gcc/rust/util/rust-stacked-contexts.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/util/rust-stacked-contexts.h 
b/gcc/rust/util/rust-stacked-contexts.h
index 39a0c08de79..fe0bc8a291b 100644
--- a/gcc/rust/util/rust-stacked-contexts.h
+++ b/gcc/rust/util/rust-stacked-contexts.h
@@ -71,6 +71,13 @@ public:
 return last;
   }
 
+  const T &peek ()
+  {
+rust_assert (!stack.empty ());
+
+return stack.back ();
+  }
+
   /**
* Are we currently inside of a special context?
*/
-- 
2.45.2



[COMMITTED 080/146] gccrs: add ptr to int and int to ptr type cast rules

2025-03-21 Thread arthur . cohen
From: Nobel 

Added rules to allow type casting pointer as integer types (u*,i*)
and integer types to be casted as pointer.

gcc/rust/ChangeLog:

* typecheck/rust-casts.cc (TypeCastRules::cast_rules): Add rule.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Nobel Singh 
---
 gcc/rust/typecheck/rust-casts.cc   | 27 --
 gcc/testsuite/rust/compile/ptr_int_cast.rs | 18 +++
 2 files changed, 43 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/ptr_int_cast.rs

diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc
index cf4de4b3320..694cbaa5db6 100644
--- a/gcc/rust/typecheck/rust-casts.cc
+++ b/gcc/rust/typecheck/rust-casts.cc
@@ -210,6 +210,16 @@ TypeCastRules::cast_rules ()
  }
  break;
 
+ case TyTy::TypeKind::POINTER: {
+   // char can't be casted as a ptr
+   bool from_char
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::CHAR;
+   if (!from_char)
+ return TypeCoercionRules::CoercionResult{{},
+  to.get_ty ()->clone ()};
+ }
+ break;
+
case TyTy::TypeKind::INFER:
case TyTy::TypeKind::USIZE:
case TyTy::TypeKind::ISIZE:
@@ -254,12 +264,25 @@ TypeCastRules::cast_rules ()
 case TyTy::TypeKind::POINTER:
   switch (to.get_ty ()->get_kind ())
{
+   case TyTy::TypeKind::USIZE:
+   case TyTy::TypeKind::ISIZE:
+   case TyTy::TypeKind::UINT:
+ case TyTy::TypeKind::INT: {
+   // refs should not cast to numeric type
+   bool from_ptr
+ = from.get_ty ()->get_kind () == TyTy::TypeKind::POINTER;
+   if (from_ptr)
+ {
+   return TypeCoercionRules::CoercionResult{
+ {}, to.get_ty ()->clone ()};
+ }
+ }
+ break;
+
case TyTy::TypeKind::REF:
case TyTy::TypeKind::POINTER:
  return check_ptr_ptr_cast ();
 
- // FIXME can you cast a pointer to a integral type?
-
default:
  return TypeCoercionRules::CoercionResult::get_error ();
}
diff --git a/gcc/testsuite/rust/compile/ptr_int_cast.rs 
b/gcc/testsuite/rust/compile/ptr_int_cast.rs
new file mode 100644
index 000..3a2a5d563d6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/ptr_int_cast.rs
@@ -0,0 +1,18 @@
+fn main(){
+let foo = 1337;
+let bar_ptr = &foo as *const i32;
+
+let bar_ptr_usize = bar_ptr as usize;
+let bar_ptr_isize = bar_ptr as isize;
+let bar_ptr_u64 = bar_ptr as u64;
+let bar_ptr_i64 = bar_ptr as i64;
+let bar_ptr_i8 = bar_ptr as i8;
+let bar_ptr_u8 = bar_ptr as u8;
+
+let _ = bar_ptr_usize as *const i32;
+let _ = bar_ptr_isize as *const i32;
+let _ = bar_ptr_u64 as *const i32;
+let _ = bar_ptr_i64 as *const i32;
+let _ = bar_ptr_i8 as *const i32;
+let _ = bar_ptr_u8 as *const i32;
+}
-- 
2.45.2



[COMMITTED 061/146] gccrs: constant evaluation like these are coercion sites

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

The code here was wrongly assuming the decl type from the folding of the
expression would be the type of the constant decl. This is not the case for
unsized coercions for slices, where the expression here is a reference to
an array then we require the coercion to fix the result up to the expected
type.

Fixes Rust-GCC#1525

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: apply coercion site to result
* backend/rust-compile-base.h: update prototype
* backend/rust-compile-implitem.cc (CompileTraitItem::visit): send in 
coercion info
* backend/rust-compile-item.cc (CompileItem::visit): likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-base.cc | 15 +---
 gcc/rust/backend/rust-compile-base.h  |  6 +++--
 gcc/rust/backend/rust-compile-implitem.cc | 11 +++--
 gcc/rust/backend/rust-compile-item.cc | 29 ---
 gcc/testsuite/rust/compile/issue-1525.rs  |  4 
 5 files changed, 50 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-1525.rs

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index fb4aace9555..bcc7fc4fcbf 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -777,13 +777,18 @@ HIRCompileBase::compile_function (
 
 tree
 HIRCompileBase::compile_constant_item (
-  TyTy::BaseType *resolved_type, const Resolver::CanonicalPath &canonical_path,
-  HIR::Expr &const_value_expr, location_t locus)
+  HirId coercion_id, TyTy::BaseType *resolved_type,
+  TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path,
+  HIR::Expr &const_value_expr, location_t locus, location_t expr_locus)
 {
   const std::string &ident = canonical_path.get ();
 
   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
   tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+  tree actual_type = TyTyResolveCompile::compile (ctx, expected_type);
+  tree actual_const_type = build_qualified_type (actual_type, TYPE_QUAL_CONST);
+
   bool is_block_expr
 = const_value_expr.get_expression_type () == HIR::Expr::ExprType::Block;
 
@@ -851,7 +856,11 @@ HIRCompileBase::compile_constant_item (
   tree call = build_call_array_loc (locus, const_type, fndecl, 0, NULL);
   tree folded_expr = fold_expr (call);
 
-  return named_constant_expression (const_type, ident, folded_expr, locus);
+  // coercion site
+  tree coerced = coercion_site (coercion_id, folded_expr, resolved_type,
+   expected_type, locus, expr_locus);
+
+  return named_constant_expression (actual_const_type, ident, coerced, locus);
 }
 
 tree
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 5fb1d83f2ee..9328a7f7483 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -90,9 +90,11 @@ protected:
   void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
  TyTy::BaseType *fn_return_ty);
 
-  tree compile_constant_item (TyTy::BaseType *resolved_type,
+  tree compile_constant_item (HirId coercion_id, TyTy::BaseType *resolved_type,
+ TyTy::BaseType *expected_type,
  const Resolver::CanonicalPath &canonical_path,
- HIR::Expr &const_value_expr, location_t locus);
+ HIR::Expr &const_value_expr, location_t locus,
+ location_t expr_locus);
 
   tree compile_function (const std::string &fn_name, HIR::SelfParam 
&self_param,
 std::vector &function_params,
diff --git a/gcc/rust/backend/rust-compile-implitem.cc 
b/gcc/rust/backend/rust-compile-implitem.cc
index 129e97879fa..71b3e8d3002 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -45,9 +45,16 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
   rust_assert (canonical_path);
 
   HIR::Expr &const_value_expr = constant.get_expr ();
+  TyTy::BaseType *expr_type = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_type (
+const_value_expr.get_mappings ().get_hirid (), &expr_type);
+  rust_assert (ok);
+
   tree const_expr
-= compile_constant_item (resolved_type, *canonical_path, const_value_expr,
-constant.get_locus ());
+= compile_constant_item (constant.get_mappings ().get_hirid (), expr_type,
+resolved_type, *canonical_path, const_value_expr,
+constant.get_locus (),
+const_value_expr.get_locus ());
   ctx->push_const (const_expr);
   ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
 
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-c

[COMMITTED 112/146] gccrs: improve mutability checks

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

This ensures that we handle var decls readonly checks much better

Addresses: Rust-GCC#807 Rust-GCC#3287

gcc/rust/ChangeLog:

* checks/errors/rust-readonly-check.cc (check_decl): improve mut check
(emit_error): helper
(check_modify_expr): likewise
(readonly_walk_fn): reuse helper
(ReadonlyCheck::Lint): cleanup context each run

gcc/testsuite/ChangeLog:

* rust/execute/torture/builtin_macro_include_bytes.rs: needs mut
* rust/compile/mutability_checks1.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/checks/errors/rust-readonly-check.cc | 54 +++
 .../rust/compile/mutability_checks1.rs| 15 ++
 .../torture/builtin_macro_include_bytes.rs|  2 +-
 3 files changed, 61 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/mutability_checks1.rs

diff --git a/gcc/rust/checks/errors/rust-readonly-check.cc 
b/gcc/rust/checks/errors/rust-readonly-check.cc
index b8998985d89..c1289332116 100644
--- a/gcc/rust/checks/errors/rust-readonly-check.cc
+++ b/gcc/rust/checks/errors/rust-readonly-check.cc
@@ -19,10 +19,13 @@
 #include "rust-readonly-check.h"
 #include "rust-tree.h"
 #include "rust-gcc.h"
+#include "print-tree.h"
 
 namespace Rust {
 namespace Analysis {
 
+static std::map assignment_map = {};
+
 // ported over from c-family/c-warn.cc
 void
 readonly_error (location_t loc, tree arg, enum lvalue_use use)
@@ -106,37 +109,68 @@ readonly_error (location_t loc, tree arg, enum lvalue_use 
use)
 }
 
 static void
-check_decl (tree *t)
+emit_error (tree *t, tree lhs, enum lvalue_use use)
 {
-  if (TREE_CODE (*t) == MODIFY_EXPR)
+  readonly_error (EXPR_LOCATION (*t), lhs, use);
+  TREE_OPERAND (*t, 0) = error_mark_node;
+}
+
+static void
+check_modify_expr (tree *t)
+{
+  tree lhs = TREE_OPERAND (*t, 0);
+  if (TREE_CODE (lhs) == ARRAY_REF || TREE_CODE (lhs) == COMPONENT_REF)
+lhs = TREE_OPERAND (lhs, 0);
+
+  tree lhs_type = TREE_TYPE (lhs);
+  if (TYPE_READONLY (lhs_type) || TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
 {
-  tree lhs = TREE_OPERAND (*t, 0);
-  if (TREE_READONLY (lhs) || TREE_CONSTANT (lhs))
+  if (TREE_CODE (lhs) != VAR_DECL)
+   emit_error (t, lhs, lv_assign);
+  else if (!DECL_ARTIFICIAL (lhs))
{
- readonly_error (EXPR_LOCATION (*t), lhs, lv_assign);
- TREE_OPERAND (*t, 0) = error_mark_node;
+ if (DECL_INITIAL (lhs) != NULL)
+   emit_error (t, lhs, lv_assign);
+ else
+   {
+ if (assignment_map.find (lhs) == assignment_map.end ())
+   {
+ assignment_map.insert ({lhs, 0});
+   }
+ assignment_map[lhs]++;
+
+ if (assignment_map[lhs] > 1)
+   emit_error (t, lhs, lv_assign);
+   }
}
 }
 }
 
-static tree
-readonly_walk_fn (tree *t, int *, void *)
+static void
+check_decl (tree *t)
 {
   switch (TREE_CODE (*t))
 {
 case MODIFY_EXPR:
-  check_decl (t);
+  check_modify_expr (t);
   break;
 
 default:
   break;
 }
+}
+
+static tree
+readonly_walk_fn (tree *t, int *, void *)
+{
+  check_decl (t);
   return NULL_TREE;
 }
 
 void
 ReadonlyCheck::Lint (Compile::Context &ctx)
 {
+  assignment_map.clear ();
   for (auto &fndecl : ctx.get_func_decls ())
 {
   for (tree p = DECL_ARGUMENTS (fndecl); p != NULL_TREE; p = DECL_CHAIN 
(p))
@@ -148,12 +182,14 @@ ReadonlyCheck::Lint (Compile::Context &ctx)
&readonly_walk_fn, &ctx);
 }
 
+  assignment_map.clear ();
   for (auto &var : ctx.get_var_decls ())
 {
   tree decl = var->get_decl ();
   check_decl (&decl);
 }
 
+  assignment_map.clear ();
   for (auto &const_decl : ctx.get_const_decls ())
 {
   check_decl (&const_decl);
diff --git a/gcc/testsuite/rust/compile/mutability_checks1.rs 
b/gcc/testsuite/rust/compile/mutability_checks1.rs
new file mode 100644
index 000..4affae03053
--- /dev/null
+++ b/gcc/testsuite/rust/compile/mutability_checks1.rs
@@ -0,0 +1,15 @@
+pub fn test() {
+let a;
+a = 1;
+a = 2 + 1;
+// { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+
+struct Foo(i32);
+let a = Foo(1);
+a.0 = 2;
+// { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+
+let a = [1, 2, 3, 4];
+a[0] = 1 + 2;
+// { dg-error "assignment of read-only variable" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs 
b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
index 6aec417e94f..c8a2daeccd9 100644
--- a/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
+++ b/gcc/testsuite/rust/execute/torture/builtin_macro_include_bytes.rs
@@ -25,7 +25,7 @@ fn print_int(value: i32) {
 fn check_bytes(bytes: &[u8; 16]) {
 let the_bytes = b"hello, include!\n";
 
-let x = true;
+let 

[COMMITTED 063/146] gccrs: add test case to show issue is fixed

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

Fixes Rust-GCC#266

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/testsuite/rust/compile/issue-266.rs 
b/gcc/testsuite/rust/compile/issue-266.rs
new file mode 100644
index 000..11196cb7d73
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-266.rs
@@ -0,0 +1,3 @@
+fn main() {
+'label: while break 'label {}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index bf4506f25d2..797e59a5c58 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -207,4 +207,5 @@ issue-2905-1.rs
 issue-2905-2.rs
 issue-2907.rs
 issue-2423.rs
+issue-266.rs
 # please don't delete the trailing newline
-- 
2.45.2



[COMMITTED 073/146] gccrs: nr1.0: Resolve lang item paths properly.

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

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Adapt resolver
to lang item paths.
* resolve/rust-ast-resolve-type.h: Likewise.
---
 gcc/rust/resolve/rust-ast-resolve-item.cc | 30 +--
 gcc/rust/resolve/rust-ast-resolve-type.h  | 11 +++--
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index a330541b682..33b4fc9b979 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -678,16 +678,32 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
   return;
 }
 
+  bool ok = true;
+
   // setup paths
   CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
-  bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path_type (),
-   canonical_trait_type);
-  if (!ok)
+  if (impl_block.get_trait_path ().get_path_kind ()
+  == AST::Path::Kind::LangItem)
 {
-  resolver->get_name_scope ().pop ();
-  resolver->get_type_scope ().pop ();
-  resolver->get_label_scope ().pop ();
-  return;
+  auto &lang_item
+   = static_cast (impl_block.get_trait_path ());
+
+  canonical_trait_type
+   = CanonicalPath::new_seg (lang_item.get_node_id (),
+ LangItem::ToString (
+   lang_item.get_lang_item_kind ()));
+}
+  else
+{
+  ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path_type (),
+  canonical_trait_type);
+  if (!ok)
+   {
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
+ resolver->get_label_scope ().pop ();
+ return;
+   }
 }
 
   rust_debug ("AST::TraitImpl resolve trait type: {%s}",
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index ed055a1f04e..7c3831a2829 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -21,8 +21,10 @@
 
 #include "rust-ast-resolve-base.h"
 #include "rust-ast-resolve-expr.h"
+#include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-path.h"
+#include "util/rust-hir-map.h"
 
 namespace Rust {
 namespace Resolver {
@@ -69,9 +71,14 @@ public:
   {
auto &type = static_cast (type_path);
 
-   Analysis::Mappings::get_lang_item (type);
+   rust_debug ("[ARTHUR]: lang item kind: %s",
+   LangItem::ToString (type.get_lang_item_kind ()).c_str ());
 
-   type.get_node_id ();
+   auto lang_item = Analysis::Mappings::get ()
+  .lookup_lang_item_node (type.get_lang_item_kind ())
+  .value ();
+
+   return lang_item;
   }
 
 rust_assert (type_path.get_path_kind () == AST::Path::Kind::Type);
-- 
2.45.2



[COMMITTED 069/146] gccrs: Fix ForeverStack::find_starting_point output parameter

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

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::find_starting_point): Use type
'std::reference_wrapper &' instead of 'Node &' for
parameter starting_point.
* resolve/rust-forever-stack.hxx
(ForeverStack::find_starting_point): Likewise.
(ForeverStack::resolve_path): Handle change to
ForeverStack::find_starting_point.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h   |  3 ++-
 gcc/rust/resolve/rust-forever-stack.hxx | 13 +++--
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index c548eeae087..064d1ab2bb3 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -614,7 +614,8 @@ private:
 
   template 
   tl::optional>
-  find_starting_point (const std::vector &segments, Node &starting_point);
+  find_starting_point (const std::vector &segments,
+  std::reference_wrapper &starting_point);
 
   template 
   tl::optional resolve_segments (Node &starting_point,
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 58164a4d328..d3d78894671 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -374,8 +374,8 @@ check_leading_kw_at_start (const S &segment, bool condition)
 template 
 template 
 tl::optional::const_iterator>
-ForeverStack::find_starting_point (const std::vector &segments,
- Node &starting_point)
+ForeverStack::find_starting_point (
+  const std::vector &segments, std::reference_wrapper &starting_point)
 {
   auto iterator = segments.begin ();
 
@@ -412,14 +412,15 @@ ForeverStack::find_starting_point (const 
std::vector &segments,
}
   if (seg.is_super_path_seg ())
{
- if (starting_point.is_root ())
+ if (starting_point.get ().is_root ())
{
  rust_error_at (seg.get_locus (), ErrorCode::E0433,
 "too many leading % keywords");
  return tl::nullopt;
}
 
- starting_point = find_closest_module (starting_point.parent.value ());
+ starting_point
+   = find_closest_module (starting_point.get ().parent.value ());
  continue;
}
 
@@ -494,12 +495,12 @@ ForeverStack::resolve_path (const std::vector 
&segments)
   if (segments.size () == 1)
 return get (segments.back ().as_string ());
 
-  auto starting_point = cursor ();
+  std::reference_wrapper starting_point = cursor ();
 
   return find_starting_point (segments, starting_point)
 .and_then ([this, &segments, &starting_point] (
 typename std::vector::const_iterator iterator) {
-  return resolve_segments (starting_point, segments, iterator);
+  return resolve_segments (starting_point.get (), segments, iterator);
 })
 .and_then ([&segments] (Node final_node) {
   return final_node.rib.get (segments.back ().as_string ());
-- 
2.45.2



[COMMITTED 126/146] gccrs: lower: Properly lower non-generic lang item type path segments.

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

gcc/rust/ChangeLog:

* hir/rust-ast-lower-type.cc (ASTLowerTypePath::visit): Adapt code to 
lang item
type path segments.
---
 gcc/rust/hir/rust-ast-lower-type.cc | 40 ++---
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index e78c1307523..8df418b272d 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -74,11 +74,20 @@ ASTLowerTypePath::visit (AST::TypePathSegment &segment)
   Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
 UNKNOWN_LOCAL_DEFID);
 
-  HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
-  translated_segment
-= new HIR::TypePathSegment (std::move (mapping), ident,
-   segment.get_separating_scope_resolution (),
-   segment.get_locus ());
+  if (segment.is_lang_item ())
+{
+  translated_segment = new HIR::TypePathSegment (std::move (mapping),
+segment.get_lang_item (),
+segment.get_locus ());
+}
+  else
+{
+  HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
+  translated_segment
+   = new HIR::TypePathSegment (std::move (mapping), ident,
+   segment.get_separating_scope_resolution (),
+   segment.get_locus ());
+}
 }
 
 void
@@ -139,27 +148,6 @@ ASTLowerTypePath::visit (AST::TypePath &path)
 path.has_opening_scope_resolution_op ());
 }
 
-// void
-// ASTLowerTypePath::visit (AST::LangItemPath &path)
-// {
-//   auto crate_num = mappings.get_current_crate ();
-//   auto hirid = mappings.get_next_hir_id (crate_num);
-
-//   Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
-//  mappings.get_next_localdef_id (crate_num));
-
-//   std::vector> translated_segments;
-//   translated_segments.emplace_back (std::unique_ptr (
-// new HIR::TypePathSegment (mapping,
-//   LangItem::ToString (path.get_lang_item_kind ()),
-//   false, path.get_locus (;
-
-//   translated
-// = new HIR::TypePath (std::move (mapping), std::move
-// (translated_segments),
-//  path.get_locus ());
-// }
-
 HIR::QualifiedPathInType *
 ASTLowerQualifiedPathInType::translate (AST::QualifiedPathInType &type)
 {
-- 
2.45.2



[COMMITTED 118/146] gccrs: Add missing name resolution to static items in blocks

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

We need to add name resolution and hir lowering for items as part of blocks
in order to typecheck and compile them correctly.

Fixes Rust-GCC#3350

gcc/rust/ChangeLog:

* hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): hir lowering
* hir/rust-ast-lower-stmt.h: likewise
* resolve/rust-ast-resolve-stmt.cc (ResolveStmt::visit): name resolution
* resolve/rust-ast-resolve-stmt.h: likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-ast-lower-stmt.cc   |  6 ++
 gcc/rust/hir/rust-ast-lower-stmt.h|  1 +
 gcc/rust/resolve/rust-ast-resolve-stmt.cc | 21 +
 gcc/rust/resolve/rust-ast-resolve-stmt.h  |  1 +
 gcc/testsuite/rust/compile/issue-3350.rs  | 10 ++
 5 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3350.rs

diff --git a/gcc/rust/hir/rust-ast-lower-stmt.cc 
b/gcc/rust/hir/rust-ast-lower-stmt.cc
index 8244e8ae2ba..fd2cdfb0f11 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.cc
+++ b/gcc/rust/hir/rust-ast-lower-stmt.cc
@@ -163,5 +163,11 @@ ASTLoweringStmt::visit (AST::TraitImpl &impl_block)
   translated = ASTLoweringItem::translate (impl_block);
 }
 
+void
+ASTLoweringStmt::visit (AST::StaticItem &var)
+{
+  translated = ASTLoweringItem::translate (var);
+}
+
 } // namespace HIR
 } // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h 
b/gcc/rust/hir/rust-ast-lower-stmt.h
index 5b1e1b9c99a..737a5f8dc4b 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -45,6 +45,7 @@ public:
   void visit (AST::Trait &trait) override;
   void visit (AST::InherentImpl &impl_block) override;
   void visit (AST::TraitImpl &impl_block) override;
+  void visit (AST::StaticItem &var) override;
 
 private:
   ASTLoweringStmt () : translated (nullptr), terminated (false) {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc 
b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
index 28852910c71..226d8e8e2f4 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc
@@ -56,5 +56,26 @@ ResolveStmt::visit (AST::TraitImpl &impl_block)
   ResolveItem::go (impl_block, prefix, canonical_prefix);
 }
 
+void
+ResolveStmt::visit (AST::StaticItem &var)
+{
+  auto decl = CanonicalPath::new_seg (var.get_node_id (),
+ var.get_identifier ().as_string ());
+  auto path = decl;
+  auto cpath = canonical_prefix.append (decl);
+  mappings.insert_canonical_path (var.get_node_id (), cpath);
+
+  resolver->get_name_scope ().insert (
+path, var.get_node_id (), var.get_locus (), false, Rib::ItemType::Static,
+[&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+  rich_location r (line_table, var.get_locus ());
+  r.add_range (locus);
+  rust_error_at (r, "redefined multiple times");
+});
+
+  ResolveType::go (var.get_type ());
+  ResolveExpr::go (var.get_expr (), path, cpath);
+}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h 
b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 8e64a7691d9..6dfac9179d7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -388,6 +388,7 @@ public:
   void visit (AST::Trait &trait) override;
   void visit (AST::InherentImpl &impl_block) override;
   void visit (AST::TraitImpl &impl_block) override;
+  void visit (AST::StaticItem &var) override;
 
 private:
   ResolveStmt (const CanonicalPath &prefix,
diff --git a/gcc/testsuite/rust/compile/issue-3350.rs 
b/gcc/testsuite/rust/compile/issue-3350.rs
new file mode 100644
index 000..8880659afe6
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3350.rs
@@ -0,0 +1,10 @@
+static FOO: i32 = 0;
+
+pub fn bar() -> i32 {
+FOO
+}
+
+pub fn baz() -> i32 {
+static QUX: i32 = 0;
+QUX
+}
-- 
2.45.2



[COMMITTED 101/146] gccrs: fix ICE in borrows to invalid expressions

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

We need to check if the borrowed value is valid before creating the
reference type. Otherwise this will lead to an ICE.

Fixes Rust-GCC#3140

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): check 
for error
* typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): likewise and 
remove debug error

gcc/testsuite/ChangeLog:

* rust/compile/issue-3046.rs: remove old error message
* rust/compile/nr2/exclude: nr2 cant handle this
* rust/compile/issue-3140.rs: New test.

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-expr.cc |  2 ++
 gcc/rust/typecheck/rust-tyty-call.cc  |  9 ++-
 gcc/testsuite/rust/compile/issue-3046.rs  |  4 +--
 gcc/testsuite/rust/compile/issue-3140.rs  | 27 +++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 5 files changed, 33 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3140.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 5a96c359d7c..2ea8b4127e6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1366,6 +1366,8 @@ void
 TypeCheckExpr::visit (HIR::BorrowExpr &expr)
 {
   TyTy::BaseType *resolved_base = TypeCheckExpr::Resolve (expr.get_expr ());
+  if (resolved_base->is ())
+return;
 
   // In Rust this is valid because of DST's
   //
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc 
b/gcc/rust/typecheck/rust-tyty-call.cc
index 5fea34de40a..2e0830e4ada 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -140,13 +140,8 @@ TypeCheckCallExpr::visit (FnType &type)
 {
   location_t arg_locus = argument->get_locus ();
   auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (*argument);
-  if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
-   {
- rust_error_at (
-   argument->get_locus (),
-   "failed to resolve type for argument expr in CallExpr");
- return;
-   }
+  if (argument_expr_tyty->is ())
+   return;
 
   // it might be a variadic function
   if (i < type.num_params ())
diff --git a/gcc/testsuite/rust/compile/issue-3046.rs 
b/gcc/testsuite/rust/compile/issue-3046.rs
index c982cc98f58..f0c72a3cef4 100644
--- a/gcc/testsuite/rust/compile/issue-3046.rs
+++ b/gcc/testsuite/rust/compile/issue-3046.rs
@@ -12,12 +12,10 @@ fn test(v: LOption) -> Res {
 return Res::BAD;
 }
 
-
 fn main() {
 // Should be:
 // test(LOption::Some(2));
-// 
+//
 test(LOption(2));
 // { dg-error "expected function, tuple struct or tuple variant, found 
enum" "" { target *-*-* } .-1 }
-// { dg-error "failed to resolve type for argument expr in CallExpr" "" { 
target *-*-* } .-2 }
 }
diff --git a/gcc/testsuite/rust/compile/issue-3140.rs 
b/gcc/testsuite/rust/compile/issue-3140.rs
new file mode 100644
index 000..dcf86db5616
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3140.rs
@@ -0,0 +1,27 @@
+enum State {
+Succeeded,
+Failed,
+}
+
+fn print_on_failure(state: &State) {
+let mut num = 0;
+match *state {
+// error: expected unit struct, unit variant or constant, found tuple
+//variant `State::Failed`
+State::Failed => {
+num = 1;
+}
+State::Succeeded => {
+num = 2;
+}
+_ => (),
+}
+}
+
+fn main() {
+let b = State::Failed(1);
+// { dg-error "expected function, tuple struct or tuple variant, found 
struct .State." "" { target *-*-* } .-1 }
+
+print_on_failure(&b);
+// { dg-error "cannot find value .b. in this scope" "" { target *-*-* } 
.-1 }
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 945a697f677..e7344ed0d59 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -195,4 +195,5 @@ issue-266.rs
 additional-trait-bounds2.rs
 auto_traits2.rs
 auto_traits3.rs
+issue-3140.rs
 # please don't delete the trailing newline
-- 
2.45.2



Re: Rust: error[E0554]: `#![feature]` may not be used on the stable release channel

2025-03-21 Thread Thomas Schwinge
Hi!

On 2025-03-17T20:03:48+, Iain Sandoe via Gcc  wrote:
>> On 17 Mar 2025, at 19:43, Toon Moene  wrote:
>> 
>> I was eager to try the new rust updates ...
>> 
>> But I got this:
>> 
>> error[E0554]: `#![feature]` may not be used on the stable release channel
>>  --> src/lib.rs:19:1
>>   |
>> 19 | #![feature(extern_types)]
>>   | ^
>> 
>> For more information about this error, try `rustc --explain E0554`.
>> error: could not compile `ffi-polonius` (lib) due to 1 previous error
>> [/home/toon/compilers/gcc/gcc/rust/Make-lang.in:506: rust/libffi_polonius.a] 
>> Error 101

This should've been resolved via 
"[15 regression] Rust fails to build (build failure: error[E0554]: 
`#![feature]` may not be used on the stable release channel)".

>> Am I the only one seeing this ?
>
> No, if I allow the cargo download to progress (another issue in itself)

This shouldn've been resolved via 
"[15 regression] Rust bootstrap fails with cargo trying to download polonius 
crates".

> I hit this too on Darwin.

Thanks for testing!


Grüße
 Thomas


[COMMITTED 123/146] gccrs: collect-lang-items: Display attribute upon error finding it

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

gcc/rust/ChangeLog:

* ast/rust-collect-lang-items.cc (get_lang_item_attr): Show unknown 
attribute upon error.
---
 gcc/rust/ast/rust-collect-lang-items.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index 50d134a429f..168123ee56e 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -36,7 +36,8 @@ get_lang_item_attr (const T &maybe_lang_item)
   const auto &str_path = attr.get_path ().as_string ();
   if (!Analysis::Attributes::is_known (str_path))
{
- rust_error_at (attr.get_locus (), "unknown attribute");
+ rust_error_at (attr.get_locus (), "unknown attribute %qs",
+str_path.c_str ());
  continue;
}
 
-- 
2.45.2



[COMMITTED 131/146] gccrs: ast-collector: Fix tuple struct pattern collection

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

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Visit tuple 
pattern items as
separated by commas.
---
 gcc/rust/ast/rust-ast-collector.cc | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 4c9c360c04d..978de648a58 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2470,10 +2470,7 @@ TokenCollector::visit (StructPattern &pattern)
 void
 TokenCollector::visit (TupleStructItemsNoRange &pattern)
 {
-  for (auto &pat : pattern.get_patterns ())
-{
-  visit (pat);
-}
+  visit_items_joined_by_separator (pattern.get_patterns ());
 }
 
 void
-- 
2.45.2



[COMMITTED 128/146] gccrs: lang-item: Add LangItem::PrettyString

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

Which formats a lang item as it appears in source code.

gcc/rust/ChangeLog:

* util/rust-lang-item.cc (LangItem::PrettyString): New.
* util/rust-lang-item.h: New.
---
 gcc/rust/util/rust-lang-item.cc | 6 ++
 gcc/rust/util/rust-lang-item.h  | 1 +
 2 files changed, 7 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 4a609096144..e038e900f94 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -118,6 +118,12 @@ LangItem::ToString (LangItem::Kind type)
   return str.value ();
 }
 
+std::string
+LangItem::PrettyString (LangItem::Kind type)
+{
+  return "#[lang = \"" + LangItem::ToString (type) + "\"]";
+}
+
 LangItem::Kind
 LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op)
 {
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 62b15d7b3fc..f947f3f021c 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -134,6 +134,7 @@ public:
 
   static tl::optional Parse (const std::string &item);
   static std::string ToString (Kind type);
+  static std::string PrettyString (Kind type);
   static Kind OperatorToLangItem (ArithmeticOrLogicalOperator op);
   static Kind
   CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op);
-- 
2.45.2



[COMMITTED 134/146] gccrs: derive(Clone): Manually generate AssertParamIsCopy struct for unions

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc (DeriveClone::visit_union): Manually 
generate
the struct used for asserting a union implements Copy.
---
 gcc/rust/expand/rust-derive-clone.cc | 38 +---
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 18436be4bf7..8093bf67ff0 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "rust-derive-clone.h"
+#include "rust-ast.h"
+#include "rust-ast-dump.h"
 #include "rust-item.h"
 
 namespace Rust {
@@ -238,13 +240,40 @@ void
 DeriveClone::visit_union (Union &item)
 {
   // FIXME: Should be $crate::core::clone::AssertParamIsCopy (or similar)
+  // (Rust-GCC#3329)
+
+  auto copy_path = TypePath (vec (builder.type_path_segment ("Copy")), loc);
+  auto sized_path = TypePath (vec (builder.type_path_segment ("Sized")), loc);
+
+  auto copy_bound = std::unique_ptr (
+new TraitBound (copy_path, item.get_locus ()));
+  auto sized_bound = std::unique_ptr (
+new TraitBound (sized_path, item.get_locus (), false, true));
+
+  auto bounds = std::vector> ();
+  bounds.emplace_back (std::move (copy_bound));
+  bounds.emplace_back (std::move (sized_bound));
+
+  // struct AssertParamIsCopy { _t: PhantomData }
+  auto assert_param_is_copy = "AssertParamIsCopy";
+  auto t = std::unique_ptr (
+new TypeParam (Identifier ("T"), item.get_locus (), std::move (bounds)));
+  auto assert_param_is_copy_struct = builder.struct_struct (
+assert_param_is_copy, vec (std::move (t)),
+{StructField (
+  Identifier ("_t"),
+  builder.single_generic_type_path (
+   "PhantomData",
+   GenericArgs (
+ {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
+  Visibility::create_private (), item.get_locus ())});
 
   // 
   auto arg = GenericArg::create_type (builder.single_type_path ("Self"));
 
   // AssertParamIsCopy::
   auto type = std::unique_ptr (
-new TypePathSegmentGeneric (PathIdentSegment ("AssertParamIsCopy", loc),
+new TypePathSegmentGeneric (PathIdentSegment (assert_param_is_copy, loc),
false, GenericArgs ({}, {arg}, {}, loc), loc));
   auto type_paths = std::vector> ();
   type_paths.emplace_back (std::move (type));
@@ -252,11 +281,12 @@ DeriveClone::visit_union (Union &item)
   auto full_path
 = std::unique_ptr (new TypePath ({std::move (type_paths)}, loc));
 
-  auto stmts = std::vector> ();
-  stmts.emplace_back (
-builder.let (builder.wildcard (), std::move (full_path), nullptr));
   auto tail_expr = builder.deref (builder.identifier ("self"));
 
+  auto stmts
+= vec (std::move (assert_param_is_copy_struct),
+  builder.let (builder.wildcard (), std::move (full_path), nullptr));
+
   auto block = builder.block (std::move (stmts), std::move (tail_expr));
 
   expanded = clone_impl (clone_fn (std::move (block)),
-- 
2.45.2



[COMMITTED 107/146] gccrs: match arms are a LUB

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

Unify rules are not the same as coercion rules. The coercion of ! is
allowed to any type but not for a unify site which is different.

Match arms are another least upper bound coercion.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): implement coercion
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): this is 
an LUB
* typecheck/rust-unify.cc (UnifyRules::go): remove unify ! coercion

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc  | 13 -
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  7 ---
 gcc/rust/typecheck/rust-unify.cc   | 10 --
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index b40aa33866e..353a498dc4e 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1156,8 +1156,19 @@ CompileExpr::visit (HIR::MatchExpr &expr)
  location_t arm_locus = kase_arm.get_locus ();
  tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
  tree result_reference = Backend::var_expression (tmp, arm_locus);
+
+ TyTy::BaseType *actual = nullptr;
+ bool ok = ctx->get_tyctx ()->lookup_type (
+   kase.get_expr ().get_mappings ().get_hirid (), &actual);
+ rust_assert (ok);
+
+ tree coerced_result
+   = coercion_site (kase.get_expr ().get_mappings ().get_hirid (),
+kase_expr_tree, actual, expr_tyty,
+expr.get_locus (), arm_locus);
+
  tree assignment
-   = Backend::assignment_statement (result_reference, kase_expr_tree,
+   = Backend::assignment_statement (result_reference, coerced_result,
 arm_locus);
  ctx->add_statement (assignment);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 7899b1a7943..113f43f6c72 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1532,9 +1532,10 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
   for (size_t i = 1; i < kase_block_tys.size (); i++)
 {
   TyTy::BaseType *kase_ty = kase_block_tys.at (i);
-  infered = unify_site (expr.get_mappings ().get_hirid (),
-   TyTy::TyWithLocation (infered),
-   TyTy::TyWithLocation (kase_ty), expr.get_locus ());
+  infered
+   = coercion_site (expr.get_mappings ().get_hirid (),
+TyTy::TyWithLocation (infered),
+TyTy::TyWithLocation (kase_ty), expr.get_locus ());
 }
 }
 
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 8159c7d52bb..b779e7d4614 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -17,7 +17,6 @@
 // .
 
 #include "rust-unify.h"
-#include "rust-tyty.h"
 
 namespace Rust {
 namespace Resolver {
@@ -238,15 +237,6 @@ UnifyRules::go ()
}
 }
 
-  // The never type should always get coerced to the type it's being matched
-  // against, so in that case, ltype. This avoids doing the same check in all
-  // the `expect_*` functions.
-  // However, this does not work if we have an annoying ltype - like INFER.
-  // TODO: Is ltype == Infer the only special case here? What about 
projections?
-  // references?
-  if (rtype->get_kind () == TyTy::NEVER && ltype->get_kind () != TyTy::INFER)
-return ltype->clone ();
-
   switch (ltype->get_kind ())
 {
 case TyTy::INFER:
-- 
2.45.2



[COMMITTED 103/146] gccrs: fix ICE with hir dump on closure

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

Return type and parameter types are optional on closures.

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): add null guard

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 5acf53e9296..798179d172e 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1244,13 +1244,17 @@ Dump::visit (ClosureExpr &e)
  auto oa = param.get_outer_attrs ();
  do_outer_attrs (oa);
  visit_field ("pattern", param.get_pattern ());
- visit_field ("type", param.get_type ());
+
+ if (param.has_type_given ())
+   visit_field ("type", param.get_type ());
+
  end ("ClosureParam");
}
   end_field ("params");
 }
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
 
   visit_field ("expr", e.get_expr ());
   end ("ClosureExpr");
-- 
2.45.2



[COMMITTED 116/146] gccrs: Fix scan-gimple testcases on LE platforms.

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

gcc/testsuite/ChangeLog:

* rust/compile/macros/builtin/eager1.rs: Switch to scan-assembler 
directive as the
GIMPLE dump does not contain strings on LE.
* rust/compile/macros/builtin/recurse2.rs: Likewise.
---
 .../rust/compile/macros/builtin/eager1.rs |  2 +-
 .../rust/compile/macros/builtin/recurse2.rs   | 26 +--
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs 
b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
index 65a80fda62e..7c6f6f95d61 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/eager1.rs
@@ -15,7 +15,7 @@ macro_rules! b {
 }
 
 fn main() {
-// { dg-final { scan-tree-dump-times {"test1canary"} 1 gimple } }
+// { dg-final { scan-assembler {"test1canary"} } }
 let _ = concat!(a!(), 1, b!());
 // should not error
 concat!(a!(), true, b!(),);
diff --git a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs 
b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
index 2e73ab54fb6..73e6ab4aa6c 100644
--- a/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
+++ b/gcc/testsuite/rust/compile/macros/builtin/recurse2.rs
@@ -15,7 +15,29 @@ macro_rules! a {
 };
 }
 
+extern "C" {
+fn printf(fmt: *const i8, ...);
+}
+
+fn print_ptr(s: &str) {
+unsafe {
+printf("%p\n\0" as *const str as *const i8, s as *const str);
+}
+}
+
+fn print_str(s: &str) {
+unsafe {
+printf(
+"%s\n\0" as *const str as *const i8,
+s as *const str as *const i8,
+);
+}
+}
+
+// { dg-final { scan-assembler {"abheyho"} } }
+static S: &str = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+
 fn main() {
-// { dg-final { scan-tree-dump-times {"abheyho"} 1 gimple } }
-let _ = concat!("a", 'b', a!(), a!(b c d e f a!()), '\0');
+print_ptr(S);
+print_str(S);
 }
-- 
2.45.2



[COMMITTED 110/146] gccrs: add two more tests to test try-catch (unwind) code generation

2025-03-21 Thread arthur . cohen
From: liushuyu 

gcc/testsuite/ChangeLog:
* rust/compile/try-catch-unwind-old.rs: add a test to test the older
try intrinsics from plain old Rust to v1.78.0
* rust/compile/try-catch-unwind-new.rs: add a test to test the newer
catch_unwind instrinsics since Rust v1.78.0
---
 .../rust/compile/try-catch-unwind-new.rs  | 20 ++
 .../rust/compile/try-catch-unwind-old.rs  | 21 +++
 2 files changed, 41 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/try-catch-unwind-new.rs
 create mode 100644 gcc/testsuite/rust/compile/try-catch-unwind-old.rs

diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-new.rs 
b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs
new file mode 100644
index 000..b176f7a100b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-catch-unwind-new.rs
@@ -0,0 +1,20 @@
+// { dg-options "-O2 -w -fdump-tree-optimized" }
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+// { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" 
} }
+fn catch_unwind(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: 
*mut u8, _: *mut u8));
+}
+
+extern "C" {
+fn try_fn(data: *mut u8);
+fn catch_fn(data: *mut u8, ex: *mut u8);
+}
+
+pub fn not_main(d: &mut u8) {
+unsafe {
+// { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } }
+catch_unwind(try_fn, d, catch_fn);
+// { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } }
+}
+}
diff --git a/gcc/testsuite/rust/compile/try-catch-unwind-old.rs 
b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs
new file mode 100644
index 000..e97d52cd64e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/try-catch-unwind-old.rs
@@ -0,0 +1,21 @@
+// { dg-options "-O2 -w -fdump-tree-optimized" }
+#![feature(intrinsics)]
+
+extern "rust-intrinsic" {
+// { dg-final { scan-tree-dump-times "__builtin_eh_pointer" 1 "optimized" 
} }
+fn r#try(try_fn: fn(_: *mut u8), data: *mut u8, catch_fn: fn(_: *mut u8, 
_: *mut u8)) -> i32;
+}
+
+extern "C" {
+fn try_fn(data: *mut u8);
+fn catch_fn(data: *mut u8, ex: *mut u8);
+}
+
+pub fn not_main(d: &mut u8) -> i32 {
+unsafe {
+// { dg-final { scan-tree-dump-times "try_fn" 1 "optimized" } }
+let _: i32 = r#try(try_fn, d, catch_fn);
+// { dg-final { scan-tree-dump-times "catch_fn" 1 "optimized" } }
+}
+42
+}
-- 
2.45.2



[COMMITTED 046/146] gccrs: Clean up some system includes

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

System includes shall use rust-system header instead.

gcc/rust/ChangeLog:

* ast/rust-stmt.h: Remove stdlib include and use rust-system instead.
* backend/rust-compile-expr.cc: Likewise.
* backend/rust-mangle-legacy.cc: Likewise.
* backend/rust-mangle-v0.cc: Likewise.
* hir/rust-hir-dump.cc: Likewise.
* typecheck/rust-hir-type-check-type.cc: Likewise.
* typecheck/rust-tyty.cc: Likewise.
* typecheck/rust-tyty.h: Likewise.
* util/rust-common.h: Likewise.
* util/rust-token-converter.cc: Likewise.
* util/rust-token-converter.h: Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-stmt.h   | 2 +-
 gcc/rust/backend/rust-compile-expr.cc  | 1 -
 gcc/rust/backend/rust-mangle-legacy.cc | 1 -
 gcc/rust/backend/rust-mangle-v0.cc | 1 -
 gcc/rust/hir/rust-hir-dump.cc  | 2 +-
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 2 +-
 gcc/rust/typecheck/rust-tyty.cc| 2 +-
 gcc/rust/typecheck/rust-tyty.h | 2 --
 gcc/rust/util/rust-common.h| 1 -
 gcc/rust/util/rust-token-converter.cc  | 3 +--
 gcc/rust/util/rust-token-converter.h   | 2 +-
 11 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index e8aec34d47e..6cbecaffd03 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -22,7 +22,7 @@
 #include "rust-ast.h"
 #include "rust-path.h"
 #include "rust-expr.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace AST {
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 05c52261cf7..7ea2a675522 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -31,7 +31,6 @@
 #include "convert.h"
 #include "print-tree.h"
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-mangle-legacy.cc 
b/gcc/rust/backend/rust-mangle-legacy.cc
index 2c0ddd92df0..7671982da3f 100644
--- a/gcc/rust/backend/rust-mangle-legacy.cc
+++ b/gcc/rust/backend/rust-mangle-legacy.cc
@@ -21,7 +21,6 @@
 #include "rust-unicode.h"
 #include "rust-diagnostics.h"
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-mangle-v0.cc 
b/gcc/rust/backend/rust-mangle-v0.cc
index 67d7e4d1885..d0df4aba27c 100644
--- a/gcc/rust/backend/rust-mangle-v0.cc
+++ b/gcc/rust/backend/rust-mangle-v0.cc
@@ -25,7 +25,6 @@
 #include "rust-unicode.h"
 #include "rust-punycode.h"
 #include "rust-compile-type.h"
-#include 
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 5d2a09db348..81cb881268f 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -22,9 +22,9 @@
 #include "rust-hir-path.h"
 #include "rust-hir-type.h"
 #include "rust-hir.h"
-#include 
 #include "rust-attribute-values.h"
 #include "tree/rust-hir-expr.h"
+#include "rust-system.h"
 
 namespace Rust {
 namespace HIR {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 4ebbaf6d836..0360c5504b7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -27,7 +27,7 @@
 #include "rust-mapping-common.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace Resolver {
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 1073dfa6adc..f0c967e0949 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -32,7 +32,7 @@
 #include "rust-hir-type-bounds.h"
 
 #include "options.h"
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 namespace TyTy {
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 49cd00c9174..a41837e35af 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -30,8 +30,6 @@
 #include "rust-system.h"
 #include "rust-hir.h"
 
-#include 
-
 namespace Rust {
 
 namespace Resolver {
diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h
index 2033694156e..71637cee68e 100644
--- a/gcc/rust/util/rust-common.h
+++ b/gcc/rust/util/rust-common.h
@@ -21,7 +21,6 @@
 #ifndef RUST_COMMON
 #define RUST_COMMON
 #include "rust-system.h"
-#include 
 
 namespace Rust {
 
diff --git a/gcc/rust/util/rust-token-converter.cc 
b/gcc/rust/util/rust-token-converter.cc
index 220e891247f..fc34adb9b19 100644
--- a/gcc/rust/util/rust-token-converter.cc
+++ b/gcc/rust/util/rust-token-converter.cc
@@ -18,8 +18,7 @@
 #include "rust-token-converter.h"
 #include "bi-map.h"
 #include "line-map.h"
-
-#include 
+#include "rust-system.h"
 
 namespace Rust {
 
diff -

[COMMITTED 146/146] gccrs: nr2.0: late: Better format PathInExpression resolution

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Improve 
formatting.
---
 .../resolve/rust-late-name-resolver-2.0.cc | 18 ++
 1 file changed, 6 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 9da56ea3214..5aea6a43ed6 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -218,19 +218,12 @@ Late::visit (AST::PathInExpression &expr)
   // in a function item` error here?
   // do we emit it in `get`?
 
-  rust_debug ("[ARTHUR]: %s", expr.as_simple_path ().as_string ().c_str ());
+  auto resolved
+= ctx.values.resolve_path (expr.get_segments ()).or_else ([&] () {
+   return ctx.types.resolve_path (expr.get_segments ());
+  });
 
-  tl::optional resolved = tl::nullopt;
-
-  if (auto value = ctx.values.resolve_path (expr.get_segments ()))
-{
-  resolved = value;
-}
-  else if (auto type = ctx.types.resolve_path (expr.get_segments ()))
-{
-  resolved = type;
-}
-  else
+  if (!resolved)
 {
   rust_error_at (expr.get_locus (),
 "could not resolve path expression: %qs",
@@ -244,6 +237,7 @@ Late::visit (AST::PathInExpression &expr)
 expr.as_string ().c_str ());
   return;
 }
+
   ctx.map_usage (Usage (expr.get_node_id ()),
 Definition (resolved->get_node_id ()));
 }
-- 
2.45.2



[COMMITTED 057/146] gccrs: hir: Remove duplicate function in TraitItemFunc

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

Both TraitItemFunc::has_definition() and TraitItemFunc::has_block_defined()
were exactly the same implementation, so remove one.

gcc/rust/ChangeLog:

* hir/tree/rust-hir-item.h: Remove TraitItemFunc::has_block_defined()
* backend/rust-compile-implitem.cc (CompileTraitItem::visit):
Call TraitItemFunc::has_definition() instead.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
* checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): 
Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
* typecheck/rust-hir-trait-resolve.cc (ResolveTraitItemToRef::visit): 
Likewise.
---
 gcc/rust/backend/rust-compile-implitem.cc   | 2 +-
 gcc/rust/checks/errors/rust-const-checker.cc| 2 +-
 gcc/rust/checks/errors/rust-hir-pattern-analysis.cc | 2 +-
 gcc/rust/checks/errors/rust-unsafe-checker.cc   | 2 +-
 gcc/rust/hir/tree/rust-hir-item.h   | 2 --
 gcc/rust/typecheck/rust-hir-trait-resolve.cc| 2 +-
 6 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-implitem.cc 
b/gcc/rust/backend/rust-compile-implitem.cc
index 352685e242f..129e97879fa 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -57,7 +57,7 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
 void
 CompileTraitItem::visit (HIR::TraitItemFunc &func)
 {
-  rust_assert (func.has_block_defined ());
+  rust_assert (func.has_definition ());
 
   rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
   TyTy::FnType *fntype = static_cast (concrete);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 420db8fb8b2..97b35288bae 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -678,7 +678,7 @@ ConstChecker::visit (StaticItem &static_item)
 void
 ConstChecker::visit (TraitItemFunc &item)
 {
-  if (item.has_block_defined ())
+  if (item.has_definition ())
 item.get_block_expr ().accept_vis (*this);
 }
 
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index db1e7272556..79416b5d50a 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -522,7 +522,7 @@ PatternChecker::visit (StaticItem &static_item)
 void
 PatternChecker::visit (TraitItemFunc &item)
 {
-  if (item.has_block_defined ())
+  if (item.has_definition ())
 item.get_block_expr ().accept_vis (*this);
 }
 
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 6c9141c2dd2..fadfd9dea83 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -776,7 +776,7 @@ UnsafeChecker::visit (StaticItem &static_item)
 void
 UnsafeChecker::visit (TraitItemFunc &item)
 {
-  if (item.has_block_defined ())
+  if (item.has_definition ())
 item.get_block_expr ().accept_vis (*this);
 }
 
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index 0fda1672b74..47447174215 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -1991,8 +1991,6 @@ public:
 
   const TraitFunctionDecl &get_decl () const { return decl; }
 
-  bool has_block_defined () const { return block_expr != nullptr; }
-
   BlockExpr &get_block_expr () { return *block_expr; }
 
   const std::string trait_identifier () const override final
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 2fbf123aa77..14e26f4512b 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -69,7 +69,7 @@ ResolveTraitItemToRef::visit (HIR::TraitItemFunc &fn)
 {
   // create trait-item-ref
   location_t locus = fn.get_locus ();
-  bool is_optional = fn.has_block_defined ();
+  bool is_optional = fn.has_definition ();
   std::string identifier = fn.get_decl ().get_function_name ().as_string ();
 
   resolved = TraitItemReference (identifier, is_optional,
-- 
2.45.2



[COMMITTED 140/146] gccrs: derive(Clone): Improve existing testcase

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

gcc/testsuite/ChangeLog:

* rust/compile/derive_macro4.rs: Mark Copy and Clone as lang items.
---
 gcc/testsuite/rust/compile/derive_macro4.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs 
b/gcc/testsuite/rust/compile/derive_macro4.rs
index b20043ba927..8bf1bcaf5f7 100644
--- a/gcc/testsuite/rust/compile/derive_macro4.rs
+++ b/gcc/testsuite/rust/compile/derive_macro4.rs
@@ -1,7 +1,10 @@
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "copy"]
 pub trait Copy {}
+
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
-- 
2.45.2



[COMMITTED 124/146] gccrs: ast: Refactor how lang item paths are handled.

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

Lang item typepaths were not handled properly, and required a complete overhaul.
All old classes that concerned lang item paths are now modified to use a simpler
version of `AST::LangItemPath`, which has been removed. TypePath segments can 
now
be lang items, as this is requied for having generic lang item paths such as
PhantomData.

gcc/rust/ChangeLog:

* ast/rust-path.h: Rework how lang item paths are represented.
* ast/rust-path.cc: Likewise.
* ast/rust-item.h: Likewise.
* ast/rust-ast.cc: Likewise.
* ast/rust-ast-collector.cc: Adapt to new lang item path system.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h: Likewise.
* expand/rust-derive-copy.cc: Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Likewise.
(ASTLowerTypePath::visit): Likewise.
* hir/rust-ast-lower-type.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise.
* resolve/rust-ast-resolve-type.h: Likewise.
* resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): 
Likewise.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
* resolve/rust-late-name-resolver-2.0.h: Likewise.
* hir/tree/rust-hir-path.cc (TypePathSegment::TypePathSegment): 
Likewise.
(TypePathSegmentGeneric::TypePathSegmentGeneric): Likewise.
* hir/tree/rust-hir-path.h: Likewise.
* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path): Likewise.
* ast/rust-ast-builder.cc: Likewise.
* ast/rust-ast-builder.h: Likewise.
---
 gcc/rust/ast/rust-ast-builder.cc  |  20 +-
 gcc/rust/ast/rust-ast-builder.h   |   4 -
 gcc/rust/ast/rust-ast-collector.cc|  13 -
 gcc/rust/ast/rust-ast-collector.h |   2 -
 gcc/rust/ast/rust-ast-visitor.cc  |  11 -
 gcc/rust/ast/rust-ast-visitor.h   |   4 -
 gcc/rust/ast/rust-ast.cc  |   4 +-
 gcc/rust/ast/rust-item.h  |  40 +-
 gcc/rust/ast/rust-path.cc |  31 +-
 gcc/rust/ast/rust-path.h  | 405 +++---
 gcc/rust/expand/rust-derive-copy.cc   |   4 +-
 gcc/rust/expand/rust-derive.h |   2 -
 gcc/rust/hir/rust-ast-lower-base.cc   |   6 -
 gcc/rust/hir/rust-ast-lower-base.h|   2 -
 gcc/rust/hir/rust-ast-lower-type.cc   |  75 ++--
 gcc/rust/hir/rust-ast-lower-type.h|   6 +-
 gcc/rust/hir/tree/rust-hir-path.cc|  21 +-
 gcc/rust/hir/tree/rust-hir-path.h |  38 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc |   8 -
 gcc/rust/resolve/rust-ast-resolve-base.h  |   2 -
 gcc/rust/resolve/rust-ast-resolve-item.cc |  27 +-
 gcc/rust/resolve/rust-ast-resolve-type.cc |  79 ++--
 gcc/rust/resolve/rust-ast-resolve-type.h  |  31 --
 .../resolve/rust-late-name-resolver-2.0.cc|  19 -
 .../resolve/rust-late-name-resolver-2.0.h |   1 -
 .../typecheck/rust-hir-type-check-type.cc |   2 +-
 26 files changed, 311 insertions(+), 546 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 22fb0d83f97..f6d0f0dc4ae 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -42,15 +42,6 @@ Builder::call (std::unique_ptr &&path,
 new CallExpr (std::move (path), std::move (args), {}, loc));
 }
 
-std::unique_ptr
-Builder::call (std::unique_ptr &&path,
-  std::vector> &&args) const
-{
-  return call (std::unique_ptr (
-new PathInExpression (std::move (path), {}, loc)),
-  std::move (args));
-}
-
 std::unique_ptr
 Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
 {
@@ -60,15 +51,6 @@ Builder::call (std::unique_ptr &&path, 
std::unique_ptr &&arg) const
   return call (std::move (path), std::move (args));
 }
 
-std::unique_ptr
-Builder::call (std::unique_ptr &&path, std::unique_ptr &&arg) const
-{
-  auto args = std::vector> ();
-  args.emplace_back (std::move (arg));
-
-  return call (std::move (path), std::move (args));
-}
-
 std::unique_ptr
 Builder::array (std::vector> &&members) const
 {
@@ -242,7 +224,7 @@ Builder::wildcard () const
 std::unique_ptr
 Builder::lang_item_path (LangItem::Kind kind) const
 {
-  return std::unique_ptr (new LangItemPath (kind, loc));
+  return std::unique_ptr (new PathInExpression (kind, {}, loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 

[COMMITTED 119/146] gccrs: nr2.0: Early resolve pending eager macro invocations

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

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc
(Early::visit): Resolve the pending eager invocations inside
builtin macro invocations.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 4 
 gcc/testsuite/rust/compile/nr2/exclude   | 5 -
 2 files changed, 4 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 55330487fd7..342f1027273 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -238,6 +238,10 @@ Early::visit (AST::MacroInvocation &invoc)
 {
   auto path = invoc.get_invoc_data ().get_path ();
 
+  if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
+for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
+  pending_invoc->accept_vis (*this);
+
   // When a macro is invoked by an unqualified identifier (not part of a
   // multi-part path), it is first looked up in textual scoping. If this does
   // not yield any results, then it is looked up in path-based scoping. If the
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 9b490c18bab..0f482df2f00 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,11 +1,6 @@
 bounds1.rs
 break-rust2.rs
 break-rust3.rs
-macros/builtin/eager1.rs
-macros/builtin/eager2.rs
-macros/builtin/recurse2.rs
-macros/builtin/include3.rs
-macros/builtin/include4.rs
 canonical_paths1.rs
 cfg1.rs
 cfg3.rs
-- 
2.45.2



[COMMITTED 132/146] gccrs: lang-items: Mark Clone trait as a lang item in testsuite

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

gcc/testsuite/ChangeLog:

* rust/compile/derive_macro1.rs: Add #[lang = "clone"] to Clone trait.
* rust/compile/derive_macro3.rs: Likewise.
* rust/compile/derive_macro6.rs: Likewise.
* rust/execute/torture/derive_macro3.rs: Likewise.
---
 gcc/testsuite/rust/compile/derive_macro1.rs | 1 +
 gcc/testsuite/rust/compile/derive_macro3.rs | 1 +
 gcc/testsuite/rust/compile/derive_macro6.rs | 7 +++
 gcc/testsuite/rust/execute/torture/derive_macro3.rs | 1 +
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/rust/compile/derive_macro1.rs 
b/gcc/testsuite/rust/compile/derive_macro1.rs
index 779aad78e11..bc10d601bb8 100644
--- a/gcc/testsuite/rust/compile/derive_macro1.rs
+++ b/gcc/testsuite/rust/compile/derive_macro1.rs
@@ -1,6 +1,7 @@
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
diff --git a/gcc/testsuite/rust/compile/derive_macro3.rs 
b/gcc/testsuite/rust/compile/derive_macro3.rs
index 1c7d4737bfe..ad40cae94b5 100644
--- a/gcc/testsuite/rust/compile/derive_macro3.rs
+++ b/gcc/testsuite/rust/compile/derive_macro3.rs
@@ -1,6 +1,7 @@
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
diff --git a/gcc/testsuite/rust/compile/derive_macro6.rs 
b/gcc/testsuite/rust/compile/derive_macro6.rs
index b7bf7a78acd..35327c03b54 100644
--- a/gcc/testsuite/rust/compile/derive_macro6.rs
+++ b/gcc/testsuite/rust/compile/derive_macro6.rs
@@ -2,6 +2,9 @@
 pub trait Sized {}
 
 pub trait Copy {}
+
+
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
@@ -9,10 +12,6 @@ pub trait Clone {
 #[lang = "phantom_data"]
 pub struct PhantomData;
 
-pub struct AssertParamIsCopy {
-pub _field: PhantomData,
-}
-
 impl Copy for i32 {}
 impl Copy for i64 {}
 impl Copy for U {}
diff --git a/gcc/testsuite/rust/execute/torture/derive_macro3.rs 
b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
index 7b3a089d751..4138a5bf7e4 100644
--- a/gcc/testsuite/rust/execute/torture/derive_macro3.rs
+++ b/gcc/testsuite/rust/execute/torture/derive_macro3.rs
@@ -1,6 +1,7 @@
 #[lang = "sized"]
 pub trait Sized {}
 
+#[lang = "clone"]
 pub trait Clone {
 fn clone(&self) -> Self;
 }
-- 
2.45.2



[COMMITTED 135/146] gccrs: derive(Clone): Mark PhantomData as a lang item

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

gcc/testsuite/ChangeLog:

* rust/compile/derive_macro4.rs: Make PhantomData a lang item.
---
 gcc/testsuite/rust/compile/derive_macro4.rs | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs 
b/gcc/testsuite/rust/compile/derive_macro4.rs
index 7802e8fd800..b20043ba927 100644
--- a/gcc/testsuite/rust/compile/derive_macro4.rs
+++ b/gcc/testsuite/rust/compile/derive_macro4.rs
@@ -6,12 +6,9 @@ pub trait Clone {
 fn clone(&self) -> Self;
 }
 
+#[lang = "phantom_data"]
 struct PhantomData;
 
-pub struct AssertParamIsCopy {
-_field: PhantomData,
-}
-
 #[derive(Clone)] // { dg-error "bounds not satisfied for U .Copy. is not 
satisfied" }
 union U {
 i: i32,
-- 
2.45.2



[COMMITTED 139/146] gccrs: derive(Clone): Add note about Clone::clone()

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc (DeriveClone::clone_call): Mention using 
`clone_fn`
lang item in the future.
---
 gcc/rust/expand/rust-derive-clone.cc | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 2f733fae910..b8c92dcc6fe 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -30,6 +30,15 @@ DeriveClone::clone_call (std::unique_ptr &&to_clone)
   // $crate::core::clone::Clone::clone for the fully qualified path - we don't
   // link with `core` yet so that might be an issue. Use `Clone::clone` for 
now?
   // TODO: Factor this function inside the DeriveAccumulator
+
+  // Interestingly, later versions of Rust have a `clone_fn` lang item which
+  // corresponds to this. But because we are first targeting 1.49, we cannot 
use
+  // it yet. Once we target a new, more recent version of the language, we'll
+  // have figured out how to compile and distribute `core`, meaning we'll be
+  // able to directly call `::core::clone::Clone::clone()`
+
+  // Not sure how to call it properly in the meantime...
+
   auto path = std::unique_ptr (
 new PathInExpression (builder.path_in_expression ({"Clone", "clone"})));
 
@@ -79,10 +88,7 @@ DeriveClone::clone_impl (
   std::unique_ptr &&clone_fn, std::string name,
   const std::vector> &type_generics)
 {
-  // should that be `$crate::core::clone::Clone` instead?
-  auto segments = std::vector> ();
-  segments.emplace_back (builder.type_path_segment ("Clone"));
-  auto clone = TypePath (std::move (segments), loc);
+  auto clone = builder.type_path (LangItem::Kind::CLONE);
 
   auto trait_items = std::vector> ();
   trait_items.emplace_back (std::move (clone_fn));
-- 
2.45.2



[COMMITTED 026/146] gccrs: hir: Mark AttrVec::get_outer_attrs as override

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

gcc/rust/ChangeLog:

* hir/tree/rust-hir.h: Add override qualifier to overriden method.
---
 gcc/rust/hir/tree/rust-hir.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index 8ce5cf4d102..8544d0d5f09 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -673,7 +673,7 @@ public:
   // Returns whether the lifetime param has an outer attribute.
   bool has_outer_attribute () const override { return outer_attrs.size () > 1; 
}
 
-  AST::AttrVec &get_outer_attrs () { return outer_attrs; }
+  AST::AttrVec &get_outer_attrs () override { return outer_attrs; }
 
   // Returns whether the lifetime param is in an error state.
   bool is_error () const { return lifetime.is_error (); }
-- 
2.45.2



[COMMITTED 086/146] gccrs: lang-item: Add Option::{None, Some}, Iterator::next, IntoIter::into_iter

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

gcc/rust/ChangeLog:

* util/rust-lang-item.h: Add new lang items.
* util/rust-lang-item.cc: Likewise.
---
 gcc/rust/util/rust-lang-item.cc | 6 ++
 gcc/rust/util/rust-lang-item.h  | 9 +
 2 files changed, 15 insertions(+)

diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
index 216202af926..c4c1d1c093a 100644
--- a/gcc/rust/util/rust-lang-item.cc
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -92,6 +92,12 @@ const BiMap 
Rust::LangItem::lang_items = {{
   {"str", Kind::STR},
   {"f32_runtime", Kind::F32_RUNTIME},
   {"f64_runtime", Kind::F64_RUNTIME},
+
+  {"Some", Kind::OPTION_SOME},
+  {"None", Kind::OPTION_NONE},
+
+  {"into_iter", Kind::INTOITER_INTOITER},
+  {"next", Kind::ITERATOR_NEXT},
 }};
 
 tl::optional
diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h
index 66d26d03907..9e432e2ccc6 100644
--- a/gcc/rust/util/rust-lang-item.h
+++ b/gcc/rust/util/rust-lang-item.h
@@ -26,6 +26,9 @@ namespace Rust {
 class LangItem
 {
 public:
+  // FIXME: We should clean up that enum to make it more inline with the list 
of
+  // lang-items in Rust 1.49
+  // 
https://github.com/rust-lang/rust/blob/1.49.0/compiler/rustc_hir/src/lang_items.rs
   enum class Kind
   {
 // 
https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
@@ -117,6 +120,12 @@ public:
 STR,
 F32_RUNTIME,
 F64_RUNTIME,
+
+OPTION_SOME,
+OPTION_NONE,
+
+INTOITER_INTOITER,
+ITERATOR_NEXT,
   };
 
   static const BiMap lang_items;
-- 
2.45.2



[COMMITTED 136/146] gccrs: derive(Copy): Use copy lang item when deriving Copy.

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

gcc/rust/ChangeLog:

* expand/rust-derive-copy.cc: Use lang item path.
---
 gcc/rust/expand/rust-derive-copy.cc | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-copy.cc 
b/gcc/rust/expand/rust-derive-copy.cc
index bcfe1db6b4a..31b4819c042 100644
--- a/gcc/rust/expand/rust-derive-copy.cc
+++ b/gcc/rust/expand/rust-derive-copy.cc
@@ -18,6 +18,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"
 
@@ -43,12 +44,7 @@ DeriveCopy::copy_impl (
   std::string name,
   const std::vector> &type_generics)
 {
-  // `$crate::core::marker::Copy` instead
-  auto segments = std::vector> ();
-  segments.emplace_back (builder.type_path_segment ("Copy"));
-
-  auto copy = TypePath (std::move (segments), loc);
-  // auto copy = TypePath (LangItem::Kind::COPY, loc);
+  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
-- 
2.45.2



[COMMITTED 035/146] gccrs: Fixes some tests appearing with a moved variant

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

A variant being moved lead to a null being created and a segfault later
down the line.

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit): Call getter
instead of size function.
* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit):
Only check privacy if the type is present.
* hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Use an optional.
* hir/tree/rust-hir-generic-param.h: Assert type before getting it.
* hir/tree/rust-hir-item.h: Assert pointers before dereference, fix
has_type condition.
* hir/tree/rust-hir-path.h: Add more assertions.
* hir/tree/rust-hir-stmt.cc: Change constructor with optionals.
* hir/tree/rust-hir-stmt.h: Use optionals over smart pointers to
emphasize these fields might be missing.
* hir/tree/rust-hir.cc (LetStmt::as_string): Use getters.
* typecheck/rust-hir-type-check-expr.cc: Clone structures to prevent
parent's fields from being nulled by the move operation.
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): Use
optionals.
* typecheck/rust-tyty.cc: Likewise.
* typecheck/rust-tyty.h: Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/backend/rust-compile-expr.cc |  2 +-
 .../errors/privacy/rust-privacy-reporter.cc   |  6 +-
 gcc/rust/hir/rust-ast-lower-stmt.cc   | 20 +++---
 gcc/rust/hir/tree/rust-hir-generic-param.h|  6 +-
 gcc/rust/hir/tree/rust-hir-item.h | 69 +++
 gcc/rust/hir/tree/rust-hir-path.h | 18 -
 gcc/rust/hir/tree/rust-hir-stmt.cc| 26 ---
 gcc/rust/hir/tree/rust-hir-stmt.h | 40 ---
 gcc/rust/hir/tree/rust-hir.cc |  4 +-
 .../typecheck/rust-hir-type-check-expr.cc |  5 +-
 .../typecheck/rust-hir-type-check-item.cc |  7 +-
 gcc/rust/typecheck/rust-tyty.cc   | 40 ---
 gcc/rust/typecheck/rust-tyty.h| 12 +++-
 13 files changed, 189 insertions(+), 66 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 107ca2eadf5..673acdeefb5 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1200,7 +1200,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
   // this assumes all fields are in order from type resolution and if a
   // base struct was specified those fields are filed via accessors
   std::vector arguments;
-  for (size_t i = 0; i < expr.get_arguments ().size (); i++)
+  for (size_t i = 0; i < expr.num_params (); i++)
{
  auto &argument = expr.get_arguments ().at (i);
  auto rvalue = CompileExpr::Compile (*argument, ctx);
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 71030e5c7ef..3413e5ab3dd 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -741,9 +741,11 @@ PrivacyReporter::visit (HIR::EmptyStmt &)
 void
 PrivacyReporter::visit (HIR::LetStmt &stmt)
 {
-  check_type_privacy (stmt.get_type ());
+  if (stmt.has_type ())
+check_type_privacy (stmt.get_type ());
 
-  stmt.get_init_expr ().accept_vis (*this);
+  if (stmt.has_init_expr ())
+stmt.get_init_expr ().accept_vis (*this);
 }
 
 void
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.cc 
b/gcc/rust/hir/rust-ast-lower-stmt.cc
index c3594594bf1..5a825fd1139 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.cc
+++ b/gcc/rust/hir/rust-ast-lower-stmt.cc
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "optional.h"
 #include "rust-ast-lower-item.h"
 #include "rust-ast-lower-stmt.h"
 #include "rust-ast-lower-type.h"
@@ -68,12 +69,16 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt)
 {
   HIR::Pattern *variables
 = ASTLoweringPattern::translate (stmt.get_pattern (), true);
-  HIR::Type *type = stmt.has_type ()
- ? ASTLoweringType::translate (stmt.get_type ())
- : nullptr;
-  HIR::Expr *init_expression
-= stmt.has_init_expr () ? ASTLoweringExpr::translate (stmt.get_init_expr 
())
-   : nullptr;
+
+  auto type
+= stmt.has_type () ? tl::optional> (
+   std::unique_ptr (ASTLoweringType::translate (stmt.get_type (
+  : tl::nullopt;
+  auto init_expression
+= stmt.has_init_expr ()
+   ? tl::optional> (std::unique_ptr (
+ ASTLoweringExpr::translate (stmt.get_init_expr (
+   : tl::nullopt;
 
   auto crate_num = mappings.get_current_crate ();
   Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (),
@@ -81,8 +86,7 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt)
 UNKNOWN_LOCAL_DEFID);
   tr

[COMMITTED 143/146] gccrs: derive(Clone): Implement clone for enum tuple variants

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc (DeriveClone::variant_match_path): New 
function.
(DeriveClone::clone_enum_identifier): Rename.
(DeriveClone::clone_enum_tuple): New function.
(DeriveClone::visit_enum): Visit tuple variants properly.
* expand/rust-derive-clone.h: Declare new functions.
---
 gcc/rust/expand/rust-derive-clone.cc | 58 ++--
 gcc/rust/expand/rust-derive-clone.h  | 12 ++
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index e4702d8a818..c2994b7b4f8 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -21,6 +21,8 @@
 #include "rust-ast-dump.h"
 #include "rust-item.h"
 #include "rust-path.h"
+#include "rust-pattern.h"
+#include "rust-system.h"
 
 namespace Rust {
 namespace AST {
@@ -236,14 +238,20 @@ 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,
const std::unique_ptr &variant)
 {
-  auto variant_path = PathInExpression (
-{builder.path_segment (item.get_identifier ().as_string ()),
- builder.path_segment (variant->get_identifier ().as_string ())},
-{}, loc, false);
+  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,
@@ -253,6 +261,45 @@ DeriveClone::clone_enum_identifier (Enum &item,
   return builder.match_case (std::move (pattern), std::move (expr));
 }
 
+MatchCase
+DeriveClone::clone_enum_tuple (Enum &item, const EnumItemTuple &variant)
+{
+  auto variant_path = variant_match_path (item, variant.get_identifier ());
+
+  auto patterns = std::vector> ();
+  auto cloned_patterns = std::vector> ();
+
+  for (size_t i = 0; i < variant.get_tuple_fields ().size (); i++)
+{
+  // The pattern we're creating for each field is `self_` where `i` is
+  // the index of the field. It doesn't actually matter what we use, as 
long
+  // as it's ordered, unique, and that we can reuse it in the match case's
+  // return expression to clone the field.
+  auto pattern_str = "__self_" + std::to_string (i);
+
+  patterns.emplace_back (builder.identifier_pattern (pattern_str));
+
+  // Now, for each tuple's element, we create a new expression calling
+  // `clone` on it for the match case's return expression
+  cloned_patterns.emplace_back (
+   clone_call (builder.ref (builder.identifier (pattern_str;
+}
+
+  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));
+
+  return builder.match_case (std::move (pattern), std::move (expr));
+}
+
 void
 DeriveClone::visit_enum (Enum &item)
 {
@@ -274,6 +321,9 @@ DeriveClone::visit_enum (Enum &item)
  cases.emplace_back (clone_enum_identifier (item, variant));
  break;
case EnumItem::Kind::Tuple:
+ cases.emplace_back (
+   clone_enum_tuple (item, static_cast (*variant)));
+ break;
case EnumItem::Kind::Struct:
  rust_unreachable ();
  break;
diff --git a/gcc/rust/expand/rust-derive-clone.h 
b/gcc/rust/expand/rust-derive-clone.h
index 339cf6357ae..d48ec5d2889 100644
--- a/gcc/rust/expand/rust-derive-clone.h
+++ b/gcc/rust/expand/rust-derive-clone.h
@@ -63,8 +63,20 @@ private:
   clone_impl (std::unique_ptr &&clone_fn, std::string name,
  const std::vector> &type_generics);
 
+  /**
+   * Get the path to use for matching and creating a variant when matching on 
an
+   * enum. E.g. for the `Option` enum, with the `None` variant, this will 
create
+   * a path `Option::None`
+   */
+  PathInExpression variant_match_path (Enum &item, const Identifier &variant);
+
+  /**
+   * Implementation of clone for all possible variants of an enum
+   */
   MatchCase clone_enum_identifier (Enum &item,
   const std::unique_ptr &variant);
+  MatchCase clone_enum_tuple (Enum &item, const EnumItemTuple &variant);
+  MatchCase clone_enum_struct (

[COMMITTED 138/146] gccrs: derive(Clone): Use lang item for PhantomData in Clone

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

gcc/rust/ChangeLog:

* expand/rust-derive-clone.cc (DeriveClone::visit_union): Create a lang 
item path
instead of a regular path.
---
 gcc/rust/expand/rust-derive-clone.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index 8093bf67ff0..2f733fae910 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -263,7 +263,7 @@ DeriveClone::visit_union (Union &item)
 {StructField (
   Identifier ("_t"),
   builder.single_generic_type_path (
-   "PhantomData",
+   LangItem::Kind::PHANTOM_DATA,
GenericArgs (
  {}, {GenericArg::create_type (builder.single_type_path ("T"))}, {})),
   Visibility::create_private (), item.get_locus ())});
-- 
2.45.2



[COMMITTED 113/146] gccrs: gcc/rust/ChangeLog:

2025-03-21 Thread arthur . cohen
From: Om Swaroop Nayak <96killera...@gmail.com>

* ast/rust-collect-lang-items.cc (get_lang_item_attr): "removed checker 
fn"
* util/rust-attributes.cc (Attributes::is_lang_item): "added fn"
* util/rust-attributes.h: "added fn"

Signed-off-by: Om Swaroop Nayak <96killera...@gmail.com>
---
 gcc/rust/ast/rust-collect-lang-items.cc | 7 +--
 gcc/rust/util/rust-attributes.cc| 8 
 gcc/rust/util/rust-attributes.h | 2 ++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index 50d134a429f..ec6919dca14 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -40,12 +40,7 @@ get_lang_item_attr (const T &maybe_lang_item)
  continue;
}
 
-  bool is_lang_item = str_path == Values::Attributes::LANG
- && attr.has_attr_input ()
- && attr.get_attr_input ().get_attr_input_type ()
-  == AST::AttrInput::AttrInputType::LITERAL;
-
-  if (is_lang_item)
+  if (Analysis::Attributes::is_lang_item (str_path, attr))
{
  auto &literal
= static_cast (attr.get_attr_input ());
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 9f63234112c..0234903ba58 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -37,6 +37,14 @@ Attributes::is_known (const std::string &attribute_path)
 
   return !lookup.is_error ();
 }
+bool
+Attributes::is_lang_item (const std::string &attribute_path,
+ const AST::Attribute &attr)
+{
+  return ((attribute_path == Values::Attributes::LANG) && attr.has_attr_input 
()
+ && (attr.get_attr_input ().get_attr_input_type ()
+ == AST::AttrInput::AttrInputType::LITERAL));
+}
 
 using Attrs = Values::Attributes;
 
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index c928c8eb9d2..30f9eef213b 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -29,6 +29,8 @@ class Attributes
 {
 public:
   static bool is_known (const std::string &attribute_path);
+  static bool is_lang_item (const std::string &attribute_path,
+   const AST::Attribute &attr);
 };
 
 enum CompilerPass
-- 
2.45.2



[COMMITTED 122/146] gccrs: attributes: Add #[derive] as a built-in attribute

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

gcc/rust/ChangeLog:

* util/rust-attribute-values.h: Declare new attribute value.
* util/rust-attributes.cc: Use it.
---
 gcc/rust/util/rust-attribute-values.h | 1 +
 gcc/rust/util/rust-attributes.cc  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index ef01e67dc52..9ef5cc52e81 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -29,6 +29,7 @@ public:
   static constexpr auto &COLD = "cold";
   static constexpr auto &CFG = "cfg";
   static constexpr auto &CFG_ATTR = "cfg_attr";
+  static constexpr auto &DERIVE_ATTR = "derive";
   static constexpr auto &DEPRECATED = "deprecated";
   static constexpr auto &ALLOW = "allow";
   static constexpr auto &ALLOW_INTERNAL_UNSTABLE = "allow_internal_unstable";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 9f63234112c..03452c75bd8 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -46,6 +46,7 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::COLD, CODE_GENERATION},
  {Attrs::CFG, EXPANSION},
  {Attrs::CFG_ATTR, EXPANSION},
+ {Attrs::DERIVE_ATTR, EXPANSION},
  {Attrs::DEPRECATED, STATIC_ANALYSIS},
  {Attrs::ALLOW, STATIC_ANALYSIS},
  {Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS},
-- 
2.45.2



[COMMITTED 095/146] gccrs: tychk: Add more support for additional trait bounds in functions

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

This commit correctly lowers and typechecks parenthesized types, which are used 
for trait objects with additional bounds.

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveType::visit): New visitor to 
handle
ParenthesizedType.
* resolve/rust-ast-resolve-type.h: Likewise.
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): 
Likewise.
* typecheck/rust-hir-type-check-type.h: Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/auto_traits2.rs: New test.
* rust/compile/auto_traits3.rs: New test.
* rust/compile/nr2/exclude: Add auto_traits2 test.
---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  6 
 gcc/rust/resolve/rust-ast-resolve-type.h  |  3 ++
 .../typecheck/rust-hir-type-check-type.cc |  6 
 gcc/rust/typecheck/rust-hir-type-check-type.h |  4 +--
 gcc/testsuite/rust/compile/auto_traits2.rs| 26 ++
 gcc/testsuite/rust/compile/auto_traits3.rs| 34 +++
 gcc/testsuite/rust/compile/nr2/exclude|  2 ++
 7 files changed, 78 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/auto_traits2.rs
 create mode 100644 gcc/testsuite/rust/compile/auto_traits3.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index cb5a18d5d47..1d004b1ba9b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -50,6 +50,12 @@ ResolveType::visit (AST::TraitObjectType &type)
 }
 }
 
+void
+ResolveType::visit (AST::ParenthesisedType &type)
+{
+  resolved_node = ResolveType::go (*type.get_type_in_parens ());
+}
+
 void
 ResolveType::visit (AST::ReferenceType &type)
 {
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 518c0d80b14..5e8cdb11b2d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -24,6 +24,7 @@
 #include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-path.h"
+#include "rust-type.h"
 #include "util/rust-hir-map.h"
 
 namespace Rust {
@@ -143,6 +144,8 @@ public:
 
   void visit (AST::TraitObjectType &type) override;
 
+  void visit (AST::ParenthesisedType &type) override;
+
   void visit (AST::SliceType &type) override;
 
 private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 4ea1a493fa8..859cdfedcd0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -790,6 +790,12 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
   std::move (specified_bounds));
 }
 
+void
+TypeCheckType::visit (HIR::ParenthesisedType &type)
+{
+  translated = TypeCheckType::Resolve (type.get_type_in_parens ());
+}
+
 void
 TypeCheckType::visit (HIR::ArrayType &type)
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h 
b/gcc/rust/typecheck/rust-hir-type-check-type.h
index bf5589cbbab..1da01b869dd 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -59,6 +59,7 @@ public:
   void visit (HIR::InferredType &type) override;
   void visit (HIR::NeverType &type) override;
   void visit (HIR::TraitObjectType &type) override;
+  void visit (HIR::ParenthesisedType &type) override;
 
   void visit (HIR::TypePathSegmentFunction &segment) override
   { /* TODO */
@@ -69,9 +70,6 @@ public:
   void visit (HIR::ImplTraitType &type) override
   { /* TODO */
   }
-  void visit (HIR::ParenthesisedType &type) override
-  { /* TODO */
-  }
   void visit (HIR::ImplTraitTypeOneBound &type) override
   { /* TODO */
   }
diff --git a/gcc/testsuite/rust/compile/auto_traits2.rs 
b/gcc/testsuite/rust/compile/auto_traits2.rs
new file mode 100644
index 000..7d0dcc11cd2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits2.rs
@@ -0,0 +1,26 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+a.a_method();
+}
+
+struct S;
+
+impl A for S {
+fn a_method(&self) {}
+}
+
+fn main() {
+let s = S;
+
+foo(&s); // { dg-error "bounds not satisfied" }
+ // { dg-error "mismatched type" "" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/rust/compile/auto_traits3.rs 
b/gcc/testsuite/rust/compile/auto_traits3.rs
new file mode 100644
index 000..81c39ecda7f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_traits3.rs
@@ -0,0 +1,34 @@
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Send {}
+#[lang = "sync"]
+pub unsafe auto trait Sync {}
+
+trait A {
+fn a_method(&self) {}
+}
+
+fn foo(a: &(dyn A + Send + Sync)) {
+a.a_method();
+}
+
+struct S;
+
+impl A for S {
+fn a_method(&self) {} // { dg-warning "unused" }
+}
+
+// These

[COMMITTED 098/146] gccrs: use StackedContexts for block context

2025-03-21 Thread arthur . cohen
From: Prajwal S N 

Replaces the DIY vector stack with a StackedContexts object for block
scopes in the type checker context.

Fixes #3284.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check.h (class TypeCheckContext): add
header file and use StackedContexts for blocks
* typecheck/rust-typecheck-context.cc: update methods
* typecheck/rust-hir-trait-resolve.cc: refactor function calls
* typecheck/rust-hir-type-check-implitem.cc: refactor function calls
* typecheck/rust-hir-type-check-type.cc: refactor function calls

Signed-off-by: Prajwal S N 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  4 +--
 .../typecheck/rust-hir-type-check-implitem.cc |  5 ++--
 .../typecheck/rust-hir-type-check-type.cc |  7 ++---
 gcc/rust/typecheck/rust-hir-type-check.h  |  8 +++---
 gcc/rust/typecheck/rust-typecheck-context.cc  | 26 +++
 5 files changed, 15 insertions(+), 35 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 14e26f4512b..82019328e16 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -278,7 +278,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
 }
   self->inherit_bounds (specified_bounds);
 
-  context->push_block_context (TypeCheckBlockContextItem (trait_reference));
+  context->block_context ().enter (TypeCheckBlockContextItem 
(trait_reference));
   std::vector item_refs;
   for (auto &item : trait_reference->get_trait_items ())
 {
@@ -308,7 +308,7 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
   // resolve the blocks of functions etc because it can end up in a recursive
   // loop of trying to resolve traits as required by the types
   tref->on_resolved ();
-  context->pop_block_context ();
+  context->block_context ().exit ();
 
   return tref;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 4521822410c..937a8a8d0ef 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -335,9 +335,10 @@ TypeCheckImplItem::Resolve (
 
   // resolve
   TypeCheckImplItem resolver (parent, self, substitutions);
-  resolver.context->push_block_context (TypeCheckBlockContextItem (&parent));
+  resolver.context->block_context ().enter (
+TypeCheckBlockContextItem (&parent));
   item.accept_vis (resolver);
-  resolver.context->pop_block_context ();
+  resolver.context->block_context ().exit ();
 
   return resolver.result;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 859cdfedcd0..bb23f8441ed 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -591,10 +591,11 @@ TypeCheckType::resolve_segments (
   bool first_segment = i == offset;
   bool selfResolveOk = false;
 
-  if (first_segment && tySegIsBigSelf && context->have_block_context ()
- && context->peek_block_context ().is_impl_block ())
+  if (first_segment && tySegIsBigSelf
+ && context->block_context ().is_in_context ()
+ && context->block_context ().peek ().is_impl_block ())
{
- TypeCheckBlockContextItem ctx = context->peek_block_context ();
+ TypeCheckBlockContextItem ctx = context->block_context ().peek ();
  TyTy::BaseType *lookup = nullptr;
  selfResolveOk
= resolve_associated_type (seg->as_string (), ctx, &lookup);
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 08c3d354f79..ef1f2dd0214 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -22,6 +22,7 @@
 #include "rust-hir-map.h"
 #include "rust-tyty.h"
 #include "rust-hir-trait-reference.h"
+#include "rust-stacked-contexts.h"
 #include "rust-autoderef.h"
 #include "rust-tyty-region.h"
 #include "rust-tyty-variance-analysis.h"
@@ -186,10 +187,7 @@ public:
 TyTy::BaseType *return_type);
   void pop_return_type ();
 
-  bool have_block_context () const;
-  TypeCheckBlockContextItem peek_block_context ();
-  void push_block_context (TypeCheckBlockContextItem item);
-  void pop_block_context ();
+  StackedContexts &block_context ();
 
   void iterate (std::function cb);
 
@@ -282,7 +280,7 @@ private:
   std::vector>
 return_type_stack;
   std::vector loop_type_stack;
-  std::vector block_stack;
+  StackedContexts block_stack;
   std::map trait_context;
   std::map receiver_context;
   std::map associated_impl_traits;
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index e72ce41606d..8ff8839f733 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -177,30

[COMMITTED 097/146] gccrs: ast: Add new Kind enums for more precise downcasting

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

This commit adds things like Item::Kind, Expr::Kind, etc, and implements the 
associated `get_*_kind` functions.
It also removes the more generic AST::Kind enum we were using, which was 
incomplete and painful to use.

gcc/rust/ChangeLog:

* ast/rust-ast.h: Add new Kind enums, remove Node class.
* ast/rust-builtin-ast-nodes.h: Use new Kind enums.
* ast/rust-expr.h (class LoopLabel): Likewise.
* ast/rust-item.h: Likewise.
* ast/rust-macro.h: Likewise.
* ast/rust-path.h: Likewise.
* expand/rust-macro-builtins-helpers.cc: Likewise.
* expand/rust-macro-builtins-utility.cc (MacroBuiltin::concat_handler): 
Likewise.
(MacroBuiltin::stringify_handler): Likewise.
* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Likewise.
* resolve/rust-early-name-resolver.cc: Likewise.
* hir/rust-ast-lower.cc (ASTLoweringBlock::visit): Likewise.
---
 gcc/rust/ast/rust-ast.h   | 94 +--
 gcc/rust/ast/rust-builtin-ast-nodes.h |  2 +
 gcc/rust/ast/rust-expr.h  | 84 -
 gcc/rust/ast/rust-item.h  | 36 ++-
 gcc/rust/ast/rust-macro.h | 34 ---
 gcc/rust/ast/rust-path.h  | 10 ++
 .../expand/rust-macro-builtins-helpers.cc |  2 +-
 .../expand/rust-macro-builtins-utility.cc |  4 +-
 gcc/rust/hir/rust-ast-lower.cc|  6 +-
 gcc/rust/resolve/rust-ast-resolve-expr.cc |  2 +-
 gcc/rust/resolve/rust-early-name-resolver.cc  | 10 +-
 11 files changed, 229 insertions(+), 55 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 42ad0119231..5e724d184de 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -70,16 +70,6 @@ namespace AST {
 class ASTVisitor;
 using AttrVec = std::vector;
 
-// The available kinds of AST Nodes
-enum class Kind
-{
-  UNKNOWN,
-  MODULE,
-  MACRO_RULES_DEFINITION,
-  MACRO_INVOCATION,
-  IDENTIFIER,
-};
-
 class Visitable
 {
 public:
@@ -87,20 +77,6 @@ public:
   virtual void accept_vis (ASTVisitor &vis) = 0;
 };
 
-// Abstract base class for all AST elements
-class Node : public Visitable
-{
-public:
-  /**
-   * Get the kind of Node this is. This is used to differentiate various AST
-   * elements with very little overhead when extracting the derived type
-   * through static casting is not necessary.
-   */
-  // FIXME: Mark this as `= 0` in the future to make sure every node
-  // implements it
-  virtual Kind get_ast_kind () const { return Kind::UNKNOWN; }
-};
-
 // Delimiter types - used in macros and whatever.
 enum DelimType
 {
@@ -1092,7 +1068,7 @@ class MetaListNameValueStr;
 /* Base statement abstract class. Note that most "statements" are not allowed
  * in top-level module scope - only a subclass of statements called "items"
  * are. */
-class Stmt : public Node
+class Stmt : public Visitable
 {
 public:
   enum class Kind
@@ -1141,6 +1117,28 @@ protected:
 class Item : public Stmt
 {
 public:
+  enum class Kind
+  {
+MacroRulesDefinition,
+MacroInvocation,
+Module,
+ExternCrate,
+UseDeclaration,
+Function,
+TypeAlias,
+Struct,
+EnumItem,
+Enum,
+Union,
+ConstantItem,
+StaticItem,
+Trait,
+Impl,
+ExternBlock,
+  };
+
+  virtual Kind get_item_kind () const = 0;
+
   // Unique pointer custom clone function
   std::unique_ptr clone_item () const
   {
@@ -1221,14 +1219,54 @@ public:
   {
 return outer_attrs;
   }
+
+  virtual Item::Kind get_item_kind () const override = 0;
 };
+
 // forward decl of ExprWithoutBlock
 class ExprWithoutBlock;
 
 // Base expression AST node - abstract
-class Expr : public Node
+class Expr : public Visitable
 {
 public:
+  enum class Kind
+  {
+PathInExpression,
+QualifiedPathInExpression,
+Literal,
+Operator,
+Grouped,
+Array,
+ArrayIndex,
+Tuple,
+TupleIndex,
+Struct,
+Call,
+MethodCall,
+FieldAccess,
+Closure,
+Block,
+Continue,
+Break,
+Range,
+Box,
+Return,
+UnsafeBlock,
+Loop,
+If,
+IfLet,
+Match,
+Await,
+AsyncBlock,
+InlineAsm,
+Identifier,
+FormatArgs,
+MacroInvocation,
+  };
+
+  virtual Kind get_expr_kind () const = 0;
+
   // Unique pointer custom clone function
   std::unique_ptr clone_expr () const
   {
@@ -1343,7 +1381,7 @@ public:
 outer_attrs = std::move (new_attrs);
   }
 
-  Kind get_ast_kind () const override { return Kind::IDENTIFIER; }
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::Identifier; }
 
 protected:
   // Clone method implementation
@@ -1410,7 +1448,7 @@ protected:
 class TraitBound;
 
 // Base class for types as represented in AST - abstract
-class Type : public Node
+class Type : public Visitable
 {
 public:
   // Unique pointer custom clone function
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc

[COMMITTED 031/146] gccrs: Improve handling of static items in toplevel 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Use DefaultResolver::visit and avoid a call
to Identifier::as_string while handling instances of StaticItem.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +++--
 1 file changed, 3 insertions(+), 6 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 ef7a727dae9..a2f695e54f6 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -241,13 +241,10 @@ TopLevel::visit (AST::BlockExpr &expr)
 void
 TopLevel::visit (AST::StaticItem &static_item)
 {
-  auto sub_vis
-= [this, &static_item] () { static_item.get_expr ().accept_vis (*this); };
-
-  ctx.scoped (Rib::Kind::Item, static_item.get_node_id (), sub_vis);
-
-  insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
+  insert_or_error_out (static_item.get_identifier (), static_item,
   Namespace::Values);
+
+  DefaultResolver::visit (static_item);
 }
 
 void
-- 
2.45.2



[COMMITTED 028/146] gccrs: asm: Fix clang warnings

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

Fixes a couple of warnings thrown by clang, with mismatched class/struct
usages and unused members.

gcc/rust/ChangeLog:

* ast/rust-expr.h: Remove invalid usage of `struct`.
* backend/rust-compile-asm.h: Remove unused `translated` member.
* backend/rust-compile-asm.cc (CompileAsm::CompileAsm): Remove usage
of `translated` member.
* checks/errors/rust-unsafe-checker.h: Mark visitor as `override`.
* hir/tree/rust-hir-expr.h (struct AnonConst): Remove unused `locus`
member.
---
 gcc/rust/ast/rust-expr.h | 24 ++--
 gcc/rust/backend/rust-compile-asm.cc |  5 ++--
 gcc/rust/backend/rust-compile-asm.h  |  2 --
 gcc/rust/checks/errors/rust-unsafe-checker.h |  2 +-
 gcc/rust/hir/tree/rust-hir-expr.h|  4 ++--
 5 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 438d3d3b86e..483e599652b 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4810,14 +4810,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-In (const struct In &other)
+In (const In &other)
 {
   reg = other.reg;
 
   expr = other.expr->clone_expr ();
 }
 
-In operator= (const struct In &other)
+In operator= (const In &other)
 {
   reg = other.reg;
   expr = other.expr->clone_expr ();
@@ -4843,14 +4843,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-Out (const struct Out &other)
+Out (const Out &other)
 {
   reg = other.reg;
   late = other.late;
   expr = other.expr->clone_expr ();
 }
 
-Out operator= (const struct Out &other)
+Out operator= (const Out &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4876,14 +4876,14 @@ public:
   rust_assert (this->expr != nullptr);
 }
 
-InOut (const struct InOut &other)
+InOut (const InOut &other)
 {
   reg = other.reg;
   late = other.late;
   expr = other.expr->clone_expr ();
 }
 
-InOut operator= (const struct InOut &other)
+InOut operator= (const InOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4913,7 +4913,7 @@ public:
   rust_assert (this->out_expr != nullptr);
 }
 
-SplitInOut (const struct SplitInOut &other)
+SplitInOut (const SplitInOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4921,7 +4921,7 @@ public:
   out_expr = other.out_expr->clone_expr ();
 }
 
-SplitInOut operator= (const struct SplitInOut &other)
+SplitInOut operator= (const SplitInOut &other)
 {
   reg = other.reg;
   late = other.late;
@@ -4953,12 +4953,12 @@ public:
 {
   rust_assert (this->expr != nullptr);
 }
-Sym (const struct Sym &other)
+Sym (const Sym &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
 }
 
-Sym operator= (const struct Sym &other)
+Sym operator= (const Sym &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
@@ -4981,12 +4981,12 @@ public:
   if (label_name.has_value ())
this->label_name = label_name.value ();
 }
-Label (const struct Label &other)
+Label (const Label &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
 }
 
-Label operator= (const struct Label &other)
+Label operator= (const Label &other)
 {
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index e85d08d0579..be553a3e70f 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -3,9 +3,8 @@
 namespace Rust {
 namespace Compile {
 
-CompileAsm::CompileAsm (Context *ctx)
-  : HIRCompileBase (ctx), translated (error_mark_node)
-{}
+CompileAsm::CompileAsm (Context *ctx) : HIRCompileBase (ctx) {}
+
 tree
 CompileAsm::tree_codegen_asm (HIR::InlineAsm &expr)
 {
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 402d950844c..4abd24eded4 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -28,8 +28,6 @@ namespace Compile {
 class CompileAsm : private HIRCompileBase
 {
 private:
-  tree translated;
-
   // RELEVANT MEMBER FUNCTIONS
 
   // The limit is 5 because it stands for the 5 things that the C version of
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h 
b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 96ccdc03c53..8dc6ab79071 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -113,7 +113,7 @@ private:
   virtual void visit (MatchExpr &expr) override;
   virtual void visit (AwaitExpr &expr) override;
   virtual void visit (AsyncBlockExpr &expr) override;
-  virtual void visit (InlineAsm &expr);
+  

[COMMITTED 127/146] gccrs: lang-items: Collect struct lang items.

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

gcc/rust/ChangeLog:

* ast/rust-collect-lang-items.cc (CollectLangItems::visit): New.
* ast/rust-collect-lang-items.h: New.
---
 gcc/rust/ast/rust-collect-lang-items.cc | 9 +
 gcc/rust/ast/rust-collect-lang-items.h  | 1 +
 2 files changed, 10 insertions(+)

diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
index 168123ee56e..11c3297d2a9 100644
--- a/gcc/rust/ast/rust-collect-lang-items.cc
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -23,6 +23,7 @@
 #include "rust-attribute-values.h"
 #include "rust-attributes.h"
 #include "rust-hir-map.h"
+#include "rust-item.h"
 
 namespace Rust {
 namespace AST {
@@ -91,5 +92,13 @@ CollectLangItems::visit (AST::Function &item)
   DefaultASTVisitor::visit (item);
 }
 
+void
+CollectLangItems::visit (AST::StructStruct &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h 
b/gcc/rust/ast/rust-collect-lang-items.h
index 1d021b1d9c5..39cb4be31a0 100644
--- a/gcc/rust/ast/rust-collect-lang-items.h
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -48,6 +48,7 @@ public:
   void visit (AST::Trait &item) override;
   void visit (AST::TraitItemType &item) override;
   void visit (AST::Function &item) override;
+  void visit (AST::StructStruct &item) override;
 
 private:
   template  void maybe_add_lang_item (const T &item);
-- 
2.45.2



[COMMITTED 121/146] gccrs: ast: Fix warning about copy elision for moved expr

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

gcc/rust/ChangeLog:

* ast/rust-ast.cc (BlockExpr::normalize_tail_expr): Remove overzealous
std::move
---
 gcc/rust/ast/rust-ast.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 25e522bf948..45189a1a4b3 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -4270,7 +4270,7 @@ BlockExpr::normalize_tail_expr ()
 
  if (!stmt.is_semicolon_followed ())
{
- expr = std::move (stmt.take_expr ());
+ expr = stmt.take_expr ();
  statements.pop_back ();
}
}
-- 
2.45.2



[COMMITTED 088/146] gccrs: ast: Add new constructors for PathInExpression

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

This commit adds two new constructors for AST::PathInExpression: One using a 
provided lang-item, and one with an already built std::unique_ptr

gcc/rust/ChangeLog:

* ast/rust-path.h: Add two new constructors.
---
 gcc/rust/ast/rust-path.h | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 563ad52a9d6..39d42fd7e15 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -715,6 +715,24 @@ public:
   marked_for_strip (false)
   {}
 
+  PathInExpression (LangItem::Kind lang_item_kind,
+   std::vector outer_attrs, location_t locus)
+: outer_attrs (std::move (outer_attrs)),
+  has_opening_scope_resolution (false), locus (locus),
+  _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  path (Rust::make_unique (lang_item_kind, locus)),
+  marked_for_strip (false)
+  {}
+
+  PathInExpression (std::unique_ptr path,
+   std::vector outer_attrs, location_t locus,
+   bool has_opening_scope_resolution = false)
+: outer_attrs (std::move (outer_attrs)),
+  has_opening_scope_resolution (has_opening_scope_resolution),
+  locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  path (std::move (path)), marked_for_strip (false)
+  {}
+
   PathInExpression (const PathInExpression &other)
 : outer_attrs (other.outer_attrs),
   has_opening_scope_resolution (other.has_opening_scope_resolution),
@@ -738,7 +756,8 @@ public:
   // Creates an error state path in expression.
   static PathInExpression create_error ()
   {
-return PathInExpression ({}, {}, UNDEF_LOCATION);
+return PathInExpression (std::vector (), {},
+UNDEF_LOCATION);
   }
 
   // Returns whether path in expression is in an error state.
-- 
2.45.2



[COMMITTED 099/146] gccrs: fix ICE during HIR dump

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

These hir nodes have optional expressions which need guarded

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::do_qualifiedpathtype): add guard
(Dump::do_traitfunctiondecl): likewise
(Dump::visit): likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 2590eed19ae..5acf53e9296 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -404,7 +404,8 @@ Dump::do_qualifiedpathtype (QualifiedPathType &e)
   do_mappings (e.get_mappings ());
   visit_field ("type", e.get_type ());
 
-  visit_field ("trait", e.get_trait ());
+  if (e.has_as_clause ())
+visit_field ("trait", e.get_trait ());
 }
 
 void
@@ -521,7 +522,8 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e)
   else
 put_field ("function_params", "empty");
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
 
   if (e.has_where_clause ())
 put_field ("where_clause", e.get_where_clause ().as_string ());
@@ -1295,7 +1297,8 @@ Dump::visit (BreakExpr &e)
   else
 put_field ("label", "none");
 
-  visit_field ("break_expr ", e.get_expr ());
+  if (e.has_break_expr ())
+visit_field ("break_expr ", e.get_expr ());
 
   end ("BreakExpr");
 }
-- 
2.45.2