[COMMITTED 035/144] gccrs: emit error code for E0758

2025-03-19 Thread arthur . cohen
From: Raiki Tamura 

gcc/rust/ChangeLog:

* lex/rust-lex.cc (Lexer::build_token): Emit error code.
* lex/rust-lex.h: Fix comment.

Signed-off-by: Raiki Tamura 
---
 gcc/rust/lex/rust-lex.cc | 9 ++---
 gcc/rust/lex/rust-lex.h  | 9 +
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index f4b8861adcc..849063824dc 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -589,7 +589,8 @@ Lexer::build_token ()
  if (current_char.is_eof ())
{
  rust_error_at (
-   loc, "unexpected EOF while looking for end of comment");
+   loc, ErrorCode::E0758,
+   "unexpected EOF while looking for end of comment");
  break;
}
  str += current_char;
@@ -644,7 +645,8 @@ Lexer::build_token ()
  if (current_char.is_eof ())
{
  rust_error_at (
-   loc, "unexpected EOF while looking for end of comment");
+   loc, ErrorCode::E0758,
+   "unexpected EOF while looking for end of comment");
  break;
}
 
@@ -708,7 +710,8 @@ Lexer::build_token ()
  if (current_char.is_eof ())
{
  rust_error_at (
-   loc, "unexpected EOF while looking for end of comment");
+   loc, ErrorCode::E0758,
+   "unexpected EOF while looking for end of comment");
  break;
}
 
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index 8265ca8239f..10293e0a812 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -115,14 +115,15 @@ private:
   // Request new Location for current column in line_table
   location_t get_current_location ();
 
-  // Skips the current input char.
+  // Skips the current input character.
   void skip_input ();
-  // Advances current input char to n + 1 chars ahead of current position.
+  // Advances current input character to n + 1 characters ahead of current
+  // position.
   void skip_input (int n);
 
-  // Peeks the current char.
+  // Peeks the current character.
   Codepoint peek_input ();
-  // Returns char n bytes ahead of current position.
+  // Returns character n characters ahead of current position.
   Codepoint peek_input (int n);
 
   // Classifies keyword (i.e. gets id for keyword).
-- 
2.45.2



[COMMITTED 029/144] gccrs: ast: Introduce class hierarchy for lang item paths

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

Create a base Path class which is derived into two children classes for
regular paths and lang item paths. This allows it to hold either the
segments of a fully formed path, or the node ID of a lang-item path.
This is required in order to create these special paths
which do not have segments, and do not necessarily have a canonical
form - they only depend on where the item was defined.

gcc/rust/ChangeLog:

* ast/rust-ast-full-decls.h (class PathPattern): Rename PathPattern 
to...
(class Path): ...Path
* ast/rust-ast-collector.cc (TokenCollector::visit): Add required 
methods
for LangItemPath and RegularPath.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-path.cc (PathPattern::as_string): Likewise.
(RegularPath::as_string): Likewise.
(LangItemPath::as_string): Likewise.
(PathPattern::convert_to_simple_path): Likewise.
(RegularPath::convert_to_simple_path): Likewise.
(RegularPath::accept_vis): Likewise.
(LangItemPath::accept_vis): Likewise.
(PathInExpression::as_string): Likewise.
(QualifiedPathInExpression::as_string): Likewise.
* ast/rust-path.h (class PathPattern): Likewise.
(class Path): Likewise.
(class RegularPath): Likewise.
(class LangItemPath): Likewise.
(class PathInExpression): Likewise.
(class QualifiedPathInExpression): Likewise.
* ast/rust-pattern.h (class PathPattern): Likewise.
(class Path): Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
---
 gcc/rust/ast/rust-ast-collector.cc|  14 ++
 gcc/rust/ast/rust-ast-collector.h |   2 +
 gcc/rust/ast/rust-ast-full-decls.h|   2 +-
 gcc/rust/ast/rust-ast-visitor.cc  |  11 +
 gcc/rust/ast/rust-ast-visitor.h   |   5 +
 gcc/rust/ast/rust-path.cc |  28 ++-
 gcc/rust/ast/rust-path.h  | 251 ++
 gcc/rust/ast/rust-pattern.h   |   2 +-
 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/resolve/rust-ast-resolve-base.cc |   9 +
 gcc/rust/resolve/rust-ast-resolve-base.h  |   2 +
 13 files changed, 294 insertions(+), 42 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 6980fef6c51..20226687846 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -21,6 +21,7 @@
 #include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
+#include "rust-system.h"
 #include "rust-token.h"
 
 namespace Rust {
@@ -560,6 +561,19 @@ TokenCollector::visit (PathInExpression &path)
   visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION);
 }
 
+void
+TokenCollector::visit (RegularPath &path)
+{
+  // FIXME: We probably want to have a proper implementation here, and call 
this
+  // function from things like the PathInExpression visitor
+}
+
+void
+TokenCollector::visit (LangItemPath &path)
+{
+  // TODO: Implement proper token collection for lang item paths
+}
+
 void
 TokenCollector::visit (TypePathSegment &segment)
 {
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index b2dc41b4318..32a5bd33da7 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -234,6 +234,8 @@ public:
   void visit (PathExprSegment &segment);
   void visit (PathIdentSegment &segment);
   void visit (PathInExpression &path);
+  void visit (RegularPath &path);
+  void visit (LangItemPath &path);
   void visit (TypePathSegment &segment);
   void visit (TypePathSegmentGeneric &segment);
   void visit (TypePathSegmentFunction &segment);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index d2ba87613e6..85f7373678a 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -61,7 +61,7 @@ class PathIdentSegment;
 struct GenericArgsBinding;
 struct GenericArgs;
 class PathExprSegment;
-class PathPattern;
+class Path;
 class PathInExpression;
 class TypePathSegment;
 class TypePathSegmentGeneric;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 866357b8cf7..b124531b09c 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -85,6 +85,17 @@ DefaultASTVisitor::visit (AST::ConstGenericParam 
&const_param)
 visit (const_param.get_default_value ());
 }
 
+void
+DefaultASTVisitor::visit (AST::RegularPath &path)
+{
+  

[COMMITTED 019/144] gccrs: Simplify construction of BIR::Statement

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder-internal.h:
Use `make_*` functions to create BIR::Statements.
* checks/errors/borrowck/rust-bir.h: Make a complete constructor
and introduce `make_*` functions to create various
BIR::Statements.

Signed-off-by: Kushal Pal 
---
 .../borrowck/rust-bir-builder-internal.h  | 28 +--
 gcc/rust/checks/errors/borrowck/rust-bir.h| 48 ++-
 2 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index 34726cf4840..74be02b90f6 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -239,7 +239,8 @@ protected:
 protected: // Helpers to add BIR statements
   void push_assignment (PlaceId lhs, AbstractExpr *rhs, location_t location)
   {
-ctx.get_current_bb ().statements.emplace_back (lhs, rhs, location);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_assignment (lhs, rhs, location));
 translated = lhs;
   }
 
@@ -266,47 +267,46 @@ protected: // Helpers to add BIR statements
std::initializer_list destinations = {})
   {
 auto copy = move_place (switch_val, location);
-ctx.get_current_bb ().statements.emplace_back (Statement::Kind::SWITCH,
-  copy);
+ctx.get_current_bb ().statements.push_back (Statement::make_switch (copy));
 ctx.get_current_bb ().successors.insert (
   ctx.get_current_bb ().successors.end (), destinations);
   }
 
   void push_goto (BasicBlockId bb)
   {
-ctx.get_current_bb ().statements.emplace_back (Statement::Kind::GOTO);
+ctx.get_current_bb ().statements.push_back (Statement::make_goto ());
 if (bb != INVALID_BB) // INVALID_BB means the goto will be resolved later.
   ctx.get_current_bb ().successors.push_back (bb);
   }
 
   void push_storage_live (PlaceId place)
   {
-ctx.get_current_bb ().statements.emplace_back (
-  Statement::Kind::STORAGE_LIVE, place);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_storage_live (place));
   }
 
   void push_storage_dead (PlaceId place)
   {
-ctx.get_current_bb ().statements.emplace_back (
-  Statement::Kind::STORAGE_DEAD, place);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_storage_dead (place));
   }
 
   void push_user_type_ascription (PlaceId place, TyTy::BaseType *ty)
   {
-ctx.get_current_bb ().statements.emplace_back (
-  Statement::Kind::USER_TYPE_ASCRIPTION, place, ty);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_user_type_ascription (place, ty));
   }
 
   void push_fake_read (PlaceId place)
   {
-ctx.get_current_bb ().statements.emplace_back (Statement::Kind::FAKE_READ,
-  place);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_fake_read (place));
   }
 
   void push_return (location_t location)
   {
-ctx.get_current_bb ().statements.emplace_back (Statement::Kind::RETURN,
-  INVALID_PLACE, location);
+ctx.get_current_bb ().statements.push_back (
+  Statement::make_return (location));
   }
 
   PlaceId borrow_place (PlaceId place_id, TyTy::BaseType *ty,
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h 
b/gcc/rust/checks/errors/borrowck/rust-bir.h
index 74c53a68a02..583d1ebd58f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -83,18 +83,44 @@ private:
   location_t location;
 
 public:
-  Statement (PlaceId lhs, AbstractExpr *rhs, location_t location)
-: kind (Kind::ASSIGNMENT), place (lhs), expr (rhs), location (location)
-  {}
-
-  explicit Statement (Kind kind, PlaceId place = INVALID_PLACE,
- location_t location = UNKNOWN_LOCATION)
-: kind (kind), place (place), location (location)
-  {}
+  static Statement make_assignment (PlaceId place, AbstractExpr *rhs,
+   location_t location)
+  {
+return Statement (Kind::ASSIGNMENT, place, rhs, nullptr, location);
+  }
+  static Statement make_switch (PlaceId place)
+  {
+return Statement (Kind::SWITCH, place);
+  }
+  static Statement make_return (location_t location)
+  {
+return Statement (Kind::RETURN, INVALID_PLACE, nullptr, nullptr, location);
+  }
+  static Statement make_goto () { return Statement (Kind::GOTO); }
+  static Statement make_storage_dead (PlaceId place)
+  {
+return Statement (Kind::STORAGE_DEAD, place);
+  }
+  static Statement make_storage_live (PlaceId place)
+  {
+return Statement (Kind::STORAGE_LIVE, place);
+  }
+  static Statement make_user_type_ascription (PlaceId place,
+  

[COMMITTED 122/144] rust: fix ICE during name resolution for impls on unit-types

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

The canonical paths need to support unit-types which are technically a
TupleType with no fields. This handles this case and adds an unreachable.

Fixes #3036

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveTypeToCanonicalPath::visit): 
add unit-type catch
* resolve/rust-ast-resolve-type.h: likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  9 +
 gcc/rust/resolve/rust-ast-resolve-type.h  |  2 ++
 gcc/testsuite/rust/compile/issue-3036.rs  | 14 ++
 gcc/testsuite/rust/compile/nr2/exclude|  1 +
 4 files changed, 26 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3036.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index cee259cceb4..ec5e8a762a7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -507,6 +507,15 @@ ResolveTypeToCanonicalPath::visit (AST::NeverType &type)
   result = CanonicalPath::new_seg (type.get_node_id (), "!");
 }
 
+void
+ResolveTypeToCanonicalPath::visit (AST::TupleType &type)
+{
+  if (!type.is_unit_type ())
+rust_unreachable ();
+
+  result = CanonicalPath::new_seg (type.get_node_id (), "()");
+}
+
 ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
   : ResolverBase (), result (CanonicalPath::create_empty ())
 {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 5e382445a14..561948e85b8 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -248,6 +248,8 @@ public:
 
   void visit (AST::NeverType &type) override;
 
+  void visit (AST::TupleType &type) override;
+
 private:
   ResolveTypeToCanonicalPath ();
 
diff --git a/gcc/testsuite/rust/compile/issue-3036.rs 
b/gcc/testsuite/rust/compile/issue-3036.rs
new file mode 100644
index 000..4418ccc04cb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3036.rs
@@ -0,0 +1,14 @@
+#[lang = "sized"]
+trait Sized {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Default: Sized {
+#[stable(feature = "rust1", since = "1.0.0")]
+fn default() -> Self;
+}
+
+impl Default for () {
+fn default() -> () {
+()
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index bfb51fd7fee..50781e56b85 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -252,3 +252,4 @@ issue-3082.rs
 issue-3139-1.rs
 issue-3139-2.rs
 issue-3139-3.rs
+issue-3036.rs
-- 
2.45.2



[COMMITTED 057/144] gccrs: Make inline mov compiles

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::asm_build_expr):
Remove debug
* expand/rust-macro-builtins-asm.cc (expand_inline_asm_strings):
properly formatted via rust instead of c
(parse_asm): formatted comment
(parse_format_strings): formatted comment
* hir/tree/rust-hir-expr.h: fix is_simple_asm()

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_parse_operand.rs: Fix format asm
* rust/compile/inline_asm_parse_output_operand.rs:
Fix format asm
* rust/execute/torture/inline_asm_mov_x_5.rs: Move to...
* rust/execute/inline_asm_mov_x_5.rs: ...here.
---
 gcc/rust/backend/rust-compile-asm.cc  |  2 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc| 67 +++
 gcc/rust/hir/tree/rust-hir-expr.h |  4 +-
 .../rust/compile/inline_asm_parse_operand.rs  | 14 ++--
 .../inline_asm_parse_output_operand.rs|  2 +-
 .../{torture => }/inline_asm_mov_x_5.rs   |  5 +-
 6 files changed, 71 insertions(+), 23 deletions(-)
 rename gcc/testsuite/rust/execute/{torture => }/inline_asm_mov_x_5.rs (75%)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 92d60d75686..045cc2866fd 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -26,7 +26,7 @@ CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
   ASM_BASIC_P (asm_expr) = expr.is_simple_asm ();
   ASM_VOLATILE_P (asm_expr) = false;
   ASM_INLINE_P (asm_expr) = expr.is_inline_asm ();
-  Backend::debug (asm_expr);
+  /*Backend::debug (asm_expr);*/
   return asm_expr;
 }
 
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 379e5d8b967..65bc6c58192 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -761,6 +761,8 @@ expand_inline_asm_strings (InlineAsmContext &inline_asm_ctx)
   auto &inline_asm = inline_asm_ctx.inline_asm;
 
   auto str_vec = inline_asm.get_template_strs ();
+
+  decltype (str_vec) resulting_template_vec;
   for (auto &template_str : str_vec)
 {
   /*std::cout << template_str.symbol << std::endl;*/
@@ -769,20 +771,57 @@ expand_inline_asm_strings (InlineAsmContext 
&inline_asm_ctx)
  Fmt::ffi::ParseMode::InlineAsm);
   auto pieces_vec = pieces.get_pieces ();
 
+  std::string transformed_template_str = "";
   for (size_t i = 0; i < pieces_vec.size (); i++)
{
  auto piece = pieces_vec[i];
  if (piece.tag == Fmt::ffi::Piece::Tag::String)
{
+ transformed_template_str += piece.string._0.to_string ();
+   }
+ else if (piece.tag == Fmt::ffi::Piece::Tag::NextArgument)
+   {
+ /*std::cout << "   " << i << ": "*/
+ /*<< piece.next_argument._0.to_string () << std::endl;*/
+
+ auto next_argument = piece.next_argument._0;
+ switch (piece.next_argument._0.position.tag)
+   {
+ case Fmt::ffi::Position::Tag::ArgumentImplicitlyIs: {
+   auto idx = next_argument.position.argument_implicitly_is._0;
+   /*auto trait = next_argument.format;*/
+   /*auto arg = arguments.at (idx);*/
+
+   /* // FIXME(Arthur): This API sucks*/
+   /* rust_assert (arg.get_kind ().kind*/
+   /*== AST::FormatArgumentKind::Kind::Normal);*/
+   /**/
+   /* args.push_back ({arg.get_expr ().clone_expr (),
+* trait});*/
+
+   transformed_template_str += "%" + std::to_string (idx);
+   /*std::cout << "argument implicitly is: " << idx <<
+* std::endl;*/
+   /*std::cout << "trait: " << trait.to_string () <<
+* std::endl;*/
+   /*std::cout << "arg: " << arg.to_string () << std::endl;*/
+ }
+ break;
+   case Fmt::ffi::Position::Tag::ArgumentIs:
+   case Fmt::ffi::Position::Tag::ArgumentNamed:
+ rust_sorry_at (inline_asm.get_locus (),
+"unhandled argument position specifier");
+ break;
+   }
}
- /*std::cout << "   " << i << ": " << piece.string._0.to_string
-  * ()*/
- /*   << std::endl;*/
}
+  template_str.symbol = transformed_template_str;
 }
 
+  inline_asm.template_strs = str_vec;
   return inline_asm_ctx;
 }
+
 tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   AST::InvocKind semicolon, AST::AsmKind is_global_asm)
@@ -791,7 +830,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   // We first parse all formatted strings. If we fail, then we ret

[COMMITTED 043/144] gccrs: Scaffolding new compile-asm files

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* Make-lang.in:
Scaffolding new compile-asm files
* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise
* hir/tree/rust-hir-expr.h: Likewise
* backend/rust-compile-asm.cc: New file. Likewise
* backend/rust-compile-asm.h: New file. Likewise
---
 gcc/rust/Make-lang.in |  1 +
 gcc/rust/backend/rust-compile-asm.cc  | 80 +++
 gcc/rust/backend/rust-compile-asm.h   | 46 +++
 gcc/rust/backend/rust-compile-expr.cc |  9 ++-
 gcc/rust/hir/tree/rust-hir-expr.h | 35 
 5 files changed, 131 insertions(+), 40 deletions(-)
 create mode 100644 gcc/rust/backend/rust-compile-asm.cc
 create mode 100644 gcc/rust/backend/rust-compile-asm.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index c892fa3091e..d291dd64765 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -196,6 +196,7 @@ GRS_OBJS = \
 rust/rust-compile-item.o \
 rust/rust-compile-implitem.o \
 rust/rust-compile-stmt.o \
+rust/rust-compile-asm.o \
 rust/rust-compile-expr.o \
 rust/rust-compile-type.o \
 rust/rust-compile-block.o \
diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
new file mode 100644
index 000..5bc7bce07e6
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -0,0 +1,80 @@
+#include "rust-compile-asm.h"
+
+#include "rust-tree.h"
+#include "rust-system.h"
+namespace Rust {
+namespace Compile {
+
+tree
+CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
+{
+  return NULL_TREE;
+  // return build_asm_expr (CompileAsm::asm_get_locus (expr),
+  //CompileAsm::asm_construct_string_tree (expr),
+  //CompileAsm::asm_construct_outputs (expr),
+  //CompileAsm::asm_construct_inputs (expr),
+  //CompileAsm::asm_construct_clobber_tree (expr),
+  //CompileAsm::asm_construct_label_tree (expr),
+  //CompileAsm::asm_is_simple (expr),
+  //CompileAsm::asm_is_inline (expr));
+}
+
+location_t
+CompileAsm::asm_get_locus (HIR::InlineAsm &expr)
+{
+  return expr.get_locus ();
+}
+tree
+CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
+{
+  if (expr.template_strs.empty ())
+return build_string (1, "");
+  // Initialize to NULL_TREE
+  tree string_chain = NULL_TREE;
+
+  for (const auto &template_str : expr.template_strs)
+{
+  auto str = template_str.symbol;
+  auto string_tree = build_string (str.size () + 1, str.c_str ());
+
+  string_chain = tree_cons (NULL_TREE, string_tree, string_chain);
+}
+  // Reverse the chain before returning
+  return nreverse (string_chain);
+}
+tree
+CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
+{
+  return NULL_TREE;
+}
+
+tree
+CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
+{
+  return NULL_TREE;
+}
+
+tree
+CompileAsm::asm_construct_clobber_tree (HIR::InlineAsm &expr)
+{
+  return NULL_TREE;
+}
+tree
+CompileAsm::asm_construct_label_tree (HIR::InlineAsm &expr)
+{
+  return NULL_TREE;
+}
+
+bool
+CompileAsm::asm_is_simple (HIR::InlineAsm &expr)
+{
+  return true;
+}
+
+bool
+CompileAsm::asm_is_inline (HIR::InlineAsm &expr)
+{
+  return true;
+}
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
new file mode 100644
index 000..58f0f51e9cf
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -0,0 +1,46 @@
+
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_COMPILE_ASM
+#define RUST_COMPILE_ASM
+
+#include "rust-compile-base.h"
+#include "rust-hir-visitor.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileAsm
+{
+public:
+  static tree asm_build_expr (HIR::InlineAsm &);
+  static location_t asm_get_locus (HIR::InlineAsm &);
+  static tree asm_construct_string_tree (HIR::InlineAsm &);
+  static tree asm_construct_outputs (HIR::InlineAsm &);
+  static tree asm_construct_inputs (HIR::InlineAsm &);
+  static tree asm_construct_clobber_tree (HIR::InlineAsm &);
+  static tree asm_construct_label_tree (HIR::InlineAsm &);
+
+  static bool asm_is_simple (HIR::InlineAsm &);
+
+  static bool asm_is_inline (H

[COMMITTED 128/144] gccrs: Handle TypeAlias during toplevel resolution 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Handle TypeAlias.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove type-alias1.rs.

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  | 1 -
 3 files changed, 10 insertions(+), 1 deletion(-)

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 35732e244b4..b0e0c1b52dc 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -348,6 +348,15 @@ TopLevel::visit (AST::ConstantItem &const_item)
   DefaultResolver::visit (const_item);
 }
 
+void
+TopLevel::visit (AST::TypeAlias &type_item)
+{
+  insert_or_error_out (type_item.get_new_type_name (), type_item,
+  Namespace::Types);
+
+  DefaultResolver::visit (type_item);
+}
+
 static void
 flatten_rebind (
   const AST::UseTreeRebind &glob,
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 09b22612f78..cc301ed7fdd 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -161,6 +161,7 @@ private:
   void visit (AST::Enum &enum_item) override;
   void visit (AST::Union &union_item) override;
   void visit (AST::ConstantItem &const_item) override;
+  void visit (AST::TypeAlias &type_item) override;
   void visit (AST::ExternCrate &crate) override;
   void visit (AST::TypeParam &type_param) override;
 
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index e0aa15531e1..1faa7b53622 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -206,7 +206,6 @@ traits7.rs
 traits8.rs
 traits9.rs
 tuple_struct1.rs
-type-alias1.rs
 type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
-- 
2.45.2



[COMMITTED 040/144] gccrs: Make sure CompileExpr::visit is reached

2025-03-19 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* hir/tree/rust-hir.cc (InlineAsm::accept_vis):
Make sure CompileExpr::visit is reached
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Likewise
gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_compile_nop.rs: New test.
---
 gcc/rust/hir/tree/rust-hir.cc|  4 +++-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc   |  4 +---
 gcc/testsuite/rust/compile/inline_asm_compile_nop.rs | 12 
 3 files changed, 16 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_compile_nop.rs

diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 8e0d444ce15..f05e5065e62 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -3833,7 +3833,9 @@ BorrowExpr::accept_vis (HIRFullVisitor &vis)
 
 void
 InlineAsm::accept_vis (HIRExpressionVisitor &vis)
-{}
+{
+  vis.visit (*this);
+}
 
 void
 InlineAsm::accept_vis (HIRFullVisitor &vis)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 6635f13ea04..1197916d1f5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -777,9 +777,7 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
 
 void
 TypeCheckExpr::visit (HIR::InlineAsm &expr)
-{
-  return;
-}
+{}
 
 void
 TypeCheckExpr::visit (HIR::RangeFullExpr &expr)
diff --git a/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs 
b/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs
new file mode 100644
index 000..c49667c879d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_compile_nop.rs
@@ -0,0 +1,12 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {}
+}
+
+fn main() {
+unsafe {
+asm!("nop");
+}
+}
\ No newline at end of file
-- 
2.45.2



[COMMITTED 125/144] gccrs: Fix ICE when typechecking non-trait item when we expect one

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

We just had an assertion here for this case where we expect a trait.
This changes the assertion into error handling producing the correct
error code with fixit suggestion like rustc.

Fixes #2499

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc 
(TraitResolver::resolve_path_to_trait):
use error handling instead of assertion
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): reuse 
trait reference
* typecheck/rust-hir-type-check-item.h: update prototype

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 27 ---
 .../typecheck/rust-hir-type-check-item.cc | 19 +
 gcc/rust/typecheck/rust-hir-type-check-item.h |  3 ++-
 gcc/testsuite/rust/compile/issue-2499.rs  | 11 
 gcc/testsuite/rust/compile/nr2/exclude|  3 ++-
 5 files changed, 46 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2499.rs

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 51a64174ea4..ec331cf6e95 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -117,19 +117,26 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath 
&path,
   return false;
 }
 
-  if (auto hid = mappings.lookup_node_to_hir (ref))
+  auto hid = mappings.lookup_node_to_hir (ref);
+  if (!hid)
 {
-  tl::optional resolved_item
-   = mappings.lookup_hir_item (hid.value ());
-  rust_assert (resolved_item.has_value ());
-  rust_assert (resolved_item.value ()->get_item_kind ()
-  == HIR::Item::ItemKind::Trait);
-  *resolved = static_cast (*resolved_item);
+  rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
+  return false;
+}
 
-  return true;
+  auto resolved_item = mappings.lookup_hir_item (hid.value ());
+  rust_assert (resolved_item.has_value ());
+  if (resolved_item.value ()->get_item_kind () != HIR::Item::ItemKind::Trait)
+{
+  rich_location r (line_table, path.get_locus ());
+  r.add_fixit_replace ("not a trait");
+  rust_error_at (r, ErrorCode::E0404, "Expected a trait found %qs",
+path.as_simple_path ().as_string ().c_str ());
+  return false;
 }
-  rust_error_at (path.get_locus (), "Failed to resolve path to hir-id");
-  return false;
+
+  *resolved = static_cast (*resolved_item);
+  return true;
 }
 
 TraitReference *
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index d707e3458f1..3858d5132f9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -453,6 +453,15 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
 {
   auto binder_pin = context->push_clean_lifetime_resolver (true);
 
+  TraitReference *trait_reference = &TraitReference::error_node ();
+  if (impl_block.has_trait_ref ())
+{
+  std::unique_ptr &ref = impl_block.get_trait_ref ();
+  trait_reference = TraitResolver::Resolve (*ref);
+  if (trait_reference->is_error ())
+   return;
+}
+
   bool failed_flag = false;
   auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
@@ -474,7 +483,7 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
 }
 
   // validate the impl items
-  validate_trait_impl_block (impl_block, self, substitutions);
+  validate_trait_impl_block (trait_reference, impl_block, self, substitutions);
 }
 
 TyTy::BaseType *
@@ -698,16 +707,16 @@ TypeCheckItem::resolve_impl_block_substitutions 
(HIR::ImplBlock &impl_block,
 
 void
 TypeCheckItem::validate_trait_impl_block (
-  HIR::ImplBlock &impl_block, TyTy::BaseType *self,
+  TraitReference *trait_reference, HIR::ImplBlock &impl_block,
+  TyTy::BaseType *self,
   std::vector &substitutions)
 {
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
-  TraitReference *trait_reference = &TraitReference::error_node ();
   if (impl_block.has_trait_ref ())
 {
   std::unique_ptr &ref = impl_block.get_trait_ref ();
-  trait_reference = TraitResolver::Resolve (*ref);
-  rust_assert (!trait_reference->is_error ());
+  if (trait_reference->is_error ())
+   return;
 
   // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
   // for example
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h 
b/gcc/rust/typecheck/rust-hir-type-check-item.h
index c5b94db2cb5..56832e75ccd 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -63,7 +63,8 @@ protected:
bool &failure_flag);
 
   void validate_trait_impl_block (
-HIR::ImplBlock &impl_b

[COMMITTED 127/144] gccrs: Fix some issues with canonical path fetching in name resolution 2.0

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

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-enumitem.cc: Add includes.
(TypeCheckEnumItem::visit): Fetch canonical paths properly when
name resolution 2.0 is enabled.
* typecheck/rust-hir-type-check-implitem.cc: Add includes.
(TypeCheckImplItem::visit): Fetch canonical paths properly when
name resolution 2.0 is enabled.
* typecheck/rust-hir-type-check-item.cc: Add include.
(TypeCheckItem::visit): Fetch canonical paths properly when name
resolution 2.0 is enabled.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 .../typecheck/rust-hir-type-check-enumitem.cc | 80 +--
 .../typecheck/rust-hir-type-check-implitem.cc | 23 +-
 .../typecheck/rust-hir-type-check-item.cc | 43 +-
 gcc/testsuite/rust/compile/nr2/exclude|  8 --
 4 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
index 72d8791fe56..a9154c64786 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc
@@ -20,6 +20,10 @@
 #include "rust-hir-type-check-expr.h"
 #include "rust-hir-type-check-enumitem.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 {
@@ -75,8 +79,23 @@ TypeCheckEnumItem::visit (HIR::EnumItem &item)
   rust_assert (ok);
   context->insert_type (mapping, isize);
 
-  auto canonical_path
-= mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+  tl::optional canonical_path;
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path
+   = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path.has_value ());
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
@@ -104,8 +123,23 @@ TypeCheckEnumItem::visit (HIR::EnumItemDiscriminant &item)
  TyTy::TyWithLocation (expected_ty),
  TyTy::TyWithLocation (capacity_type), item.get_locus ());
 
-  auto canonical_path
-= mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+  tl::optional canonical_path;
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path
+   = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path.has_value ());
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
@@ -151,8 +185,23 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item)
   rust_assert (ok);
   context->insert_type (mapping, isize);
 
-  auto canonical_path
-= mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+  tl::optional canonical_path;
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path
+   = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path.has_value ());
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
@@ -197,8 +246,23 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item)
   rust_assert (ok);
   context->insert_type (mapping, isize);
 
-  auto canonical_path
-= mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+  tl::optional canonical_path;
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.types.to_canonical_path (item.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path
+   = mappings.lookup_canonical_path (item.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path.has_value ());
 
   RustIdent ident{*canonical_path, item.get_locus ()};
   variant = new TyTy::VariantDef (item.get_mappings ().get_hirid (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc 
b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 58d59d97cec..0036e9a6c89 

[COMMITTED 124/144] gccrs: Add test case to show ICE is fixed

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

This was resolved in: 18422c9c386 which was missing the name
resolution step for unit-types.

Fixes #2203

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude:
* rust/compile/issue-2203.rs: New test.

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

diff --git a/gcc/testsuite/rust/compile/issue-2203.rs 
b/gcc/testsuite/rust/compile/issue-2203.rs
new file mode 100644
index 000..961381d69f7
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2203.rs
@@ -0,0 +1,3 @@
+trait A {}
+
+impl A for () {}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index c30af607edb..e792462ba33 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -254,3 +254,4 @@ issue-3139-2.rs
 issue-3139-3.rs
 issue-3036.rs
 issue-2951.rs
+issue-2203.rs
\ No newline at end of file
-- 
2.45.2



[COMMITTED 048/144] gccrs: Added new test for prep of output {}

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_parse_output_operand.rs: New test.
---
 .../compile/inline_asm_parse_output_operand.rs | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 
gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs

diff --git a/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs 
b/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs
new file mode 100644
index 000..3134c73b3c2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_parse_output_operand.rs
@@ -0,0 +1,18 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {};
+}
+
+fn main() {
+let mut _num1: i32 = 10;
+let mut _num2: i32 = 10;
+unsafe {
+asm!(
+"mov {0}, 4",
+out(reg) _num1,
+out(reg) _num2,
+);
+}
+}
-- 
2.45.2



[COMMITTED 018/144] gccrs: Loan errors with locations

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
(BorrowCheckerDiagnostics::report_loan_errors): Add label to
where the borrow occurs and where the invalid access occurs.
(BorrowCheckerDiagnostics::get_statement):
Fetch BIR::Statement from Polonius::Point
(BorrowCheckerDiagnostics::get_loan):
Fetch BIR::Loan from Polonius::Loan
* checks/errors/borrowck/rust-borrow-checker-diagnostics.h:
Function definition of helpers.

gcc/testsuite/ChangeLog:

* rust/borrowck/reference.rs: Test rich errors for
borrow-checker.
* rust/borrowck/return_ref_to_local.rs: Likewise.
* rust/borrowck/tmp.rs: Likewise.
* rust/borrowck/use_while_mut.rs: Likewise.
* rust/borrowck/use_while_mut_fr.rs: Likewise.
* rust/borrowck/well_formed_function_inputs.rs: Likewise.

Signed-off-by: Kushal Pal 
---
 .../rust-borrow-checker-diagnostics.cc| 47 -
 .../rust-borrow-checker-diagnostics.h | 13 +++
 gcc/testsuite/rust/borrowck/reference.rs  | 96 +--
 .../rust/borrowck/return_ref_to_local.rs  | 15 ++-
 gcc/testsuite/rust/borrowck/tmp.rs| 95 --
 gcc/testsuite/rust/borrowck/use_while_mut.rs  | 21 +++-
 .../rust/borrowck/use_while_mut_fr.rs | 19 +++-
 .../borrowck/well_formed_function_inputs.rs   | 21 +++-
 8 files changed, 295 insertions(+), 32 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
index a8eaa807ebb..0365dc3bd6f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "rust-borrow-checker-diagnostics.h"
+#include "polonius/rust-polonius-ffi.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace BIR {
@@ -43,11 +45,16 @@ BorrowCheckerDiagnostics::report_move_errors ()
 void
 BorrowCheckerDiagnostics::report_loan_errors ()
 {
-  if (!loan_errors.empty ())
+  for (const auto &pair : loan_errors)
 {
-  rust_error_at (hir_function->get_locus (),
-"Found loan errors in function %s",
-hir_function->get_function_name ().as_string ().c_str ());
+  auto error_location = get_statement (pair.first).get_location ();
+  for (const auto &loan : pair.second)
+   {
+ auto loan_struct = get_loan (loan);
+ multi_label_error ("use of borrowed value", error_location,
+{{"borrow occurs here", loan_struct.location},
+ {"borrowed value used here", error_location}});
+   }
 }
 }
 
@@ -63,5 +70,37 @@ BorrowCheckerDiagnostics::report_subset_errors ()
 }
 }
 
+const BIR::Statement &
+BorrowCheckerDiagnostics::get_statement (Polonius::Point point)
+{
+  auto statement_index = Polonius::FullPoint::extract_stmt (point);
+  auto bb_index = Polonius::FullPoint::extract_bb (point);
+  // assert that the extracted indexes are valid
+  rust_assert (bb_index < bir_function.basic_blocks.size ());
+  rust_assert (statement_index
+  < bir_function.basic_blocks[bb_index].statements.size ());
+  return bir_function.basic_blocks[bb_index].statements[statement_index];
+}
+
+const BIR::Loan &
+BorrowCheckerDiagnostics::get_loan (Polonius::Loan loan)
+{
+  return bir_function.place_db.get_loans ()[loan];
+}
+
+void
+BorrowCheckerDiagnostics::multi_label_error (
+  const char *error_message, location_t error_location,
+  std::vector location_label_pairs)
+{
+  rich_location r{line_table, error_location};
+  for (auto &label_location : location_label_pairs)
+{
+  r.add_range (label_location.location, SHOW_RANGE_WITHOUT_CARET,
+  &label_location.label);
+}
+  rust_error_at (r, "%s", error_message);
+}
+
 } // namespace BIR
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
index 90d5ed8aaef..136f4679075 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.h
@@ -22,6 +22,7 @@
 #include "polonius/rust-polonius.h"
 #include "rust-bir.h"
 #include "rust-hir-item.h"
+#include "text-range-label.h"
 
 namespace Rust {
 namespace BIR {
@@ -62,6 +63,18 @@ private:
   void report_move_errors ();
   void report_loan_errors ();
   void report_subset_errors ();
+
+  const BIR::Statement &get_statement (Polonius::Point point);
+  const BIR::Loan &get_loan (Polonius::Loan loan);
+
+  struct LabelLocationPair
+  {
+text_range_label label;
+location_t location;
+  };
+  static void
+  multi_label_error (const char *error_message, location_t error_location,
+

[COMMITTED 066/144] gccrs: Strong type LoanId

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-dump.cc (Dump::visit): Use new
API, i.e get_loan_id() instead of get_loan().
* checks/errors/borrowck/rust-bir-fact-collector.h (points): Use
value of LoanId in Polonius facts.
* checks/errors/borrowck/rust-bir-place.h (struct LoanId):
LoanId is a struct now.
* checks/errors/borrowck/rust-bir.h (class AbstractExpr): Use
new API, as we are getting a LoanId and not a loan itself.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-dump.cc   |  2 +-
 .../errors/borrowck/rust-bir-fact-collector.h | 44 +--
 .../checks/errors/borrowck/rust-bir-place.h   | 20 -
 gcc/rust/checks/errors/borrowck/rust-bir.h|  4 +-
 4 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index e69c0002b3c..85ba3ee2ce4 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -279,7 +279,7 @@ Dump::visit (const BorrowExpr &expr)
 {
   stream << "&"
 << "'?" << expr.get_origin () << " ";
-  if (func.place_db.get_loans ()[expr.get_loan ()].mutability
+  if (func.place_db.get_loan (expr.get_loan_id ()).mutability
   == Mutability::Mut)
 stream << "mut ";
   visit_place (expr.get_place ());
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
index ebf8eec7053..774f2b9e298 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -305,7 +305,7 @@ protected: // Main collection entry points (for different 
categories).
 rust_debug ("\t_%u = BorrowExpr(_%u)", lhs.value - 1,
expr.get_place ().value - 1);
 
-auto loan = place_db.get_loans ()[expr.get_loan ()];
+auto loan = place_db.get_loan (expr.get_loan_id ());
 
 auto &base_place = place_db[expr.get_place ()];
 auto &ref_place = place_db[lhs];
@@ -324,14 +324,14 @@ protected: // Main collection entry points (for different 
categories).
   ->is_mutable ())
  rust_error_at (location,
 "Cannot reborrow immutable borrow as mutable");
-   issue_loan (expr.get_origin (), expr.get_loan ());
+   issue_loan (expr.get_origin (), expr.get_loan_id ());
  }
 
push_subset (main_loan_place.regions[0], {expr.get_origin ()});
   }
 else
   {
-   issue_loan (expr.get_origin (), expr.get_loan ());
+   issue_loan (expr.get_origin (), expr.get_loan_id ());
   }
 
 auto loan_regions = base_place.regions.prepend ({expr.get_origin ()});
@@ -511,24 +511,25 @@ protected: // Generic BIR operations.
 
   void issue_loan (Polonius::Origin origin, LoanId loan_id)
   {
-facts.loan_issued_at.emplace_back (origin, loan_id,
+facts.loan_issued_at.emplace_back (origin, loan_id.value,
   get_current_point_mid ());
 
-check_for_borrow_conficts (place_db.get_loans ()[loan_id].place, loan_id,
-  place_db.get_loans ()[loan_id].mutability);
+check_for_borrow_conficts (place_db.get_loan (loan_id).place, loan_id,
+  place_db.get_loan (loan_id).mutability);
   }
 
   void issue_locals_dealloc ()
   {
-for (LoanId loan_id = 0; loan_id < place_db.get_loans ().size (); 
++loan_id)
+for (LoanId loan_id = {0}; loan_id.value < place_db.get_loans ().size ();
+++loan_id.value)
   {
-   auto &loan = place_db.get_loans ()[loan_id];
+   auto &loan = place_db.get_loan (loan_id);
auto loaned_var_id = place_db.get_var (loan.place);
if (place_db[loaned_var_id].tyty->is ())
  continue;
if (loaned_var_id >= first_local)
  facts.loan_invalidated_at.emplace_back (get_current_point_start (),
- loan_id);
+ loan_id.value);
   }
   }
 
@@ -546,20 +547,20 @@ protected: // Generic BIR operations.
 place_db.for_each_path_segment (place_id, [&] (PlaceId id) {
   for (auto loan : place_db[id].borrowed_by)
{
- if (place_db.get_loans ()[loan].mutability == Mutability::Mut)
+ if (place_db.get_loan (loan).mutability == Mutability::Mut)
{
  facts.loan_invalidated_at.emplace_back (
-   get_current_point_start (), loan);
+   get_current_point_start (), loan.value);
}
}
 });
 place_db.for_each_path_from_root (place_id, [&] (PlaceId id) {
   for (auto loan : place_db[id].borrowed_by)
{
- if (place_db.get_loans ()[loan].mutability == Mutability::Mut)
+ if (place_db.get_loan (loan).mutability == Muta

[COMMITTED 023/144] gccrs: Map locations to placeholder regions

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

Mapped placeholder regions to their respective HIR nodes so we can fetch
locations during error reporting.

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder.h: Map regions to
their respective HIR nodes.
* checks/errors/borrowck/rust-bir.h (struct Function):
Add unordered_map to maintain the mapping.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-builder.h | 23 +++
 gcc/rust/checks/errors/borrowck/rust-bir.h|  1 +
 2 files changed, 24 insertions(+)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
index b7d0651fcdd..e3d61b5b36e 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder.h
@@ -50,6 +50,8 @@ public:
   handle_param (param);
 
 handle_body (*function.get_definition ());
+auto region_hir_map
+  = map_region_to_hir (function.get_generic_params (), 
ctx.fn_free_regions);
 
 return Function{
   std::move (ctx.place_db),
@@ -57,6 +59,7 @@ public:
   std::move (ctx.basic_blocks),
   std::move (ctx.fn_free_regions),
   std::move (universal_region_bounds),
+  std::move (region_hir_map),
   function.get_locus (),
 };
   }
@@ -161,6 +164,26 @@ private:
push_return (return_location);
   }
   }
+
+  // Maps named lifetime parameters to their respective HIR node
+  const std::unordered_map
+  map_region_to_hir (
+const std::vector> &generic_params,
+const FreeRegions ®ions)
+  {
+std::unordered_map result;
+size_t region_index = 0;
+for (auto &generic_param : generic_params)
+  {
+   if (generic_param->get_kind ()
+   == HIR::GenericParam::GenericKind::LIFETIME)
+ {
+   result[regions[region_index++]]
+ = static_cast (generic_param.get ());
+ }
+  }
+return result;
+  }
 };
 
 } // namespace BIR
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h 
b/gcc/rust/checks/errors/borrowck/rust-bir.h
index 583d1ebd58f..e8b7e39c550 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -47,6 +47,7 @@ struct Function
   std::vector basic_blocks;
   FreeRegions universal_regions;
   std::vector> universal_region_bounds;
+  std::unordered_map region_hir_map;
   location_t location;
 };
 
-- 
2.45.2



[COMMITTED 025/144] gccrs: Move errors with locations

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
(BorrowCheckerDiagnostics::report_move_errors): Specify
locations for code causing errors and related moves.

gcc/testsuite/ChangeLog:

* rust/borrowck/test_move.rs: Test rich-errors related to moves.
* rust/borrowck/test_move_conditional.rs: Likewise.

Signed-off-by: Kushal Pal 
---
 .../rust-borrow-checker-diagnostics.cc| 39 ++--
 gcc/testsuite/rust/borrowck/test_move.rs  | 22 +++--
 .../rust/borrowck/test_move_conditional.rs| 45 +--
 3 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc 
b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
index dc010291073..f2e4c38cfa0 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker-diagnostics.cc
@@ -34,11 +34,42 @@ BorrowCheckerDiagnostics::report_errors ()
 void
 BorrowCheckerDiagnostics::report_move_errors ()
 {
-  if (!move_errors.empty ())
+  for (const auto &pair : move_errors)
 {
-  rust_error_at (hir_function->get_locus (),
-"Found move errors in function %s",
-hir_function->get_function_name ().as_string ().c_str ());
+  auto error_location = get_statement (pair.first).get_location ();
+
+  // in future, we can use the assigned at location to hint the
+  // user to implement copy trait for the type
+  /*
+  for (auto it : facts.path_assigned_at_base)
+   {
+ if (pair.second[0] == it.first)
+   {
+ auto point_assigned_at = it.second;
+ auto assigned_at_location
+   = get_statement (point_assigned_at).get_location ();
+   }
+   }
+   */
+
+  std::vector labels{
+   {"moved value used here", error_location}};
+  // add labels to all the moves for the given path
+  for (auto it : facts.path_moved_at_base)
+   {
+ if (pair.second[0] == it.first)
+   {
+ auto point_moved_at = it.second;
+ // don't label the move location where the error occured
+ if (pair.first != point_moved_at)
+   {
+ auto move_at_location
+   = get_statement (point_moved_at).get_location ();
+ labels.push_back ({"value moved here", move_at_location});
+   }
+   }
+   }
+  multi_label_error ("use of moved value", error_location, labels);
 }
 }
 
diff --git a/gcc/testsuite/rust/borrowck/test_move.rs 
b/gcc/testsuite/rust/borrowck/test_move.rs
index 26a1a5b7bde..b6475839c04 100644
--- a/gcc/testsuite/rust/borrowck/test_move.rs
+++ b/gcc/testsuite/rust/borrowck/test_move.rs
@@ -1,11 +1,27 @@
-// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
-fn test_move() { // { dg-error "Found move errors in function test_move" }
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
+
+fn test_move() {
 struct A {
 i: i32,
 }
 let a = A { i: 1 };
 let b = a;
-let c = a;
+let c = a; //~ ERROR
+// { dg-error "use of moved value" "" { target *-*-* } .-1 }
+/*
+ { dg-begin-multiline-output "" }
+   NN | let b = a;
+  | ~
+  | |
+  | value moved here
+   NN | let c = a; //~ ERROR
+  | ^
+  | |
+  | moved value used here
+ { dg-end-multiline-output "" }
+ */
+
 }
 
 fn test_move_fixed() {
diff --git a/gcc/testsuite/rust/borrowck/test_move_conditional.rs 
b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
index e1e8e2025cf..94882bca5a7 100644
--- a/gcc/testsuite/rust/borrowck/test_move_conditional.rs
+++ b/gcc/testsuite/rust/borrowck/test_move_conditional.rs
@@ -1,6 +1,7 @@
-// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck" }
+// { dg-additional-options "-frust-compile-until=compilation 
-frust-borrowcheck -fdiagnostics-show-caret -fdiagnostics-show-line-numbers" }
+// { dg-enable-nn-line-numbers "" }
 
-fn test_move_conditional(b1: bool, b2:bool) { // { dg-error "Found move errors 
in function test_move" }
+fn test_move_conditional(b1: bool, b2:bool) {
 struct A {
 i: i32,
 }
@@ -9,9 +10,47 @@ fn test_move_conditional(b1: bool, b2:bool) { // { dg-error 
"Found move errors i
 let b = a;
 if b1 {
 let b = a;
+// { dg-error "use of moved value" "" { target *-*-* } .-1 }
+/*
+ { dg-begin-multiline-output "" }
+   NN | let b = a;
+  | ~
+  | |
+  | value moved here
+   NN | if b1 {
+   NN | let b =

[COMMITTED 027/144] gccrs: ast: PathPattern: Remove `remove_all_segments` method

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

This method was used only for stripping PathPattern AST nodes during
`cfg-strip`, which seems like a misnomer and makes it a good candidate
for simplification.

gcc/rust/ChangeLog:

* ast/rust-path.h (class PathInExpression): Remove `remove_all_segments`
method, add a `marked_for_strip` flag instead.
---
 gcc/rust/ast/rust-path.h | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index b20f31cc4ad..53ccf1dbb6b 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -581,13 +581,6 @@ protected:
* possible, and creates a SimplePath from them. */
   SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const;
 
-  // Removes all segments of the path.
-  void remove_all_segments ()
-  {
-segments.clear ();
-segments.shrink_to_fit ();
-  }
-
 public:
   /* Returns whether the path is a single segment (excluding qualified path
* initial as segment). */
@@ -611,6 +604,8 @@ class PathInExpression : public PathPattern, public PathExpr
   location_t locus;
   NodeId _node_id;
 
+  bool marked_for_strip;
+
 public:
   std::string as_string () const override;
 
@@ -621,7 +616,8 @@ public:
 : PathPattern (std::move (path_segments)),
   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 ())
+  locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()),
+  marked_for_strip (false)
   {}
 
   // Creates an error state path in expression.
@@ -650,9 +646,8 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  // Invalid if path is empty (error state), so base stripping on that.
-  void mark_for_strip () override { remove_all_segments (); }
-  bool is_marked_for_strip () const override { return is_error (); }
+  void mark_for_strip () override { marked_for_strip = true; }
+  bool is_marked_for_strip () const override { return marked_for_strip; }
 
   bool opening_scope_resolution () const
   {
-- 
2.45.2



[COMMITTED 038/144] gccrs: Fix the parser's operand and flags storage

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_reg_operand):
Fix parsing logic & reassignment logic
(parse_reg_operand_in): Fix parsing
(parse_reg_operand_out): Fix parsing
(parse_reg_operand_inout): Fix parsing
(parse_reg_operand_unexpected): Remove rust_unreachable()
(parse_asm_arg): Fix parsing logic
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 7f0498fdef4..492bcfe3172 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -226,10 +226,12 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   // Loop over and execute the parsing functions, if the parser successfullly
   // parses or if the parser fails to parse while it has committed to a token,
   // we propogate the result.
+  int count = 0;
   tl::expected parsing_operand (
 inline_asm_ctx);
   for (auto &parse_func : parse_funcs)
 {
+  count++;
   auto result = parsing_operand.and_then (parse_func);
 
   // Per rust's asm.rs's structure
@@ -238,8 +240,7 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
 
   if (result.has_value ())
{
- //
- inline_asm_ctx = *result;
+ inline_asm_ctx = result.value ();
  break;
}
   else if (result.error () == COMMITTED)
@@ -687,7 +688,9 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
{
  auto expected = parse_clobber_abi (inline_asm_ctx);
  if (expected.has_value ())
-   continue;
+   {
+ continue;
+   }
  else if (expected.error () == COMMITTED)
return expected;
 
@@ -699,7 +702,9 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
{
  auto expected = parse_options (inline_asm_ctx);
  if (expected.has_value ())
-   continue;
+   {
+ continue;
+   }
  else if (expected.error () == COMMITTED)
return expected;
 
@@ -712,9 +717,13 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
 
   auto expected = parse_reg_operand (inline_asm_ctx);
   if (expected.has_value ())
-   continue;
+   {
+ continue;
+   }
   else if (expected.error () == COMMITTED)
-   return expected;
+   {
+ return expected;
+   }
 
   // Since parse_reg_operand is the last thing we've considered,
   // The non-committed parse error type means that we have exhausted our
-- 
2.45.2



[COMMITTED 042/144] gccrs: Setting up interfaces for codegen

2025-03-19 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit):
Setting up interfaces for codegen
* hir/tree/rust-hir-expr.h: Likewise.
---
 gcc/rust/backend/rust-compile-expr.cc |  6 --
 gcc/rust/hir/tree/rust-hir-expr.h | 26 ++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 7c7bc225e7e..2792e8b5f04 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -321,8 +321,10 @@ CompileExpr::visit (HIR::IfExpr &expr)
 void
 CompileExpr::visit (HIR::InlineAsm &expr)
 {
-  tree test_string = build_string(expr.template_strs[0].symbol.size() + 1, 
expr.template_strs[0].symbol.c_str());
-  debug(test_string);
+  // translated = build_asm_expr()(expr.get_locus(),
+  //  expr.construct_string_tree(), expr.construct_outputs(),
+  //  expr.construct_inputs(),   expr.construct_clobber_tree(),
+  //  expr.construct_label_tree(), expr.is_simple(), expr.is_inline_asm());
 }
 
 void
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 7b2e32ec259..ee469806847 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -25,6 +25,7 @@
 #include "rust-hir-path.h"
 #include "rust-operators.h"
 #include "rust-expr.h"
+#include "tree.h"
 namespace Rust {
 namespace HIR {
 
@@ -4163,8 +4164,33 @@ public:
 
   {}
 
+  tree construct_string_tree ()
+  {
+if (template_strs.empty ())
+  return build_string (1, "");
+// Initialize to NULL_TREE
+tree string_chain = NULL_TREE;
+
+for (const auto &template_str : template_strs)
+  {
+   auto str = template_str.symbol;
+   auto string_tree = build_string (str.size () + 1, str.c_str ());
+
+   string_chain = tree_cons (NULL_TREE, string_tree, string_chain);
+  }
+// Reverse the chain before returning
+return nreverse (string_chain);
+  }
+
+  tree construct_clobber_tree () { return NULL_TREE; }
+  tree construct_label_tree () { return NULL_TREE; }
+  tree construct_inputs () { return NULL_TREE; }
+  tree construct_outputs () { return NULL_TREE; }
   // This function checks if the assembly macro is "simple" or not, according 
to
   // the tree defition (tree.h) of the
+
+  // SIMPLE indicates whether there was anything at all after the
+  // string in the asm expression
   bool is_simple ()
   {
 return operands.size () == 0 && clobber_abi.size () == 0
-- 
2.45.2



[COMMITTED 082/144] gccrs: Create new test system for name resolution 2.0

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

This runs the standard compile/**.rs tests
with name resolution 2.0 enabled. The exclude file
can be used to exclude tests which are not yet working
with name resolution 2.0.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/compile.exp: New test.
* rust/compile/nr2/exclude: New.

Signed-off-by: Owen Avery 
---
 gcc/testsuite/rust/compile/nr2/compile.exp | 136 ++
 gcc/testsuite/rust/compile/nr2/exclude | 293 +
 2 files changed, 429 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/nr2/compile.exp
 create mode 100644 gcc/testsuite/rust/compile/nr2/exclude

diff --git a/gcc/testsuite/rust/compile/nr2/compile.exp 
b/gcc/testsuite/rust/compile/nr2/compile.exp
new file mode 100644
index 000..0afe36c3c40
--- /dev/null
+++ b/gcc/testsuite/rust/compile/nr2/compile.exp
@@ -0,0 +1,136 @@
+# Copyright (C) 2021-2024 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Compile tests, no torture testing, for name resolution 2.0
+#
+# These tests raise errors in the front end; torture testing doesn't apply.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+namespace eval rust-nr2-ns {
+# Exclude tests which aren't passing yet
+# These should be removed from the exclude file over time
+
+set exclude_fh [open $srcdir/$subdir/exclude r]
+set exclude_raw [lsort [split [read $exclude_fh] "\n"]]
+close $exclude_fh
+unset exclude_fh
+
+set exclude ""
+foreach ent $exclude_raw {
+if [regexp {^[^#].*} $ent] {
+lappend exclude $ent
+   }
+}
+unset exclude_raw
+
+# Run tests in directories
+# Manually specifying these, in case some other test file
+# does something weird
+set test_dirs {. compile macros/builtin macros/mbe macros/proc}
+
+set tests_expect_ok ""
+set tests_expect_err ""
+
+foreach test_dir $test_dirs {
+foreach test [lsort [glob -nocomplain -tails -directory 
$srcdir/$subdir/../$test_dir *.rs]] {
+   if {$test_dir == "."} {
+   set test_lbl $test
+   } else {
+   set test_lbl "$test_dir/$test"
+}
+   set idx [lsearch -exact -sorted $exclude $test_lbl]
+   if {$idx == -1} {
+   lappend tests_expect_ok $srcdir/$subdir/../$test_dir/$test
+   } else {
+   lappend tests_expect_err $srcdir/$subdir/../$test_dir/$test
+   set exclude [lreplace $exclude $idx $idx]
+   }
+   }
+}
+
+# Generate failures for unmatched tests in the exclude list
+foreach ent $exclude {
+fail "$ent: could not exclude test"
+}
+unset exclude
+
+# run a test while catching record_test calls
+set record_test_out ""
+proc try_test { test } {
+variable record_test_out
+   rename ::record_test record_test_old
+
+   proc ::record_test { type msg args } {
+   namespace eval ::rust-nr2-ns {
+   set type [uplevel 1 {set type}]
+   set msg [uplevel 1 {set msg}]
+   variable record_test_out
+   switch $type {
+   FAIL {
+   lappend record_test_out "$type: $msg"
+   }
+   XPASS {
+   lappend record_test_out "$type: $msg"
+   }
+   }
+}
+   }
+
+namespace eval :: {
+   set saved-dg-do-what-default ${dg-do-what-default}
+   set dg-do-what-default "compile"
+dg-runtest [list [uplevel 1 {set test}]] 
"-frust-name-resolution-2.0" ""
+   set dg-do-what-default ${saved-dg-do-what-default}
+   }
+
+rename ::record_test ""
+   rename record_test_old ::record_test
+
+   set record_test_cache $record_test_out
+set record_test_out ""
+   return $record_test_cache
+}
+
+# check for unexpected failures
+foreach test $tests_expect_ok {
+set fails [try_test $test]
+   if {[llength $fails] != 0} {
+   foreach ent $fails {
+   record_test FAIL "$test: nr2 failure: $ent"
+   }
+   } else {
+   record_test PASS "$test: nr2 success"
+   }
+}
+
+#check for unexpected successes
+foreach test $tests_expect_err {
+set 

[COMMITTED 049/144] gccrs: Added counting to check for asm_construct_outputs

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::asm_construct_outputs):
Set up counting to check
---
 gcc/rust/backend/rust-compile-asm.cc | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 0dd4f672008..9305a9088bb 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -96,6 +96,13 @@ tree
 CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
+  int count = 0;
+
+  for (auto &output : expr.get_operands ())
+{
+  if (output.register_type == AST::InlineAsmOperand::RegisterType::Out)
+   count++;
+}
   return NULL_TREE;
 }
 
-- 
2.45.2



[COMMITTED 041/144] gccrs: Local testing for build_string and debug()

2025-03-19 Thread arthur . cohen
From: jjasmine 

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::visit):
Local testing for build_string and debug()
---
 gcc/rust/backend/rust-compile-expr.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index e23c691d1db..7c7bc225e7e 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -320,7 +320,10 @@ CompileExpr::visit (HIR::IfExpr &expr)
 
 void
 CompileExpr::visit (HIR::InlineAsm &expr)
-{}
+{
+  tree test_string = build_string(expr.template_strs[0].symbol.size() + 1, 
expr.template_strs[0].symbol.c_str());
+  debug(test_string);
+}
 
 void
 CompileExpr::visit (HIR::IfExprConseqElse &expr)
-- 
2.45.2



[COMMITTED 014/144] gccrs: Add location support to BIR::Statement

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

This commit adds location_t to BIR::Statement where type is ASSIGNMENT
this information will be later used for reporting borrow-checking
errors.

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::visit): Added location parameter.
* checks/errors/borrowck/rust-bir-builder-internal.h: Likewise.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h:
Likewise.
* checks/errors/borrowck/rust-bir-builder-pattern.h: Likewise.
* checks/errors/borrowck/rust-bir-builder.h: Likewise.
* checks/errors/borrowck/rust-bir.h: Likewise.

Signed-off-by: Kushal Pal 
---
 .../borrowck/rust-bir-builder-expr-stmt.cc| 145 --
 .../borrowck/rust-bir-builder-internal.h  |  67 
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |  74 -
 .../borrowck/rust-bir-builder-pattern.h   |   7 +-
 .../checks/errors/borrowck/rust-bir-builder.h |   3 +-
 gcc/rust/checks/errors/borrowck/rust-bir.h|  19 ++-
 6 files changed, 194 insertions(+), 121 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index acfcdd88425..49b830124d7 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -80,14 +80,21 @@ ExprStmtBuilder::visit (HIR::ClosureExpr &expr)
 {
   auto closure_ty = lookup_type (expr)->as ();
   std::vector captures;
+  std::vector capture_locations;
   for (auto &capture : closure_ty->get_captures ())
 {
   captures.push_back (ctx.place_db.lookup_variable (capture));
+  auto location = Analysis::Mappings::get ()
+   .lookup_ast_item (capture)
+   .value ()
+   ->get_locus ();
+  capture_locations.push_back (location);
 }
-  move_all (captures);
+  move_all (captures, capture_locations);
 
   // Note: Not a coercion site for captures.
-  return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr));
+  return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr),
+  expr.get_locus ());
 }
 
 void
@@ -96,23 +103,31 @@ ExprStmtBuilder::visit (HIR::StructExprStructFields 
&fields)
   auto *p_adt_type = lookup_type (fields)->as ();
   auto struct_ty = p_adt_type->get_variants ().at (0);
   auto init_values = StructBuilder (ctx, struct_ty).build (fields);
-  move_all (init_values);
+  // collect fields locations
+  std::vector field_locations;
+  for (auto &field : fields.get_fields ())
+{
+  field_locations.push_back (field->get_locus ());
+}
+  move_all (init_values, field_locations);
   return_expr (new InitializerExpr (std::move (init_values)),
-  lookup_type (fields));
+  lookup_type (fields), fields.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::StructExprStruct &expr)
 {
   // There is no way to modify empty struct, which makes them constant.
-  return_place (ctx.place_db.get_constant (lookup_type (expr)));
+  return_place (ctx.place_db.get_constant (lookup_type (expr)),
+   expr.get_locus ());
 }
 
 void
 ExprStmtBuilder::visit (HIR::LiteralExpr &expr)
 {
   // Different literal values of the same type are not distinguished in BIR.
-  return_place (ctx.place_db.get_constant (lookup_type (expr)));
+  return_place (ctx.place_db.get_constant (lookup_type (expr)),
+   expr.get_locus ());
 }
 
 void
@@ -122,12 +137,12 @@ ExprStmtBuilder::visit (HIR::BorrowExpr &expr)
   if (ctx.place_db[operand].is_constant ())
 {
   // Cannot borrow a constant, must create a temporary copy.
-  push_tmp_assignment (operand);
+  push_tmp_assignment (operand, expr.get_locus ());
   operand = translated;
 }
 
   // BorrowExpr cannot be annotated with lifetime.
-  return_borrowed (operand, lookup_type (expr));
+  return_borrowed (operand, lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -135,7 +150,8 @@ ExprStmtBuilder::visit (HIR::DereferenceExpr &expr)
 {
   auto operand = visit_expr (*expr.get_expr ());
   return_place (ctx.place_db.lookup_or_add_path (Place::DEREF,
-lookup_type (expr), operand));
+lookup_type (expr), operand),
+   expr.get_locus ());
 }
 
 void
@@ -149,7 +165,8 @@ void
 ExprStmtBuilder::visit (HIR::NegationExpr &expr)
 {
   PlaceId operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({move_place (operand)}), lookup_type (expr));
+  return_expr (new Operator<1> ({move_place (operand, expr.get_locus ())}),
+  lookup_type (expr), expr.get_locus ());
 }
 
 void
@@ -157,8 +174,10 @@ ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ()

[COMMITTED 031/144] gccrs: attributes: Start handling prelude_import properly

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

This commit adds basic handling for the `#[prelude_import]` attribute,
without doing anything functionality wise.

gcc/rust/ChangeLog:

* checks/errors/rust-feature-gate.cc (FeatureGate::visit): Add base
feature gating for `#[feature(prelude_import)]`.
* checks/errors/rust-feature-gate.h: Likewise.
* checks/errors/rust-feature.cc (Feature::create): Likewise.
* checks/errors/rust-feature.h: Likewise.
* util/rust-attribute-values.h: Add base handling for 
`#[prelude_import]`
attribute.
* util/rust-attributes.cc: Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/prelude_import.rs: New test.
---
 gcc/rust/checks/errors/rust-feature-gate.cc  |  8 
 gcc/rust/checks/errors/rust-feature-gate.h   |  2 +-
 gcc/rust/checks/errors/rust-feature.cc   |  4 
 gcc/rust/checks/errors/rust-feature.h|  1 +
 gcc/rust/util/rust-attribute-values.h|  1 +
 gcc/rust/util/rust-attributes.cc |  3 ++-
 gcc/testsuite/rust/compile/prelude_import.rs | 12 
 7 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/prelude_import.rs

diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 580afc9e110..ca19374b4f3 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -217,4 +217,12 @@ FeatureGate::visit (AST::RangePattern &pattern)
  "exclusive range pattern syntax is experimental");
 }
 
+void
+FeatureGate::visit (AST::UseTreeGlob &use)
+{
+  // At the moment, UseTrees do not have outer attributes, but they should. we
+  // need to eventually gate `#[prelude_import]` on use-trees based on the
+  // #[feature(prelude_import)]
+}
+
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h 
b/gcc/rust/checks/errors/rust-feature-gate.h
index 31c2ed65904..7d62a63a61b 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -107,7 +107,7 @@ public:
   void visit (AST::TypeBoundWhereClauseItem &item) override {}
   void visit (AST::Module &module) override {}
   void visit (AST::ExternCrate &crate) override {}
-  void visit (AST::UseTreeGlob &use_tree) override {}
+  void visit (AST::UseTreeGlob &use_tree) override;
   void visit (AST::UseTreeList &use_tree) override {}
   void visit (AST::UseTreeRebind &use_tree) override {}
   void visit (AST::UseDeclaration &use_decl) override {}
diff --git a/gcc/rust/checks/errors/rust-feature.cc 
b/gcc/rust/checks/errors/rust-feature.cc
index 917e3b2bdd0..eba8f5bfea8 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/rust-feature.cc
@@ -58,6 +58,9 @@ Feature::create (Feature::Name name)
   return Feature (Feature::Name::EXCLUSIVE_RANGE_PATTERN,
  Feature::State::ACTIVE, "exclusive_range_pattern",
  "1.11.0", 37854, tl::nullopt, "");
+case Feature::Name::PRELUDE_IMPORT:
+  return Feature (Feature::Name::PRELUDE_IMPORT, Feature::State::ACTIVE,
+ "prelude_import", "1.0.0", 0, tl::nullopt, "");
 default:
   rust_unreachable ();
 }
@@ -79,6 +82,7 @@ const std::map 
Feature::name_hash_map = {
   {"dropck_eyepatch", Feature::Name::DROPCK_EYEPATCH},
   {"raw_ref_op", Feature::Name::RAW_REF_OP},
   {"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN},
+  {"prelude_import", Feature::Name::PRELUDE_IMPORT},
 }; // namespace Rust
 
 tl::optional
diff --git a/gcc/rust/checks/errors/rust-feature.h 
b/gcc/rust/checks/errors/rust-feature.h
index 698aac2dc63..2b134e2d2c8 100644
--- a/gcc/rust/checks/errors/rust-feature.h
+++ b/gcc/rust/checks/errors/rust-feature.h
@@ -50,6 +50,7 @@ public:
 DROPCK_EYEPATCH,
 RAW_REF_OP,
 EXCLUSIVE_RANGE_PATTERN,
+PRELUDE_IMPORT,
   };
 
   const std::string &as_string () { return m_name_str; }
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 90417012ed7..ef01e67dc52 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -56,6 +56,7 @@ public:
   static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable";
   static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable";
   static constexpr auto &MAY_DANGLE = "may_dangle";
+  static constexpr auto &PRELUDE_IMPORT = "prelude_import";
 };
 } // namespace Values
 } // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index c9e376400fd..958f7c35284 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -64,7 +64,8 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::UNSTABLE, STATIC_ANALYSIS},
  // assuming we keep these for static analysis
  {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
- {Attrs::RUSTC_CONST_UNSTABLE, STATIC_AN

[COMMITTED 050/144] gccrs: Start work on expand inline asm

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_reg_operand):
Remove warnings
(parse_reg_operand_out): Remove warnings
(expand_inline_asm): New function for eventual expansion
(parse_asm): Use expand_inline_asm

gcc/testsuite/ChangeLog:

* rust/execute/torture/inline_asm_mov_x_5.rs: New test.
---
 gcc/rust/expand/rust-macro-builtins-asm.cc| 33 +--
 .../execute/torture/inline_asm_mov_x_5.rs | 19 +++
 2 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 492bcfe3172..bbb8fff180f 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -21,6 +21,7 @@
 #include "rust-macro-builtins-asm.h"
 #include "rust-ast-fragment.h"
 #include "rust-ast.h"
+#include "rust-fmt.h"
 #include "rust-stmt.h"
 
 namespace Rust {
@@ -240,7 +241,7 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
 
   if (result.has_value ())
{
- inline_asm_ctx = result.value ();
+ inline_asm_ctx = *result;
  break;
}
   else if (result.error () == COMMITTED)
@@ -741,6 +742,31 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
   return tl::expected (inline_asm_ctx);
 }
 
+tl::expected
+expand_inline_asm (InlineAsmContext &inline_asm_ctx)
+{
+  auto &inline_asm = inline_asm_ctx.inline_asm;
+
+  auto str_vec = inline_asm.get_template_strs ();
+  for (auto &template_str : str_vec)
+{
+  std::cout << template_str.symbol << std::endl;
+
+  auto pieces = Fmt::Pieces::collect (template_str.symbol, false,
+ Fmt::ffi::ParseMode::Format)
+ .get_pieces ();
+
+  for (size_t i = 0; i < pieces.size (); i++)
+   {
+ auto piece = pieces[i];
+ if (piece.tag == Fmt::ffi::Piece::Tag::String)
+   std::cout << "   " << i << ": " << piece.string._0.to_string ()
+ << std::endl;
+   }
+}
+
+  return inline_asm_ctx;
+}
 tl::optional
 parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
   AST::InvocKind semicolon, AST::AsmKind is_global_asm)
@@ -770,7 +796,10 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   // here Per Arthur's advice we would actually do the validation in a 
different
   // stage. and visit on the InlineAsm AST instead of it's context.
   auto is_valid = (bool) resulting_context;
-
+  if (is_valid)
+{
+  expand_inline_asm (resulting_context.value ());
+}
   if (is_valid)
 {
   auto node = inline_asm_ctx.inline_asm.clone_expr_without_block ();
diff --git a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
new file mode 100644
index 000..18bc87ab554
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
@@ -0,0 +1,19 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {};
+}
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+fn main() {
+let mut _x: i32 = 0;
+unsafe {
+asm!(
+"mov {}, 5",
+out(reg) _x
+);
+}
+}
-- 
2.45.2



[COMMITTED 059/144] gccrs: Rehaul, Apply code review from Arthur

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::visit):
Change API, public/private, comments, formatting from code
review
(CompileAsm::asm_build_expr): Likewise.
(CompileAsm::tree_codegen_asm): Likewise.
* backend/rust-compile-asm.h (class CompileAsm): Likewise.
* backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
* checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit): Likewise.
* expand/rust-macro-builtins-asm.cc (strip_double_quotes): Likewise.
(parse_options): Likewise.
(parse_asm_arg): Likewise.
(expand_inline_asm_strings): Likewise.
(parse_asm): Likewise.
* expand/rust-macro-builtins-asm.h (strip_double_quotes): Likewise.
(expand_inline_asm_strings): Likewise.
(expand_inline_asm_string): Likewise.
* hir/tree/rust-hir-expr.h: Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_typecheck.rs: Change comments
---
 gcc/rust/backend/rust-compile-asm.cc  |  8 +--
 gcc/rust/backend/rust-compile-asm.h   | 67 ++-
 gcc/rust/backend/rust-compile-expr.cc |  4 +-
 .../errors/privacy/rust-privacy-reporter.cc   |  4 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc| 61 +++--
 gcc/rust/expand/rust-macro-builtins-asm.h | 10 +--
 gcc/rust/hir/tree/rust-hir-expr.h |  4 +-
 .../rust/compile/inline_asm_typecheck.rs  |  7 +-
 8 files changed, 42 insertions(+), 123 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 045cc2866fd..8294feb2197 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -7,14 +7,8 @@ namespace Compile {
 CompileAsm::CompileAsm (Context *ctx)
   : HIRCompileBase (ctx), translated (error_mark_node)
 {}
-void
-CompileAsm::visit (HIR::InlineAsm &expr)
-{
-  ctx->add_statement (asm_build_expr (expr));
-}
-
 tree
-CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
+CompileAsm::tree_codegen_asm (HIR::InlineAsm &expr)
 {
   auto asm_expr
 = asm_build_stmt (expr.get_locus (), {asm_construct_string_tree (expr),
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 9779a4ad7fb..402d950844c 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -1,4 +1,3 @@
-
 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
 
 // This file is part of GCC.
@@ -26,16 +25,11 @@
 namespace Rust {
 namespace Compile {
 
-class CompileAsm : private HIRCompileBase, protected HIR::HIRExpressionVisitor
+class CompileAsm : private HIRCompileBase
 {
 private:
   tree translated;
 
-public:
-  // WE WILL OPEN THIS UP WHEN WE WANT TO ADD A DEDICATED PASS OF HIR'S ASM
-  // translation.
-  // static tree Compile (HIR::Expr *expr, Context *ctx);
-
   // RELEVANT MEMBER FUNCTIONS
 
   // The limit is 5 because it stands for the 5 things that the C version of
@@ -46,7 +40,6 @@ public:
   // build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
   //   tree clobbers, tree labels, bool simple, bool is_inline)
   static const int ASM_TREE_ARRAY_LENGTH = 5;
-  tree asm_build_expr (HIR::InlineAsm &);
   tree asm_build_stmt (location_t,
   const std::array &);
 
@@ -56,60 +49,14 @@ public:
   tree asm_construct_clobber_tree (HIR::InlineAsm &);
   tree asm_construct_label_tree (HIR::InlineAsm &);
 
-  CompileAsm (Context *ctx);
-
-  void visit (HIR::InlineAsm &) override;
+public:
+  // WE WILL OPEN THIS UP WHEN WE WANT TO ADD A DEDICATED PASS OF HIR'S ASM
+  // translation.
+  // static tree Compile (HIR::Expr *expr, Context *ctx);
 
-  // NON RELEVANT MEMBER FUNCTIONS
+  CompileAsm (Context *ctx);
 
-  void visit (HIR::TupleIndexExpr &) override {}
-  void visit (HIR::TupleExpr &) override {}
-  void visit (HIR::ReturnExpr &) override {}
-  void visit (HIR::CallExpr &) override {}
-  void visit (HIR::MethodCallExpr &) override {}
-  void visit (HIR::LiteralExpr &) override {}
-  void visit (HIR::AssignmentExpr &) override {}
-  void visit (HIR::CompoundAssignmentExpr &) override {}
-  void visit (HIR::ArrayIndexExpr &) override {}
-  void visit (HIR::ArrayExpr &) override {}
-  void visit (HIR::ArithmeticOrLogicalExpr &) override {}
-  void visit (HIR::ComparisonExpr &) override {}
-  void visit (HIR::LazyBooleanExpr &) override {}
-  void visit (HIR::NegationExpr &) override {}
-  void visit (HIR::TypeCastExpr &) override {}
-  void visit (HIR::IfExpr &) override {}
-  void visit (HIR::IfExprConseqElse &) override {}
-  void visit (HIR::BlockExpr &) override {}
-  void visit (HIR::UnsafeBlockExpr &) override {}
-  void visit (HIR::StructExprStruct &struct_) override {}
-  void visit (HIR::StructExprStructFields &struct_) override {}
-  void visit (HIR::GroupedExpr &) override {}
-  void visit (HIR::FieldAccessExpr &) override {}

[COMMITTED 143/144] gccrs: Use name resolver 2.0 in pattern checker

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

gcc/rust/ChangeLog:

* checks/errors/rust-hir-pattern-analysis.cc: Add includes.
(PatternChecker::visit): Use name resolver 2.0 when enabled.

Signed-off-by: Owen Avery 
---
 .../checks/errors/rust-hir-pattern-analysis.cc   | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index fdbc6e8d2ec..f46f429e930 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -26,6 +26,10 @@
 #include "rust-mapping-common.h"
 #include "rust-system.h"
 #include "rust-tyty.h"
+#include "rust-immutable-name-resolution-context.h"
+
+// for flag_name_resolution_2_0
+#include "options.h"
 
 namespace Rust {
 namespace Analysis {
@@ -234,7 +238,17 @@ PatternChecker::visit (CallExpr &expr)
 
   NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
   NodeId ref_node_id;
-  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
+   return;
+}
+  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))
-- 
2.45.2



[COMMITTED 063/144] gccrs: Strong type PlaceId

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-dump.cc (renumber_places):
Use value of PlaceId as index.
(Dump::visit_place): Likewise.
(Dump::visit_scope): Likewise.
(Dump::go): Refill `place_map` with for loop instead of
using std::iota().
* checks/errors/borrowck/rust-bir-fact-collector.h (points): Use
value as index.
* checks/errors/borrowck/rust-bir-place.h (struct PlaceId):
PlaceId is now a class holding a uint32_t value. Overloaded
comparision operators for easier comparision.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-dump.cc   | 25 --
 .../errors/borrowck/rust-bir-fact-collector.h | 61 +++--
 .../checks/errors/borrowck/rust-bir-place.h   | 88 +++
 3 files changed, 103 insertions(+), 71 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index a35f47b86d6..924c7d9a6e8 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -53,16 +53,20 @@ renumber_places (const Function &func, std::vector 
&place_map)
 {
   // Renumbering places to avoid gaps in the place id space.
   // This is needed to match MIR's shape.
-  size_t next_out_id = 0;
+  PlaceId next_out_id = INVALID_PLACE;
 
-  for (size_t in_id = FIRST_VARIABLE_PLACE; in_id < func.place_db.size ();
-   ++in_id)
+  for (PlaceId in_id = FIRST_VARIABLE_PLACE;
+   in_id.value < func.place_db.size (); ++in_id.value)
 {
   const Place &place = func.place_db[in_id];
   if (place.kind == Place::VARIABLE || place.kind == Place::TEMPORARY)
-   place_map[in_id] = next_out_id++;
+   {
+ place_map[in_id.value] = next_out_id;
+ ++next_out_id.value;
+   }
+
   else
-   place_map[in_id] = INVALID_PLACE;
+   place_map[in_id.value] = INVALID_PLACE;
 }
 }
 
@@ -110,7 +114,10 @@ Dump::go (bool enable_simplify_cfg)
   // To avoid mutation of the BIR, we use indirection through bb_fold_map.
   std::iota (bb_fold_map.begin (), bb_fold_map.end (), 0);
 
-  std::iota (place_map.begin (), place_map.end (), 0);
+  for (size_t i = 0; i < place_map.size (); ++i)
+{
+  place_map[i] = {i};
+}
 
   if (enable_simplify_cfg)
 simplify_cfg (func, bb_fold_map);
@@ -119,7 +126,7 @@ Dump::go (bool enable_simplify_cfg)
 
   stream << "fn " << name << "(";
   print_comma_separated (stream, func.arguments, [this] (PlaceId place_id) {
-stream << "_" << place_map[place_id] << ": "
+stream << "_" << place_map[place_id.value].value << ": "
   << get_tyty_name (func.place_db[place_id].tyty);
   });
   stream << ") -> " << get_tyty_name (func.place_db[RETURN_VALUE_PLACE].tyty);
@@ -228,7 +235,7 @@ Dump::visit_place (PlaceId place_id)
 {
 case Place::TEMPORARY:
 case Place::VARIABLE:
-  stream << "_" << place_map[place_id];
+  stream << "_" << place_map[place_id.value].value;
   break;
 case Place::DEREF:
   stream << "(";
@@ -365,7 +372,7 @@ Dump::visit_scope (ScopeId id, size_t depth)
   for (auto &local : scope.locals)
 {
   indent (depth + 1) << "let _";
-  stream << place_map[local] << ": "
+  stream << place_map[local.value].value << ": "
 << get_tyty_name (func.place_db[local].tyty);
   stream << ";\t";
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
index bddaf59..fa7cbb38eef 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -88,8 +88,9 @@ public:
 protected: // Constructor and destructor.
   explicit FactCollector (Function &func)
 : place_db (func.place_db), basic_blocks (func.basic_blocks),
-  first_local (func.arguments.empty () ? FIRST_VARIABLE_PLACE
-  : *func.arguments.rbegin () + 1),
+  first_local (func.arguments.empty ()
+? FIRST_VARIABLE_PLACE
+: PlaceId{func.arguments.rbegin ()->value + 1}),
   location (func.location), tyctx (*Resolver::TypeCheckContext::get ()),
   next_fresh_region (place_db.peek_next_free_region ())
   {}
@@ -118,7 +119,8 @@ protected: // Main collection entry points (for different 
categories).
 
   void visit_places (const std::vector &args)
   {
-for (PlaceId place_id = 0; place_id < place_db.size (); ++place_id)
+for (PlaceId place_id = INVALID_PLACE; place_id.value < place_db.size ();
+++place_id.value)
   {
auto &place = place_db[place_id];
 
@@ -126,24 +128,28 @@ protected: // Main collection entry points (for different 
categories).
  {
  case Place::VARIABLE:
  case Place::TEMPORARY:
-   facts.path_is_var.emplace_back (place_id, place_id);
+   f

[COMMITTED 108/144] gccrs: Add default resolver parent functions by default

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

gcc/rust/ChangeLog:

* resolve/rust-finalize-imports-2.0.h: Add parent member functions
from default resolver.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-finalize-imports-2.0.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h 
b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index 2b3157e9b42..0fba5a517a1 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -97,6 +97,8 @@ public:
   void go (AST::Crate &crate);
 
 private:
+  using AST::DefaultASTVisitor::visit;
+
   void visit (AST::UseDeclaration &) override;
 
   Early::ImportMappings data;
-- 
2.45.2



[COMMITTED 070/144] gccrs: Used `IndexVec` for Scopes

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-place.h:
Used `IndexVec` with ScopeId as index.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-place.h   | 25 +--
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index 23564608892..bf4dfe625a0 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -218,6 +218,8 @@ public:
   size_t size () const { return internal_vector.size (); }
 };
 
+using Scopes = IndexVec;
+
 /** Allocated places and keeps track of paths. */
 class PlaceDB
 {
@@ -225,7 +227,7 @@ private:
   // Possible optimizations: separate variables to speedup lookup.
   std::vector places;
   std::unordered_map constants_lookup;
-  std::vector scopes;
+  Scopes scopes;
   ScopeId current_scope = ROOT_SCOPE;
 
   std::vector loans;
@@ -257,14 +259,11 @@ public:
 
   ScopeId get_current_scope_id () const { return current_scope; }
 
-  const std::vector &get_scopes () const { return scopes; }
+  const Scopes &get_scopes () const { return scopes; }
 
-  const Scope &get_current_scope () const
-  {
-return scopes[current_scope.value];
-  }
+  const Scope &get_current_scope () const { return scopes[current_scope]; }
 
-  const Scope &get_scope (ScopeId id) const { return scopes[id.value]; }
+  const Scope &get_scope (ScopeId id) const { return scopes[id]; }
 
   FreeRegion get_next_free_region ()
   {
@@ -280,15 +279,15 @@ public:
   {
 ScopeId new_scope = {scopes.size ()};
 scopes.emplace_back ();
-scopes[new_scope.value].parent = current_scope;
-scopes[current_scope.value].children.push_back (new_scope);
+scopes[new_scope].parent = current_scope;
+scopes[current_scope].children.push_back (new_scope);
 current_scope = new_scope;
 return new_scope;
   }
 
   ScopeId pop_scope ()
   {
-current_scope = scopes[current_scope.value].parent;
+current_scope = scopes[current_scope].parent;
 return current_scope;
   }
 
@@ -304,7 +303,7 @@ public:
 
 if (new_place_ref.kind == Place::VARIABLE
|| new_place_ref.kind == Place::TEMPORARY)
-  scopes[current_scope.value].locals.push_back (new_place);
+  scopes[current_scope].locals.push_back (new_place);
 
 auto variances = Resolver::TypeCheckContext::get ()
   ->get_variance_analysis_ctx ()
@@ -494,9 +493,9 @@ private:
   WARN_UNUSED_RESULT bool is_in_scope (PlaceId place) const
   {
 for (ScopeId scope = current_scope; scope != INVALID_SCOPE;
-scope = scopes[scope.value].parent)
+scope = scopes[scope].parent)
   {
-   auto &scope_ref = scopes[scope.value];
+   auto &scope_ref = scopes[scope];
if (std::find (scope_ref.locals.begin (), scope_ref.locals.end (),
   place)
!= scope_ref.locals.end ())
-- 
2.45.2



[COMMITTED 067/144] gccrs: Strong type ScopeId

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
(ExprStmtBuilder::setup_loop): Use value of ScopeId.
(ExprStmtBuilder::visit): Use continue scope id instead of
continue basic block id.
* checks/errors/borrowck/rust-bir-builder-internal.h: Use value
of ScopeId.
* checks/errors/borrowck/rust-bir-dump.cc (Dump::go): Use
ROOT_VALUE instead of hardcoded 0.
(Dump::visit_scope): Use value of ScopeId.
* checks/errors/borrowck/rust-bir-place.h (struct ScopeId):
ScopeId is now a struct.
(std::numeric_limits::max): Set invalid ScopeId.

Signed-off-by: Kushal Pal 
---
 .../borrowck/rust-bir-builder-expr-stmt.cc|  5 ++-
 .../borrowck/rust-bir-builder-internal.h  |  4 +-
 .../checks/errors/borrowck/rust-bir-dump.cc   | 10 ++---
 .../checks/errors/borrowck/rust-bir-place.h   | 43 +--
 4 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 8d4d90aab80..1713bf6fcf8 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -45,7 +45,8 @@ ExprStmtBuilder::setup_loop (HIR::BaseLoopExpr &expr)
 
   BasicBlockId break_bb = new_bb ();
   // We are still outside the loop block;
-  ScopeId continue_scope = ctx.place_db.get_current_scope_id () + 1;
+  ScopeId continue_scope
+= ctx.place_db.get_current_scope_id ().next_scope_id ();
   ctx.loop_and_label_stack.emplace_back (true, label, label_var, break_bb,
 continue_bb, continue_scope);
 
@@ -414,7 +415,7 @@ ExprStmtBuilder::visit (HIR::ContinueExpr &cont)
   LoopAndLabelCtx info = cont.has_label () ? get_label_ctx (cont.get_label ())
   : get_unnamed_loop_ctx ();
   start_new_consecutive_bb ();
-  unwind_until (info.continue_bb);
+  unwind_until (info.continue_scope);
   push_goto (info.continue_bb);
   // No code allowed after continue. Handled in BlockExpr.
 }
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index b27f7717cd0..e0d8bb3d2fc 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -156,7 +156,7 @@ protected:
 
 auto place_id = ctx.place_db.add_variable (nodeid, ty);
 
-if (ctx.place_db.get_current_scope_id () != 0)
+if (ctx.place_db.get_current_scope_id () != INVALID_SCOPE)
   push_storage_live (place_id);
 
 if (user_type_annotation)
@@ -170,7 +170,7 @@ protected:
   void pop_scope ()
   {
 auto &scope = ctx.place_db.get_current_scope ();
-if (ctx.place_db.get_current_scope_id () != 0)
+if (ctx.place_db.get_current_scope_id () != INVALID_SCOPE)
   {
std::for_each (scope.locals.rbegin (), scope.locals.rend (),
   [&] (PlaceId place) { push_storage_dead (place); });
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 85ba3ee2ce4..0c0e55567b5 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -133,7 +133,7 @@ Dump::go (bool enable_simplify_cfg)
   stream << " {\n";
 
   // Print locals declaration.
-  visit_scope (0);
+  visit_scope (ROOT_SCOPE);
 
   // Print BBs.
   for (statement_bb = 0; statement_bb < func.basic_blocks.size ();
@@ -366,8 +366,8 @@ Dump::visit_scope (ScopeId id, size_t depth)
   if (scope.locals.empty () && scope.children.empty ())
 return;
 
-  if (id > 1)
-indent (depth) << "scope " << id - 1 << " {\n";
+  if (id.value > 1)
+indent (depth) << "scope " << id.value - 1 << " {\n";
 
   for (auto &local : scope.locals)
 {
@@ -385,9 +385,9 @@ Dump::visit_scope (ScopeId id, size_t depth)
   stream << "]\n";
 }
   for (auto &child : scope.children)
-visit_scope (child, (id >= 1) ? depth + 1 : depth);
+visit_scope (child, (id.value >= 1) ? depth + 1 : depth);
 
-  if (id > 1)
+  if (id.value > 1)
 indent (depth) << "}\n";
 }
 
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index c78492a2394..f7018d3af7f 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -165,13 +165,25 @@ public:
   }
 };
 
-using ScopeId = uint32_t;
+struct ScopeId
+{
+  uint32_t value;
+  ScopeId next_scope_id () const { return {value + 1}; }
+  // some overloads for comparision
+  bool operator== (const ScopeId &rhs) const { return value == rhs.value; }
+  bool operator!= (const ScopeId &rhs) const { return !(operator== (rhs)); }
+  bool operator< (const ScopeId &rhs) const { r

[COMMITTED 141/144] gccrs: Use name resolver 2.0 in const checker

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

gcc/rust/ChangeLog:

* checks/errors/rust-const-checker.cc: Add includes.
(ConstChecker::visit): Use name resolver 2.0 to lookup
function definitions 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-const-checker.cc | 16 +++-
 gcc/testsuite/rust/compile/nr2/exclude   |  3 ---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 2beee210279..84c09dd307e 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -22,6 +22,10 @@
 #include "rust-hir-stmt.h"
 #include "rust-hir-item.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 {
@@ -354,8 +358,18 @@ ConstChecker::visit (CallExpr &expr)
   NodeId ast_node_id = expr.get_fnexpr ()->get_mappings ().get_nodeid ();
   NodeId 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
+   return;
+}
   // We don't care about types here
-  if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+  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 a698164fbd5..ecef6d2bb25 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -27,8 +27,6 @@ closure_no_type_anno.rs
 complex-path1.rs
 complex_qualified_path_in_expr.rs
 const-issue1440.rs
-const1.rs
-const3.rs
 const_generics_3.rs
 const_generics_4.rs
 const_generics_5.rs
@@ -38,7 +36,6 @@ derive_macro1.rs
 derive_macro3.rs
 derive_macro4.rs
 derive_macro6.rs
-diagnostic_underline.rs
 expected_type_args2.rs
 expected_type_args3.rs
 feature_rust_attri0.rs
-- 
2.45.2



[COMMITTED 117/144] gccrs: Add box definition to avoid error

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

Box definition is part of the standard library and cannot be found during
name resolution. This simple definition prevent any error from being
emitted.

gcc/testsuite/ChangeLog:

* rust/compile/box_syntax_feature_gate.rs: Add box land item
definition.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/box_syntax_feature_gate.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs 
b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
index 8eb5503dde6..5f62a59a04b 100644
--- a/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
+++ b/gcc/testsuite/rust/compile/box_syntax_feature_gate.rs
@@ -1,4 +1,6 @@
 // { dg-options "-frust-compile-until=lowering" }
+#[lang = "owned_box"]
+pub struct Box;
 
 fn main() {
 let x: Box<_> = box 1; //{ dg-error "box expression syntax is 
experimental." "" { target *-*-* }  }
-- 
2.45.2



Код безопасности для учетной записи Майкрософт

2025-03-19 Thread Служба технической поддержки учетных записей Майкрософт
Используйте для учетной записи Майкрософт gc**t...@gcc.gnu.org следующий код 
безопасности.

Код безопасности: 141211


Если вы не узнаете учетную запись Майкрософт 
gc**t...@gcc.gnu.org, вы можете щелкнуть 
https://account.live.com/dp?ft=-DtmAsBRNn4g995WFEbyX5qTs*mnIihUdmpS8hg3sA3cWASgVuW8L2fdGKz9mgJI2cijrprcqdIyqIeCkuRq*fMnF4Jp0GqM6SgZx1RYcCjWjFdtSfhzt*sQsBt0jSK5oevsGqfyqLusB0dws7B6Gg1cbHZF2SattKUis0!*3XKH8*QeDDA9DnWcb*vhgS6hHvEzHgFDq0FV0OjA!D01kEzbUQD40cKh!irTVf8un7XMt,
 чтобы удалить свой адрес электронной почты из этой учетной записи.


С уважением,
Служба технической поддержки учетных записей Майкрософт 
Заявление о конфиденциальности: https://go.microsoft.com/fwlink/?LinkId=521839
Microsoft Corporation, One Microsoft Way, Redmond, WA 98052


Подтверждение безопасности учетной записи Майкрософт

2025-03-19 Thread Служба технической поддержки учетных записей Майкрософт
Здравствуйте, Rust!
Ваша учетная запись gcc-rust@gcc.gnu.org будет закрыта 18.04.2025.

Нам жалко, что вы нас покидаете. Если вы передумаете и решите продолжить 
пользоваться этой учетной записью Майкрософт, просто войдите в нее до 
18.04.2025. Ваши файлы, данные и сведения не будут удаляться до этого времени.

Если вы не помечали эту учетную запись для закрытия, это сделал кто-то другой! 
Повторно откройте свою учетную запись и измените пароль, перейдя по адресу 
https://account.live.com/password/Reset.

С уважением,
Служба технической поддержки учетных записей Майкрософт 
Заявление о конфиденциальности: https://go.microsoft.com/fwlink/?LinkId=521839
Microsoft Corporation, One Microsoft Way, Redmond, WA 98052


Проверка адреса электронной почты

2025-03-19 Thread Служба технической поддержки учетных записей Майкрософт
Учетная запись Майкрософт

Проверка адреса электронной почты

Чтобы завершить настройку учетной записи Майкрософт, нам нужно убедиться, что 
это ваш адрес электронной почты.

Для проверки адреса электронной почты используйте этот код безопасности: 367853

Если вы не запрашивали этот код, можете смело игнорировать это сообщение 
электронной почты. Возможно, кто-то ввел ваш адрес электронной почты по ошибке.

С уважением,
Служба технической поддержки учетных записей Майкрософт 
Заявление о конфиденциальности: https://go.microsoft.com/fwlink/?LinkId=521839
Microsoft Corporation, One Microsoft Way, Redmond, WA 98052


Проверка адреса электронной почты

2025-03-19 Thread Служба технической поддержки учетных записей Майкрософт
Учетная запись Майкрософт

Проверка адреса электронной почты

Чтобы завершить настройку учетной записи Майкрософт, нам нужно убедиться, что 
это ваш адрес электронной почты.

Для проверки адреса электронной почты используйте этот код безопасности: 409181

Если вы не запрашивали этот код, можете смело игнорировать это сообщение 
электронной почты. Возможно, кто-то ввел ваш адрес электронной почты по ошибке.

С уважением,
Служба технической поддержки учетных записей Майкрософт 
Заявление о конфиденциальности: https://go.microsoft.com/fwlink/?LinkId=521839
Microsoft Corporation, One Microsoft Way, Redmond, WA 98052


[PATCH v2 1/4] rust: Use FLOAT_TYPE_P instead of manual checking

2025-03-19 Thread Andrew Pinski
This moves is_floating_point over to using FLOAT_TYPE_P instead
of manually checking. Note before it would return true for all
COMPLEX_TYPE but complex types' inner type could be integral.

Also fixes up the comment to be in more of the GNU style.

Bootstrapped and tested on x86_64-linux-gnu.

gcc/rust/ChangeLog:

* rust-gcc.cc (is_floating_point): Use FLOAT_TYPE_P
instead of manually checking the type.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 273ab7889b0..43c4b3ee816 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1018,12 +1018,12 @@ operator_to_tree_code (LazyBooleanOperator op)
 }
 }
 
-/* Helper function for deciding if a tree is a floating point node. */
+/* Returns true if the type of EXP is a floating point type.
+   False otherwise.  */
 bool
-is_floating_point (tree t)
+is_floating_point (tree exp)
 {
-  auto tree_type = TREE_CODE (TREE_TYPE (t));
-  return tree_type == REAL_TYPE || tree_type == COMPLEX_TYPE;
+  return FLOAT_TYPE_P (TREE_TYPE (exp));
 }
 
 // Return an expression for the negation operation OP EXPR.
-- 
2.43.0



[COMMITTED 088/144] gccrs: Remove some overloaded methods from DefaultResolver.

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

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Remove some empty overloads which
DefaultASTVisitor::visit should be able to handle.
* resolve/rust-default-resolver.h
(DefaultResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-default-resolver.cc | 84 ---
 gcc/rust/resolve/rust-default-resolver.h  | 21 --
 gcc/testsuite/rust/compile/nr2/exclude| 16 -
 3 files changed, 121 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 6de694f48f4..89e7e39f5bb 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -548,70 +548,6 @@ void
 DefaultResolver::visit (AST::MetaListNameValueStr &)
 {}
 
-void
-DefaultResolver::visit (AST::RangePatternBoundPath &)
-{}
-
-void
-DefaultResolver::visit (AST::RangePatternBoundQualPath &)
-{}
-
-void
-DefaultResolver::visit (AST::RangePattern &)
-{}
-
-void
-DefaultResolver::visit (AST::ReferencePattern &)
-{}
-
-void
-DefaultResolver::visit (AST::StructPatternFieldTuplePat &)
-{}
-
-void
-DefaultResolver::visit (AST::StructPatternFieldIdentPat &)
-{}
-
-void
-DefaultResolver::visit (AST::StructPatternFieldIdent &)
-{}
-
-void
-DefaultResolver::visit (AST::StructPattern &)
-{}
-
-void
-DefaultResolver::visit (AST::TupleStructItemsNoRange &)
-{}
-
-void
-DefaultResolver::visit (AST::TupleStructItemsRange &)
-{}
-
-void
-DefaultResolver::visit (AST::TupleStructPattern &)
-{}
-
-void
-DefaultResolver::visit (AST::TuplePatternItemsMultiple &)
-{}
-
-void
-DefaultResolver::visit (AST::TuplePatternItemsRanged &)
-{}
-
-void
-DefaultResolver::visit (AST::TuplePattern &)
-{}
-
-void
-DefaultResolver::visit (AST::GroupedPattern &)
-{}
-
-void
-DefaultResolver::visit (AST::SlicePattern &)
-{}
-
 void
 DefaultResolver::visit (AST::AltPattern &)
 {}
@@ -632,10 +568,6 @@ void
 DefaultResolver::visit (AST::TraitObjectType &)
 {}
 
-void
-DefaultResolver::visit (AST::ParenthesisedType &)
-{}
-
 void
 DefaultResolver::visit (AST::ImplTraitTypeOneBound &)
 {}
@@ -644,22 +576,6 @@ void
 DefaultResolver::visit (AST::TraitObjectTypeOneBound &)
 {}
 
-void
-DefaultResolver::visit (AST::TupleType &)
-{}
-
-void
-DefaultResolver::visit (AST::ReferenceType &)
-{}
-
-void
-DefaultResolver::visit (AST::ArrayType &)
-{}
-
-void
-DefaultResolver::visit (AST::SliceType &)
-{}
-
 void
 DefaultResolver::visit (AST::BareFunctionType &)
 {}
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 6bca8b7b6a1..3774603daaa 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -126,34 +126,13 @@ public:
   void visit (AST::MetaItemSeq &);
   void visit (AST::MetaListPaths &);
   void visit (AST::MetaListNameValueStr &);
-  void visit (AST::RangePatternBoundPath &);
-  void visit (AST::RangePatternBoundQualPath &);
-  void visit (AST::RangePattern &);
-  void visit (AST::ReferencePattern &);
-  void visit (AST::StructPatternFieldTuplePat &);
-  void visit (AST::StructPatternFieldIdentPat &);
-  void visit (AST::StructPatternFieldIdent &);
-  void visit (AST::StructPattern &);
-  void visit (AST::TupleStructItemsNoRange &);
-  void visit (AST::TupleStructItemsRange &);
-  void visit (AST::TupleStructPattern &);
-  void visit (AST::TuplePatternItemsMultiple &);
-  void visit (AST::TuplePatternItemsRanged &);
-  void visit (AST::TuplePattern &);
-  void visit (AST::GroupedPattern &);
-  void visit (AST::SlicePattern &);
   void visit (AST::AltPattern &);
   void visit (AST::EmptyStmt &);
   void visit (AST::TraitBound &);
   void visit (AST::ImplTraitType &);
   void visit (AST::TraitObjectType &);
-  void visit (AST::ParenthesisedType &);
   void visit (AST::ImplTraitTypeOneBound &);
   void visit (AST::TraitObjectTypeOneBound &);
-  void visit (AST::TupleType &);
-  void visit (AST::ReferenceType &);
-  void visit (AST::ArrayType &);
-  void visit (AST::SliceType &);
   void visit (AST::BareFunctionType &);
   void visit (AST::FunctionParam &);
   void visit (AST::VariadicParam &);
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 3251921acd4..8993c6d5750 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -4,9 +4,6 @@ debug-diagnostics-on.rs
 
 # main list
 all-cast.rs
-array3.rs
-arrays1.rs
-arrays2.rs
 attr-mismatch-crate-name.rs
 attr_deprecated.rs
 attr_deprecated_2.rs
@@ -37,11 +34,8 @@ complex-path1.rs
 complex_qualified_path_in_expr.rs
 const-issue1440.rs
 const1.rs
-const10.rs
 const3.rs
 const4.rs
-const5.rs
-const6.rs
 const8.rs
 const9.rs
 const_generics_1.rs
@@ -84,13 +78,11 @@ infer-crate-name.rs
 issue-1005.rs
 issue-1006.rs
 issue-1019.rs
-issue-1023.rs
 issue-1031.

[PATCH v2 0/4] rust: Small cleanups of rust-gcc.cc

2025-03-19 Thread Andrew Pinski
This is a set of 4 patches that do some small cleanups of rust-gcc.cc
The first patch might fix a bug in some cases but I am not 100% sure since
I suspect complex types here might only be floating point types but who knows.
The rest are using GCC's checks better or just other small changes that help
the readability.

Andrew Pinski (4):
  rust: Use FLOAT_TYPE_P instead of manual checking
  rust: Use error_operand_p in rust-gcc.cc
  rust: use range for inside rust-gcc.cc [PR119341]
  rust: Add comment inside block [PR119342]

 gcc/rust/rust-gcc.cc | 254 +++
 1 file changed, 114 insertions(+), 140 deletions(-)

-- 
2.43.0



[PATCH v2 3/4] rust: use range for inside rust-gcc.cc [PR119341]

2025-03-19 Thread Andrew Pinski
There are some places inside rust-gcc.cc which are candidates
to use range for instead of iterators directly. This changes
the locations I saw and makes the code slightly more readable.

gcc/rust/ChangeLog:

PR rust/119341
* rust-gcc.cc (function_type): Use range fors.
(function_type_variadic): Likewise.
(fill_in_fields): Likewise.
(statement_list): Likewise.
(block): Likewise.
(block_add_statements): Likewise.
(function_set_parameters): Likewise.
(write_global_definitions): Likewise.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 57 
 1 file changed, 21 insertions(+), 36 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 78e8ddbed00..1252798a87a 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -478,10 +478,9 @@ function_type (const typed_identifier &receiver,
   pp = &TREE_CHAIN (*pp);
 }
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
@@ -527,10 +526,9 @@ function_type_variadic (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 args[offs++] = receiver.type;
 
-  for (std::vector::const_iterator p = parameters.begin ();
-   p != parameters.end (); ++p)
+  for (const auto &p : parameters)
 {
-  tree t = p->type;
+  tree t = p.type;
   if (error_operand_p (t))
return error_mark_node;
   args[offs++] = t;
@@ -608,14 +606,13 @@ fill_in_fields (tree fill, const 
std::vector &fields)
 {
   tree field_trees = NULL_TREE;
   tree *pp = &field_trees;
-  for (std::vector::const_iterator p = fields.begin ();
-   p != fields.end (); ++p)
+  for (const auto &p : fields)
 {
-  tree name_tree = get_identifier_from_string (p->name);
-  tree type_tree = p->type;
+  tree name_tree = get_identifier_from_string (p.name);
+  tree type_tree = p.type;
   if (error_operand_p (type_tree))
return error_mark_node;
-  tree field = build_decl (p->location, FIELD_DECL, name_tree, type_tree);
+  tree field = build_decl (p.location, FIELD_DECL, name_tree, type_tree);
   DECL_CONTEXT (field) = fill;
   *pp = field;
   pp = &DECL_CHAIN (field);
@@ -1721,10 +1718,8 @@ tree
 statement_list (const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree t : statements)
 {
-  tree t = (*p);
   if (error_operand_p (t))
return error_mark_node;
   append_to_statement_list (t, &stmt_list);
@@ -1778,10 +1773,9 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
 }
 
   tree *pp = &BLOCK_VARS (block_tree);
-  for (std::vector::const_iterator pv = vars.begin ();
-   pv != vars.end (); ++pv)
+  for (Bvariable *bv : vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   if (!error_operand_p (*pp))
pp = &DECL_CHAIN (*pp);
 }
@@ -1801,10 +1795,8 @@ void
 block_add_statements (tree bind_tree, const std::vector &statements)
 {
   tree stmt_list = NULL_TREE;
-  for (std::vector::const_iterator p = statements.begin ();
-   p != statements.end (); ++p)
+  for (tree s : statements)
 {
-  tree s = (*p);
   if (!error_operand_p (s))
append_to_statement_list (s, &stmt_list);
 }
@@ -2248,10 +2240,9 @@ function_set_parameters (tree function,
 
   tree params = NULL_TREE;
   tree *pp = ¶ms;
-  for (std::vector::const_iterator pv = param_vars.begin ();
-   pv != param_vars.end (); ++pv)
+  for (Bvariable *bv : param_vars)
 {
-  *pp = (*pv)->get_decl ();
+  *pp = bv->get_decl ();
   gcc_assert (!error_operand_p (*pp));
   pp = &DECL_CHAIN (*pp);
 }
@@ -2277,10 +2268,9 @@ write_global_definitions (const std::vector 
&type_decls,
 
   // Convert all non-erroneous declarations into Gimple form.
   size_t i = 0;
-  for (std::vector::const_iterator p = variable_decls.begin ();
-   p != variable_decls.end (); ++p)
+  for (Bvariable *bv : variable_decls)
 {
-  tree v = (*p)->get_decl ();
+  tree v = bv->get_decl ();
   if (error_operand_p (v))
continue;
defs[i] = v;
@@ -2288,10 +2278,8 @@ write_global_definitions (const std::vector 
&type_decls,
++i;
 }
 
-  for (std::vector::const_iterator p = type_decls.begin ();
-   p != type_decls.end (); ++p)
+  for (tree type_tree : type_decls)
 {
-  tree type_tree = (*p);
   if (!error_operand_p (type_tree) && IS_TYPE_OR_DECL_P (type_tree))
{
  defs[i] = TYPE_NAME (type_tree);
@@ -2300,20 +2288,17 @@ write_global_definitions (const std::vector 
&type_decls,
  ++i

[Bug rust/119333] [15 regression] Rust bootstrap fails with cargo trying to download polonius crates

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

Andrew Pinski  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #6 from Andrew Pinski  ---
Confirmed fixed.

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

[PATCH v2 4/4] rust: Add comment inside block [PR119342]

2025-03-19 Thread Andrew Pinski
Inside a BLOCK node, all of the variables of the scope/block
are chained together and that connects them to the block.
This just adds a comment to that effect as reading the code
it is not so obvious why they need to be chained together.

gcc/rust/ChangeLog:

PR rust/119342
* rust-gcc.cc (block): Add comment on why chaining
the variables of the scope toether.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 1252798a87a..32d3aabbbe4 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -1772,6 +1772,8 @@ block (tree fndecl, tree enclosing, const 
std::vector &vars,
   *pp = block_tree;
 }
 
+  // Chain the variables of the scope together so they are all connected
+  // to the block.
   tree *pp = &BLOCK_VARS (block_tree);
   for (Bvariable *bv : vars)
 {
-- 
2.43.0



[PATCH v2 2/4] rust: Use error_operand_p in rust-gcc.cc

2025-03-19 Thread Andrew Pinski
Just a simple cleanupof the code to use error_operand_p
instead of directly comparing against error_mark_node.

This also moves some cdoe around when dealing with error_operand_p
just to be faster and/or slightly tighten up the code slightly.

gcc/rust/ChangeLog:

* rust-gcc.cc (Bvariable::get_tree): Use error_operand_p.
(pointer_type): Likewise.
(reference_type): Likewise.
(immutable_type): Likewise.
(function_type): Likewise.
(function_type_variadic): Likewise.
Cleanup the check for receiver.type first.
(function_ptr_type): Use error_operand_p.
(fill_in_fields): Likewise.
(fill_in_array): Likewise.
(named_type): Likewise.
(type_size): Likewise.
(type_alignment): Likewise.
(type_field_alignment): Likewise.
(type_field_offset): Likewise.
(zero_expression): Likewise.
(float_constant_expression): Likewise.
(convert_expression): Likewise.
(struct_field_expression): Likewise.
(compound_expression): Likewise.
(conditional_expression): Likewise.
(negation_expression): Likewise.
(arithmetic_or_logical_expression): Likewise.
(arithmetic_or_logical_expression_checked): Likewise.
(comparison_expression): Likewise.
(lazy_boolean_expression): Likewise.
(constructor_expression): Likewise.
(array_constructor_expression): Likewise.
(array_index_expression): Likewise.
(call_expression): Likewise.
(init_statement): Likewise.
(assignment_statement): Likewise.
(return_statement): Likewise.
(exception_handler_statement): Likewise.
(if_statement): Likewise.
(compound_statement): Likewise.
Tighten up the code, removing t variable.
(statement_list): Use error_operand_p.
(block): Likewise.
(block_add_statements): Likewise.
(convert_tree): Likewise.
(global_variable): Likewise.
(global_variable_set_init): Likewise.
(local_variable): Likewise.
(parameter_variable): Likewise.
(static_chain_variable): Likewise.
(temporary_variable): Likewise.
(function): Likewise. Tighten up the code.
(function_defer_statement): Use error_operand_p.
(function_set_parameters): Use error_operand_p.
(write_global_definitions): Use error_operand_p.
Tighten up the code around the loop.

Signed-off-by: Andrew Pinski 
---
 gcc/rust/rust-gcc.cc | 189 ---
 1 file changed, 88 insertions(+), 101 deletions(-)

diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 43c4b3ee816..78e8ddbed00 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -61,7 +61,7 @@
 tree
 Bvariable::get_tree (location_t location) const
 {
-  if (this->t_ == error_mark_node)
+  if (error_operand_p (this->t_))
 return error_mark_node;
 
   TREE_USED (this->t_) = 1;
@@ -431,7 +431,7 @@ float_type (int bits)
 tree
 pointer_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_pointer_type (to_type);
   return type;
@@ -442,7 +442,7 @@ pointer_type (tree to_type)
 tree
 reference_type (tree to_type)
 {
-  if (to_type == error_mark_node)
+  if (error_operand_p (to_type))
 return error_mark_node;
   tree type = build_reference_type (to_type);
   return type;
@@ -453,7 +453,7 @@ reference_type (tree to_type)
 tree
 immutable_type (tree base)
 {
-  if (base == error_mark_node)
+  if (error_operand_p (base))
 return error_mark_node;
   tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
   return constified;
@@ -472,7 +472,7 @@ function_type (const typed_identifier &receiver,
   if (receiver.type != NULL_TREE)
 {
   tree t = receiver.type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -482,7 +482,7 @@ function_type (const typed_identifier &receiver,
p != parameters.end (); ++p)
 {
   tree t = p->type;
-  if (t == error_mark_node)
+  if (error_operand_p (t))
return error_mark_node;
   *pp = tree_cons (NULL_TREE, t, NULL_TREE);
   pp = &TREE_CHAIN (*pp);
@@ -502,11 +502,11 @@ function_type (const typed_identifier &receiver,
   gcc_assert (result_struct != NULL);
   result = result_struct;
 }
-  if (result == error_mark_node)
+  if (error_operand_p (result))
 return error_mark_node;
 
   tree fntype = build_function_type (result, args);
-  if (fntype == error_mark_node)
+  if (error_operand_p (fntype))
 return error_mark_node;
 
   return build_pointer_type (fntype);
@@ -521,21 +521,17 @@ function_type_variadic (const typed_identifier &receiver,
   size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
   tree *

[COMMITTED 115/144] gccrs: Make node id getter const.

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

gcc/rust/ChangeLog:

* ast/rust-ast.h: Node id getter could be const.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-ast.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index f5a2e77af3f..129a3041c7f 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1587,7 +1587,7 @@ public:
 
   virtual Kind get_kind () const = 0;
 
-  NodeId get_node_id () { return node_id; }
+  NodeId get_node_id () const { return node_id; }
 
 protected:
   GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
-- 
2.45.2



[COMMITTED 138/144] gccrs: Use name resolver 2.0 in MarkLive

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

gcc/rust/ChangeLog:

* checks/lints/rust-lint-marklive.cc
(MarkLive::visit_path_segment): Use name resolver 2.0 when
enabled.
(MarkLive::visit): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/checks/lints/rust-lint-marklive.cc | 31 ++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 24df933c805..ca26a669003 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -155,7 +155,17 @@ MarkLive::visit_path_segment (HIR::PathExprSegment seg)
   //
   // We should mark them alive all and ignoring other kind of segments.
   // If the segment we dont care then just return false is fine
-  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
+   return false;
+}
+  else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
 {
   if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
return false;
@@ -232,9 +242,22 @@ MarkLive::visit (HIR::TupleIndexExpr &expr)
 void
 MarkLive::visit (HIR::TypeAlias &alias)
 {
-  NodeId ast_node_id;
-  resolver->lookup_resolved_type (
-alias.get_type_aliased ()->get_mappings ().get_nodeid (), &ast_node_id);
+  NodeId ast_node_id = UNKNOWN_NODEID;
+  if (flag_name_resolution_2_0)
+{
+  auto &nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  if (auto id = nr_ctx.lookup (
+   alias.get_type_aliased ()->get_mappings ().get_nodeid ()))
+   ast_node_id = *id;
+}
+  else
+{
+  resolver->lookup_resolved_type (
+   alias.get_type_aliased ()->get_mappings ().get_nodeid (), &ast_node_id);
+}
+
   if (auto hid = mappings.lookup_node_to_hir (ast_node_id))
 mark_hir_id (*hid);
   else
-- 
2.45.2



[COMMITTED 110/144] gccrs: Move failing test to xfail

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

We want to begin experimenting with this new name resolution 2.0
algorithm as soon as possible. This test highlight a problem where the
compiler should emit an error and should be fixed soon.

gcc/testsuite/ChangeLog:

* rust/compile/name_resolution21.rs: Move to...
* rust/compile/xfail/name_resolution21.rs: ...here.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/{ => xfail}/name_resolution21.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
 rename gcc/testsuite/rust/compile/{ => xfail}/name_resolution21.rs (62%)

diff --git a/gcc/testsuite/rust/compile/name_resolution21.rs 
b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
similarity index 62%
rename from gcc/testsuite/rust/compile/name_resolution21.rs
rename to gcc/testsuite/rust/compile/xfail/name_resolution21.rs
index 3d0af2b37b7..df48d001598 100644
--- a/gcc/testsuite/rust/compile/name_resolution21.rs
+++ b/gcc/testsuite/rust/compile/xfail/name_resolution21.rs
@@ -5,7 +5,8 @@ pub mod foo {
 }
 
 use foo::bar;
-use foo::bar; // { dg-error ".bar. defined multiple times" }
+use foo::bar;
+// { dg-error ".bar. defined multiple times" "" { xfail *-*-* } .-1 }
 
 fn main() {
 bar!();
-- 
2.45.2



[Bug rust/119353] [15 regression] Rust fails to build (build failure: error[E0554]: `#![feature]` may not be used on the stable release channel)

2025-03-19 Thread cohenarthur at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119353

--- Comment #9 from Arthur Cohen  ---
This should now be fixed by our latest patch upload. If anyone would like to
try again and report back please do, and I'll close this out

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

[COMMITTED 078/144] gccrs: Emit error on auto-traits

2025-03-19 Thread arthur . cohen
From: "benjamin.thos" 

Throw an error when auto-traits used without feature attribute.

gcc/rust/ChangeLog:

* checks/errors/rust-feature-gate.cc (FeatureGate::visit): Emit error
on trait when auto field member true.
* checks/errors/rust-feature-gate.h: add prototype of trait visitor.
* checks/errors/rust-feature.cc (Feature::create): add
optin_builtin_traits in match of feature.

gcc/testsuite/ChangeLog:

* rust/compile/auto_trait_super_trait.rs: Add feature attribute.
* rust/compile/generic_auto_trait.rs: likewise.
* rust/compile/auto_trait.rs: add test for error without
feature attribute

Signed-off-by: benjamin.thos 
---
 gcc/rust/checks/errors/rust-feature-gate.cc  | 9 +
 gcc/rust/checks/errors/rust-feature-gate.h   | 1 +
 gcc/rust/checks/errors/rust-feature.cc   | 3 +++
 gcc/testsuite/rust/compile/auto_trait.rs | 1 +
 gcc/testsuite/rust/compile/auto_trait_super_trait.rs | 1 +
 gcc/testsuite/rust/compile/generic_auto_trait.rs | 1 +
 6 files changed, 16 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/auto_trait.rs

diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 4ab614e8853..f3daa61f170 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -173,6 +173,15 @@ FeatureGate::visit (AST::TraitImpl &impl)
   AST::DefaultASTVisitor::visit (impl);
 }
 
+void
+FeatureGate::visit (AST::Trait &trait)
+{
+  if (trait.is_auto ())
+gate (Feature::Name::AUTO_TRAITS, trait.get_locus (),
+ "auto traits are experimental and possibly buggy");
+  AST::DefaultASTVisitor::visit (trait);
+}
+
 void
 FeatureGate::visit (AST::BoxExpr &expr)
 {
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h 
b/gcc/rust/checks/errors/rust-feature-gate.h
index 7ffb6ef9d66..f1011e53224 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -42,6 +42,7 @@ public:
   void visit (AST::UseTreeGlob &use_tree) override;
   void visit (AST::Function &function) override;
   void visit (AST::TraitImpl &impl) override;
+  void visit (AST::Trait &trait) override;
   void visit (AST::ExternalTypeItem &item) override;
   void visit (AST::ExternBlock &block) override;
   void visit (AST::MacroRulesDefinition &rules_def) override;
diff --git a/gcc/rust/checks/errors/rust-feature.cc 
b/gcc/rust/checks/errors/rust-feature.cc
index 6900bb834db..25af46cbed8 100644
--- a/gcc/rust/checks/errors/rust-feature.cc
+++ b/gcc/rust/checks/errors/rust-feature.cc
@@ -55,6 +55,9 @@ Feature::create (Feature::Name f)
  "1.11.0", 37854);
 case Feature::Name::PRELUDE_IMPORT:
   return Feature (f, Feature::State::ACTIVE, "prelude_import", "1.0.0");
+case Feature::Name::AUTO_TRAITS:
+  return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits",
+ "1.0.0", 13231);
 default:
   rust_unreachable ();
 }
diff --git a/gcc/testsuite/rust/compile/auto_trait.rs 
b/gcc/testsuite/rust/compile/auto_trait.rs
new file mode 100644
index 000..47bd119ba36
--- /dev/null
+++ b/gcc/testsuite/rust/compile/auto_trait.rs
@@ -0,0 +1 @@
+auto trait Valid {} // { dg-error "auto traits are experimental and possibly 
buggy" }
diff --git a/gcc/testsuite/rust/compile/auto_trait_super_trait.rs 
b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs
index 1080afb5124..06746e91497 100644
--- a/gcc/testsuite/rust/compile/auto_trait_super_trait.rs
+++ b/gcc/testsuite/rust/compile/auto_trait_super_trait.rs
@@ -1,3 +1,4 @@
+#![feature(optin_builtin_traits)]
 trait Cold {}
 
 auto trait IsCool: Cold {}
diff --git a/gcc/testsuite/rust/compile/generic_auto_trait.rs 
b/gcc/testsuite/rust/compile/generic_auto_trait.rs
index ae6a51d0244..a0a414cdbbd 100644
--- a/gcc/testsuite/rust/compile/generic_auto_trait.rs
+++ b/gcc/testsuite/rust/compile/generic_auto_trait.rs
@@ -1,2 +1,3 @@
+#![feature(optin_builtin_traits)]
 auto trait IsCooler {}
 // { dg-error "auto traits cannot have generic parameters .E0567." "" { target 
*-*-* } .-1 }
-- 
2.45.2



[Bug rust/119353] [15 regression] Rust fails to build (build failure: error[E0554]: `#![feature]` may not be used on the stable release channel)

2025-03-19 Thread doko at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119353

--- Comment #8 from Matthias Klose  ---
mentioned on irc, #gcc:
https://github.com/Rust-GCC/gccrs/commit/1bd6cdbd8d2a6e0bfaaf5c8ef61ca453f09899cf

that works for me on x86_64-linux-gnu at least

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

[Bug rust/119353] [15 regression] Rust fails to build (build failure: error[E0554]: `#![feature]` may not be used on the stable release channel)

2025-03-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119353

Eric Botcazou  changed:

   What|Removed |Added

 CC||ebotcazou at gcc dot gnu.org
 Status|ASSIGNED|NEW

--- Comment #7 from Eric Botcazou  ---
Any stopgap fix in the meantime?

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

[COMMITTED 134/144] gccrs: Provide input operand for gccrs

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::asm_construct_inputs):
Provide input operand for gccrs
* expand/rust-macro-builtins-asm.cc (parse_reg_operand_in):
Move expr to In
(expand_inline_asm_strings):
Add comments to debug strings

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_parse_operand.rs:
Remove inout, functionality not supported. Remove redundant {}
* rust/execute/torture/inline_asm_mov_x_5_ARM.rs: Add operand in
* rust/execute/torture/inline_asm_mov_x_5_x86_64.rs: Likewise
---
 gcc/rust/backend/rust-compile-asm.cc  | 22 +--
 gcc/rust/expand/rust-macro-builtins-asm.cc|  9 
 .../rust/compile/inline_asm_parse_operand.rs  |  6 ++---
 .../execute/torture/inline_asm_mov_x_5_ARM.rs | 14 +++-
 .../torture/inline_asm_mov_x_5_x86_64.rs  | 19 
 5 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 8294feb2197..e85d08d0579 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,5 +1,4 @@
 #include "rust-compile-asm.h"
-#include "rust-system.h"
 #include "rust-compile-expr.h"
 namespace Rust {
 namespace Compile {
@@ -107,7 +106,26 @@ tree
 CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
-  return NULL_TREE;
+  tree head = NULL_TREE;
+  for (auto &input : expr.get_operands ())
+{
+  if (input.get_register_type () == 
AST::InlineAsmOperand::RegisterType::In)
+   {
+ auto in = input.get_in ();
+
+ tree in_tree = CompileExpr::Compile (in.expr.get (), this->ctx);
+ // expects a tree list
+ // TODO: This assumes that the input is a register
+ std::string expr_name = "r";
+ auto name = build_string (expr_name.size () + 1, expr_name.c_str ());
+ head
+   = chainon (head, build_tree_list (build_tree_list (NULL_TREE, name),
+ in_tree));
+
+ /*head = chainon (head, out_tree);*/
+   }
+}
+  return head;
 }
 
 tree
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 1017d9fd6c4..e970f285202 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -330,8 +330,8 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
 
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
-  // struct AST::InlineAsmOperand::In in (reg, nullptr);
-  // inline_asm_ctx.inline_asm.operands.push_back (in);
+  struct AST::InlineAsmOperand::In in (reg, std::move (expr));
+  inline_asm_ctx.inline_asm.operands.push_back (in);
   return inline_asm_ctx;
 }
   return tl::unexpected (NONCOMMITED);
@@ -792,8 +792,9 @@ expand_inline_asm_strings (InlineAsmContext inline_asm_ctx)
 * trait});*/
 
transformed_template_str += "%" + std::to_string (idx);
-   /*std::cout << "argument implicitly is: " << idx <<
-* std::endl;*/
+   // std::cout << "argument implicitly is: " << idx <<
+   // std::endl; std::cout << "transformed template str is:"
+   // << transformed_template_str << std::endl;
/*std::cout << "trait: " << trait.to_string () <<
 * std::endl;*/
/*std::cout << "arg: " << arg.to_string () << std::endl;*/
diff --git a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs 
b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
index e0efe1c420d..c7bc152c7ce 100644
--- a/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
+++ b/gcc/testsuite/rust/compile/inline_asm_parse_operand.rs
@@ -8,7 +8,7 @@ macro_rules! asm {
 fn main() -> i32 {
 unsafe {
 asm!(
-"add {}, {}",
+"add {}, 1",
 in(reg) 0
 );
 }
@@ -21,15 +21,15 @@ fn main() -> i32 {
 unsafe {
 asm!(
 "add {}, {}",
-inout(reg) num1 =>_num1,
 in(reg) _num2,
+out(reg) _num1,
 );
 }
 
 let mut _output_testing: u32 = 0;
 unsafe {
 asm!(
-"add {}, {}",
+"add {}, 1",
 in(reg) _num1,
 //out(reg) _,
 );
diff --git a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
index 4e762608230..0c867df657e 100644
--- a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
@@ -1,5 +1,5 @@
 /* { dg-do run { target arm*-*-* } } */
-/* { dg-output "5\r*\n" }*/
+/* { dg-output "5\r*\n9\r*\n" }*/
 
 #![feature(r

[COMMITTED 135/144] gccrs: Fix compiler error on ast wrong implicit construct push_back

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins-asm.cc (parse_reg_operand_in): Fix
compiler error on ast wrong implicit construct push_back
---
 gcc/rust/expand/rust-macro-builtins-asm.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index e970f285202..5ed24d641ce 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -314,6 +314,7 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
   // For the keyword IN, currently we count it as a seperate keyword called
   // Rust::IN search for #define RS_TOKEN_LIST in code base.
   auto &parser = inline_asm_ctx.parser;
+  location_t locus = parser.peek_current_token ()->get_locus ();
   if (!inline_asm_ctx.is_global_asm () && parser.skip_token (IN))
 {
   auto reg = parse_reg (inline_asm_ctx);
@@ -331,7 +332,7 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
   struct AST::InlineAsmOperand::In in (reg, std::move (expr));
-  inline_asm_ctx.inline_asm.operands.push_back (in);
+  inline_asm_ctx.inline_asm.operands.emplace_back (in, locus);
   return inline_asm_ctx;
 }
   return tl::unexpected (NONCOMMITED);
-- 
2.45.2



[COMMITTED 139/144] gccrs: Make const references to ForeverStack more useful

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

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h
(ForeverStack::to_canonical_path): Make const.
(ForeverStack::to_rib): Add const overload.
(ForeverStack::reverse_iter): Add const overloads.
(ForeverStack::ConstDfsResult): Add.
(ForeverStack::dfs): Add const overload.
(ForeverStack::dfs_rib): Likewise.
* resolve/rust-forever-stack.hxx
(ForeverStack::reverse_iter): Add const overloads.
(ForeverStack::dfs): Add const overload.
(ForeverStack::to_canonical_path): Make const.
(ForeverStack::dfs_rib): Likewise.
(ForeverStack::to_rib): Add const overload.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-forever-stack.h   | 15 +++-
 gcc/rust/resolve/rust-forever-stack.hxx | 91 -
 2 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index c24289d0c7e..8c5e207a70d 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -513,10 +513,11 @@ public:
   tl::optional resolve_path (const std::vector &segments);
 
   // FIXME: Documentation
-  tl::optional to_canonical_path (NodeId id);
+  tl::optional to_canonical_path (NodeId id) const;
 
   // FIXME: Documentation
   tl::optional to_rib (NodeId rib_id);
+  tl::optional to_rib (NodeId rib_id) const;
 
   std::string as_debug_string ();
 
@@ -579,9 +580,12 @@ private:
 
   /* Reverse iterate on `Node`s from the cursor, in an outwards fashion */
   void reverse_iter (std::function lambda);
+  void reverse_iter (std::function lambda) const;
 
   /* Reverse iterate on `Node`s from a specified one, in an outwards fashion */
   void reverse_iter (Node &start, std::function lambda);
+  void reverse_iter (const Node &start,
+std::function lambda) const;
 
   Node &cursor ();
   const Node &cursor () const;
@@ -617,11 +621,20 @@ private:
 Node &first;
 std::string second;
   };
+  struct ConstDfsResult
+  {
+const Node &first;
+std::string second;
+  };
 
   // FIXME: Documentation
   tl::optional dfs (Node &starting_point, NodeId to_find);
+  tl::optional dfs (const Node &starting_point,
+   NodeId to_find) const;
   // FIXME: Documentation
   tl::optional dfs_rib (Node &starting_point, NodeId to_find);
+  tl::optional dfs_rib (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 4a8b6b59d17..5a5a7c73f32 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -192,6 +192,14 @@ ForeverStack::reverse_iter (std::function lambda)
   return reverse_iter (cursor (), lambda);
 }
 
+template 
+void
+ForeverStack::reverse_iter (
+  std::function lambda) const
+{
+  return reverse_iter (cursor (), lambda);
+}
+
 template 
 void
 ForeverStack::reverse_iter (Node &start,
@@ -212,6 +220,26 @@ ForeverStack::reverse_iter (Node &start,
 }
 }
 
+template 
+void
+ForeverStack::reverse_iter (
+  const Node &start, std::function lambda) const
+{
+  auto *tmp = &start;
+
+  while (true)
+{
+  auto keep_going = lambda (*tmp);
+  if (keep_going == KeepGoing::No)
+   return;
+
+  if (tmp->is_root ())
+   return;
+
+  tmp = &tmp->parent.value ();
+}
+}
+
 template 
 typename ForeverStack::Node &
 ForeverStack::cursor ()
@@ -507,22 +535,53 @@ ForeverStack::dfs (ForeverStack::Node 
&starting_point, NodeId to_find)
   return tl::nullopt;
 }
 
+template 
+tl::optional::ConstDfsResult>
+ForeverStack::dfs (const ForeverStack::Node &starting_point,
+ NodeId to_find) const
+{
+  auto values = starting_point.rib.get_values ();
+
+  for (auto &kv : values)
+{
+  for (auto id : kv.second.ids_shadowable)
+   if (id == to_find)
+ return {{starting_point, kv.first}};
+  for (auto id : kv.second.ids_non_shadowable)
+   if (id == to_find)
+ return {{starting_point, kv.first}};
+  for (auto id : kv.second.ids_globbed)
+   if (id == to_find)
+ return {{starting_point, kv.first}};
+}
+
+  for (auto &child : starting_point.children)
+{
+  auto candidate = dfs (child.second, to_find);
+
+  if (candidate.has_value ())
+   return candidate;
+}
+
+  return tl::nullopt;
+}
+
 template 
 tl::optional
-ForeverStack::to_canonical_path (NodeId id)
+ForeverStack::to_canonical_path (NodeId id) const
 {
   // find the id in the current forever stack, starting from the root,
   // performing either a BFS or DFS once the Node containing the ID is found, 
go
   // back up to the root (parent().parent().parent()...) accumulate link
   // segments reverse them that's your canonical path
 
-  return dfs (root, id).map ([this, id] (DfsResult tuple) {

[COMMITTED 144/144] gccrs: Handle external static items in toplevel resolver 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Handle ExternalStaticItem.
* resolve/rust-toplevel-name-resolver-2.0.h
(TopLevel::visit): Likewise.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 7 +++
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h  | 1 +
 2 files changed, 8 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 c9d51039f0e..a0d8492b7eb 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -264,6 +264,13 @@ TopLevel::visit (AST::StaticItem &static_item)
   Namespace::Values);
 }
 
+void
+TopLevel::visit (AST::ExternalStaticItem &static_item)
+{
+  insert_or_error_out (static_item.get_identifier ().as_string (), static_item,
+  Namespace::Values);
+}
+
 void
 TopLevel::visit (AST::StructStruct &struct_item)
 {
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 e9e0306f11a..7f4e29585de 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -152,6 +152,7 @@ private:
   void visit (AST::Function &function) override;
   void visit (AST::BlockExpr &expr) override;
   void visit (AST::StaticItem &static_item) override;
+  void visit (AST::ExternalStaticItem &static_item) override;
   void visit (AST::StructStruct &struct_item) override;
   void visit (AST::TupleStruct &tuple_struct) override;
   void visit (AST::EnumItem &variant) override;
-- 
2.45.2



[COMMITTED 083/144] gccrs: Check if the type has been correctly resolved

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

We did not check the optional was valid, this lead to rogue dereference
and undefined behaviors.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add optional
check.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 9 ++---
 1 file changed, 6 insertions(+), 3 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 9ac09456fbd..068d231c6fb 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -23,6 +23,7 @@
 #include "rust-default-resolver.h"
 #include "rust-name-resolution-context.h"
 #include "rust-path.h"
+#include "rust-system.h"
 #include "rust-tyty.h"
 #include "rust-hir-type-check.h"
 
@@ -223,9 +224,11 @@ Late::visit (AST::TypePath &type)
   // typepath-like path resolution? that sounds good
 
   auto resolved = ctx.types.get (type.get_segments ().back ()->as_string ());
-
-  ctx.map_usage (Usage (type.get_node_id ()),
-Definition (resolved->get_node_id ()));
+  if (resolved)
+ctx.map_usage (Usage (type.get_node_id ()),
+  Definition (resolved->get_node_id ()));
+  else
+rust_unreachable ();
 }
 
 void
-- 
2.45.2



[COMMITTED 089/144] rust: fix ICE when compiling impl block for !

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

We need to resolve the never type which is its own special AST node so it
doesnt magically get handled like the regular builtin type paths such as
i32.

Fixes #3035

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-type.cc (ResolveType::visit):
handle never type
(ResolveTypeToCanonicalPath::visit): likewise
* resolve/rust-ast-resolve-type.h: missing never type
* resolve/rust-name-resolver.cc (Resolver::generate_builtins):
track never type node_id
(Resolver::setup_builtin): likewise
* resolve/rust-name-resolver.h: new never type getter

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/resolve/rust-ast-resolve-type.cc |  8 +++-
 gcc/rust/resolve/rust-ast-resolve-type.h  |  2 ++
 gcc/rust/resolve/rust-name-resolver.cc|  9 ++--
 gcc/rust/resolve/rust-name-resolver.h |  7 ++-
 gcc/testsuite/rust/compile/issue-3035.rs  | 25 +++
 gcc/testsuite/rust/compile/nr2/exclude|  3 ++-
 6 files changed, 49 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3035.rs

diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc 
b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 934d6ea3fbd..cee259cceb4 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -69,7 +69,7 @@ ResolveType::visit (AST::InferredType &)
 void
 ResolveType::visit (AST::NeverType &)
 {
-  // FIXME
+  resolved_node = resolver->get_never_type_node_id ();
 }
 
 void
@@ -501,6 +501,12 @@ ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &)
   rust_unreachable ();
 }
 
+void
+ResolveTypeToCanonicalPath::visit (AST::NeverType &type)
+{
+  result = CanonicalPath::new_seg (type.get_node_id (), "!");
+}
+
 ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath ()
   : ResolverBase (), result (CanonicalPath::create_empty ())
 {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h 
b/gcc/rust/resolve/rust-ast-resolve-type.h
index 0076424ef51..5e382445a14 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -246,6 +246,8 @@ public:
 
   void visit (AST::TraitObjectType &type) override;
 
+  void visit (AST::NeverType &type) override;
+
 private:
   ResolveTypeToCanonicalPath ();
 
diff --git a/gcc/rust/resolve/rust-name-resolver.cc 
b/gcc/rust/resolve/rust-name-resolver.cc
index ee52e5cc3d1..21147bd86fa 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -429,7 +429,10 @@ Resolver::generate_builtins ()
   setup_builtin ("isize", isize);
   setup_builtin ("char", char_tyty);
   setup_builtin ("str", str);
-  setup_builtin ("!", never);
+
+  // never type
+  NodeId never_node_id = setup_builtin ("!", never);
+  set_never_type_node_id (never_node_id);
 
   // unit type ()
   TyTy::TupleType *unit_tyty
@@ -443,7 +446,7 @@ Resolver::generate_builtins ()
   set_unit_type_node_id (unit_type->get_node_id ());
 }
 
-void
+NodeId
 Resolver::setup_builtin (const std::string &name, TyTy::BaseType *tyty)
 {
   AST::PathIdentSegment seg (name, BUILTINS_LOCATION);
@@ -459,6 +462,8 @@ Resolver::setup_builtin (const std::string &name, 
TyTy::BaseType *tyty)
   mappings.insert_canonical_path (
 builtin_type->get_node_id (),
 CanonicalPath::new_seg (builtin_type->get_node_id (), name));
+
+  return builtin_type->get_node_id ();
 }
 
 void
diff --git a/gcc/rust/resolve/rust-name-resolver.h 
b/gcc/rust/resolve/rust-name-resolver.h
index c34002eb18e..43b79e51005 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -163,9 +163,13 @@ public:
   Scope &get_macro_scope () { return macro_scope; }
 
   NodeId get_global_type_node_id () { return global_type_node_id; }
+
   void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
   NodeId get_unit_type_node_id () { return unit_ty_node_id; }
 
+  void set_never_type_node_id (NodeId id) { never_ty_node_id = id; }
+  NodeId get_never_type_node_id () { return never_ty_node_id; }
+
   void push_new_module_scope (NodeId module_id)
   {
 current_module_stack.push_back (module_id);
@@ -208,7 +212,7 @@ private:
   Resolver ();
 
   void generate_builtins ();
-  void setup_builtin (const std::string &name, TyTy::BaseType *tyty);
+  NodeId setup_builtin (const std::string &name, TyTy::BaseType *tyty);
 
   Analysis::Mappings &mappings;
   TypeCheckContext *tyctx;
@@ -222,6 +226,7 @@ private:
 
   NodeId global_type_node_id;
   NodeId unit_ty_node_id;
+  NodeId never_ty_node_id;
 
   // map a AST Node to a Rib
   std::map name_ribs;
diff --git a/gcc/testsuite/rust/compile/issue-3035.rs 
b/gcc/testsuite/rust/compile/issue-3035.rs
new file mode 100644
index 000..3266d841dea
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3035.rs
@@ -0,0 +1,25 @@
+#[

[COMMITTED 136/144] gccrs: Disambiguate generic args during name resolution 2.0

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Visit GenericArgs and GenericArg, the former
because the latter involves a non-virtual member function call.
* resolve/rust-late-name-resolver-2.0.h
(Late::visit): Likewise.

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 32 +++
 .../resolve/rust-late-name-resolver-2.0.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index daf0c871a62..43f33dfab02 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -275,5 +275,37 @@ Late::visit (AST::StructExprStructFields &s)
   DefaultResolver::visit (s);
 }
 
+// needed because Late::visit (AST::GenericArg &) is non-virtual
+void
+Late::visit (AST::GenericArgs &args)
+{
+  for (auto &lifetime : args.get_lifetime_args ())
+visit (lifetime);
+
+  for (auto &generic : args.get_generic_args ())
+visit (generic);
+
+  for (auto &binding : args.get_binding_args ())
+visit (binding);
+}
+
+void
+Late::visit (AST::GenericArg &arg)
+{
+  if (arg.get_kind () == AST::GenericArg::Kind::Either)
+{
+  // prefer type parameter to const parameter on ambiguity
+  auto type = ctx.types.get (arg.get_path ());
+  auto value = ctx.values.get (arg.get_path ());
+
+  if (!type.has_value () && value.has_value ())
+   arg = arg.disambiguate_to_const ();
+  else
+   arg = arg.disambiguate_to_type ();
+}
+
+  DefaultResolver::visit (arg);
+}
+
 } // namespace Resolver2_0
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index c4d0d82162e..7e33c965805 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -49,6 +49,8 @@ public:
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
   void visit (AST::StructStruct &) override;
+  void visit (AST::GenericArgs &) override;
+  void visit (AST::GenericArg &);
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
-- 
2.45.2



[COMMITTED 086/144] gccrs: adjust hir dump of BlockExpr

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

Add tail_reachable and label fields to the dump.

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): Add missing fields.

Signed-off-by: Marc Poulhiès 
---
 gcc/rust/hir/rust-hir-dump.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 67749de49a6..b4413773234 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1270,6 +1270,8 @@ Dump::visit (BlockExpr &e)
   begin ("BlockExpr");
   do_expr (e);
   do_inner_attrs (e);
+  put_field ("tail_reachable", std::to_string (e.is_tail_reachable ()));
+  put_field ("label", e.get_label ().as_string ());
 
   visit_collection ("statements", e.get_statements ());
 
-- 
2.45.2



[COMMITTED 098/144] gccrs: imports: Make FinalizeImports a resolver visitor as well

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

gcc/rust/ChangeLog:

* resolve/rust-finalize-imports-2.0.cc (FinalizeImports::go): Turn
static method into method.
(FinalizeImports::visit): New.
* resolve/rust-finalize-imports-2.0.h (class FinalizeImports): Make
FinalizeImports a visitor.
* resolve/rust-early-name-resolver-2.0.cc (Early::go): Use new 
FinalizeImports API.
(Early::resolve_glob_import): Use new API.
(Early::resolve_simple_import): Likewise.
(Early::resolve_rebind_import): Likewise.
(Early::build_import_mapping): Likewise.
* resolve/rust-early-name-resolver-2.0.h: Likewise.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): 
Likewise.
* resolve/rust-toplevel-name-resolver-2.0.h: Likewise.
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 84 ---
 .../resolve/rust-early-name-resolver-2.0.h| 14 ++--
 gcc/rust/resolve/rust-finalize-imports-2.0.cc | 23 -
 gcc/rust/resolve/rust-finalize-imports-2.0.h  | 23 -
 .../rust-toplevel-name-resolver-2.0.cc| 10 ++-
 .../resolve/rust-toplevel-name-resolver-2.0.h |  5 +-
 6 files changed, 114 insertions(+), 45 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 ba73a54d412..ac8eb940c8d 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -59,7 +59,7 @@ Early::go (AST::Crate &crate)
 build_import_mapping (std::move (import));
 
   // Once this is done, we finalize their resolution
-  FinalizeImports::go (import_mappings, toplevel, ctx);
+  FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
   // We now proceed with resolving macros, which can be nested in almost any
   // items
@@ -70,7 +70,7 @@ Early::go (AST::Crate &crate)
 }
 
 bool
-Early::resolve_glob_import (TopLevel::ImportKind &&glob)
+Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
 {
   auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
   if (!resolved.has_value ())
@@ -84,58 +84,86 @@ Early::resolve_glob_import (TopLevel::ImportKind &&glob)
   // here, we insert the module's NodeId into the import_mappings and will look
   // up the module proper in `FinalizeImports`
   // The namespace does not matter here since we are dealing with a glob
-  import_mappings.insert ({std::move (glob), ImportData::Glob (*resolved)});
+  // TODO: Ugly
+  import_mappings.insert (
+{use_dec_id, {{std::move (glob), ImportData::Glob (*resolved)}}});
 
   return true;
 }
 
 bool
-Early::resolve_simple_import (TopLevel::ImportKind &&import)
+Early::resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import)
 {
   return ctx.resolve_path (import.to_resolve)
 .map ([&] (std::pair def_ns) {
-  import_mappings.insert (
-   {std::move (import), ImportData::Simple (def_ns)});
+  // We insert an empty vector, unless an element was already present for
+  // `use_dec_id` - which is returned in the tuple's first member
+  auto tuple = import_mappings.insert ({use_dec_id, {}});
+  // We then get that tuple's first member, which will be an iterator to 
the
+  // existing vec> OR an iterator to our newly
+  // created empty vector (plus its key since this is a hashmap iterator).
+  // we then access the second member of the pair to get access to the
+  // vector directly.
+  auto &imports = tuple.first->second;
+
+  imports.emplace_back (
+   std::make_pair (std::move (import), ImportData::Simple (def_ns)));
 })
 .has_value ();
 }
 
 bool
-Early::resolve_rebind_import (TopLevel::ImportKind &&rebind_import)
+Early::resolve_rebind_import (NodeId use_dec_id,
+ TopLevel::ImportKind &&rebind_import)
 {
   return ctx.resolve_path (rebind_import.to_resolve)
 .map ([&] (std::pair def_ns) {
-  import_mappings.insert (
-   {std::move (rebind_import), ImportData::Rebind (def_ns)});
+  // We insert an empty vector, unless an element was already present for
+  // `use_dec_id` - which is returned in the tuple's first member
+  auto tuple = import_mappings.insert ({use_dec_id, {}});
+  // We then get that tuple's first member, which will be an iterator to 
the
+  // existing vec> OR an iterator to our newly
+  // created empty vector (plus its key since this is a hashmap iterator).
+  // we then access the second member of the pair to get access to the
+  // vector directly.
+  auto &imports = tuple.first->second;
+
+  imports.emplace_back (std::make_pair (std::move (rebind_import),
+   ImportData::Rebind (def_ns)));
 })
 .has_value ();
 }
 
 void
-Early::build_import_mapping (TopLevel::ImportKind &&import)
+Early::build_import_mapping (
+  std::pair> &&use_import)
 {
   auto found = false;
+  aut

[COMMITTED 062/144] gccrs: Avoid accidental insertion into map

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

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-pattern.cc
(PatternDeclaration::check_bindings_consistency): Check if
outer_bindings_map contains an entry before indexing.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-ast-resolve-pattern.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc 
b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 9b383b722c8..ee84be8942b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -330,7 +330,8 @@ PatternDeclaration::check_bindings_consistency (
  if (!ident_is_outer_bound && !missing_bindings.count (ident))
missing_bindings.insert ({ident, inner_info});
 
- else if (outer_bindings_map[ident] != inner_info
+ else if (outer_bindings_map.count (ident)
+  && outer_bindings_map[ident] != inner_info
   && !inconsistent_bindings.count (ident))
inconsistent_bindings.insert ({ident, inner_info});
}
-- 
2.45.2



[COMMITTED 090/144] gccrs: rust fix ICE when hir lowering qualified path expressions without an as

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

Qualified path expressions usually are ::... but the as is optional
this adds the extra checking in hir lowering to not hit that nullptr.

Fixes #3082

gcc/rust/ChangeLog:

* hir/rust-ast-lower-type.cc (ASTLowerQualifiedPathInType::visit):
check for valid as segment

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-ast-lower-type.cc  | 11 +--
 gcc/testsuite/rust/compile/issue-3082.rs |  9 +
 gcc/testsuite/rust/compile/nr2/exclude   |  1 +
 3 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3082.rs

diff --git a/gcc/rust/hir/rust-ast-lower-type.cc 
b/gcc/rust/hir/rust-ast-lower-type.cc
index 883af4adb47..7d6ac5ddffa 100644
--- a/gcc/rust/hir/rust-ast-lower-type.cc
+++ b/gcc/rust/hir/rust-ast-lower-type.cc
@@ -145,8 +145,15 @@ ASTLowerQualifiedPathInType::visit 
(AST::QualifiedPathInType &path)
 
   HIR::Type *qual_type
 = ASTLoweringType::translate (path.get_qualified_path_type ().get_type ());
-  HIR::TypePath *qual_trait = ASTLowerTypePath::translate (
-path.get_qualified_path_type ().get_as_type_path ());
+
+  HIR::TypePath *qual_trait = nullptr;
+  if (!path.get_qualified_path_type ().is_error ())
+{
+  AST::QualifiedPathType &qualifier = path.get_qualified_path_type ();
+  if (qualifier.has_as_clause ())
+   qual_trait
+ = ASTLowerTypePath::translate (qualifier.get_as_type_path ());
+}
 
   HIR::QualifiedPathType qual_path_type (
 qual_mappings, std::unique_ptr (qual_type),
diff --git a/gcc/testsuite/rust/compile/issue-3082.rs 
b/gcc/testsuite/rust/compile/issue-3082.rs
new file mode 100644
index 000..4b873955dde
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3082.rs
@@ -0,0 +1,9 @@
+#![allow(unused)]
+fn main() {
+trait Hello {
+type Who;
+
+fn hello() -> ::You;
+// { dg-error "failed to resolve return type" "" { target *-*-* } .-1 }
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 5f5863bde87..3412617f7eb 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -277,3 +277,4 @@ dropck_eyepatch_feature_gate.rs
 inline_asm_parse_output_operand.rs
 issue-3030.rs
 issue-3035.rs
+issue-3082.rs
\ No newline at end of file
-- 
2.45.2



[COMMITTED 103/144] gccrs: Loop on expansion if a new export has been defined

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

When a use statement requires a reexported item it cannot find it in
the same pass, an additional pass shall be performed. This means we need
to detect whether a new item has been reexported and resolve until the
end.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::Early): Add dirty
flag initialization.
(Early::go): Set dirty flag using top level resolver.
* resolve/rust-early-name-resolver-2.0.h: Add dirty flag.
* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::TopLevel):
Initialize dirty flag.
(TopLevel::insert_or_error_out): Set dirty flag on successful
namespace modification.
* resolve/rust-toplevel-name-resolver-2.0.h: Add dirty flag.
* rust-session-manager.cc (Session::expansion): Modify fixed point
condition to include name resolution modifications.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc| 4 +++-
 gcc/rust/resolve/rust-early-name-resolver-2.0.h | 4 
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 7 ---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h  | 6 ++
 gcc/rust/rust-session-manager.cc| 5 -
 5 files changed, 21 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 c4f9b27e297..55330487fd7 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -26,7 +26,8 @@
 namespace Rust {
 namespace Resolver2_0 {
 
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
+Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty 
(false)
+{}
 
 void
 Early::insert_once (AST::MacroInvocation &invocation, NodeId resolved)
@@ -61,6 +62,7 @@ Early::go (AST::Crate &crate)
   // Once this is done, we finalize their resolution
   FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
 
+  dirty = toplevel.is_dirty ();
   // We now proceed with resolving macros, which can be nested in almost any
   // items
   textual_scope.push ();
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index ec1d914c05d..a7ad0f78fb8 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -34,9 +34,13 @@ class Early : public DefaultResolver
 {
   using DefaultResolver::visit;
 
+  bool dirty;
+
 public:
   Early (NameResolutionContext &ctx);
 
+  bool is_dirty () { return dirty; }
+
   void go (AST::Crate &crate);
 
   const std::vector &get_macro_resolve_errors () const
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 47f3adee14c..6a54978a67c 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -27,7 +27,7 @@ namespace Rust {
 namespace Resolver2_0 {
 
 TopLevel::TopLevel (NameResolutionContext &resolver)
-  : DefaultResolver (resolver)
+  : DefaultResolver (resolver), dirty (false)
 {}
 
 template 
@@ -47,8 +47,9 @@ TopLevel::insert_or_error_out (const Identifier &identifier,
   node_locations.emplace (node_id, locus);
 
   auto result = ctx.insert (identifier, node_id, ns);
-
-  if (!result && result.error ().existing != node_id)
+  if (result)
+dirty = true;
+  else if (result.error ().existing != node_id)
 {
   rich_location rich_loc (line_table, locus);
   rich_loc.add_range (node_locations[result.error ().existing]);
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 acb60d36e13..99ed65398c6 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -43,6 +43,8 @@ public:
 
   void go (AST::Crate &crate);
 
+  bool is_dirty () { return dirty; }
+
   // Each import will be transformed into an instance of `ImportKind`, a class
   // representing some of the data we need to resolve in the
   // `EarlyNameResolver`. Basically, for each `UseTree` that we see in
@@ -129,6 +131,10 @@ public:
Namespace ns);
 
 private:
+  // If a new export has been defined whilst visiting the visitor is considered
+  // dirty
+  bool dirty;
+
   // FIXME: Do we move these to our mappings?
   std::unordered_map node_locations;
 
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index a5cd97f18d7..5668d4d65d3 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -928,18 +928,21 @@ Session::expansion (AST::Crate &crate, 
Resolver2_0::NameResolutionContext &ctx)
   if (saw_errors ())
break;
 
+  bool visitor_dirty = false;
+
   if (flag_name_resolution_2_0)
{
 

[COMMITTED 105/144] gccrs: Remove empty visit functions

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

We can let the default visitor visit those nodes anyway so we're sure
all nodes can be reached.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Remove
empty visit function implementations.
* resolve/rust-default-resolver.h: Remove corresponding prototypes.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.cc | 268 --
 gcc/rust/resolve/rust-default-resolver.h  |  69 +-
 2 files changed, 1 insertion(+), 336 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index b2cdc5f52d2..5ecea06bc6e 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -164,14 +164,6 @@ DefaultResolver::visit (AST::Enum &type)
  variant_fn, type.get_identifier ());
 }
 
-void
-DefaultResolver::visit (AST::StructExprFieldIdentifierValue &)
-{}
-
-void
-DefaultResolver::visit (AST::StructExprFieldIndexValue &)
-{}
-
 void
 DefaultResolver::visit (AST::ClosureExprInner &expr)
 {
@@ -211,34 +203,6 @@ DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
   expr.get_return_type ().accept_vis (*this);
 }
 
-void
-DefaultResolver::visit (AST::ContinueExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::RangeFromToExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::RangeFromExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::RangeToExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::RangeFromToInclExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::RangeToInclExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::ReturnExpr &expr)
-{}
-
 void
 DefaultResolver::visit (AST::CallExpr &expr)
 {
@@ -269,18 +233,6 @@ DefaultResolver::visit (AST::MethodCallExpr &expr)
 param->accept_vis (*this);
 }
 
-void
-DefaultResolver::visit (AST::LoopExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::WhileLoopExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::WhileLetLoopExpr &expr)
-{}
-
 void
 DefaultResolver::visit (AST::IfExpr &expr)
 {
@@ -296,14 +248,6 @@ DefaultResolver::visit (AST::IfExprConseqElse &expr)
   expr.get_else_block ().accept_vis (*this);
 }
 
-void
-DefaultResolver::visit (AST::IfLetExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::IfLetExprConseqElse &)
-{}
-
 void
 DefaultResolver::visit (AST::MatchExpr &expr)
 {
@@ -321,34 +265,6 @@ DefaultResolver::visit (AST::MatchExpr &expr)
 }
 }
 
-void
-DefaultResolver::visit (AST::AwaitExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::AsyncBlockExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::DelimTokenTree &)
-{}
-
-void
-DefaultResolver::visit (AST::AttrInputMetaItemContainer &)
-{}
-
-void
-DefaultResolver::visit (AST::IdentifierExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::LifetimeParam &)
-{}
-
-void
-DefaultResolver::visit (AST::ConstGenericParam &)
-{}
-
 void
 DefaultResolver::visit (AST::PathInExpression &expr)
 {
@@ -366,98 +282,6 @@ DefaultResolver::visit (AST::PathInExpression &expr)
   }
 }
 
-void
-DefaultResolver::visit (AST::TypePathSegmentGeneric &)
-{}
-
-void
-DefaultResolver::visit (AST::TypePathSegmentFunction &)
-{}
-
-void
-DefaultResolver::visit (AST::TypePath &)
-{}
-
-void
-DefaultResolver::visit (AST::QualifiedPathInExpression &)
-{}
-
-void
-DefaultResolver::visit (AST::QualifiedPathInType &)
-{}
-
-void
-DefaultResolver::visit (AST::LiteralExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::AttrInputLiteral &)
-{}
-
-void
-DefaultResolver::visit (AST::AttrInputMacro &)
-{}
-
-void
-DefaultResolver::visit (AST::MetaItemLitExpr &expr)
-{}
-
-void
-DefaultResolver::visit (AST::MetaItemPathLit &)
-{}
-
-void
-DefaultResolver::visit (AST::StructExprStruct &)
-{}
-
-void
-DefaultResolver::visit (AST::StructExprStructFields &)
-{}
-
-void
-DefaultResolver::visit (AST::StructExprStructBase &)
-{}
-
-void
-DefaultResolver::visit (AST::TypeParam &)
-{}
-
-void
-DefaultResolver::visit (AST::LifetimeWhereClauseItem &)
-{}
-
-void
-DefaultResolver::visit (AST::TypeBoundWhereClauseItem &)
-{}
-
-void
-DefaultResolver::visit (AST::ExternCrate &)
-{}
-
-void
-DefaultResolver::visit (AST::UseTreeGlob &)
-{}
-
-void
-DefaultResolver::visit (AST::UseTreeList &)
-{}
-
-void
-DefaultResolver::visit (AST::UseTreeRebind &)
-{}
-
-void
-DefaultResolver::visit (AST::UseDeclaration &)
-{}
-
-void
-DefaultResolver::visit (AST::TypeAlias &)
-{}
-
-void
-DefaultResolver::visit (AST::EnumItem &)
-{}
-
 void
 DefaultResolver::visit (AST::EnumItemTuple &item)
 {
@@ -503,97 +327,5 @@ DefaultResolver::visit (AST::StaticItem &item)
   ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
 }
 
-void
-DefaultResolver::visit (AST::TraitItemConst &)
-{}
-
-void
-DefaultResolver::visit (AST::TraitItemType &)
-{}
-
-void
-DefaultResolver::visit (AST::ExternalTypeItem &)
-{}
-
-void
-DefaultResolver::visit (AST::ExternalStaticItem &)
-{}
-
-void
-DefaultResolver::visit (AST::M

[COMMITTED 104/144] gccrs: Mark virtual function override in default resolver

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

Those function prototype were not marked as override and throwing
warning.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.h: Make most visit function override.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.h | 178 +++
 1 file changed, 89 insertions(+), 89 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 3774603daaa..fd1f7bec20e 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -42,101 +42,101 @@ public:
   // First, our lexical scope expressions - these visit their sub nodes, always
   // these nodes create new scopes and ribs - they are often used to declare 
new
   // variables, such as a for loop's iterator, or a function's arguments
-  void visit (AST::BlockExpr &);
-  void visit (AST::Module &);
-  void visit (AST::Function &);
-  void visit (AST::ForLoopExpr &);
-  void visit (AST::Trait &);
-  void visit (AST::InherentImpl &);
-  void visit (AST::TraitImpl &);
+  void visit (AST::BlockExpr &) override;
+  void visit (AST::Module &) override;
+  void visit (AST::Function &) override;
+  void visit (AST::ForLoopExpr &) override;
+  void visit (AST::Trait &) override;
+  void visit (AST::InherentImpl &) override;
+  void visit (AST::TraitImpl &) override;
 
   // type dec nodes, which visit their fields or variants by default
-  void visit (AST::StructStruct &);
-  void visit (AST::Enum &);
+  void visit (AST::StructStruct &) override;
+  void visit (AST::Enum &) override;
 
   // Visitors that visit their expression node(s)
-  void visit (AST::StructExprFieldIdentifierValue &);
-  void visit (AST::StructExprFieldIndexValue &);
-  void visit (AST::ClosureExprInner &);
-  void visit (AST::ClosureExprInnerTyped &);
-  void visit (AST::ContinueExpr &);
-  void visit (AST::RangeFromToExpr &);
-  void visit (AST::RangeFromExpr &);
-  void visit (AST::RangeToExpr &);
-  void visit (AST::RangeFromToInclExpr &);
-  void visit (AST::RangeToInclExpr &);
-  void visit (AST::ReturnExpr &);
-  void visit (AST::CallExpr &);
-  void visit (AST::MethodCallExpr &);
-  void visit (AST::LoopExpr &);
-  void visit (AST::WhileLoopExpr &);
-  void visit (AST::WhileLetLoopExpr &);
-  void visit (AST::IfExpr &);
-  void visit (AST::IfExprConseqElse &);
-  void visit (AST::IfLetExpr &);
-  void visit (AST::IfLetExprConseqElse &);
-  void visit (AST::MatchExpr &);
-  void visit (AST::AwaitExpr &);
-  void visit (AST::AsyncBlockExpr &);
+  void visit (AST::StructExprFieldIdentifierValue &) override;
+  void visit (AST::StructExprFieldIndexValue &) override;
+  void visit (AST::ClosureExprInner &) override;
+  void visit (AST::ClosureExprInnerTyped &) override;
+  void visit (AST::ContinueExpr &) override;
+  void visit (AST::RangeFromToExpr &) override;
+  void visit (AST::RangeFromExpr &) override;
+  void visit (AST::RangeToExpr &) override;
+  void visit (AST::RangeFromToInclExpr &) override;
+  void visit (AST::RangeToInclExpr &) override;
+  void visit (AST::ReturnExpr &) override;
+  void visit (AST::CallExpr &) override;
+  void visit (AST::MethodCallExpr &) override;
+  void visit (AST::LoopExpr &) override;
+  void visit (AST::WhileLoopExpr &) override;
+  void visit (AST::WhileLetLoopExpr &) override;
+  void visit (AST::IfExpr &) override;
+  void visit (AST::IfExprConseqElse &) override;
+  void visit (AST::IfLetExpr &) override;
+  void visit (AST::IfLetExprConseqElse &) override;
+  void visit (AST::MatchExpr &) override;
+  void visit (AST::AwaitExpr &) override;
+  void visit (AST::AsyncBlockExpr &) override;
 
   // Leaf visitors, which do nothing by default
-  void visit (AST::DelimTokenTree &);
-  void visit (AST::AttrInputMetaItemContainer &);
-  void visit (AST::IdentifierExpr &);
-  void visit (AST::LifetimeParam &);
-  void visit (AST::ConstGenericParam &);
-  void visit (AST::PathInExpression &);
-  void visit (AST::TypePathSegmentGeneric &);
-  void visit (AST::TypePathSegmentFunction &);
-  void visit (AST::TypePath &);
-  void visit (AST::QualifiedPathInExpression &);
-  void visit (AST::QualifiedPathInType &);
-  void visit (AST::LiteralExpr &);
-  void visit (AST::AttrInputLiteral &);
-  void visit (AST::AttrInputMacro &);
-  void visit (AST::MetaItemLitExpr &);
-  void visit (AST::MetaItemPathLit &);
-  void visit (AST::StructExprStruct &);
-  void visit (AST::StructExprStructFields &);
-  void visit (AST::StructExprStructBase &);
-  void visit (AST::TypeParam &);
-  void visit (AST::LifetimeWhereClauseItem &);
-  void visit (AST::TypeBoundWhereClauseItem &);
-  void visit (AST::ExternCrate &);
-  void visit (AST::UseTreeGlob &);
-  void visit (AST::UseTreeList &);
-  void visit (AST::UseTreeRebind &);
-  void visit (AST::UseDeclaration &);
-  void visit (AST::TypeAlias &);
-  void visit (AST::EnumItem &);
-  void visit (AST::EnumItemTuple &);
-  void visit (AST::EnumItemStruct 

[COMMITTED 102/144] gccrs: Fix missing error on duplicated nodes

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

When we tried to insert a shadowable node and another shadowable node has
been inserted before, we didn't emit any error if the node has already
been inserted previously and failed silently.

gcc/rust/ChangeLog:

* resolve/rust-rib.cc (Rib::insert): Emit an error when trying to
insert an already inserted node.

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

diff --git a/gcc/rust/resolve/rust-rib.cc b/gcc/rust/resolve/rust-rib.cc
index 0a8fce34a1a..714507219e0 100644
--- a/gcc/rust/resolve/rust-rib.cc
+++ b/gcc/rust/resolve/rust-rib.cc
@@ -92,9 +92,9 @@ Rib::insert (std::string name, Definition def)
{
  if (std::find (current.ids.cbegin (), current.ids.cend (), id)
  == current.ids.cend ())
-   {
- current.ids.push_back (id);
-   }
+   current.ids.push_back (id);
+ else
+   return tl::make_unexpected (DuplicateNameError (name, id));
}
 }
   else if (it->second.shadowable)
-- 
2.45.2



[COMMITTED 106/144] gccrs: Remove regular visit code

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

Regular visit code can be replaced with default visit functions.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Remove
default visit code and replace it with call to default visitor.
* resolve/rust-default-resolver.h: Remove removed function's
prototypes.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.cc | 118 +-
 gcc/rust/resolve/rust-default-resolver.h  |   8 --
 2 files changed, 3 insertions(+), 123 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 5ecea06bc6e..02617216799 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -170,17 +170,7 @@ DefaultResolver::visit (AST::ClosureExprInner &expr)
   if (expr.is_marked_for_strip ())
 return;
 
-  for (auto ¶m : expr.get_params ())
-{
-  if (param.is_error ())
-   continue;
-
-  param.get_pattern ().accept_vis (*this);
-  if (param.has_type_given ())
-   param.get_type ().accept_vis (*this);
-}
-
-  expr.get_definition_expr ().accept_vis (*this);
+  AST::DefaultASTVisitor::visit (expr);
 }
 
 void
@@ -189,63 +179,7 @@ DefaultResolver::visit (AST::ClosureExprInnerTyped &expr)
   if (expr.is_marked_for_strip ())
 return;
 
-  for (auto ¶m : expr.get_params ())
-{
-  if (param.is_error ())
-   continue;
-
-  param.get_pattern ().accept_vis (*this);
-  if (param.has_type_given ())
-   param.get_type ().accept_vis (*this);
-}
-
-  expr.get_definition_block ().accept_vis (*this);
-  expr.get_return_type ().accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::CallExpr &expr)
-{
-  expr.get_function_expr ().accept_vis (*this);
-
-  for (auto ¶m : expr.get_params ())
-param->accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::MethodCallExpr &expr)
-{
-  expr.get_receiver_expr ().accept_vis (*this);
-
-  if (expr.get_method_name ().has_generic_args ())
-{
-  auto &args = expr.get_method_name ().get_generic_args ();
-  for (auto &arg : args.get_generic_args ())
-   arg.accept_vis (*this);
-  for (auto &arg : args.get_binding_args ())
-   if (!arg.is_error ())
- arg.get_type ().accept_vis (*this);
-  for (auto &arg : args.get_lifetime_args ())
-   arg.accept_vis (*this);
-}
-
-  for (auto ¶m : expr.get_params ())
-param->accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::IfExpr &expr)
-{
-  expr.get_condition_expr ().accept_vis (*this);
-  expr.get_if_block ().accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::IfExprConseqElse &expr)
-{
-  expr.get_condition_expr ().accept_vis (*this);
-  expr.get_if_block ().accept_vis (*this);
-  expr.get_else_block ().accept_vis (*this);
+  AST::DefaultASTVisitor::visit (expr);
 }
 
 void
@@ -254,53 +188,7 @@ DefaultResolver::visit (AST::MatchExpr &expr)
   if (expr.is_marked_for_strip ())
 return;
 
-  expr.get_scrutinee_expr ().accept_vis (*this);
-  for (auto &arm : expr.get_match_cases ())
-{
-  arm.get_expr ().accept_vis (*this);
-  for (auto &pat : arm.get_arm ().get_patterns ())
-   pat->accept_vis (*this);
-  if (arm.get_arm ().has_match_arm_guard ())
-   arm.get_arm ().get_guard_expr ().accept_vis (*this);
-}
-}
-
-void
-DefaultResolver::visit (AST::PathInExpression &expr)
-{
-  for (auto &seg : expr.get_segments ())
-if (seg.has_generic_args ())
-  {
-   auto &args = seg.get_generic_args ();
-   for (auto &arg : args.get_generic_args ())
- arg.accept_vis (*this);
-   for (auto &arg : args.get_binding_args ())
- if (!arg.is_error ())
-   arg.get_type ().accept_vis (*this);
-   for (auto &arg : args.get_lifetime_args ())
- arg.accept_vis (*this);
-  }
-}
-
-void
-DefaultResolver::visit (AST::EnumItemTuple &item)
-{
-  for (auto &field : item.get_tuple_fields ())
-field.get_field_type ().accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::EnumItemStruct &item)
-{
-  for (auto &field : item.get_struct_fields ())
-field.get_field_type ().accept_vis (*this);
-}
-
-void
-DefaultResolver::visit (AST::EnumItemDiscriminant &item)
-{
-  if (item.has_expr ())
-item.get_expr ().accept_vis (*this);
+  AST::DefaultASTVisitor::visit (expr);
 }
 
 void
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 553afae77c0..9fcddd15851 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -57,17 +57,9 @@ public:
   // Visitors that visit their expression node(s)
   void visit (AST::ClosureExprInner &) override;
   void visit (AST::ClosureExprInnerTyped &) override;
-  void visit (AST::CallExpr &) override;
-  void visit (AST::MethodCallExpr &) override;
-  void visit (AST::IfExpr &) override;
-  void visit (AST::If

[COMMITTED 107/144] gccrs: Change lambda content with default visitor call

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

We can reduce code duplication by using the default visitor functions
from within the scoped lambda function.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Use
default visitor instead.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.cc | 83 ---
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 02617216799..57b1cc44815 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -30,13 +30,7 @@ DefaultResolver::visit (AST::BlockExpr &expr)
   // extracting the lambda from the `scoped` call otherwise the code looks like
   // a hot turd thanks to our .clang-format
 
-  auto inner_fn = [this, &expr] () {
-for (auto &stmt : expr.get_statements ())
-  stmt->accept_vis (*this);
-
-if (expr.has_tail_expr ())
-  expr.get_tail_expr ().accept_vis (*this);
-  };
+  auto inner_fn = [this, &expr] () { AST::DefaultASTVisitor::visit (expr); };
 
   ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
 }
@@ -44,10 +38,7 @@ DefaultResolver::visit (AST::BlockExpr &expr)
 void
 DefaultResolver::visit (AST::Module &module)
 {
-  auto item_fn = [this, &module] () {
-for (auto &item : module.get_items ())
-  item->accept_vis (*this);
-  };
+  auto item_fn = [this, &module] () { AST::DefaultASTVisitor::visit (module); 
};
 
   ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn,
  module.get_name ());
@@ -56,38 +47,8 @@ DefaultResolver::visit (AST::Module &module)
 void
 DefaultResolver::visit (AST::Function &function)
 {
-  auto def_fn = [this, &function] () {
-for (auto &p : function.get_function_params ())
-  {
-   if (p->is_variadic ())
- {
-   auto ¶m = static_cast (*p);
-   if (param.has_pattern ())
- param.get_pattern ().accept_vis (*this);
- }
-   else if (p->is_self ())
- {
-   auto ¶m = static_cast (*p);
-
-   if (param.has_type ())
- param.get_type ().accept_vis (*this);
-
-   param.get_lifetime ().accept_vis (*this);
- }
-   else
- {
-   auto ¶m = static_cast (*p);
-   param.get_pattern ().accept_vis (*this);
-   param.get_type ().accept_vis (*this);
- }
-  }
-
-if (function.has_return_type ())
-  visit (function.get_return_type ());
-
-if (function.has_body ())
-  function.get_definition ().value ()->accept_vis (*this);
-  };
+  auto def_fn
+= [this, &function] () { AST::DefaultASTVisitor::visit (function); };
 
   ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
 }
@@ -95,20 +56,14 @@ DefaultResolver::visit (AST::Function &function)
 void
 DefaultResolver::visit (AST::ForLoopExpr &expr)
 {
-  ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), [this, &expr] () {
-expr.get_pattern ().accept_vis (*this);
-expr.get_iterator_expr ().accept_vis (*this);
-expr.get_loop_block ().accept_vis (*this);
-  });
+  ctx.scoped (Rib::Kind::Normal, expr.get_node_id (),
+ [this, &expr] () { AST::DefaultASTVisitor::visit (expr); });
 }
 
 void
 DefaultResolver::visit (AST::Trait &trait)
 {
-  auto inner_fn = [this, &trait] () {
-for (auto &item : trait.get_trait_items ())
-  item->accept_vis (*this);
-  };
+  auto inner_fn = [this, &trait] () { AST::DefaultASTVisitor::visit (trait); };
 
   ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn,
  trait.get_identifier () /* FIXME: Is that valid?*/);
@@ -117,11 +72,7 @@ DefaultResolver::visit (AST::Trait &trait)
 void
 DefaultResolver::visit (AST::InherentImpl &impl)
 {
-  auto inner_fn = [this, &impl] () {
-visit (impl.get_type ());
-for (auto &item : impl.get_impl_items ())
-  item->accept_vis (*this);
-  };
+  auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
 
   ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
 }
@@ -129,10 +80,7 @@ DefaultResolver::visit (AST::InherentImpl &impl)
 void
 DefaultResolver::visit (AST::TraitImpl &impl)
 {
-  auto inner_fn = [this, &impl] () {
-for (auto &item : impl.get_impl_items ())
-  item->accept_vis (*this);
-  };
+  auto inner_fn = [this, &impl] () { AST::DefaultASTVisitor::visit (impl); };
 
   ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
 }
@@ -155,10 +103,7 @@ DefaultResolver::visit (AST::Enum &type)
 {
   // FIXME: Do we need to scope anything by default?
 
-  auto variant_fn = [this, &type] () {
-for (auto &variant : type.get_variants ())
-  variant->accept_vis (*this);
-  };
+  auto variant_fn = [this, &type] () { AST::DefaultASTVisitor::visit (type); };
 
   ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
  variant_fn

[COMMITTED 126/144] gccrs: Improve Rib::Definition shadowing

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

gcc/rust/ChangeLog:

* resolve/rust-finalize-imports-2.0.cc
(GlobbingVisitor::visit): Replace calls to insert_shadowable with
insert_globbed.
* resolve/rust-forever-stack.h
(ForeverStack::insert_globbed): Add.
* resolve/rust-forever-stack.hxx
(ForeverStack::insert_globbed): Add.
(ForeverStack::dfs): Handle modifications to Rib::Definition
fields.
* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Make IdentifierPattern-based declarations
shadowable.
* resolve/rust-name-resolution-context.cc
(NameResolutionContext::insert_globbed): Add.
* resolve/rust-name-resolution-context.h
(NameResolutionContext::insert_globbed): Add.
* resolve/rust-rib.cc
(Rib::Definition::Definition): Use Rib::Definition::Mode to
indicate shadowing mode instead of boolean, handle modifications
to Rib::Definition fields.
(Rib::Definition::is_ambiguous): Handle modifications to
Rib::Definition fields.
(Rib::Definition::to_string): Likewise.
(Rib::Definition::Shadowable): Handle changed constructor
signature.
(Rib::Definition::NonShadowable): Likewise.
(Rib::Definition::Globbed): Add.
(Rib::insert): Handle changes to Rib::Definition fields.
* resolve/rust-rib.h
(Rib::Definition::Globbed): Add.
(Rib::Definition::ids): Remove.
(Rib::Definition::ids_shadowable): Add.
(Rib::Definition::ids_non_shadowable): Add.
(Rib::Definition::ids_globbed): Add.
(Rib::Definition::get_node_id): Handle modifications to
Rib::Definition fields.
(Rib::Definition::Mode): Add.
(Rib::Definition::Definition): Use Rib::Definition::Mode to
indicate shadowing mode instead of boolean.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove shadow1.rs.

Signed-off-by: Owen Avery 
---
 gcc/rust/resolve/rust-finalize-imports-2.0.cc |  44 
 gcc/rust/resolve/rust-forever-stack.h |  16 +++
 gcc/rust/resolve/rust-forever-stack.hxx   |  24 +++-
 .../resolve/rust-late-name-resolver-2.0.cc|   4 +-
 .../resolve/rust-name-resolution-context.cc   |  18 +++
 .../resolve/rust-name-resolution-context.h|   3 +
 gcc/rust/resolve/rust-rib.cc  | 103 ++
 gcc/rust/resolve/rust-rib.h   |  30 -
 gcc/testsuite/rust/compile/nr2/exclude|   1 -
 9 files changed, 187 insertions(+), 56 deletions(-)

diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc 
b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index 5ce05a9c624..71916ae432b 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -37,32 +37,32 @@ void
 GlobbingVisitor::visit (AST::Module &module)
 {
   if (module.get_visibility ().is_public ())
-ctx.insert_shadowable (module.get_name (), module.get_node_id (),
-  Namespace::Types);
+ctx.insert_globbed (module.get_name (), module.get_node_id (),
+   Namespace::Types);
 }
 
 void
 GlobbingVisitor::visit (AST::MacroRulesDefinition ¯o)
 {
   if (macro.get_visibility ().is_public ())
-ctx.insert_shadowable (macro.get_rule_name (), macro.get_node_id (),
-  Namespace::Macros);
+ctx.insert_globbed (macro.get_rule_name (), macro.get_node_id (),
+   Namespace::Macros);
 }
 
 void
 GlobbingVisitor::visit (AST::Function &function)
 {
   if (function.get_visibility ().is_public ())
-ctx.insert_shadowable (function.get_function_name (),
-  function.get_node_id (), Namespace::Values);
+ctx.insert_globbed (function.get_function_name (), function.get_node_id (),
+   Namespace::Values);
 }
 
 void
 GlobbingVisitor::visit (AST::StaticItem &static_item)
 {
   if (static_item.get_visibility ().is_public ())
-ctx.insert_shadowable (static_item.get_identifier (),
-  static_item.get_node_id (), Namespace::Values);
+ctx.insert_globbed (static_item.get_identifier (),
+   static_item.get_node_id (), Namespace::Values);
 }
 
 void
@@ -70,11 +70,11 @@ GlobbingVisitor::visit (AST::StructStruct &struct_item)
 {
   if (struct_item.get_visibility ().is_public ())
 {
-  ctx.insert_shadowable (struct_item.get_identifier (),
-struct_item.get_node_id (), Namespace::Types);
+  ctx.insert_globbed (struct_item.get_identifier (),
+ struct_item.get_node_id (), Namespace::Types);
   if (struct_item.is_unit_struct ())
-   ctx.insert_shadowable (struct_item.get_identifier (),
-  struct_item.get_node_id (), Namespace::Values);
+   ctx.insert_globbed (struct_item.get_identifier (),
+   struct_item.get_node_id (), Name

[COMMITTED 123/144] gccrs: add test case to show impl block on ! works

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

The resolution with ! was fixed in: 09cfe530f9c this adds a
test case to show the other issue is also fixed.

Fixes #2951

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: nr2 is crashing here
* rust/compile/issue-2951.rs: New test.

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

diff --git a/gcc/testsuite/rust/compile/issue-2951.rs 
b/gcc/testsuite/rust/compile/issue-2951.rs
new file mode 100644
index 000..d30a3bf2adf
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2951.rs
@@ -0,0 +1,13 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "clone"]
+pub trait Clone: Sized {
+fn clone(&self) -> Self;
+}
+
+impl Clone for ! {
+fn clone(&self) -> Self {
+*self
+}
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 50781e56b85..c30af607edb 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -253,3 +253,4 @@ issue-3139-1.rs
 issue-3139-2.rs
 issue-3139-3.rs
 issue-3036.rs
+issue-2951.rs
-- 
2.45.2



[COMMITTED 130/144] gccrs: Insert static items into the value namespace

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

gcc/rust/ChangeLog:

* backend/rust-compile-item.cc
(CompileItem::visit): Check canonical path of StaticItem
properly when name resolution 2.0 is enabled.
* resolve/rust-toplevel-name-resolver-2.0.cc
(TopLevel::visit): Insert static items into the value namespace.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index c0cac686e8d..08787163c2a 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -42,8 +42,23 @@ CompileItem::visit (HIR::StaticItem &var)
 
   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
 
-  auto canonical_path = ctx->get_mappings ().lookup_canonical_path (
-var.get_mappings ().get_nodeid ());
+  tl::optional canonical_path;
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  canonical_path
+   = nr_ctx.values.to_canonical_path (var.get_mappings ().get_nodeid ());
+}
+  else
+{
+  canonical_path = ctx->get_mappings ().lookup_canonical_path (
+   var.get_mappings ().get_nodeid ());
+}
+
+  rust_assert (canonical_path.has_value ());
 
   HIR::Expr *const_value_expr = var.get_expr ().get ();
   ctx->push_const_context ();
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 b0e0c1b52dc..d3a3c5d78bc 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -248,6 +248,9 @@ TopLevel::visit (AST::StaticItem &static_item)
 = [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,
+  Namespace::Values);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 1faa7b53622..166977e7bac 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -100,8 +100,6 @@ issue-2139.rs
 issue-2142.rs
 issue-2165.rs
 issue-2166.rs
-issue-2178.rs
-issue-2188.rs
 issue-2190-1.rs
 issue-2190-2.rs
 issue-2195.rs
-- 
2.45.2



[COMMITTED 129/144] gccrs: Rework InlineAsmOperand

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

Not thrilled with some of this boilerplate, but it does seem like an
improvement.

gcc/rust/ChangeLog:

* ast/rust-expr.h
(InlineAsmOperand): Replace multiple mutually-exclusive tl::optional
fields with a std::unique_ptr and modify nested classes to allow
this. Also, make getters return references where possible.
* expand/rust-macro-builtins-asm.cc
(parse_reg_operand_out): Pass location when constructing
InlineAsmOperand.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-expr.h   | 183 +
 gcc/rust/expand/rust-macro-builtins-asm.cc |   3 +-
 2 files changed, 150 insertions(+), 36 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 749fdc05f2b..438d3d3b86e 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4771,7 +4771,7 @@ struct InlineAsmRegOrRegClass
 class InlineAsmOperand
 {
 public:
-  enum RegisterType
+  enum class RegisterType
   {
 In,
 Out,
@@ -4782,8 +4782,24 @@ public:
 Label,
   };
 
-  struct In
+  class Register
   {
+  public:
+Register () {}
+virtual ~Register () = default;
+
+std::unique_ptr clone () const
+{
+  return std::unique_ptr (clone_impl ());
+}
+
+  protected:
+virtual Register *clone_impl () const = 0;
+  };
+
+  class In : public Register
+  {
+  public:
 tl::optional reg;
 std::unique_ptr expr;
 
@@ -4808,10 +4824,14 @@ public:
 
   return *this;
 }
+
+  private:
+In *clone_impl () const { return new In (*this); }
   };
 
-  struct Out
+  class Out : public Register
   {
+  public:
 tl::optional reg;
 bool late;
 std::unique_ptr expr; // can be null
@@ -4837,10 +4857,14 @@ public:
   expr = other.expr->clone_expr ();
   return *this;
 }
+
+  private:
+Out *clone_impl () const { return new Out (*this); }
   };
 
-  struct InOut
+  class InOut : public Register
   {
+  public:
 tl::optional reg;
 bool late;
 std::unique_ptr expr; // this can't be null
@@ -4867,10 +4891,14 @@ public:
 
   return *this;
 }
+
+  private:
+InOut *clone_impl () const { return new InOut (*this); }
   };
 
-  struct SplitInOut
+  class SplitInOut : public Register
   {
+  public:
 tl::optional reg;
 bool late;
 std::unique_ptr in_expr;
@@ -4902,15 +4930,23 @@ public:
 
   return *this;
 }
+
+  private:
+SplitInOut *clone_impl () const { return new SplitInOut (*this); }
   };
 
-  struct Const
+  class Const : public Register
   {
+  public:
 AnonConst anon_const;
+
+  private:
+Const *clone_impl () const { return new Const (*this); }
   };
 
-  struct Sym
+  class Sym : public Register
   {
+  public:
 std::unique_ptr expr;
 
 Sym (std::unique_ptr expr) : expr (std::move (expr))
@@ -4927,10 +4963,14 @@ public:
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
 }
+
+  private:
+Sym *clone_impl () const { return new Sym (*this); }
   };
 
-  struct Label
+  class Label : public Register
   {
+  public:
 std::string label_name;
 std::unique_ptr expr;
 
@@ -4951,27 +4991,37 @@ public:
   expr = std::unique_ptr (other.expr->clone_expr ());
   return *this;
 }
+
+  private:
+Label *clone_impl () const { return new Label (*this); }
   };
 
   InlineAsmOperand (const InlineAsmOperand &other)
-: register_type (other.register_type), in (other.in), out (other.out),
-  in_out (other.in_out), split_in_out (other.split_in_out),
-  cnst (other.cnst), sym (other.sym)
+: register_type (other.register_type), locus (other.locus),
+  reg (other.reg->clone ())
   {}
 
-  InlineAsmOperand (const struct In ®) : register_type (In), in (reg) {}
-  InlineAsmOperand (const struct Out ®) : register_type (Out), out (reg) {}
-  InlineAsmOperand (const struct InOut ®)
-: register_type (InOut), in_out (reg)
+  InlineAsmOperand (const In ®, location_t locus)
+: register_type (RegisterType::In), locus (locus), reg (new In (reg))
+  {}
+  InlineAsmOperand (const Out ®, location_t locus)
+: register_type (RegisterType::Out), locus (locus), reg (new Out (reg))
+  {}
+  InlineAsmOperand (const InOut ®, location_t locus)
+: register_type (RegisterType::InOut), locus (locus), reg (new InOut (reg))
+  {}
+  InlineAsmOperand (const SplitInOut ®, location_t locus)
+: register_type (RegisterType::SplitInOut), locus (locus),
+  reg (new SplitInOut (reg))
   {}
-  InlineAsmOperand (const struct SplitInOut ®)
-: register_type (SplitInOut), split_in_out (reg)
+  InlineAsmOperand (const Const ®, location_t locus)
+: register_type (RegisterType::Const), locus (locus), reg (new Const (reg))
   {}
-  InlineAsmOperand (const struct Const ®) : register_type (Const), cnst 
(reg)
+  InlineAsmOperand (const Sym ®, location_t locus)
+: register_type (RegisterType::Sym), locus (locus), reg (new Sym (reg))
   {}
-  InlineAsmOperand 

[COMMITTED 051/144] gccrs: Move strip double quotes, add scaffold expand

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (strip_double_quotes):
Move strip double quotes to parse phase
(CompileAsm::asm_construct_string_tree): Likewise
* backend/rust-compile-asm.h (strip_double_quotes): Likewise
* expand/rust-macro-builtins-asm.cc (strip_double_quotes):
Likewise
(expand_inline_asm): Renamed to expand_inline_asm_strings
(expand_inline_asm_strings): Renamed from expand_inline_asm
(parse_asm): Move strip double quotes to parse phase
(parse_format_strings): Likewise
* expand/rust-macro-builtins-asm.h (strip_double_quotes):
Likewise
(expand_inline_asm_strings): Inline asm expansion fn
(expand_inline_asm_string): Inline asm expansion fn
---
 gcc/rust/backend/rust-compile-asm.cc   | 16 +
 gcc/rust/backend/rust-compile-asm.h|  3 --
 gcc/rust/expand/rust-macro-builtins-asm.cc | 40 --
 gcc/rust/expand/rust-macro-builtins-asm.h  |  9 +
 4 files changed, 39 insertions(+), 29 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 9305a9088bb..30a8cacf203 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,22 +1,8 @@
 #include "rust-compile-asm.h"
-
 #include "rust-system.h"
 namespace Rust {
 namespace Compile {
 
-std::string
-strip_double_quotes (const std::string &str)
-{
-  // Helper function strips the beginning and ending double quotes from a
-  // string.
-  std::string result = str;
-
-  rust_assert (result.size () >= 3);
-  result.erase (0, 1);
-  result.erase (result.size () - 1, 1);
-  return result;
-}
-
 CompileAsm::CompileAsm (Context *ctx)
   : HIRCompileBase (ctx), translated (error_mark_node)
 {}
@@ -86,7 +72,7 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
   // debugging and reading)
   std::stringstream ss;
   for (const auto &template_str : expr.template_strs)
-ss << strip_double_quotes (template_str.symbol) << "\n\t";
+ss << template_str.symbol << "\n\t";
 
   std::string result = ss.str ();
   return build_string (result.size () + 1, result.c_str ());
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 8307d895bd5..05bb99ab40d 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -26,9 +26,6 @@
 namespace Rust {
 namespace Compile {
 
-std::string
-strip_double_quotes (const std::string &);
-
 class CompileAsm : private HIRCompileBase, protected HIR::HIRExpressionVisitor
 {
 private:
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index bbb8fff180f..379e5d8b967 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -742,26 +742,42 @@ parse_asm_arg (InlineAsmContext inline_asm_ctx)
   return tl::expected (inline_asm_ctx);
 }
 
+std::string
+strip_double_quotes (const std::string &str)
+{
+  // Helper function strips the beginning and ending double quotes from a
+  // string.
+  std::string result = str;
+
+  rust_assert (result.size () >= 3);
+  result.erase (0, 1);
+  result.erase (result.size () - 1, 1);
+  return result;
+}
+
 tl::expected
-expand_inline_asm (InlineAsmContext &inline_asm_ctx)
+expand_inline_asm_strings (InlineAsmContext &inline_asm_ctx)
 {
   auto &inline_asm = inline_asm_ctx.inline_asm;
 
   auto str_vec = inline_asm.get_template_strs ();
   for (auto &template_str : str_vec)
 {
-  std::cout << template_str.symbol << std::endl;
+  /*std::cout << template_str.symbol << std::endl;*/
 
   auto pieces = Fmt::Pieces::collect (template_str.symbol, false,
- Fmt::ffi::ParseMode::Format)
- .get_pieces ();
+ Fmt::ffi::ParseMode::InlineAsm);
+  auto pieces_vec = pieces.get_pieces ();
 
-  for (size_t i = 0; i < pieces.size (); i++)
+  for (size_t i = 0; i < pieces_vec.size (); i++)
{
- auto piece = pieces[i];
+ auto piece = pieces_vec[i];
  if (piece.tag == Fmt::ffi::Piece::Tag::String)
-   std::cout << "   " << i << ": " << piece.string._0.to_string ()
- << std::endl;
+   {
+   }
+ /*std::cout << "   " << i << ": " << piece.string._0.to_string
+  * ()*/
+ /*   << std::endl;*/
}
 }
 
@@ -798,7 +814,7 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData 
&invoc,
   auto is_valid = (bool) resulting_context;
   if (is_valid)
 {
-  expand_inline_asm (resulting_context.value ());
+  expand_inline_asm_strings (*resulting_context);
 }
   if (is_valid)
 {
@@ -846,7 +862,8 @@ parse_format_strings (InlineAsmContext inline_asm_ctx)
   else
 {
   auto template_str
-   = AST::TupleTemplateStr (token->get_locu

[Bug rust/119353] [15 regression] Rust fails to build (build failure: error[E0554]: `#![feature]` may not be used on the stable release channel)

2025-03-19 Thread ebotcazou at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119353

Eric Botcazou  changed:

   What|Removed |Added

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

--- Comment #11 from Eric Botcazou  ---
Confirmed, thanks for the quick turnaround.

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

[COMMITTED 003/144] gccrs: [gccrs#3045] #[may_dangle] in safe impl

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

gcc/rust/ChangeLog:
* ast/rust-ast.cc:
Fix Attribute constructors to copy inner_attribute
* checks/errors/rust-unsafe-checker.cc:
Add pass for #[may_dangle] in safe impl's
* hir/rust-ast-lower-item.cc:
Add support for unsafe impl's
* hir/rust-ast-lower-type.cc:
Lower attributes in impl's from AST to HIR
* hir/rust-hir-dump.cc:
Change single attribute to AttrVec
* hir/tree/rust-hir-item.h:
Add unsafe support to Impl blocks in HIR
* hir/tree/rust-hir.cc:
Change single attribute to AttrVec
* hir/tree/rust-hir.h:
Add has/get_outer_attribute to GenericParam

gcc/testsuite/ChangeLog:
* rust/compile/issue-3045-1.rs:
Add test for #[may_dangle] Generic Type triggering error
* rust/compile/issue-3045-2.rs:
Add test for #[may_dangle] Lifetime triggering error

Signed-off-by: Liam Naddell 
---
 gcc/rust/ast/rust-ast.cc  |  4 ++-
 gcc/rust/checks/errors/rust-unsafe-checker.cc | 18 -
 gcc/rust/hir/rust-ast-lower-item.cc   |  5 ++--
 gcc/rust/hir/rust-ast-lower-type.cc   | 14 +-
 gcc/rust/hir/rust-hir-dump.cc |  3 ++-
 gcc/rust/hir/tree/rust-hir-item.h | 26 ++-
 gcc/rust/hir/tree/rust-hir.cc | 22 +++-
 gcc/rust/hir/tree/rust-hir.h  | 26 +--
 gcc/testsuite/rust/compile/issue-3045-1.rs| 21 +++
 gcc/testsuite/rust/compile/issue-3045-2.rs| 20 ++
 10 files changed, 122 insertions(+), 37 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3045-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3045-2.rs

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index bf7d31d8676..1d52352daaa 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -311,7 +311,8 @@ Attribute::get_traits_to_derive ()
 
 // Copy constructor must deep copy attr_input as unique pointer
 Attribute::Attribute (Attribute const &other)
-  : path (other.path), locus (other.locus)
+  : path (other.path), locus (other.locus),
+inner_attribute (other.inner_attribute)
 {
   // guard to protect from null pointer dereference
   if (other.attr_input != nullptr)
@@ -324,6 +325,7 @@ Attribute::operator= (Attribute const &other)
 {
   path = other.path;
   locus = other.locus;
+  inner_attribute = other.inner_attribute;
   // guard to protect from null pointer dereference
   if (other.attr_input != nullptr)
 attr_input = other.attr_input->clone_attr_input ();
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index c6ed9221565..4c8db3a554e 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -784,7 +784,23 @@ UnsafeChecker::visit (Trait &trait)
 void
 UnsafeChecker::visit (ImplBlock &impl)
 {
-  // FIXME: Handle unsafe impls
+  bool safe = !impl.is_unsafe ();
+  // Check for unsafe-only attributes on generics and lifetimes
+  if (safe)
+for (auto &parm : impl.get_generic_params ())
+  {
+   for (auto o_attr : parm->get_outer_attrs ())
+ {
+   rust_assert (!o_attr.is_inner_attribute ());
+
+   Rust::AST::SimplePath path = o_attr.get_path ();
+   if (path == Values::Attributes::MAY_DANGLE)
+ rust_error_at (
+   o_attr.get_locus (), ErrorCode::E0569,
+   "use of % is unsafe and requires unsafe impl");
+ }
+  }
+
   for (auto &item : impl.get_impl_items ())
 item->accept_vis (*this);
 }
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc 
b/gcc/rust/hir/rust-ast-lower-item.cc
index 25345ce7589..0ef4f357c8e 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -542,7 +542,7 @@ ASTLoweringItem::visit (AST::InherentImpl &impl_block)
 mapping, std::move (impl_items), std::move (generic_params),
 std::unique_ptr (impl_type), nullptr, where_clause, polarity,
 vis, impl_block.get_inner_attrs (), impl_block.get_outer_attrs (),
-impl_block.get_locus ());
+impl_block.get_locus (), false);
   translated = hir_impl_block;
 
   mappings.insert_hir_impl_block (hir_impl_block);
@@ -623,6 +623,7 @@ void
 ASTLoweringItem::visit (AST::TraitImpl &impl_block)
 {
   std::vector> where_clause_items;
+  bool unsafe = impl_block.is_unsafe ();
   for (auto &item : impl_block.get_where_clause ().get_items ())
 {
   HIR::WhereClauseItem *i = ASTLowerWhereClauseItem::translate (*item);
@@ -696,7 +697,7 @@ ASTLoweringItem::visit (AST::TraitImpl &impl_block)
 std::unique_ptr (impl_type),
 std::unique_ptr (trait_ref), where_clause, polarity, vis,
 impl_block.get_inner_attrs (), impl_block.get_outer_attrs (),
-impl_block.get_locus ());
+impl_block.get_locus (), unsafe);
   translated = hir

[COMMITTED 005/144] gccrs: ffi-polonius: Remove usage of extern types.

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

This will allow us to revert our dependency on extern types, which would
help our godbolt build as well as our various builders.

gcc/rust/ChangeLog:

* checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs: Remove extern
type feature.
* checks/errors/borrowck/ffi-polonius/src/lib.rs: Define FFIVector
per the nomicon's recommendation
https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
---
 .../errors/borrowck/ffi-polonius/src/gccrs_ffi.rs | 11 ---
 .../checks/errors/borrowck/ffi-polonius/src/lib.rs|  2 --
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
index 0cb85078158..7377e3aaf85 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/gccrs_ffi.rs
@@ -30,11 +30,16 @@
 // ```
 include!("gccrs_ffi_generated.rs");
 
+use std::marker::{PhantomData, PhantomPinned};
+
 use crate::GccrsAtom;
 
-// Using opqaue types
-extern "C" {
-pub type FFIVector;
+// We define an opaque C type per the nomicon's recommendation:
+// https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
+#[repr(C)]
+pub struct FFIVector {
+_empty: [u8; 0],
+marker: PhantomData<(*mut u8, PhantomPinned)>,
 }
 
 impl Into<(GccrsAtom, GccrsAtom)> for Pair
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs
index 782a63f8078..c5c0ae9756e 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/src/lib.rs
@@ -16,8 +16,6 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
-#![feature(extern_types)]
-
 mod gccrs_ffi;
 
 use gccrs_ffi::FFIVector;
-- 
2.45.2



[PATCHSET] Update Rust frontend 19/03/2024 2/4

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

This is the second of the patchsets we plan on upstreaming in the coming
days. This one notably contains the commit which fixes PR119353, which
had not yet been upstreamed but was present in our development repo for
a while. We will continue working on improving our support for all
distributions when it comes to our Rust code, and plan on finishing
downgrading our minimum Rust version to 1.49 in time for GCC 15.1. This
will also enable gccrs to compile its own Rust component once it becomes
more mature.

This patchset contains multiple additions to the borrow-checker, handling
for a lot of required attributes used in Rust's `core` crate, more
additions to our handling of inline assembly, and multiple type-system
fixes.

Thanks again for all the testing and bug reports. We'll keep on
investigating the failures found with the last patchset.

Best regards,

Arthur


[COMMITTED 002/144] gccrs: Add rustc test directory for testsuite adaptor

2025-03-19 Thread arthur . cohen
From: Muhammad Mahad 

gcc/testsuite/ChangeLog:

* rust/rustc/README.md: information about
rustc external directory.
* rust/rustc/rustc.exp: New test.

Signed-off-by: Muhammad Mahad 
---
 gcc/testsuite/rust/rustc/README.md |  4 
 gcc/testsuite/rust/rustc/rustc.exp | 35 ++
 2 files changed, 39 insertions(+)
 create mode 100644 gcc/testsuite/rust/rustc/README.md
 create mode 100644 gcc/testsuite/rust/rustc/rustc.exp

diff --git a/gcc/testsuite/rust/rustc/README.md 
b/gcc/testsuite/rust/rustc/README.md
new file mode 100644
index 000..ddf4d95e9a8
--- /dev/null
+++ b/gcc/testsuite/rust/rustc/README.md
@@ -0,0 +1,4 @@
+This repository contains test cases from the 
+[rustc test suite](https://github.com/rust-lang/rust/tree/master/tests). The
+conversion of these tests into the DejaGnu format is done by the rustc 
+testsuite adaptor, a tool specifically designed for this purpose.
diff --git a/gcc/testsuite/rust/rustc/rustc.exp 
b/gcc/testsuite/rust/rustc/rustc.exp
new file mode 100644
index 000..ac891db246e
--- /dev/null
+++ b/gcc/testsuite/rust/rustc/rustc.exp
@@ -0,0 +1,35 @@
+# Copyright (C) 2021-2024 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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
+# .
+
+# Compile tests, no torture testing.
+#
+# These tests raise errors in the front end; torture testing doesn't apply.
+
+# Load support procs.
+load_lib rust-dg.exp
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set saved-dg-do-what-default ${dg-do-what-default}
+
+set dg-do-what-default "compile"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" ""
+set dg-do-what-default ${saved-dg-do-what-default}
+
+# All done.
+dg-finish
-- 
2.45.2



[COMMITTED 009/144] gccrs: Fix the parser's operand and flags storage

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct InlineAsmOperand):
Add construction for register_type
* expand/rust-macro-builtins-asm.cc (parse_reg_operand):
Fix parsing logic & reassignment logic
(parse_reg_operand_in): Fix parsing
(parse_reg_operand_out): Fix parsing
(parse_reg_operand_inout): Fix parsing
(parse_reg_operand_unexpected): Remove rust_unreachable()
(parse_asm_arg): Fix parsing logic
* expand/rust-macro-builtins-asm.h: Add = operator overloading

gcc/testsuite/ChangeLog:

* rust/compile/inline_asm_illegal_operands.rs: Test now passing
* rust/compile/inline_asm_parse_operand.rs: Remove _, not
supported right now
---
 gcc/rust/ast/rust-expr.h  |  5 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc| 63 +--
 gcc/rust/expand/rust-macro-builtins-asm.h | 10 ++-
 .../compile/inline_asm_illegal_operands.rs|  6 +-
 .../rust/compile/inline_asm_parse_operand.rs  |  4 +-
 5 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9477bf06d6c..8a3baf7ca2b 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4964,8 +4964,9 @@ struct InlineAsmOperand
 
   InlineAsmOperand () {}
   InlineAsmOperand (const InlineAsmOperand &other)
-: in (other.in), out (other.out), in_out (other.in_out),
-  split_in_out (other.split_in_out), cnst (other.cnst), sym (other.sym)
+: register_type (other.register_type), in (other.in), out (other.out),
+  in_out (other.in_out), split_in_out (other.split_in_out),
+  cnst (other.cnst), sym (other.sym)
   {}
 
   void set_in (const tl::optional ®)
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 214265d63a8..d270621d1bf 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -227,20 +227,28 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   // Loop over and execute the parsing functions, if the parser successfullly
   // parses or if the parser fails to parse while it has committed to a token,
   // we propogate the result.
+  tl::expected parsing_operand (
+inline_asm_ctx);
   for (auto &parse_func : parse_funcs)
 {
-  auto parsing_operand
-   = tl::expected (inline_asm_ctx);
-  parsing_operand.map (parse_func);
+  auto result = parsing_operand.and_then (parse_func);
 
   // Per rust's asm.rs's structure
   // After we've parse successfully, we break out and do a local validation
   // of named, positional & explicit register operands
 
-  if (parsing_operand.has_value ())
-   break;
-  if (parsing_operand.error () == COMMITTED)
-   return parsing_operand;
+  if (result.has_value ())
+   {
+ //
+ inline_asm_ctx = *result;
+ break;
+   }
+  else if (result.error () == COMMITTED
+  && parse_func != parse_reg_operand_unexpected)
+   return result;
+  else if (result.error () == COMMITTED
+  && parse_func == parse_reg_operand_unexpected)
+   return inline_asm_ctx;
 }
 
   auto &inline_asm = inline_asm_ctx.inline_asm;
@@ -303,7 +311,7 @@ parse_reg_operand_in (InlineAsmContext inline_asm_ctx)
  return tl::unexpected (COMMITTED);
}
 
-  auto expr = parse_format_string (inline_asm_ctx);
+  auto expr = parser.parse_expr ();
 
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
@@ -323,14 +331,19 @@ parse_reg_operand_out (InlineAsmContext inline_asm_ctx)
   if (!inline_asm_ctx.is_global_asm () && check_identifier (parser, "out"))
 {
   auto reg = parse_reg (inline_asm_ctx);
+  std::unique_ptr expr = parser.parse_expr ();
 
-  auto expr = parse_format_string (inline_asm_ctx);
+  rust_assert (expr != nullptr);
+
+  /*auto expr_ptr =
+std::make_unique(AST::LiteralExpr(Literal))*/
 
   // TODO: When we've succesfully parse an expr, remember to clone_expr()
   // instead of nullptr
-  //  struct AST::InlineAsmOperand::Out out (reg, false, nullptr);
-  //  reg_operand.set_out (out);
-  //  inline_asm_ctx.inline_asm.operands.push_back (reg_operand);
+  struct AST::InlineAsmOperand::Out out (reg, false, std::move (expr));
+
+  reg_operand.set_out (out);
+  inline_asm_ctx.inline_asm.operands.push_back (reg_operand);
 
   return inline_asm_ctx;
 }
@@ -378,7 +391,10 @@ parse_reg_operand_inout (InlineAsmContext inline_asm_ctx)
   // TODO: Is error propogation our top priority, the ? in rust's asm.rs is
   // doing a lot of work.
   // TODO: Not sure how to use parse_expr
-  auto expr = parse_format_string (inline_asm_ctx);
+  auto exist_ident1 = check_identifier (parser, "");
+  if (!exist_ident1)
+   ru

[COMMITTED 001/144] gccrs: Properly striping struct fields when using attrs

2025-03-19 Thread arthur . cohen
From: Antonio Gomes 

gcc/rust/ChangeLog:
* expand/rust-cfg-strip.cc:
Strip struct expr fields and strip fields in struct definition
* expand/rust-cfg-strip.h:
Signatures for new function maybe_strip_struct_expr_fields

gcc/testsuite/ChangeLog:
* rust/compile/macro-issue2983_2984.rs:
Add test to check for correct stripped fields

Signed-off-by: Antonio Gomes 
---
 gcc/rust/expand/rust-cfg-strip.cc | 26 ++
 gcc/rust/expand/rust-cfg-strip.h  |  2 ++
 .../rust/compile/macro-issue2983_2984.rs  | 27 +++
 3 files changed, 55 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/macro-issue2983_2984.rs

diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index 8abc5cb766e..4e6a8ac2b5f 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -194,6 +194,26 @@ CfgStrip::maybe_strip_struct_fields 
(std::vector &fields)
 }
 }
 
+void
+CfgStrip::maybe_strip_struct_expr_fields (
+  std::vector> &fields)
+{
+  for (auto it = fields.begin (); it != fields.end ();)
+{
+  auto &field = *it;
+
+  auto &field_attrs = field->get_outer_attrs ();
+  expand_cfg_attrs (field_attrs);
+  if (fails_cfg_with_expand (field_attrs))
+   {
+ it = fields.erase (it);
+ continue;
+   }
+
+  ++it;
+}
+}
+
 void
 CfgStrip::maybe_strip_tuple_fields (std::vector &fields)
 {
@@ -962,6 +982,8 @@ CfgStrip::visit (AST::StructExprStructFields &expr)
   "cannot strip expression in this position - outer "
   "attributes not allowed");
 }
+
+  maybe_strip_struct_expr_fields (expr.get_fields ());
 }
 
 void
@@ -1852,6 +1874,10 @@ CfgStrip::visit (AST::StructStruct &struct_item)
 }
 
   AST::DefaultASTVisitor::visit (struct_item);
+
+  /* strip struct fields if required - this is presumably
+   * allowed by spec */
+  maybe_strip_struct_fields (struct_item.get_fields ());
 }
 void
 CfgStrip::visit (AST::TupleStruct &tuple_struct)
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 773bfdeaf8c..4900ae893ed 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -36,6 +36,8 @@ public:
   void go (AST::Crate &crate);
 
   void maybe_strip_struct_fields (std::vector &fields);
+  void maybe_strip_struct_expr_fields (
+std::vector> &fields);
   void maybe_strip_tuple_fields (std::vector &fields);
   void maybe_strip_function_params (
 std::vector> ¶ms);
diff --git a/gcc/testsuite/rust/compile/macro-issue2983_2984.rs 
b/gcc/testsuite/rust/compile/macro-issue2983_2984.rs
new file mode 100644
index 000..637d5728c50
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue2983_2984.rs
@@ -0,0 +1,27 @@
+pub struct ReadDir {
+pub inner: i32,
+#[cfg(not(A))]
+pub end_of_stream: bool,
+#[cfg(A)]
+pub end_of_stream_but_different: bool,
+}
+
+fn main() {
+// Success
+let _ = ReadDir {
+inner: 14,
+#[cfg(not(A))]
+end_of_stream: false,
+#[cfg(A)]
+end_of_stream_but_different: false,
+};
+
+// Error
+let _ = ReadDir {
+inner: 14,
+end_of_stream: false,
+end_of_stream_but_different: false, // { dg-error "failed to resolve 
type for field" }
+// { dg-error "unknown field" "" { target *-*-* } .-1 }
+// { dg-prune-output "compilation terminated" }
+};
+}
-- 
2.45.2



[COMMITTED 109/144] gccrs: Make AST default visitor visit functions public

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

Make those functions public so they can be used within a lambda on GCC
4.8.

gcc/rust/ChangeLog:

* ast/rust-ast-visitor.h: Make visit functions public.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-ast-visitor.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 56fea88a061..50b93016d62 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -244,7 +244,6 @@ class DefaultASTVisitor : public ASTVisitor
 public:
   virtual void visit (AST::Crate &crate);
 
-protected:
   virtual void visit (AST::Token &tok) override;
   virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
   virtual void visit (AST::AttrInputMetaItemContainer &input) override;
-- 
2.45.2



[COMMITTED 093/144] gccrs: toplevel: Build list of imports for Early to resolve

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

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc: Comment out handle_use
call and error emission.
* resolve/rust-toplevel-name-resolver-2.0.h: Create ImportKind class.
---
 .../rust-toplevel-name-resolver-2.0.cc| 37 +++-
 .../resolve/rust-toplevel-name-resolver-2.0.h | 59 +++
 2 files changed, 81 insertions(+), 15 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 b18b86ca821..3ce16307508 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -749,21 +749,28 @@ TopLevel::visit (AST::UseDeclaration &use)
   const auto &tree = use.get_tree ();
   flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
 
-  for (auto &path : paths)
-if (!handle_use_dec (path))
-  rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-"unresolved import %qs", path.as_string ().c_str ());
-
-  for (auto &glob : glob_path)
-if (!handle_use_glob (glob))
-  rust_error_at (glob.get_final_segment ().get_locus (), ErrorCode::E0433,
-"unresolved import %qs", glob.as_string ().c_str ());
-
-  for (auto &rebind : rebind_path)
-if (!handle_rebind (rebind))
-  rust_error_at (rebind.first.get_final_segment ().get_locus (),
-ErrorCode::E0433, "unresolved import %qs",
-rebind.first.as_string ().c_str ());
+  for (auto &&path : paths)
+imports_to_resolve.emplace_back (ImportKind::Simple (std::move (path)));
+
+  // if (!handle_use_dec (path))
+  //   rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
+  //"unresolved import %qs", path.as_string ().c_str ());
+
+  for (auto &&glob : glob_path)
+imports_to_resolve.emplace_back (ImportKind::Glob (std::move (glob)));
+
+  // if (!handle_use_glob (glob))
+  //   rust_error_at (glob.get_final_segment ().get_locus (), ErrorCode::E0433,
+  //"unresolved import %qs", glob.as_string ().c_str ());
+
+  for (auto &&rebind : rebind_path)
+imports_to_resolve.emplace_back (
+  ImportKind::Rebind (std::move (rebind.first), std::move 
(rebind.second)));
+
+  // if (!handle_rebind (rebind))
+  //   rust_error_at (rebind.first.get_final_segment ().get_locus (),
+  //ErrorCode::E0433, "unresolved import %qs",
+  //rebind.first.as_string ().c_str ());
 }
 
 } // namespace Resolver2_0
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 affddb97d50..12c85c86a81 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -19,7 +19,10 @@
 #ifndef RUST_TOPLEVEL_NAME_RESOLVER_2_0_H
 #define RUST_TOPLEVEL_NAME_RESOLVER_2_0_H
 
+#include "optional.h"
 #include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-item.h"
 #include "rust-name-resolution-context.h"
 #include "rust-default-resolver.h"
 
@@ -87,6 +90,62 @@ private:
   // definition and its new local name.
   std::unordered_map node_forwarding;
 
+  // Each import will be transformed into an instance of `ImportKind`, a class
+  // representing some of the data we need to resolve in the
+  // `EarlyNameResolver`. Basically, for each `UseTree` that we see in
+  // `TopLevel`, create one of these. `TopLevel` should build a list of these
+  // `ImportKind`s, which `Early` can then resolve to their proper definitions.
+  // Then, a final pass will insert the definitions into the `ForeverStack` -
+  // `FinalizeImports`.
+  //
+  // Using this struct should be very simple - each path within a `UseTree`
+  // becomes one `ImportKind`. The complex case is glob imports, in which case
+  // one glob import will become one `ImportKind` which will later become
+  // multiple definitions thanks to the `GlobbingVisitor`.
+  struct ImportKind
+  {
+enum class Kind
+{
+  Glob,
+  Simple,
+  Rebind,
+} kind;
+
+static ImportKind Glob (AST::SimplePath &&to_resolve)
+{
+  return ImportKind (Kind::Glob, std::move (to_resolve));
+}
+
+static ImportKind Simple (AST::SimplePath &&to_resolve)
+{
+  return ImportKind (Kind::Simple, std::move (to_resolve));
+}
+
+static ImportKind Rebind (AST::SimplePath &&to_resolve,
+ AST::UseTreeRebind &&rebind)
+{
+  return ImportKind (Kind::Rebind, std::move (to_resolve),
+std::move (rebind));
+}
+
+// The path for `Early` to resolve.
+AST::SimplePath to_resolve;
+
+// The path to rebind an import to - only present if kind is Kind::Rebind
+tl::optional rebind;
+
+  private:
+ImportKind (Kind kind, AST::SimplePath &&to_resolve,
+   tl::optional &&rebind = tl::nullopt)
+  : kind (kind), to_resolve (std::move (to_resolve)

[COMMITTED 113/144] gccrs: Update exclude list with working tests

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

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove working tests from nr2 exclude list.

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

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 3412617f7eb..695da317cf0 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -3,7 +3,6 @@
 debug-diagnostics-on.rs
 
 # main list
-all-cast.rs
 attr-mismatch-crate-name.rs
 attr_deprecated.rs
 attr_deprecated_2.rs
@@ -11,13 +10,9 @@ auto_trait_super_trait.rs
 auto_trait_valid.rs
 auto_trait_invalid.rs
 bad=file-name.rs
-bad_type2.rs
 bounds1.rs
-break-rust1.rs
 break-rust2.rs
 break-rust3.rs
-break2.rs
-break_with_value_inside_loop.rs
 macros/builtin/eager1.rs
 macros/builtin/eager2.rs
 macros/builtin/recurse2.rs
@@ -35,14 +30,9 @@ complex_qualified_path_in_expr.rs
 const-issue1440.rs
 const1.rs
 const3.rs
-const4.rs
-const8.rs
-const9.rs
-const_generics_1.rs
 const_generics_3.rs
 const_generics_4.rs
 const_generics_5.rs
-const_generics_6.rs
 const_generics_7.rs
 const_generics_8.rs
 derive_empty.rs
@@ -51,7 +41,6 @@ derive_macro3.rs
 derive_macro4.rs
 derive_macro6.rs
 diagnostic_underline.rs
-expand_macro_qual_path_in_type.rs
 expected_type_args2.rs
 expected_type_args3.rs
 feature_rust_attri0.rs
@@ -59,7 +48,6 @@ feature_rust_attri1.rs
 for_lifetimes.rs
 format_args_basic_expansion.rs
 found_struct.rs
-func1.rs
 generic-default1.rs
 generics1.rs
 generics10.rs
@@ -73,20 +61,17 @@ generics7.rs
 generics8.rs
 generics9.rs
 if_let_expr.rs
-implicit_returns_err4.rs
 infer-crate-name.rs
 issue-1005.rs
 issue-1006.rs
 issue-1019.rs
 issue-1031.rs
 issue-1034.rs
-issue-1073.rs
 issue-1089.rs
 issue-1128.rs
 issue-1129-2.rs
 issue-1130.rs
 issue-1131.rs
-issue-1152.rs
 issue-1165.rs
 issue-1173.rs
 issue-1235.rs
@@ -96,7 +81,6 @@ issue-1289.rs
 issue-1383.rs
 issue-1447.rs
 issue-1483.rs
-issue-1524.rs
 issue-1589.rs
 issue-1725-1.rs
 issue-1725-2.rs
@@ -142,7 +126,6 @@ issue-2772-2.rs
 issue-2775.rs
 issue-2747.rs
 issue-2782.rs
-issue-2788.rs
 issue-2812.rs
 issue-850.rs
 issue-852.rs
@@ -157,14 +140,12 @@ macros/mbe/macro15.rs
 macros/mbe/macro20.rs
 macros/mbe/macro23.rs
 macros/mbe/macro40.rs
-macros/mbe/macro42.rs
 macros/mbe/macro43.rs
 macros/mbe/macro44.rs
 macros/mbe/macro50.rs
 macros/mbe/macro54.rs
 macros/mbe/macro55.rs
 macros/mbe/macro6.rs
-macros/mbe/macro9.rs
 macros/mbe/macro_rules_macro_rules.rs
 macros/mbe/macro_use1.rs
 match-never-ltype.rs
@@ -204,10 +185,7 @@ privacy5.rs
 privacy6.rs
 privacy8.rs
 macros/proc/attribute_non_function.rs
-macros/proc/attribute_non_root_method.rs
 macros/proc/derive_non_function.rs
-macros/proc/non_root_method.rs
-macros/proc/non_root_trait_method.rs
 macros/proc/non_function.rs
 pub_restricted_1.rs
 pub_restricted_2.rs
@@ -256,7 +234,6 @@ use_2.rs
 v0-mangle1.rs
 v0-mangle2.rs
 while_break_expr.rs
-rust-const-blog-issue.rs
 negative_impls.rs
 auto_trait.rs
 exhaustiveness1.rs
@@ -272,9 +249,7 @@ issue-3045-1.rs
 issue-3045-2.rs
 issue-3046.rs
 unknown-associated-item.rs
-box_syntax_feature_gate.rs
-dropck_eyepatch_feature_gate.rs
 inline_asm_parse_output_operand.rs
 issue-3030.rs
 issue-3035.rs
-issue-3082.rs
\ No newline at end of file
+issue-3082.rs
-- 
2.45.2



[COMMITTED 028/144] gccrs: ast: Remove PathExpr abstract class

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

Inherit directly from ExprWithoutBlock instead.

gcc/rust/ChangeLog:

* ast/rust-ast.h (class PathExpr): Remove class.
* ast/rust-path.h (class PathInExpression): Inherit from 
ExprWithoutBlock.
(class QualifiedPathInExpression): Likewise.
---
 gcc/rust/ast/rust-ast.h  | 5 -
 gcc/rust/ast/rust-path.h | 4 ++--
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 4f40efff2a9..f5a2e77af3f 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -2048,11 +2048,6 @@ public:
   }
 };
 
-// Base path expression AST node - abstract
-class PathExpr : public ExprWithoutBlock
-{
-};
-
 } // namespace AST
 } // namespace Rust
 
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 53ccf1dbb6b..bf758018b58 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -597,7 +597,7 @@ public:
 
 /* AST node representing a path-in-expression pattern (path that allows
  * generic arguments) */
-class PathInExpression : public PathPattern, public PathExpr
+class PathInExpression : public PathPattern, public ExprWithoutBlock
 {
   std::vector outer_attrs;
   bool has_opening_scope_resolution;
@@ -1221,7 +1221,7 @@ public:
 
 /* AST node representing a qualified path-in-expression pattern (path that
  * allows specifying trait functions) */
-class QualifiedPathInExpression : public PathPattern, public PathExpr
+class QualifiedPathInExpression : public PathPattern, public ExprWithoutBlock
 {
   std::vector outer_attrs;
   QualifiedPathType path_type;
-- 
2.45.2



[COMMITTED 058/144] gccrs: Fix return type of asm mov 5 to i32:0, tortured

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/testsuite/ChangeLog:

* rust/execute/inline_asm_mov_x_5.rs: Move to...
* rust/execute/torture/inline_asm_mov_x_5.rs: ...here.
---
 gcc/testsuite/rust/execute/{ => torture}/inline_asm_mov_x_5.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
 rename gcc/testsuite/rust/execute/{ => torture}/inline_asm_mov_x_5.rs (93%)

diff --git a/gcc/testsuite/rust/execute/inline_asm_mov_x_5.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
similarity index 93%
rename from gcc/testsuite/rust/execute/inline_asm_mov_x_5.rs
rename to gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
index e09ea1a030a..4f1555e6f2d 100644
--- a/gcc/testsuite/rust/execute/inline_asm_mov_x_5.rs
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
@@ -10,7 +10,7 @@ extern "C" {
 fn printf(s: *const i8, ...);
 }
 
-fn main() {
+fn main() -> i32 {
 let mut _x: i32 = 0;
 unsafe {
 asm!(
@@ -19,4 +19,5 @@ fn main() {
 );
 printf("%d\n\0" as *const str as *const i8, _x);
 }
+0
 }
-- 
2.45.2



[COMMITTED 052/144] gccrs: Lower the HIR to tree with CompileExpr

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::asm_construct_outputs):
Lower the HIR to tree with CompileExpr
* backend/rust-compile-asm.h: Remove static from method
---
 gcc/rust/backend/rust-compile-asm.cc | 15 +++
 gcc/rust/backend/rust-compile-asm.h  | 18 +-
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index 30a8cacf203..32ad84e60e7 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,5 +1,6 @@
 #include "rust-compile-asm.h"
 #include "rust-system.h"
+#include "rust-compile-expr.h"
 namespace Rust {
 namespace Compile {
 
@@ -82,14 +83,20 @@ tree
 CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
-  int count = 0;
 
+  tree head = NULL_TREE;
   for (auto &output : expr.get_operands ())
 {
-  if (output.register_type == AST::InlineAsmOperand::RegisterType::Out)
-   count++;
+  if (output.get_register_type ()
+ == AST::InlineAsmOperand::RegisterType::Out)
+   {
+ auto out = output.get_out ();
+ tree out_tree = CompileExpr::Compile (out.expr.get (), this->ctx);
+ Backend::debug (out_tree);
+ /*head = chainon (head, out_tree);*/
+   }
 }
-  return NULL_TREE;
+  return head;
 }
 
 tree
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index 05bb99ab40d..9779a4ad7fb 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -46,15 +46,15 @@ public:
   // build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
   //   tree clobbers, tree labels, bool simple, bool is_inline)
   static const int ASM_TREE_ARRAY_LENGTH = 5;
-  static tree asm_build_expr (HIR::InlineAsm &);
-  static tree asm_build_stmt (location_t,
- const std::array &);
-
-  static tree asm_construct_string_tree (HIR::InlineAsm &);
-  static tree asm_construct_outputs (HIR::InlineAsm &);
-  static tree asm_construct_inputs (HIR::InlineAsm &);
-  static tree asm_construct_clobber_tree (HIR::InlineAsm &);
-  static tree asm_construct_label_tree (HIR::InlineAsm &);
+  tree asm_build_expr (HIR::InlineAsm &);
+  tree asm_build_stmt (location_t,
+  const std::array &);
+
+  tree asm_construct_string_tree (HIR::InlineAsm &);
+  tree asm_construct_outputs (HIR::InlineAsm &);
+  tree asm_construct_inputs (HIR::InlineAsm &);
+  tree asm_construct_clobber_tree (HIR::InlineAsm &);
+  tree asm_construct_label_tree (HIR::InlineAsm &);
 
   CompileAsm (Context *ctx);
 
-- 
2.45.2



[COMMITTED 114/144] gccrs: Change resolved type segment

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.h: Add visit function prototype.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Change resolved
type segment.

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

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index df67b4f9873..287972c34ce 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -224,14 +224,23 @@ Late::visit (AST::TypePath &type)
   // maybe we can overload `resolve_path` to only do
   // typepath-like path resolution? that sounds good
 
-  auto resolved = ctx.types.get (type.get_segments ().back ()->as_string ());
-  if (resolved)
+  auto str = type.get_segments ().back ()->get_ident_segment ().as_string ();
+  auto values = ctx.types.peek ().get_values ();
+
+  if (auto resolved = ctx.types.get (str))
 ctx.map_usage (Usage (type.get_node_id ()),
   Definition (resolved->get_node_id ()));
   else
 rust_unreachable ();
 }
 
+void
+Late::visit (AST::StructStruct &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::StructExprStructBase &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 b44b2d96387..c4d0d82162e 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -48,6 +48,7 @@ public:
   void visit (AST::TypePath &) override;
   void visit (AST::StructExprStructBase &) override;
   void visit (AST::StructExprStructFields &) override;
+  void visit (AST::StructStruct &) override;
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
-- 
2.45.2



[COMMITTED 120/144] gccrs: Remove some passing test from nr2 passing list

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

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove cast_generics.rs, issue-1131.rs,
issue-1383.rs and unsafe10.rs

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

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 695da317cf0..769a6de8931 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -19,7 +19,6 @@ macros/builtin/recurse2.rs
 macros/builtin/include3.rs
 macros/builtin/include4.rs
 canonical_paths1.rs
-cast_generics.rs
 cfg1.rs
 cfg3.rs
 cfg4.rs
@@ -71,14 +70,12 @@ issue-1089.rs
 issue-1128.rs
 issue-1129-2.rs
 issue-1130.rs
-issue-1131.rs
 issue-1165.rs
 issue-1173.rs
 issue-1235.rs
 issue-1237.rs
 issue-1272.rs
 issue-1289.rs
-issue-1383.rs
 issue-1447.rs
 issue-1483.rs
 issue-1589.rs
@@ -221,7 +218,6 @@ type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
 unsafe1.rs
-unsafe10.rs
 unsafe11.rs
 unsafe2.rs
 unsafe3.rs
-- 
2.45.2



[COMMITTED 056/144] gccrs: Use's array type when constring string tree

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* backend/rust-compile-asm.cc (CompileAsm::asm_build_expr):
Use's array type when constring string tree
(CompileAsm::asm_construct_string_tree):
Use's array type when constring string tree
---
 gcc/rust/backend/rust-compile-asm.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index d179c355f21..92d60d75686 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -26,7 +26,7 @@ CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
   ASM_BASIC_P (asm_expr) = expr.is_simple_asm ();
   ASM_VOLATILE_P (asm_expr) = false;
   ASM_INLINE_P (asm_expr) = expr.is_inline_asm ();
-  /*Backend::debug (asm_expr);*/
+  Backend::debug (asm_expr);
   return asm_expr;
 }
 
@@ -74,10 +74,10 @@ CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
   // debugging and reading)
   std::stringstream ss;
   for (const auto &template_str : expr.template_strs)
-ss << template_str.symbol << "\n\t";
+ss << template_str.symbol << "\n";
 
   std::string result = ss.str ();
-  return build_string (result.size () + 1, result.c_str ());
+  return Backend::string_constant_expression (result);
 }
 
 tree
-- 
2.45.2



[COMMITTED 060/144] gccrs: Provide new asm test case for amd64

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/testsuite/ChangeLog:

* rust/execute/torture/inline_asm_mov_x_5.rs: Move to...
* rust/execute/torture/inline_asm_mov_x_5_ARM.rs: ...here.
* rust/execute/torture/inline_asm_mov_x_5_x86_64.rs: New test.
---
 ...m_mov_x_5.rs => inline_asm_mov_x_5_ARM.rs} |  1 +
 .../torture/inline_asm_mov_x_5_x86_64.rs  | 24 +++
 2 files changed, 25 insertions(+)
 rename gcc/testsuite/rust/execute/torture/{inline_asm_mov_x_5.rs => 
inline_asm_mov_x_5_ARM.rs} (90%)
 create mode 100644 
gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_x86_64.rs

diff --git a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
similarity index 90%
rename from gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
rename to gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
index 4f1555e6f2d..4e762608230 100644
--- a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5.rs
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_ARM.rs
@@ -1,3 +1,4 @@
+/* { dg-do run { target arm*-*-* } } */
 /* { dg-output "5\r*\n" }*/
 
 #![feature(rustc_attrs)]
diff --git a/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_x86_64.rs 
b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_x86_64.rs
new file mode 100644
index 000..c6086e00d46
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/inline_asm_mov_x_5_x86_64.rs
@@ -0,0 +1,24 @@
+/* { dg-do run { target x86_64*-*-* } } */
+/* { dg-output "5\r*\n" }*/
+
+#![feature(rustc_attrs)]
+#[rustc_builtin_macro]
+macro_rules! asm {
+() => {};
+}
+
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
+fn main() -> i32 {
+let mut _x: i32 = 0;
+unsafe {
+asm!(
+"mov $5, {}",
+out(reg) _x
+);
+printf("%d\n\0" as *const str as *const i8, _x);
+}
+0
+}
-- 
2.45.2



[COMMITTED 053/144] gccrs: Perform type check on InlineAsm's operand

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
Perform type check on InlineAsm's operand
(typecheck_inline_asm_operand): Likewise
---
 .../typecheck/rust-hir-type-check-expr.cc | 65 +--
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 1197916d1f5..a9255fc69f2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -623,9 +623,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
  && (((TyTy::InferType *) loop_context_type)->get_infer_kind ()
  != TyTy::InferType::GENERAL));
 
-  infered = loop_context_type_infered ? loop_context_type
- : TyTy::TupleType::get_unit_type (
-   expr.get_mappings ().get_hirid ());
+  infered = loop_context_type_infered
+ ? loop_context_type
+ : TyTy::TupleType::get_unit_type (
+ expr.get_mappings ().get_hirid ());
 }
   else
 {
@@ -775,9 +776,63 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
   infered = SubstMapperInternal::Resolve (adt, subst);
 }
 
+void
+typecheck_inline_asm_operand (HIR::InlineAsm &expr)
+{
+  const auto &operands = expr.get_operands ();
+  using RegisterType = AST::InlineAsmOperand::RegisterType;
+  for (auto &operand : operands)
+{
+  switch (operand.get_register_type ())
+   {
+ case RegisterType::In: {
+   auto in = operand.get_in ();
+   TypeCheckExpr::Resolve (in.expr.get ());
+   break;
+ }
+ case RegisterType::Out: {
+   auto out = operand.get_out ();
+   TypeCheckExpr::Resolve (out.expr.get ());
+   break;
+ }
+ case RegisterType::InOut: {
+   auto in_out = operand.get_in_out ();
+   TypeCheckExpr::Resolve (in_out.expr.get ());
+   break;
+ }
+ case RegisterType::SplitInOut: {
+   auto split_in_out = operand.get_split_in_out ();
+   TypeCheckExpr::Resolve (split_in_out.in_expr.get ());
+   TypeCheckExpr::Resolve (split_in_out.out_expr.get ());
+   break;
+ }
+ case RegisterType::Const: {
+   auto anon_const = operand.get_const ().anon_const;
+   TypeCheckExpr::Resolve (anon_const.expr.get ());
+   break;
+ }
+ case RegisterType::Sym: {
+   auto sym = operand.get_sym ();
+   TypeCheckExpr::Resolve (sym.expr.get ());
+   break;
+ }
+ case RegisterType::Label: {
+   auto label = operand.get_label ();
+   TypeCheckExpr::Resolve (label.expr.get ());
+   break;
+ }
+   }
+}
+}
 void
 TypeCheckExpr::visit (HIR::InlineAsm &expr)
-{}
+{
+  typecheck_inline_asm_operand (expr);
+
+  // TODO: Hoise out if we have noreturn as an option
+  // to return a never type
+  infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+}
 
 void
 TypeCheckExpr::visit (HIR::RangeFullExpr &expr)
@@ -1570,7 +1625,7 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
   TyTy::TyVar result_type
 = expr.has_return_type ()
? TyTy::TyVar (
- TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
+   TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
: TyTy::TyVar::get_implicit_infer_var (expr.get_locus ());
 
   // resolve the block
-- 
2.45.2



[COMMITTED 099/144] gccrs: early: Do not emit errors for unresolved imports, store them instead

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

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::visit_attributes):
Store errors for later.
---
 gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 15 +--
 1 file changed, 9 insertions(+), 6 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 ac8eb940c8d..47582a6f339 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -161,8 +161,9 @@ Early::build_import_mapping (
}
 
   if (!found)
-   rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-  "unresolved import %qs", path.as_string ().c_str ());
+   collect_error (Error (path.get_final_segment ().get_locus (),
+ ErrorCode::E0433, "unresolved import %qs",
+ path.as_string ().c_str ()));
 }
 }
 
@@ -303,8 +304,9 @@ Early::visit_attributes (std::vector &attrs)
  if (!definition.has_value ())
{
  // FIXME: Change to proper error message
- rust_error_at (trait.get ().get_locus (),
-"could not resolve trait");
+ collect_error (Error (trait.get ().get_locus (),
+   "could not resolve trait %qs",
+   trait.get ().as_string ().c_str ()));
  continue;
}
 
@@ -326,8 +328,9 @@ Early::visit_attributes (std::vector &attrs)
  if (!definition.has_value ())
{
  // FIXME: Change to proper error message
- rust_error_at (attr.get_locus (),
-"could not resolve attribute macro invocation");
+ collect_error (
+   Error (attr.get_locus (),
+  "could not resolve attribute macro invocation"));
  return;
}
  auto pm_def = mappings.lookup_attribute_proc_macro_def (
-- 
2.45.2



[COMMITTED 069/144] gccrs: Introduce `IndexVec`

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-place.h (struct Loan):
Introduce new class `IndexVec` inspired from IndexVec of rust.
It acts as a wrapper around `std::vector` and lets user specify
a strong type to use as index.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-place.h   | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index f7018d3af7f..23564608892 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -199,6 +199,25 @@ struct Loan
   location_t location;
 };
 
+// I is the index type, T is the contained type
+template  class IndexVec
+{
+  std::vector internal_vector;
+
+public:
+  T &at (I pid) { return internal_vector[pid.value]; }
+  const T &at (I pid) const { return internal_vector[pid.value]; }
+  T &operator[] (I pid) { return internal_vector[pid.value]; }
+  const T &operator[] (I pid) const { return internal_vector[pid.value]; }
+
+  void push_back (T &¶m) { internal_vector.push_back (std::move (param)); }
+  template  void emplace_back (Args &&... args)
+  {
+internal_vector.emplace_back (std::forward (args)...);
+  }
+  size_t size () const { return internal_vector.size (); }
+};
+
 /** Allocated places and keeps track of paths. */
 class PlaceDB
 {
-- 
2.45.2



[COMMITTED 074/144] gccrs: Use `IndexVec` for bb_fold_map

2025-03-19 Thread arthur . cohen
From: Kushal Pal 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-dump.cc (simplify_cfg):
Used `IndexVec` for bb_fold_map.
(Dump::go): Use strong type as index instead of value as now we
are using `IndexVec`.
(Dump::visit): Likewise.
* checks/errors/borrowck/rust-bir-dump.h (class Dump): Use
`IndexVec` for bb_fold_map.
* checks/errors/borrowck/rust-bir-place.h: Add constructor for
`IndexVec` that can reserve size.

Signed-off-by: Kushal Pal 
---
 .../checks/errors/borrowck/rust-bir-dump.cc   | 27 +--
 .../checks/errors/borrowck/rust-bir-dump.h|  2 +-
 .../checks/errors/borrowck/rust-bir-place.h   |  3 +++
 3 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index b01d08a0456..c9e01545c6a 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -71,7 +71,7 @@ renumber_places (const Function &func, std::vector 
&place_map)
 }
 
 void
-simplify_cfg (Function &func, std::vector &bb_fold_map)
+simplify_cfg (Function &func, IndexVec 
&bb_fold_map)
 {
   // The BIR builder can generate many useless basic blocks, which contain only
   // a goto.
@@ -84,11 +84,11 @@ simplify_cfg (Function &func, std::vector 
&bb_fold_map)
   // BB0 cannot be folded as it is an entry block.
   for (BasicBlockId i = {1}; i.value < func.basic_blocks.size (); 
++i.value)
{
- const BasicBlock &bb = func.basic_blocks[bb_fold_map[i.value]];
+ const BasicBlock &bb = func.basic_blocks[bb_fold_map[i]];
  if (bb.statements.empty () && bb.is_goto_terminated ())
{
  auto dst = bb.successors.at (0);
- if (bb_fold_map[dst.value] != dst)
+ if (bb_fold_map[dst] != dst)
{
  rust_error_at (
UNKNOWN_LOCATION,
@@ -100,12 +100,12 @@ simplify_cfg (Function &func, std::vector 
&bb_fold_map)
  for (BasicBlockId i = ENTRY_BASIC_BLOCK;
   i.value < bb_fold_map.size (); ++i.value)
{
- bb_fold_map[i.value] = i;
+ bb_fold_map[i] = i;
}
  stabilized = true;
  break;
}
- bb_fold_map[i.value] = dst;
+ bb_fold_map[i] = dst;
  stabilized = false;
}
}
@@ -119,7 +119,7 @@ Dump::go (bool enable_simplify_cfg)
   for (BasicBlockId i = ENTRY_BASIC_BLOCK; i.value < bb_fold_map.size ();
++i.value)
 {
-  bb_fold_map[i.value] = i;
+  bb_fold_map[i] = i;
 }
   for (size_t i = 0; i < place_map.size (); ++i)
 {
@@ -146,7 +146,7 @@ Dump::go (bool enable_simplify_cfg)
   for (statement_bb = ENTRY_BASIC_BLOCK;
statement_bb.value < func.basic_blocks.size (); ++statement_bb.value)
 {
-  if (bb_fold_map[statement_bb.value] != statement_bb)
+  if (bb_fold_map[statement_bb] != statement_bb)
continue; // This BB was folded.
 
   if (func.basic_blocks[statement_bb].statements.empty ()
@@ -157,7 +157,7 @@ Dump::go (bool enable_simplify_cfg)
 
   BasicBlock &bb = func.basic_blocks[statement_bb];
   stream << "\n";
-  stream << indentation << "bb" << bb_fold_map[statement_bb.value].value
+  stream << indentation << "bb" << bb_fold_map[statement_bb].value
 << ": {\n";
   size_t i = 0;
   for (auto &stmt : bb.statements)
@@ -168,8 +168,8 @@ Dump::go (bool enable_simplify_cfg)
}
   if (!bb_terminated)
stream << indentation << indentation << "goto -> bb"
-  << bb_fold_map[bb.successors.at (0).value].value << ";\t\t"
-  << i++ << "\n";
+  << bb_fold_map[bb.successors.at (0)].value << ";\t\t" << i++
+  << "\n";
 
   stream << indentation << "}\n";
 }
@@ -194,7 +194,7 @@ Dump::visit (const Statement &stmt)
   stream << ") -> [";
   print_comma_separated (stream, 
func.basic_blocks[statement_bb].successors,
 [this] (BasicBlockId succ) {
-  stream << "bb" << bb_fold_map[succ.value].value;
+  stream << "bb" << bb_fold_map[succ].value;
 });
   stream << "]";
   bb_terminated = true;
@@ -206,8 +206,7 @@ Dump::visit (const Statement &stmt)
 case Statement::Kind::GOTO:
   stream
<< "goto -> bb"
-   << bb_fold_map[func.basic_blocks[statement_bb].successors.at (0).value]
-.value;
+   << bb_fold_map[func.basic_blocks[statement_bb].successors.at (0)].value;
   bb_terminated = true;
   break;
 case Statement::Kind::STORAGE_DEAD:
@@ -329,7 +328,7 @@ Dump::visit (const CallExpr &expr)
   stream << ") -> [";
   print_comma_separated (stream, func.

[COMMITTED 121/144] rust: Add support for Clone and Copy derive on generic types

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

When we generate derivations for Copy and Clone we need to make sure
the associated impl block sets up the generic parameters and arguments
correctly. This patch introduces the framework to copy chunks of the AST
because we need to make sure these new AST nodes have their own associated
id, calling clone on the nodes will just confuse name-resolution and
subsequent mappings.

Fixes #3139

gcc/rust/ChangeLog:

* Make-lang.in: new objects
* ast/rust-ast-builder.cc (Builder::generic_type_path_segment): new 
helper
(Builder::single_generic_type_path): likewise
(Builder::new_type): likewise
(Builder::new_lifetime_param): likewise
(Builder::new_type_param): likewise
(Builder::new_lifetime): likewise
(Builder::new_generic_args): likewise
* ast/rust-ast-builder.h: new helper decls
* ast/rust-ast.h: new const getters
* ast/rust-path.h: likewise
* ast/rust-type.h: likewise
* expand/rust-derive-clone.cc (DeriveClone::clone_impl): take the types 
generics
(DeriveClone::visit_tuple): likewise
(DeriveClone::visit_struct): likewise
(DeriveClone::visit_union): likewise
* expand/rust-derive-clone.h: update header
* expand/rust-derive-copy.cc (DeriveCopy::copy_impl): similarly take 
type generics
(DeriveCopy::visit_struct): likewise
(DeriveCopy::visit_tuple): likewise
(DeriveCopy::visit_enum): likewise
(DeriveCopy::visit_union): likewise
* expand/rust-derive-copy.h: likewse
* ast/rust-ast-builder-type.cc: New file.
* ast/rust-ast-builder-type.h: New file.

gcc/testsuite/ChangeLog:

* rust/compile/issue-3139-1.rs: New test.
* rust/compile/issue-3139-2.rs: New test.
* rust/compile/issue-3139-3.rs: New test.
* rust/compile/nr2/exclude: these all break nr2
---
 gcc/rust/Make-lang.in  |   1 +
 gcc/rust/ast/rust-ast-builder-type.cc  | 164 +
 gcc/rust/ast/rust-ast-builder-type.h   |  57 ++
 gcc/rust/ast/rust-ast-builder.cc   | 201 -
 gcc/rust/ast/rust-ast-builder.h|  17 ++
 gcc/rust/ast/rust-ast.h|  20 +-
 gcc/rust/ast/rust-path.h   |  14 +-
 gcc/rust/ast/rust-type.h   |  10 +
 gcc/rust/expand/rust-derive-clone.cc   |  88 -
 gcc/rust/expand/rust-derive-clone.h|   5 +-
 gcc/rust/expand/rust-derive-copy.cc|  87 -
 gcc/rust/expand/rust-derive-copy.h |   4 +-
 gcc/testsuite/rust/compile/issue-3139-1.rs |  45 +
 gcc/testsuite/rust/compile/issue-3139-2.rs |  57 ++
 gcc/testsuite/rust/compile/issue-3139-3.rs |  32 
 gcc/testsuite/rust/compile/nr2/exclude |   3 +
 16 files changed, 783 insertions(+), 22 deletions(-)
 create mode 100644 gcc/rust/ast/rust-ast-builder-type.cc
 create mode 100644 gcc/rust/ast/rust-ast-builder-type.h
 create mode 100644 gcc/testsuite/rust/compile/issue-3139-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3139-2.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3139-3.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 51645be6ff6..b1777e39963 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -92,6 +92,7 @@ GRS_OBJS = \
 rust/rust-cfg-strip.o \
 rust/rust-expand-visitor.o \
 rust/rust-ast-builder.o \
+rust/rust-ast-builder-type.o \
 rust/rust-derive.o \
 rust/rust-derive-clone.o \
 rust/rust-derive-copy.o \
diff --git a/gcc/rust/ast/rust-ast-builder-type.cc 
b/gcc/rust/ast/rust-ast-builder-type.cc
new file mode 100644
index 000..e76d0de0e9a
--- /dev/null
+++ b/gcc/rust/ast/rust-ast-builder-type.cc
@@ -0,0 +1,164 @@
+// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-ast-builder-type.h"
+#include "rust-ast-builder.h"
+#include "rust-ast-full.h"
+#include "rust-common.h"
+#include "rust-make-unique.h"
+
+namespace Rust {
+namespace AST {
+
+ASTTypeBuilder::ASTTypeBuilder () : translated (nullptr) {}
+
+Type *
+ASTTypeBuilder::build (Type &type)
+{
+  ASTTypeBuilder builder;
+  type.accept_vis (builder);
+  rust_assert (builder.translated != nullptr);
+  return builder.translated;
+}
+
+void
+ASTTypeBu

[COMMITTED 132/144] gccrs: Allow identifiers and paths to reference types during nr2.0

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

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc
(Late::visit): Allow IdentifierExpr and PathInExpression to
reference types as well as values, remove ability for
IdentifierExpr to reference labels.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Owen Avery 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 35 +--
 gcc/testsuite/rust/compile/nr2/exclude|  4 ---
 2 files changed, 24 insertions(+), 15 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 c58cd967c97..daf0c871a62 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -164,16 +164,14 @@ Late::visit (AST::IdentifierExpr &expr)
   // TODO: same thing as visit(PathInExpression) here?
 
   tl::optional resolved = tl::nullopt;
-  auto label = ctx.labels.get (expr.get_ident ());
-  auto value = ctx.values.get (expr.get_ident ());
 
-  if (label)
+  if (auto value = ctx.values.get (expr.get_ident ()))
 {
-  resolved = label;
+  resolved = value;
 }
-  else if (value)
+  else if (auto type = ctx.types.get (expr.get_ident ()))
 {
-  resolved = value;
+  resolved = type;
 }
   else
 {
@@ -202,18 +200,33 @@ Late::visit (AST::PathInExpression &expr)
   // do we emit it in `get`?
 
   rust_debug ("[ARTHUR]: %s", expr.as_simple_path ().as_string ().c_str ());
-  auto value = ctx.values.resolve_path (expr.get_segments ());
-  if (!value.has_value ())
-rust_unreachable (); // Should have been resolved earlier
 
-  if (value->is_ambiguous ())
+  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
+{
+  rust_error_at (expr.get_locus (),
+"could not resolve path expression: %qs",
+expr.as_simple_path ().as_string ().c_str ());
+  return;
+}
+
+  if (resolved->is_ambiguous ())
 {
   rust_error_at (expr.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
 expr.as_string ().c_str ());
   return;
 }
   ctx.map_usage (Usage (expr.get_node_id ()),
-Definition (value->get_node_id ()));
+Definition (resolved->get_node_id ()));
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 6c7d5041291..f91cf3132c7 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -45,7 +45,6 @@ feature_rust_attri0.rs
 feature_rust_attri1.rs
 for_lifetimes.rs
 format_args_basic_expansion.rs
-found_struct.rs
 generic-default1.rs
 generics1.rs
 generics10.rs
@@ -145,10 +144,8 @@ match2.rs
 match3.rs
 match4.rs
 match5.rs
-match8.rs
 match9.rs
 method2.rs
-missing_constructor_fields.rs
 multi_reference_type.rs
 multiple_bindings1.rs
 multiple_bindings2.rs
@@ -203,7 +200,6 @@ traits6.rs
 traits7.rs
 traits8.rs
 traits9.rs
-tuple_struct1.rs
 type-bindings1.rs
 unconstrained_type_param.rs
 undeclared_label.rs
-- 
2.45.2



[COMMITTED 116/144] gccrs: This test requires the standard library

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

It requires the standard library and Copy to work correctly which we
cannot provide. Stopping the compiler before the name resolution allow us
to prevent an error whilst resolving Copy and keep the test's goal.

gcc/testsuite/ChangeLog:

* rust/compile/functions_without_body.rs: Add compile step argument.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/functions_without_body.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/rust/compile/functions_without_body.rs 
b/gcc/testsuite/rust/compile/functions_without_body.rs
index 36ddea52161..0a0e6021e84 100644
--- a/gcc/testsuite/rust/compile/functions_without_body.rs
+++ b/gcc/testsuite/rust/compile/functions_without_body.rs
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-compile-until=nameresolution" }
 struct MyStruct;
 
 trait X {}
-- 
2.45.2



[COMMITTED 016/144] gccrs: Implement resolve expr for inline asm ast

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit):
Implement resolve expr for inline asm ast
(translate_operand): Likewise.
* resolve/rust-ast-resolve-expr.h: Likewise.
---
 gcc/rust/resolve/rust-ast-resolve-expr.cc | 67 +--
 gcc/rust/resolve/rust-ast-resolve-expr.h  |  2 +
 2 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc 
b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 44ba2a8dffc..7c2ba9c9d2c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -347,6 +347,60 @@ ResolveExpr::visit (AST::BlockExpr &expr)
   resolver->get_label_scope ().pop ();
 }
 
+void
+translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix,
+  const CanonicalPath &canonical_prefix)
+{
+  const auto &operands = expr.get_operands ();
+  using RegisterType = AST::InlineAsmOperand::RegisterType;
+  for (auto &operand : operands)
+{
+  switch (operand.get_register_type ())
+   {
+ case RegisterType::In: {
+   auto in = operand.get_in ();
+   ResolveExpr::go (*in.expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::Out: {
+   auto out = operand.get_out ();
+   ResolveExpr::go (*out.expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::InOut: {
+   auto in_out = operand.get_in_out ();
+   ResolveExpr::go (*in_out.expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::SplitInOut: {
+   auto split_in_out = operand.get_split_in_out ();
+   ResolveExpr::go (*split_in_out.in_expr, prefix, canonical_prefix);
+   ResolveExpr::go (*split_in_out.out_expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::Const: {
+   auto anon_const = operand.get_const ().anon_const;
+   ResolveExpr::go (*anon_const.expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::Sym: {
+   auto sym = operand.get_sym ();
+   ResolveExpr::go (*sym.expr, prefix, canonical_prefix);
+   break;
+ }
+ case RegisterType::Label: {
+   auto label = operand.get_label ();
+   ResolveExpr::go (*label.expr, prefix, canonical_prefix);
+   break;
+ }
+   }
+}
+}
+void
+ResolveExpr::visit (AST::InlineAsm &expr)
+{
+  translate_operand (expr, prefix, canonical_prefix);
+}
 void
 ResolveExpr::visit (AST::UnsafeBlockExpr &expr)
 {
@@ -478,12 +532,13 @@ ResolveExpr::visit (AST::BreakExpr &expr)
   auto &break_expr = expr.get_break_expr ();
   if (break_expr.get_ast_kind () == AST::Kind::IDENTIFIER)
{
- /* This is a break with an expression, and the expression is just a
-single identifier.  See if the identifier is either "rust" or
-"gcc", in which case we have "break rust" or "break gcc", and so
-may need to emit our funny error.  We cannot yet emit the error
-here though, because the identifier may still be in scope, and
-ICE'ing on valid programs would not be very funny.  */
+ /* This is a break with an expression, and the expression is
+just a single identifier.  See if the identifier is either
+"rust" or "gcc", in which case we have "break rust" or "break
+gcc", and so may need to emit our funny error.  We cannot yet
+emit the error here though, because the identifier may still
+be in scope, and ICE'ing on valid programs would not be very
+funny.  */
  std::string ident
= static_cast (break_expr).as_string ();
  if (ident == "rust" || ident == "gcc")
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h 
b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 75b07b81ec7..51a69e9886c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -20,6 +20,7 @@
 #define RUST_AST_RESOLVE_EXPR_H
 
 #include "rust-ast-resolve-base.h"
+#include "rust-ast.h"
 #include "rust-ast-resolve-pattern.h"
 
 namespace Rust {
@@ -54,6 +55,7 @@ public:
   void visit (AST::IfLetExpr &expr) override;
   void visit (AST::IfLetExprConseqElse &expr) override;
   void visit (AST::BlockExpr &expr) override;
+  void visit (AST::InlineAsm &expr) override;
   void visit (AST::UnsafeBlockExpr &expr) override;
   void visit (AST::ArrayElemsValues &elems) override;
   void visit (AST::ArrayExpr &expr) override;
-- 
2.45.2



[COMMITTED 004/144] gccrs: Move procedural macro test to their own directory

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

gcc/testsuite/ChangeLog:

* rust/compile/macros/proc/proc_macro.exp: New deja gnu file to execute
proc-macro tests.
* rust/compile/proc_macro_attribute_crate_type.rs: Move to...
* rust/compile/macros/proc/attribute_crate_type.rs: ...here.
* rust/compile/proc_macro_attribute_non_function.rs: Move to...
* rust/compile/macros/proc/attribute_non_function.rs: ...here.
* rust/compile/proc_macro_attribute_non_root_function.rs: Move to...
* rust/compile/macros/proc/attribute_non_root_function.rs: ...here.
* rust/compile/proc_macro_attribute_non_root_method.rs: Move to...
* rust/compile/macros/proc/attribute_non_root_method.rs: ...here.
* rust/compile/proc_macro_attribute_non_root_module.rs: Move to...
* rust/compile/macros/proc/attribute_non_root_module.rs: ...here.
* rust/compile/proc_macro_attribute_private.rs: Move to...
* rust/compile/macros/proc/attribute_private.rs: ...here.
* rust/compile/proc_macro_crate_type.rs: Move to...
* rust/compile/macros/proc/crate_type.rs: ...here.
* rust/compile/proc_macro_derive_crate_type.rs: Move to...
* rust/compile/macros/proc/derive_crate_type.rs: ...here.
* rust/compile/proc_macro_derive_malformed.rs: Move to...
* rust/compile/macros/proc/derive_malformed.rs: ...here.
* rust/compile/proc_macro_derive_non_function.rs: Move to...
* rust/compile/macros/proc/derive_non_function.rs: ...here.
* rust/compile/proc_macro_derive_non_root_function.rs: Move to...
* rust/compile/macros/proc/derive_non_root_function.rs: ...here.
* rust/compile/proc_macro_derive_non_root_module.rs: Move to...
* rust/compile/macros/proc/derive_non_root_module.rs: ...here.
* rust/compile/proc_macro_derive_private.rs: Move to...
* rust/compile/macros/proc/derive_private.rs: ...here.
* rust/compile/proc_macro_non_function.rs: Move to...
* rust/compile/macros/proc/non_function.rs: ...here.
* rust/compile/proc_macro_non_root_function.rs: Move to...
* rust/compile/macros/proc/non_root_function.rs: ...here.
* rust/compile/proc_macro_non_root_method.rs: Move to...
* rust/compile/macros/proc/non_root_method.rs: ...here.
* rust/compile/proc_macro_non_root_module.rs: Move to...
* rust/compile/macros/proc/non_root_module.rs: ...here.
* rust/compile/proc_macro_derive_non_root_method.rs: Move to...
* rust/compile/macros/proc/non_root_trait_method.rs: ...here.
* rust/compile/proc_macro_private.rs: Move to...
* rust/compile/macros/proc/private.rs: ...here.
* rust/compile/proc_macro_pub_function.rs: Move to...
* rust/compile/macros/proc/pub_function.rs: ...here.
* rust/compile/proc_macro_pub_module.rs: Move to...
* rust/compile/macros/proc/pub_module.rs: ...here.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../proc/attribute_crate_type.rs} |  0
 .../proc/attribute_non_function.rs}   |  0
 .../proc/attribute_non_root_function.rs}  |  0
 .../proc/attribute_non_root_method.rs}|  0
 .../proc/attribute_non_root_module.rs}|  0
 .../proc/attribute_private.rs}|  0
 .../proc/crate_type.rs}   |  0
 .../proc/derive_crate_type.rs}|  0
 .../proc/derive_malformed.rs} |  0
 .../proc/derive_non_function.rs}  |  0
 .../proc/derive_non_root_function.rs} |  0
 .../proc/derive_non_root_module.rs}   |  0
 .../proc/derive_private.rs}   |  0
 .../proc/non_function.rs} |  0
 .../proc/non_root_function.rs}|  0
 .../proc/non_root_method.rs}  |  0
 .../proc/non_root_module.rs}  |  0
 .../proc/non_root_trait_method.rs}|  0
 .../proc/private.rs}  |  0
 .../rust/compile/macros/proc/proc_macro.exp   | 35 +++
 .../proc/pub_function.rs} |  0
 .../proc/pub_module.rs}   |  0
 22 files changed, 35 insertions(+)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_crate_type.rs => 
macros/proc/attribute_crate_type.rs} (100%)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_non_function.rs => 
macros/proc/attribute_non_function.rs} (100%)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_non_root_function.rs 
=> macros/proc/attribute_non_root_function.rs} (100%)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_non_root_method.rs => 
macros/proc/attribute_non_root_method.rs} (100%)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_non_root_module.rs => 
macros/proc/attribute_non_root_module.rs} (100%)
 rename gcc/testsuite/rust/compile/{proc_macro_attribute_private.rs => 
macros/proc/attribute_private.rs} (100%)
 rename gcc/testsuite/rust/compile

[COMMITTED 010/144] gccrs: Use new constructors and control flow for operand

2025-03-19 Thread arthur . cohen
From: badumbatish 

gcc/rust/ChangeLog:

* ast/rust-expr.h (struct InlineAsmOperand): changed to class
(class InlineAsmOperand): Have appropriate constructor,
and getter
* expand/rust-macro-builtins-asm.cc (parse_reg_operand):
Use the new implement constructors and new control flow.
(parse_reg_operand_in): Likewise
(parse_reg_operand_out): Likewise
(parse_reg_operand_inout): Likewise
(parse_reg_operand_const): Likewise
---
 gcc/rust/ast/rust-expr.h   | 98 +-
 gcc/rust/expand/rust-macro-builtins-asm.cc | 39 -
 2 files changed, 53 insertions(+), 84 deletions(-)

diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 8a3baf7ca2b..749fdc05f2b 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4768,8 +4768,9 @@ struct InlineAsmRegOrRegClass
   location_t locus;
 };
 
-struct InlineAsmOperand
+class InlineAsmOperand
 {
+public:
   enum RegisterType
   {
 In,
@@ -4952,75 +4953,52 @@ struct InlineAsmOperand
 }
   };
 
-  RegisterType register_type;
-
-  tl::optional in;
-  tl::optional out;
-  tl::optional in_out;
-  tl::optional split_in_out;
-  tl::optional cnst;
-  tl::optional sym;
-  tl::optional label;
-
-  InlineAsmOperand () {}
   InlineAsmOperand (const InlineAsmOperand &other)
 : register_type (other.register_type), in (other.in), out (other.out),
   in_out (other.in_out), split_in_out (other.split_in_out),
   cnst (other.cnst), sym (other.sym)
   {}
 
-  void set_in (const tl::optional ®)
-  {
-this->register_type = In;
-
-if (reg.has_value ())
-  this->in = reg.value ();
-  }
-
-  void set_out (const tl::optional ®)
-  {
-this->register_type = Out;
-
-if (reg.has_value ())
-  this->out = reg.value ();
-  }
-
-  void set_in_out (const tl::optional ®)
-  {
-this->register_type = InOut;
-if (reg.has_value ())
-  this->in_out = reg.value ();
-  }
-
-  void set_split_in_out (const tl::optional ®)
-  {
-this->register_type = SplitInOut;
-if (reg.has_value ())
-  this->split_in_out = reg.value ();
-  }
-
-  void set_cnst (const tl::optional ®)
-  {
-this->register_type = Const;
-if (reg.has_value ())
-  this->cnst = reg.value ();
-  }
+  InlineAsmOperand (const struct In ®) : register_type (In), in (reg) {}
+  InlineAsmOperand (const struct Out ®) : register_type (Out), out (reg) {}
+  InlineAsmOperand (const struct InOut ®)
+: register_type (InOut), in_out (reg)
+  {}
+  InlineAsmOperand (const struct SplitInOut ®)
+: register_type (SplitInOut), split_in_out (reg)
+  {}
+  InlineAsmOperand (const struct Const ®) : register_type (Const), cnst 
(reg)
+  {}
+  InlineAsmOperand (const struct Sym ®) : register_type (Sym), sym (reg) {}
+  InlineAsmOperand (const struct Label ®)
+: register_type (Label), label (reg)
+  {}
 
-  void set_sym (const tl::optional ®)
-  {
-this->register_type = Sym;
-if (reg.has_value ())
-  this->sym = reg.value ();
-  }
+  location_t get_locus () const { return locus; }
+  RegisterType get_register_type () const { return register_type; }
+
+  // Potentially fail immediately if you don't use get_register_type() to
+  // inspect the RegisterType first before calling the following functions 
Check
+  // first
+  struct In get_in () const { return in.value (); }
+  struct Out get_out () const { return out.value (); }
+  struct InOut get_in_out () const { return in_out.value (); }
+  struct SplitInOut get_split_in_out () const { return split_in_out.value (); }
+  struct Const get_const () const { return cnst.value (); }
+  struct Sym get_sym () const { return sym.value (); }
+  struct Label get_label () const { return label.value (); }
 
-  void set_label (const tl::optional ®)
-  {
-this->register_type = Label;
-if (reg.has_value ())
-  this->label = reg.value ();
-  }
+private:
+  RegisterType register_type;
 
   location_t locus;
+  tl::optional in;
+  tl::optional out;
+  tl::optional in_out;
+  tl::optional split_in_out;
+  tl::optional cnst;
+  tl::optional sym;
+  tl::optional label;
 };
 
 struct InlineAsmPlaceHolder
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index d270621d1bf..7f0498fdef4 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -193,7 +193,6 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
   //   None
   //   };
   auto &parser = inline_asm_ctx.parser;
-  AST::InlineAsmOperand reg_operand;
   auto token = parser.peek_current_token ();
   auto iden_token = parser.peek_current_token ();
 
@@ -243,12 +242,13 @@ parse_reg_operand (InlineAsmContext inline_asm_ctx)
  inline_asm_ctx = *result;
  break;
}
-  else if (result.error () == COMMITTED
-  && parse_func != parse_reg_operand_unexpected)
-   return result;
-  else if (result.e

  1   2   >