[Bug rust/113472] rust/compile/issue-1446.rs FAILs

2024-08-01 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113472

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|14.2|14.3

--- Comment #3 from Jakub Jelinek  ---
GCC 14.2 is being released, retargeting bugs to GCC 14.3.

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

[Bug rust/113473] rust/compile/iterators1.rs etc. FAIL

2024-08-01 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113473

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|14.2|14.3

--- Comment #3 from Jakub Jelinek  ---
GCC 14.2 is being released, retargeting bugs to GCC 14.3.

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

[Bug rust/113477] rust/compile/torture/alt_patterns1.rs FAILs

2024-08-01 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113477

Jakub Jelinek  changed:

   What|Removed |Added

   Target Milestone|14.2|14.3

--- Comment #2 from Jakub Jelinek  ---
GCC 14.2 is being released, retargeting bugs to GCC 14.3.

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

☝ Buildbot (Sourceware): gccrust - worker not available (master)

2024-08-01 Thread builder
A retry build has been detected on builder gccrust-fedora-x86_64 while building 
gccrust.

Full details are available at:
https://builder.sourceware.org/buildbot/#/builders/16/builds/2953

Build state: worker not available
Revision: (unknown)
Worker: bb2-2
Build Reason: (unknown)
Blamelist: 0xn4utilus , Aldy Hernandez 
, Alex Coplan , Alexander Westbrooks 
, Alexandre Oliva , Andre Simoes 
Dias Vieira , Andre Vieira 
, Andreas Schwab , Andrew 
Carlotti , Andrew Pinski , 
Andrew Stubbs , Antoni Boucher , Antonio 
Gomes , Arthur Cohen , 
Bernhard Reutner-Fischer , Brian Inglis 
, Christoph Müllner , 
Christophe Lyon , Chung-Lin Tang 
, Cupertino Miranda , Daniel 
Cederman , David Faust , David 
Malcolm , Dimitar Dimitrov , Edwin Lu , Eric Botcazou , 
Fangrui Song , Fangrui Song , Filip 
Kastl , Francois-Xavier Coudert , 
François Dumont , GCC Administrator 
, Gaius Mulley , Georg-Johann Lay 
, Gerald Pfeifer , Greg McGary 
, H.J. Lu <(no_default)>, H.J. Lu , 
Hans-Peter Nilsson , Hans-Peter Nilsson , 
Haochen Gui , Haochen Jiang , 
Harald Anlauf , Huanghui Nie , Iain Buclaw 
, Iain Sandoe , Ian Lance Taylor 
, Ilya Leoshkevich , Jakub Dupak 
, Jakub Jelinek , Jan Dubiec 
, Jan Hubicka , Jason Merrill , Jeevitha , Jeff Law , 
Jerry DeLisle , Jiahao Xu , Jin Ma 
, John David Anglin , Jonathan 
Wakely , Jonathan Yong <10wa...@gmail.com>, Jose E. 
Marchesi , Joseph Myers , 
Juergen Christ , Jun Sha (Joshua) 
, Juzhe-Zhong , Ken 
Matsui , Kewen Lin , Khem Raj 
, Kito Cheng , Kuan-Lin Chen 
, Kushal Pal , Kwok Cheung Yeung 
, Kwok Cheung Yeung , Lehua Ding 
, Lewis Hyatt , Li Wei 
, Liam Naddell , Lulu Cheng 
, M V V S Manoj Kumar 
 , Maciej W. Rozycki , Maciej W. 
Rozycki , Mael Cravero , Manos 
Anagnostakis , Marc Poulhiès , 
Marc Poulhiès , Marek Polacek , Mark 
Wielaard , Martin Jambor , Martin Uecker 
, Mary Bennett , Matteo Italia 
, Matthieu Longo , Maxim Kuvyrkov 
, Mikael Morin , Mikael 
Pettersson , Monk Chiang , 
Muhammad Mahad , Nathaniel Shead 
, Nirmal Patel , Nobel Singh 
, Oleg Endo , Owen Avery 
, Palmer Dabbelt , Pan Li 
, Patrick O'Neill , Patrick Palka , Paul Keir 
, Peter Bergner , Peter Hill 
, Philip Herron , 
Pierre-Emmanuel Patry , Prathamesh Kulkarni 
, Raiki Tamura , Rainer 
Orth , Richard Ball , 
Richard Biener , Richard Earnshaw , 
Richard Sandiford , Robert Goss 
, Robin Dapp , Robin Dapp 
, Roger Sayle , Ronan 
Desplanques , SIGMazer , Sahil 
Yeole , Sam James , Sandra Loosemore 
, Sandra Loosemore , Saurabh 
Jha , Stam Markianos
 -Wright , Steve Kargl , 
Szabolcs Nagy , Takayuki 'January June' Suwa 
, Tamar Christina , Tejas 
Belagod , Thomas Schwinge , 
Tobias Burnus , Tom Tromey , Torbjörn 
SVENSSON , Uros Bizjak , 
Victor Do Nascimento , Vineet Gupta 
, Vladimir N. Makarov , Wilco 
Dijkstra , Will Hawkins , Xi Ruoyao 
, Yang Yujie , Yanzhang Wang 
, YunQiang Su , YunQiang Su 
, Zac Walker , ansh 
, badumbatish , chenguoqi 
, chenxiaolong , dave , demin.han 
, jjasmine , liuhongt 
, waffl3x , xuli 
, zhanghe9702 

Steps:

- 0: worker_preparation ( exception )
Logs:
- err.text: 
https://builder.sourceware.org/buildbot/#/builders/16/builds/2953/steps/0/logs/err_text
- err.html: 
https://builder.sourceware.org/buildbot/#/builders/16/builds/2953/steps/0/logs/err_html



[PATCH 001/125] Rust: Make 'tree'-level 'MAIN_NAME_P' work

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

'gcc/tree.h':

#define main_identifier_nodeglobal_trees[TI_MAIN_IDENTIFIER]
#define MAIN_NAME_P(NODE) \
  (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)

..., which is not initialized by default, but has to be set up by every front
end individually.  'MAIN_NAME_P' enables certain code optimizations, but is
especially also relevant for back ends that emit additional program entry setup
code for 'main'.

gcc/rust/
* backend/rust-compile-base.cc (HIRCompileBase::compile_function):
For 'main', initialize 'main_identifier_node'.
---
 gcc/rust/backend/rust-compile-base.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 984492f6607..4d6f0275b00 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -657,6 +657,12 @@ HIRCompileBase::compile_function (
 
   // we don't mangle the main fn since we haven't implemented the main shim
   bool is_main_fn = fn_name.compare ("main") == 0;
+  if (is_main_fn)
+{
+  rust_assert (!main_identifier_node);
+  /* So that 'MAIN_NAME_P' works.  */
+  main_identifier_node = get_identifier (ir_symbol_name.c_str ());
+}
   std::string asm_name = fn_name;
 
   unsigned int flags = 0;
-- 
2.45.2



[PATCH 002/125] gccrs: Fix false positive for top-level AltPattern

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* hir/rust-ast-lower-pattern.cc
(ASTLoweringPattern::visit):
Reset is_let_top_level while visiting GroupedPattern.

gcc/testsuite/ChangeLog:

* rust/compile/let_alt.rs: Check for false positive.

Signed-off-by: Owen Avery 
---
 gcc/rust/hir/rust-ast-lower-pattern.cc | 1 +
 gcc/testsuite/rust/compile/let_alt.rs  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc 
b/gcc/rust/hir/rust-ast-lower-pattern.cc
index a2228488ad2..d534b829517 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -276,6 +276,7 @@ ASTLoweringPattern::visit (AST::RangePattern &pattern)
 void
 ASTLoweringPattern::visit (AST::GroupedPattern &pattern)
 {
+  is_let_top_level = false;
   pattern.get_pattern_in_parens ()->accept_vis (*this);
 }
 
diff --git a/gcc/testsuite/rust/compile/let_alt.rs 
b/gcc/testsuite/rust/compile/let_alt.rs
index a2735bdbe77..ff16e6428ff 100644
--- a/gcc/testsuite/rust/compile/let_alt.rs
+++ b/gcc/testsuite/rust/compile/let_alt.rs
@@ -1,4 +1,5 @@
 fn main() {
 let _a | _a = 12;
 // { dg-error "top level or-patterns are not allowed for .let. bindings" 
"" { target *-*-* } .-1 }
+let (_b | _b) = 12;
 }
-- 
2.45.2



[PATCH 003/125] gccrs: minor cleanup in langhook.type_for_mode

2024-08-01 Thread Arthur Cohen
From: Marc Poulhiès 

gcc/rust/ChangeLog:

* rust-lang.cc (grs_langhook_type_for_mode): simplify code for
xImode. Add missing long_double_type_node.

Signed-off-by: Marc Poulhiès 
---
 gcc/rust/rust-lang.cc | 39 +++
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index 4c2ef108bce..a1f5fe3978d 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -169,38 +169,29 @@ static tree
 grs_langhook_type_for_mode (machine_mode mode, int unsignedp)
 {
   // TODO: change all this later to match rustc types
-  if (mode == TYPE_MODE (float_type_node))
-return float_type_node;
-
-  if (mode == TYPE_MODE (double_type_node))
-return double_type_node;
-
-  if (mode == TYPE_MODE (intQI_type_node)) // quarter integer mode - single 
byte
-  // treated as integer
+  if (mode == QImode)
 return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
-  if (mode
-  == TYPE_MODE (intHI_type_node)) // half integer mode - two-byte integer
+
+  if (mode == HImode)
 return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
-  if (mode
-  == TYPE_MODE (intSI_type_node)) // single integer mode - four-byte 
integer
+
+  if (mode == SImode)
 return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
-  if (mode
-  == TYPE_MODE (
-   intDI_type_node)) // double integer mode - eight-byte integer
+
+  if (mode == DImode)
 return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
-  if (mode
-  == TYPE_MODE (intTI_type_node)) // tetra integer mode - 16-byte integer
+
+  if (mode == TYPE_MODE (intTI_type_node))
 return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 
-  if (mode == TYPE_MODE (integer_type_node))
-return unsignedp ? unsigned_type_node : integer_type_node;
+  if (mode == TYPE_MODE (float_type_node))
+return float_type_node;
 
-  if (mode == TYPE_MODE (long_integer_type_node))
-return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (mode == TYPE_MODE (double_type_node))
+return double_type_node;
 
-  if (mode == TYPE_MODE (long_long_integer_type_node))
-return unsignedp ? long_long_unsigned_type_node
-: long_long_integer_type_node;
+  if (mode == TYPE_MODE (long_double_type_node))
+return long_double_type_node;
 
   if (COMPLEX_MODE_P (mode))
 {
-- 
2.45.2



[PATCH 008/125] Rust: Don't cache 'libformat_parser.a'

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

gcc/rust/
* Make-lang.in (LIBFORMAT_PARSER): Point to the actual build artifact.
($(LIBFORMAT_PARSER)): Don't cache it.
---
 gcc/rust/Make-lang.in | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index bcf424e6c18..497a3c76166 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,7 +212,7 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER = rust/libformat_parser.a
+LIBFORMAT_PARSER = 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -417,7 +417,6 @@ rust/%.o: rust/lex/%.cc
 # TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
 $(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
-   cp 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a $@
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
-- 
2.45.2



[PATCH 009/125] Rust: Move 'libformat_parser' build into the GCC build directory

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

Fixes #2883.

gcc/rust/ChangeLog:
* Make-lang.in (LIBFORMAT_PARSER): Point to the GCC build
directory.
* ($(LIBFORMAT_PARSER)): Build in the GCC build directory.
---
 gcc/rust/Make-lang.in | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 497a3c76166..b3301f5ce6f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,7 +212,8 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER = 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a
+LIBFORMAT_PARSER_D = rust/libformat_parser
+LIBFORMAT_PARSER = $(LIBFORMAT_PARSER_D)/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -416,7 +417,13 @@ rust/%.o: rust/lex/%.cc
 
 # TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
 $(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
+   cargo \
+ --config $(srcdir)/../libgrust/libformat_parser/.cargo/config \
+ build \
+   --offline \
+   --target-dir $(LIBFORMAT_PARSER_D) \
+   --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml \
+   # FIXME: Not always '--release', right?
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
-- 
2.45.2



[PATCH 010/125] Rust: Move 'libformat_parser' build into libgrust

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

Addresses #2883.

contrib/
* gcc_update (files_and_dependencies): Update for
'libformat_parser' in libgrust.
gcc/rust/
* Make-lang.in (LIBFORMAT_PARSER): Point to 'libformat_parser'
build in libgrust.
(%.toml:, $(LIBFORMAT_PARSER):): Remove.
libgrust/
* libformat_parser/Makefile.am: New.
* Makefile.am [!TARGET_LIBRARY] (SUBDIRS): Add 'libformat_parser'.
* configure.ac: Handle it.
(TARGET_LIBRARY): New 'AM_CONDITIONAL'.
* libformat_parser/Makefile.in: Generate.
* Makefile.in: Regenerate.
* configure: Likewise.
---
 contrib/gcc_update|   1 +
 gcc/rust/Make-lang.in |  16 +-
 libgrust/Makefile.am  |   6 +-
 libgrust/Makefile.in  |   5 +-
 libgrust/configure|  22 +-
 libgrust/configure.ac |   3 +
 libgrust/libformat_parser/Makefile.am |  13 +
 libgrust/libformat_parser/Makefile.in | 441 ++
 8 files changed, 487 insertions(+), 20 deletions(-)
 create mode 100644 libgrust/libformat_parser/Makefile.am
 create mode 100644 libgrust/libformat_parser/Makefile.in

diff --git a/contrib/gcc_update b/contrib/gcc_update
index fac86d0e33e..417e0483b3f 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -158,6 +158,7 @@ libgomp/config.h.in: libgomp/configure.ac libgomp/aclocal.m4
 libgrust/Makefile.in: libgrust/Makefile.am libgrust/aclocal.m4
 libgrust/aclocal.m4: libgrust/configure.ac
 libgrust/configure: libgrust/configure.ac libgrust/aclocal.m4
+libgrust/libformat_parser/Makefile.in: libgrust/libformat_parser/Makefile.am 
libgrust/aclocal.m4
 libgrust/libproc_macro_internal/Makefile.in: 
libgrust/libproc_macro_internal/Makefile.am libgrust/aclocal.m4
 libitm/aclocal.m4: libitm/configure.ac libitm/acinclude.m4
 libitm/Makefile.in: libitm/Makefile.am libitm/aclocal.m4
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index b3301f5ce6f..baf55161d78 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,8 +212,7 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
-LIBFORMAT_PARSER_D = rust/libformat_parser
-LIBFORMAT_PARSER = $(LIBFORMAT_PARSER_D)/debug/liblibformat_parser.a
+LIBFORMAT_PARSER = ../libgrust/libformat_parser/debug/liblibformat_parser.a
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
@@ -412,19 +411,6 @@ rust/%.o: rust/lex/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
 
-%.toml: 
-   echo $@
-
-# TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
-$(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cargo \
- --config $(srcdir)/../libgrust/libformat_parser/.cargo/config \
- build \
-   --offline \
-   --target-dir $(LIBFORMAT_PARSER_D) \
-   --manifest-path $(srcdir)/../libgrust/libformat_parser/Cargo.toml \
-   # FIXME: Not always '--release', right?
-
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/libgrust/Makefile.am b/libgrust/Makefile.am
index 5b38c8842cb..7a4512cae96 100644
--- a/libgrust/Makefile.am
+++ b/libgrust/Makefile.am
@@ -11,7 +11,11 @@ TOP_GCCDIR := $(shell cd $(top_srcdir) && cd .. && pwd)
 GCC_DIR = $(TOP_GCCDIR)/gcc
 RUST_SRC = $(GCC_DIR)/rust
 
-SUBDIRS = libproc_macro_internal
+SUBDIRS =
+if !TARGET_LIBRARY
+SUBDIRS += libformat_parser
+endif
+SUBDIRS += libproc_macro_internal
 
 RUST_BUILDDIR := $(shell pwd)
 
diff --git a/libgrust/Makefile.in b/libgrust/Makefile.in
index d065584d196..6665f8da738 100644
--- a/libgrust/Makefile.in
+++ b/libgrust/Makefile.in
@@ -88,6 +88,7 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
+@TARGET_LIBRARY_FALSE@am__append_1 = libformat_parser
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -165,7 +166,7 @@ am__define_uniq_tagged_files = \
 ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = libformat_parser libproc_macro_internal
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -308,7 +309,7 @@ AM_CFLAGS = -I $(srcdir)/../libgcc -I 
$(MULTIBUILDTOP)../../gcc/include
 TOP_GCCDIR := $(shell cd $(top_srcdir) && cd .. && pwd)
 GCC_DIR = $(TOP_GCCDIR)/gcc
 RUST_SRC = $(GCC_DIR)/rust
-SUBDIRS = libproc_macro_internal
+SUBDIRS = $(am__append_1) libproc_macro_internal
 RUST_BUILDDIR := $(shell pwd)
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
diff --git a/libgrus

[PATCH 020/125] gccrs: Adjust error checks to match name resolution 2.0

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/testsuite/ChangeLog:

* rust/compile/bad_stmt_enums.rs: Adjust redefinition error.
* rust/compile/bad_toplevel_enums.rs: Likewise.
* rust/compile/redef_error1.rs: Likewise.
* rust/compile/redef_error3.rs: Likewise.
* rust/compile/redef_error4.rs: Likewise.
* rust/compile/redef_error6.rs: Likewise.

Signed-off-by: Owen Avery 
---
 gcc/testsuite/rust/compile/bad_stmt_enums.rs | 6 +++---
 gcc/testsuite/rust/compile/bad_toplevel_enums.rs | 6 +++---
 gcc/testsuite/rust/compile/redef_error1.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error3.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error4.rs   | 2 +-
 gcc/testsuite/rust/compile/redef_error6.rs   | 2 +-
 6 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/gcc/testsuite/rust/compile/bad_stmt_enums.rs 
b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
index 7b09a94fd27..b83137f96b8 100644
--- a/gcc/testsuite/rust/compile/bad_stmt_enums.rs
+++ b/gcc/testsuite/rust/compile/bad_stmt_enums.rs
@@ -5,17 +5,17 @@ fn main ()
   Alpha { alpha: i32 },
   pub Beta (u8),
   pub Gamma,
-  Gamma { gamma: u32 } // { dg-error "redefined" }
+  Gamma { gamma: u32 } // { dg-error "defined multiple times" }
 }
 
   struct EE2 { }
-  enum EE2 { } // { dg-error "redefined" }
+  enum EE2 { } // { dg-error "defined multiple times" }
 
   enum EE1
 {
   pub Alpha,
   Beta = 41,
-  Beta = 42, // { dg-error "redefined" }
+  Beta = 42, // { dg-error "defined multiple times" }
   pub Gamma = 3,
   D,
 }
diff --git a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs 
b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
index b655e30a93d..137095bf00c 100644
--- a/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
+++ b/gcc/testsuite/rust/compile/bad_toplevel_enums.rs
@@ -3,17 +3,17 @@ pub enum E
   pub A { a: i32 },
   B (u8),
   pub C,
-  B // { dg-error "redefined" }
+  B // { dg-error "defined multiple times" }
 }
 
 enum E2 { }
-struct E2 { } // { dg-error "redefined" }
+struct E2 { } // { dg-error "defined multiple times" }
 
 enum E1
 {
   A,
   pub B = 42,
   C = 3,
-  A { a: u8 }, // { dg-error "redefined" }
+  A { a: u8 }, // { dg-error "defined multiple times" }
   pub D
 }
diff --git a/gcc/testsuite/rust/compile/redef_error1.rs 
b/gcc/testsuite/rust/compile/redef_error1.rs
index ae51e36c87f..5a85f1e50fe 100644
--- a/gcc/testsuite/rust/compile/redef_error1.rs
+++ b/gcc/testsuite/rust/compile/redef_error1.rs
@@ -3,6 +3,6 @@ struct S1 {
 y: f64,
 }
 
-struct S1(i32, bool); // { dg-error "redefined multiple times" }
+struct S1(i32, bool); // { dg-error "defined multiple times" }
 
 fn main() {}
diff --git a/gcc/testsuite/rust/compile/redef_error3.rs 
b/gcc/testsuite/rust/compile/redef_error3.rs
index a4bf1ed3d8c..cc1cceba8bb 100644
--- a/gcc/testsuite/rust/compile/redef_error3.rs
+++ b/gcc/testsuite/rust/compile/redef_error3.rs
@@ -2,7 +2,7 @@ fn test() -> bool {
 true
 }
 
-fn test() -> i32 { // { dg-error "redefined multiple times" }
+fn test() -> i32 { // { dg-error "defined multiple times" }
 123
 }
 
diff --git a/gcc/testsuite/rust/compile/redef_error4.rs 
b/gcc/testsuite/rust/compile/redef_error4.rs
index a250c0ac00e..3faebb75abe 100644
--- a/gcc/testsuite/rust/compile/redef_error4.rs
+++ b/gcc/testsuite/rust/compile/redef_error4.rs
@@ -9,7 +9,7 @@ impl Foo {
 test()
 }
 
-fn test() -> bool { // { dg-error "redefined multiple times" }
+fn test() -> bool { // { dg-error "defined multiple times" }
 true
 }
 }
diff --git a/gcc/testsuite/rust/compile/redef_error6.rs 
b/gcc/testsuite/rust/compile/redef_error6.rs
index 664c6ae9894..f7f688b5f36 100644
--- a/gcc/testsuite/rust/compile/redef_error6.rs
+++ b/gcc/testsuite/rust/compile/redef_error6.rs
@@ -5,7 +5,7 @@ impl Foo {
 123
 }
 
-fn test(self) -> i32 { // { dg-error "redefined multiple times" }
+fn test(self) -> i32 { // { dg-error "defined multiple times" }
 self.0
 }
 }
-- 
2.45.2



[PATCH 022/125] gccrs: lang-items: Cleanup parsing and lookups of lang items.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* Make-lang.in: Compile new rust-lang-item.o.
* util/rust-lang-item.h: Split into header and source.
* util/rust-lang-item.cc: Cleanup parsing of lang items by using a 
hashmap
and returning optional values, cleanup handling of exhaustive lang item
lookups.
* hir/rust-ast-lower-base.cc 
(ASTLoweringBase::handle_lang_item_attribute): Use
new optional API.
---
 gcc/rust/Make-lang.in   |   1 +
 gcc/rust/hir/rust-ast-lower-base.cc |  13 +-
 gcc/rust/util/rust-lang-item.cc | 191 +++
 gcc/rust/util/rust-lang-item.h  | 508 +---
 4 files changed, 206 insertions(+), 507 deletions(-)
 create mode 100644 gcc/rust/util/rust-lang-item.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index baf55161d78..af5d775a3a6 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -203,6 +203,7 @@ GRS_OBJS = \
 rust/rust-dir-owner.o \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
+   rust/rust-lang-item.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index 3ff0f52e0c6..815b98f9f0a 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -789,13 +789,12 @@ ASTLoweringBase::handle_lang_item_attribute (const 
ItemWrapper &item,
   auto &literal = static_cast (attr.get_attr_input 
());
   const auto &lang_item_type_str = literal.get_literal ().as_string ();
   auto lang_item_type = Analysis::RustLangItem::Parse (lang_item_type_str);
-  if (lang_item_type == Analysis::RustLangItem::ItemType::UNKNOWN)
-{
-  rust_error_at (attr.get_locus (), "unknown lang item");
-  return;
-}
-  mappings->insert_lang_item (lang_item_type,
- item.get_mappings ().get_defid ());
+
+  if (lang_item_type)
+mappings->insert_lang_item (*lang_item_type,
+   item.get_mappings ().get_defid ());
+  else
+rust_error_at (attr.get_locus (), "unknown lang item");
 }
 
 bool
diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc
new file mode 100644
index 000..9fe212d412d
--- /dev/null
+++ b/gcc/rust/util/rust-lang-item.cc
@@ -0,0 +1,191 @@
+// 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-lang-item.h"
+#include "rust-system.h"
+
+namespace Rust {
+namespace Analysis {
+
+const BiMap
+  Rust::Analysis::RustLangItem::lang_items = {{
+{"add", ADD},
+{"sub", SUBTRACT},
+{"mul", MULTIPLY},
+{"div", DIVIDE},
+{"rem", REMAINDER},
+{"bitand", BITAND},
+{"bitor", BITOR},
+{"bitxor", BITXOR},
+{"shl", SHL},
+{"shr", SHR},
+{"neg", NEGATION},
+{"not", NOT},
+{"add_assign", ADD_ASSIGN},
+{"sub_assign", SUB_ASSIGN},
+{"mul_assign", MUL_ASSIGN},
+{"div_assign", DIV_ASSIGN},
+{"rem_assign", REM_ASSIGN},
+{"bitand_assign", BITAND_ASSIGN},
+{"bitor_assign", BITOR_ASSIGN},
+{"bitxor_assign", BITXOR_ASSIGN},
+{"shl_assign", SHL_ASSIGN},
+{"shr_assign", SHR_ASSIGN},
+{"deref", DEREF},
+{"deref_mut", DEREF_MUT},
+{"index", INDEX},
+{"index_mut", INDEX_MUT},
+{"RangeFull", RANGE_FULL},
+{"Range", RANGE},
+{"RangeFrom", RANGE_FROM},
+{"RangeTo", RANGE_TO},
+{"RangeInclusive", RANGE_INCLUSIVE},
+{"RangeToInclusive", RANGE_TO_INCLUSIVE},
+{"phantom_data", PHANTOM_DATA},
+{"fn", FN},
+{"fn_mut", FN_MUT},
+{"fn_once", FN_ONCE},
+{"fn_once_output", FN_ONCE_OUTPUT},
+{"copy", COPY},
+{"clone", CLONE},
+{"sized", SIZED},
+{"slice_alloc", SLICE_ALLOC},
+{"slice_u8_alloc", SLICE_U8_ALLOC},
+{"str_alloc", STR_ALLOC},
+{"array", ARRAY},
+{"bool", BOOL},
+{"char", CHAR},
+{"f32", F32},
+{"f64", F64},
+{"i8", I8},
+{"i16", I16},
+{"i32", I32},
+{"i64", I64},
+{"i128", I128},
+{"isize", ISIZE},
+{"u8", U8},
+{"u16", U16},
+{"u32", U32},
+{"u64", U64},
+{"u128", U128},
+{"usize", USIZE},
+{"const_ptr", CONST_PTR},
+{"const_slice_ptr", CONST_SLICE_PTR},
+{"mut_ptr", MUT_PTR},
+{"mut_slice_ptr", MUT_SLICE_PTR},
+{"slice_u8", SLICE_U8},
+{"slice", SLICE},
+{

[PATCH 006/125] gccrs: Add 'gcc/rust/Make-lang.in:LIBFORMAT_PARSER'

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

... to avoid verbatim repetition.

gcc/rust/
* Make-lang.in (LIBPROC_MACRO_INTERNAL): New.
(RUST_LIBDEPS, crab1$(exeext), rust/libformat_parser.a): Use it.
---
 gcc/rust/Make-lang.in | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 8ac0d1d1973..bcf424e6c18 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -212,6 +212,9 @@ RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
 rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
 
 LIBPROC_MACRO_INTERNAL = 
../libgrust/libproc_macro_internal/libproc_macro_internal.a
+LIBFORMAT_PARSER = rust/libformat_parser.a
+
+RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER)
 
 
 RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
@@ -220,7 +223,7 @@ RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
 crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(RUST_LIBDEPS) 
$(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) rust/libformat_parser.a  $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) $(LIBFORMAT_PARSER) $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
 
 # Build hooks.
@@ -411,9 +414,10 @@ rust/%.o: rust/lex/%.cc
 %.toml: 
echo $@
 
-rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
-   cargo build --manifest-path 
$(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always 
release, right?
-   cp 
$(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
+# TODO: Improve `cargo` invocation with host specific flags, possibly creating 
a $(CARGO) variable?
+$(LIBFORMAT_PARSER): $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
+   cd $(srcdir)/../libgrust/libformat_parser && cargo build --offline  # 
FIXME: Not always release, right?
+   cp 
$(srcdir)/../libgrust/libformat_parser/target/debug/liblibformat_parser.a $@
 
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
-- 
2.45.2



[PATCH 004/125] gccrs: fmt: Start working on format_args!() parser

2024-08-01 Thread Arthur Cohen
This commit adds a base class for parsing the various constructs of a
Rust format string, according to the grammar in the reference:

https://doc.rust-lang.org/std/fmt/index.html#syntax

gcc/rust/ChangeLog:

* Make-lang.in: Compile rust-fmt object
* ast/rust-fmt.cc: New file.
* ast/rust-fmt.h: New file.
---
 gcc/rust/Make-lang.in|   1 +
 gcc/rust/ast/rust-fmt.cc |  96 
 gcc/rust/ast/rust-fmt.h  | 133 +++
 3 files changed, 230 insertions(+)
 create mode 100644 gcc/rust/ast/rust-fmt.cc
 create mode 100644 gcc/rust/ast/rust-fmt.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index e437c32e347..c0df49a7fee 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -100,6 +100,7 @@ GRS_OBJS = \
 rust/rust-proc-macro-invoc-lexer.o \
 rust/rust-macro-substitute-ctx.o \
 rust/rust-macro-builtins.o \
+   rust/rust-fmt.o \
 rust/rust-hir.o \
 rust/rust-hir-map.o \
 rust/rust-attributes.o \
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
new file mode 100644
index 000..9f9ba48f0c3
--- /dev/null
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2020-2023 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-fmt.h"
+
+namespace Rust {
+tl::expected
+Fmt::parse_fmt_string (Fmt::Input input)
+{
+  return Fmt ();
+}
+
+tl::expected>, Fmt::Error>
+Fmt::maybe_format (Fmt::Input input)
+{
+  tl::optional none = tl::nullopt;
+
+  return Fmt::Result (input, none);
+}
+
+tl::expected, Fmt::Error>
+Fmt::format (Input input)
+{
+  return Fmt::Result (input, Format ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::argument (Input input)
+{
+  return Fmt::Result (input, Argument ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::format_spec (Input input)
+{
+  return Fmt::Result (input, FormatSpec ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::fill (Input input)
+{
+  return Fmt::Result (input, Fill ());
+}
+
+tl::expected, Fmt::Error>
+Fmt::align (Input input)
+{
+  switch (input[0])
+{
+case '<':
+  return Fmt::Result (input.substr (1), Align::Left);
+case '^':
+  return Fmt::Result (input.substr (1), Align::Top);
+case '>':
+  return Fmt::Result (input.substr (1), Align::Right);
+default:
+  // TODO: Store the character here
+  // TODO: Can we have proper error locations?
+  // TODO: Maybe we should use a Rust::Literal string instead of a string
+  return tl::make_unexpected (Error::Align);
+}
+}
+
+tl::expected, Fmt::Error>
+Fmt::sign (Input input)
+{
+  switch (input[0])
+{
+case '+':
+  return Fmt::Result (input.substr (1), Sign::Plus);
+case '-':
+  return Fmt::Result (input.substr (1), Sign::Minus);
+default:
+  // TODO: Store the character here
+  // TODO: Can we have proper error locations?
+  // TODO: Maybe we should use a Rust::Literal string instead of a string
+  return tl::make_unexpected (Error::Sign);
+}
+}
+
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
new file mode 100644
index 000..f3dd53da979
--- /dev/null
+++ b/gcc/rust/ast/rust-fmt.h
@@ -0,0 +1,133 @@
+// Copyright (C) 2020-2023 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_FMT_H
+#define RUST_FMT_H
+
+#include "expected.h"
+#include "optional.h"
+#include "rust-ast.h"
+#include "rust-system.h"
+
+namespace Rust {
+
+/**
+ * This class implements the parsing of Rust format strings according to the
+ * grammar here: https://doc.rust-lang.org/std/fmt/index.html#syntax
+ */
+// TODO: Are there features that are only present in specific Rust edition

[PATCH 017/125] gccrs: rust-fmt: Store parsed string in Pieces struct

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::collect): Fix signature to take ownership
of the given string.
* ast/rust-fmt.h (struct Pieces): Store parsed string in the struct.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Add debug prompt.
---
 gcc/rust/ast/rust-fmt.cc | 4 ++--
 gcc/rust/ast/rust-fmt.h  | 7 +--
 libgrust/libformat_parser/src/lib.rs | 1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index f6ee8a20913..511e94740c5 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -23,7 +23,7 @@ namespace Rust {
 namespace Fmt {
 
 Pieces
-Pieces::collect (const std::string &to_parse)
+Pieces::collect (std::string &&to_parse)
 {
   auto piece_slice = collect_pieces (to_parse.c_str ());
 
@@ -34,7 +34,7 @@ Pieces::collect (const std::string &to_parse)
   // auto pieces = std::vector (piece_slice.base_ptr,
   //piece_slice.base_ptr + piece_slice.len);
 
-  return Pieces (piece_slice);
+  return Pieces (piece_slice, std::move (to_parse));
 }
 
 Pieces::~Pieces () { destroy_pieces (slice); }
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 50aeff6433e..0bf9695bb6d 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -251,13 +251,16 @@ void destroy_pieces (PieceSlice);
 
 struct Pieces
 {
-  static Pieces collect (const std::string &to_parse);
+  static Pieces collect (std::string &&to_parse);
   ~Pieces ();
 
 private:
-  Pieces (PieceSlice slice) : slice (slice) {}
+  Pieces (PieceSlice slice, std::string &&to_parse)
+: slice (slice), to_parse (std::move (to_parse))
+  {}
 
   PieceSlice slice;
+  std::string to_parse;
 };
 
 } // namespace Fmt
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index 9b2bffed05d..eb3e1060e5d 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -340,6 +340,7 @@ pub struct PieceSlice {
 pub extern "C" fn collect_pieces(input: *const libc::c_char) -> PieceSlice {
 // FIXME: Add comment
 let str = unsafe { CStr::from_ptr(input) };
+dbg!(str);
 
 // FIXME: No unwrap
 let pieces: Vec> = 
rust::collect_pieces(str.to_str().unwrap())
-- 
2.45.2



[PATCH 025/125] gccrs: hir: Add ExternalTypeItem node

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* hir/tree/rust-hir-item.h (class ExternalTypeItem): New class.
* hir/tree/rust-hir.cc (ExternalTypeItem::as_string): Likewise.
* backend/rust-compile-extern.h: Add base for handling 
HIR::ExternalTypeItem
node.
* checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
* checks/errors/borrowck/rust-function-collector.h: Likewise.
* checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise.
* checks/errors/rust-const-checker.h: Likewise.
* checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise.
* checks/errors/rust-unsafe-checker.h: Likewise.
* hir/rust-ast-lower-extern.h: Likewise.
* hir/rust-hir-dump.cc (Dump::visit): Likewise.
* hir/rust-hir-dump.h: Likewise.
* hir/tree/rust-hir-full-decls.h (class ExternalTypeItem): Likewise.
* hir/tree/rust-hir-visitor.h: Likewise.
(ExternalTypeItem::accept_vis): Likewise.
* typecheck/rust-hir-type-check-implitem.cc 
(TypeCheckTopLevelExternItem::visit): Likewise.
* typecheck/rust-hir-type-check-implitem.h: Likewise.
---
 gcc/rust/backend/rust-compile-extern.h|   7 +
 .../errors/borrowck/rust-bir-builder-struct.h |   1 +
 .../errors/borrowck/rust-function-collector.h |   1 +
 gcc/rust/checks/errors/rust-const-checker.cc  |   4 +
 gcc/rust/checks/errors/rust-const-checker.h   |   1 +
 gcc/rust/checks/errors/rust-unsafe-checker.cc |   4 +
 gcc/rust/checks/errors/rust-unsafe-checker.h  |   1 +
 gcc/rust/hir/rust-ast-lower-extern.h  |   5 +
 gcc/rust/hir/rust-hir-dump.cc |  10 ++
 gcc/rust/hir/rust-hir-dump.h  |   1 +
 gcc/rust/hir/tree/rust-hir-full-decls.h   |   1 +
 gcc/rust/hir/tree/rust-hir-item.h |  39 +-
 gcc/rust/hir/tree/rust-hir-visitor.h  |   3 +
 gcc/rust/hir/tree/rust-hir.cc |  25 
 .../typecheck/rust-hir-type-check-implitem.cc | 129 ++
 .../typecheck/rust-hir-type-check-implitem.h  |   1 +
 16 files changed, 230 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-extern.h 
b/gcc/rust/backend/rust-compile-extern.h
index 778553e5b37..b17ac954167 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -22,6 +22,8 @@
 #include "rust-compile-base.h"
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-type.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-full-decls.h"
 
 namespace Rust {
 namespace Compile {
@@ -152,6 +154,11 @@ public:
 reference = address_expression (fndecl, ref_locus);
   }
 
+  void visit (HIR::ExternalTypeItem &type) override
+  {
+rust_sorry_at (type.get_locus (), "extern types are not supported yet");
+  }
+
 private:
   CompileExternItem (Context *ctx, TyTy::BaseType *concrete,
 location_t ref_locus)
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index d6390392d7f..6a990e25c43 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -189,6 +189,7 @@ protected:
   void visit (HIR::ImplBlock &impl) override { rust_unreachable (); }
   void visit (HIR::ExternalStaticItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternalFunctionItem &item) override { rust_unreachable (); 
}
+  void visit (HIR::ExternalTypeItem &item) override { rust_unreachable (); }
   void visit (HIR::ExternBlock &block) override { rust_unreachable (); }
   void visit (HIR::LiteralPattern &pattern) override { rust_unreachable (); }
   void visit (HIR::IdentifierPattern &pattern) override { rust_unreachable (); 
}
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index b19bfdf855e..18f2f5e11d1 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -155,6 +155,7 @@ public:
   void visit (HIR::ImplBlock &impl) override {}
   void visit (HIR::ExternalStaticItem &item) override {}
   void visit (HIR::ExternalFunctionItem &item) override {}
+  void visit (HIR::ExternalTypeItem &item) override {}
   void visit (HIR::ExternBlock &block) override {}
   void visit (HIR::LiteralPattern &pattern) override {}
   void visit (HIR::IdentifierPattern &pattern) override {}
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index aaf8fc0c3f6..886ae18d314 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -714,6 +714,10 @@ void
 ConstChecker::visit (ExternalFunctionItem &)
 {}
 
+void
+ConstChecker::visit (ExternalTypeItem &)
+{}
+
 void
 ConstChecker::visit (ExternBlock &block)
 {
diff --git a/gcc/rust/checks/errors/rust-const-che

[PATCH 011/125] gccrs: libformat_parser: Add FFI safe interface

2024-08-01 Thread Arthur Cohen
libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Add generic
library.
* libformat_parser/src/lib.rs: Add base for FFI interface.
---
 .../generic_format_parser/src/lib.rs  |   2 +-
 libgrust/libformat_parser/src/lib.rs  | 301 +-
 2 files changed, 298 insertions(+), 5 deletions(-)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index f42c9d8dffb..87a20dc18c5 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -1099,4 +1099,4 @@ fn unescape_string(string: &str) -> 
Option {
 // rustc_index::static_assert_size!(Piece<'_>, 16);
 
 // #[cfg(test)]
-// mod tests;
\ No newline at end of file
+// mod tests;
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index e6dc16eeb49..49821e7cd2f 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -5,8 +5,298 @@
 
 use std::ffi::CStr;
 
-// TODO: Use rustc's version here #3
-use generic_format_parser::Piece;
+mod ffi {
+use std::ops::Deref;
+
+// Note: copied from rustc_span
+/// Range inside of a `Span` used for diagnostics when we only have access 
to relative positions.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[repr(C)]
+pub struct InnerSpan {
+pub start: usize,
+pub end: usize,
+}
+
+// impl InnerSpan {
+// pub fn new(start: usize, end: usize) -> InnerSpan {
+// InnerSpan { start, end }
+// }
+// }
+
+/// The location and before/after width of a character whose width has 
changed from its source code
+/// representation
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(C)]
+pub struct InnerWidthMapping {
+/// Index of the character in the source
+pub position: usize,
+/// The inner width in characters
+pub before: usize,
+/// The transformed width in characters
+pub after: usize,
+}
+
+// impl InnerWidthMapping {
+// pub fn new(position: usize, before: usize, after: usize) -> 
InnerWidthMapping {
+// InnerWidthMapping {
+// position,
+// before,
+// after,
+// }
+// }
+// }
+
+/// Whether the input string is a literal. If yes, it contains the inner 
width mappings.
+#[derive(Clone, PartialEq, Eq)]
+#[repr(C)]
+enum InputStringKind {
+NotALiteral,
+Literal {
+width_mappings: Vec,
+},
+}
+
+/// The type of format string that we are parsing.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[repr(C)]
+pub enum ParseMode {
+/// A normal format string as per `format_args!`.
+Format,
+/// An inline assembly template string for `asm!`.
+InlineAsm,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct InnerOffset(usize);
+
+/// A piece is a portion of the format string which represents the next 
part
+/// to emit. These are emitted as a stream by the `Parser` class.
+#[derive(Clone, Debug, PartialEq)]
+#[repr(C)]
+pub enum Piece<'a> {
+/// A literal string which should directly be emitted
+String(&'a str),
+/// This describes that formatting should process the next argument (as
+/// specified inside) for emission.
+NextArgument(Box>),
+}
+
+/// Representation of an argument specification.
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(C)]
+pub struct Argument<'a> {
+/// Where to find this argument
+pub position: Position<'a>,
+/// The span of the position indicator. Includes any whitespace in 
implicit
+/// positions (`{  }`).
+pub position_span: InnerSpan,
+/// How to format the argument
+pub format: FormatSpec<'a>,
+}
+
+/// Specification for the formatting of an argument in the format string.
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(C)]
+pub struct FormatSpec<'a> {
+/// Optionally specified character to fill alignment with.
+pub fill: Option,
+/// Span of the optionally specified fill character.
+pub fill_span: Option,
+/// Optionally specified alignment.
+pub align: Alignment,
+/// The `+` or `-` flag.
+pub sign: Option,
+/// The `#` flag.
+pub alternate: bool,
+/// The `0` flag.
+pub zero_pad: bool,
+/// The `x` or `X` flag. (Only for `Debug`.)
+pub debug_hex: Option,
+/// The integer precision to use.
+pub precision: Count<'a>,
+/// The span of the precision formatting flag (for diagnostics).
+pub precision_span: Option,
+/// The string width requested for the result

[PATCH 005/125] gccrs: libgrust: Add format_parser library

2024-08-01 Thread Arthur Cohen
Compile libformat_parser and link to it.

gcc/rust/ChangeLog:

* Make-lang.in: Compile libformat_parser.
* ast/rust-fmt.cc: New FFI definitions.
* ast/rust-fmt.h: Likewise.
* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler): 
Call
into libformat_parser.
* expand/rust-macro-builtins.h: Define format_args!() handler proper.

libgrust/ChangeLog:

* libformat_parser/Cargo.lock: New file.
* libformat_parser/Cargo.toml: New file.
* libformat_parser/generic_format_parser/Cargo.toml: New file.
* libformat_parser/generic_format_parser/src/lib.rs: New file.
* libformat_parser/src/bin.rs: New file.
* libformat_parser/src/lib.rs: New file.
---
 gcc/rust/Make-lang.in |   11 +-
 gcc/rust/ast/rust-fmt.cc  |   77 +-
 gcc/rust/ast/rust-fmt.h   |  189 +--
 gcc/rust/expand/rust-macro-builtins.cc|   12 +-
 gcc/rust/expand/rust-macro-builtins.h |3 +
 libgrust/libformat_parser/Cargo.lock  |   30 +
 libgrust/libformat_parser/Cargo.toml  |   21 +
 .../generic_format_parser/Cargo.toml  |9 +
 .../generic_format_parser/src/lib.rs  | 1102 +
 libgrust/libformat_parser/src/bin.rs  |7 +
 libgrust/libformat_parser/src/lib.rs  |   41 +
 11 files changed, 1349 insertions(+), 153 deletions(-)
 create mode 100644 libgrust/libformat_parser/Cargo.lock
 create mode 100644 libgrust/libformat_parser/Cargo.toml
 create mode 100644 libgrust/libformat_parser/generic_format_parser/Cargo.toml
 create mode 100644 libgrust/libformat_parser/generic_format_parser/src/lib.rs
 create mode 100644 libgrust/libformat_parser/src/bin.rs
 create mode 100644 libgrust/libformat_parser/src/lib.rs

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index c0df49a7fee..8ac0d1d1973 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -54,6 +54,8 @@ GCCRS_D_OBJS = \
rust/rustspec.o \
$(END)
 
+LIBS += -ldl -lpthread
+
 gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
  $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
@@ -218,7 +220,7 @@ RUST_LIBDEPS = $(LIBDEPS) $(LIBPROC_MACRO_INTERNAL)
 crab1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(RUST_LIBDEPS) 
$(rust.prev)
@$(call LINK_PROGRESS,$(INDEX.rust),start)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
- $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) $(BACKENDLIBS)
+ $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) 
$(LIBPROC_MACRO_INTERNAL) rust/libformat_parser.a  $(BACKENDLIBS)
@$(call LINK_PROGRESS,$(INDEX.rust),end)
 
 # Build hooks.
@@ -406,6 +408,13 @@ rust/%.o: rust/lex/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
 
+%.toml: 
+   echo $@
+
+rust/libformat_parser.a: $(srcdir)/../libgrust/libformat_parser/Cargo.toml 
$(wildcard $(srcdir)/../libgrust/libformat_parser/src/*.rs)
+   cargo build --manifest-path 
$(srcdir)/../libgrust/libformat_parser/Cargo.toml --release # FIXME: Not always 
release, right?
+   cp 
$(srcdir)/../libgrust/libformat_parser/target/release/liblibformat_parser.a $@
+
 # build all rust/parse files in rust folder, add cross-folder includes
 rust/%.o: rust/parse/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index 9f9ba48f0c3..559b1c8b579 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -19,78 +19,23 @@
 #include "rust-fmt.h"
 
 namespace Rust {
-tl::expected
-Fmt::parse_fmt_string (Fmt::Input input)
-{
-  return Fmt ();
-}
+namespace Fmt {
 
-tl::expected>, Fmt::Error>
-Fmt::maybe_format (Fmt::Input input)
+Pieces
+Pieces::collect (const std::string &to_parse)
 {
-  tl::optional none = tl::nullopt;
+  auto piece_slice = collect_pieces (to_parse.c_str ());
 
-  return Fmt::Result (input, none);
-}
+  rust_debug ("[ARTHUR] %p, %lu", (void *) piece_slice.ptr, piece_slice.len);
 
-tl::expected, Fmt::Error>
-Fmt::format (Input input)
-{
-  return Fmt::Result (input, Format ());
-}
+  // this performs multiple copies, can we avoid them maybe?
+  auto pieces
+= std::vector (piece_slice.ptr, piece_slice.ptr + piece_slice.len);
 
-tl::expected, Fmt::Error>
-Fmt::argument (Input input)
-{
-  return Fmt::Result (input, Argument ());
-}
+  rust_debug ("[ARTHUR] %p, %lu", (void *) pieces.data (), pieces.size ());
 
-tl::expected, Fmt::Error>
-Fmt::format_spec (Input input)
-{
-  return Fmt::Result (input, FormatSpec ());
-}
-
-tl::expected, Fmt::Error>
-Fmt::fill (Input input)
-{
-  return Fmt::Result (input, Fill ());
-}
-
-tl::expected, Fmt::Error>
-Fmt::align (Input input)
-{
-  switch (input[0])
-{
-case '<':
-  return Fmt::Result (input.substr (1), Align::Left);
-

[PATCH 012/125] gccrs: libformat_parser: Start experimenting with cbindgen

2024-08-01 Thread Arthur Cohen
libgrust/ChangeLog:

* libformat_parser/cbindgen.toml: New file.
* libformat_parser/libformat-parser.h: New file.

gcc/rust/ChangeLog:

* ast/rust-fmt.h: Add remaining FFI types.
---
 gcc/rust/ast/rust-fmt.h  |   4 +-
 libgrust/libformat_parser/cbindgen.toml  |   0
 libgrust/libformat_parser/libformat-parser.h | 224 +++
 3 files changed, 226 insertions(+), 2 deletions(-)
 create mode 100644 libgrust/libformat_parser/cbindgen.toml
 create mode 100644 libgrust/libformat_parser/libformat-parser.h

diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 0050977358f..27c1c3625d3 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -92,11 +92,11 @@ struct FormatSpec
   /// The `x` or `X` flag. (Only for `Debug`.)
   tl::optional debug_hex;
   /// The integer precision to use.
-  // Count <'a> precision;
+  Count precision;
   /// The span of the precision formatting flag (for diagnostics).
   tl::optional precision_span;
   /// The string width requested for the resulting format.
-  // Count <'a> width;
+  Count width;
   /// The span of the width formatting flag (for diagnostics).
   tl::optional width_span;
   /// The descriptor string representing the name of the format desired for
diff --git a/libgrust/libformat_parser/cbindgen.toml 
b/libgrust/libformat_parser/cbindgen.toml
new file mode 100644
index 000..e69de29bb2d
diff --git a/libgrust/libformat_parser/libformat-parser.h 
b/libgrust/libformat_parser/libformat-parser.h
new file mode 100644
index 000..a4bc8a75494
--- /dev/null
+++ b/libgrust/libformat_parser/libformat-parser.h
@@ -0,0 +1,224 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/// Enum of alignments which are supported.
+enum class Alignment
+{
+  /// The value will be aligned to the left.
+  AlignLeft,
+  /// The value will be aligned to the right.
+  AlignRight,
+  /// The value will be aligned in the center.
+  AlignCenter,
+  /// The value will take on a default alignment.
+  AlignUnknown,
+};
+
+/// Enum for the debug hex flags.
+enum class DebugHex
+{
+  /// The `x` flag in `{:x?}`.
+  Lower,
+  /// The `X` flag in `{:X?}`.
+  Upper,
+};
+
+/// Enum for the sign flags.
+enum class Sign
+{
+  /// The `+` flag.
+  Plus,
+  /// The `-` flag.
+  Minus,
+};
+
+template  struct Box;
+
+template  struct Option;
+
+/// Enum describing where an argument for a format can be located.
+struct Position
+{
+  enum class Tag
+  {
+/// The argument is implied to be located at an index
+ArgumentImplicitlyIs,
+/// The argument is located at a specific index given in the format,
+ArgumentIs,
+/// The argument has a name.
+ArgumentNamed,
+  };
+
+  struct ArgumentImplicitlyIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct ArgumentIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct ArgumentNamed_Body
+  {
+const str *_0;
+  };
+
+  Tag tag;
+  union
+  {
+ArgumentImplicitlyIs_Body argument_implicitly_is;
+ArgumentIs_Body argument_is;
+ArgumentNamed_Body argument_named;
+  };
+};
+
+/// Range inside of a `Span` used for diagnostics when we only have access to
+/// relative positions.
+struct InnerSpan
+{
+  uintptr_t start;
+  uintptr_t end;
+};
+
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+struct Count
+{
+  enum class Tag
+  {
+/// The count is specified explicitly.
+CountIs,
+/// The count is specified by the argument with the given name.
+CountIsName,
+/// The count is specified by the argument at the given index.
+CountIsParam,
+/// The count is specified by a star (like in `{:.*}`) that refers to the
+/// argument at the given index.
+CountIsStar,
+/// The count is implied and cannot be explicitly specified.
+CountImplied,
+  };
+
+  struct CountIs_Body
+  {
+uintptr_t _0;
+  };
+
+  struct CountIsName_Body
+  {
+const str *_0;
+InnerSpan _1;
+  };
+
+  struct CountIsParam_Body
+  {
+uintptr_t _0;
+  };
+
+  struct CountIsStar_Body
+  {
+uintptr_t _0;
+  };
+
+  Tag tag;
+  union
+  {
+CountIs_Body count_is;
+CountIsName_Body count_is_name;
+CountIsParam_Body count_is_param;
+CountIsStar_Body count_is_star;
+  };
+};
+
+/// Specification for the formatting of an argument in the format string.
+struct FormatSpec
+{
+  /// Optionally specified character to fill alignment with.
+  Option fill;
+  /// Span of the optionally specified fill character.
+  Option fill_span;
+  /// Optionally specified alignment.
+  Alignment align;
+  /// The `+` or `-` flag.
+  Option sign;
+  /// The `#` flag.
+  bool alternate;
+  /// The `0` flag.
+  bool zero_pad;
+  /// The `x` or `X` flag. (Only for `Debug`.)
+  Option debug_hex;
+  /// The integer precision to use.
+  Count precision;
+  /// The span of the precision formatting flag (for diagnostics).
+  Option precision_span;
+  /// The st

[PATCH 024/125] gccrs: extern-types: Declare external types in name resolver.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-implitem.h: Declare external types as new
types.
---
 gcc/rust/resolve/rust-ast-resolve-implitem.h | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h 
b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index fabc25817f5..4f4d2893f83 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -228,6 +228,25 @@ public:
 mappings->insert_module_child_item (current_module, decl);
   }
 
+  void visit (AST::ExternalTypeItem &type) override
+  {
+auto decl = CanonicalPath::new_seg (type.get_node_id (),
+   type.get_identifier ().as_string ());
+auto path = prefix.append (decl);
+
+resolver->get_type_scope ().insert (
+  path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
+  [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+   rich_location r (line_table, type.get_locus ());
+   r.add_range (locus);
+
+   rust_error_at (r, "redefined multiple times");
+  });
+
+NodeId current_module = resolver->peek_current_module_scope ();
+mappings->insert_module_child_item (current_module, decl);
+  }
+
 private:
   ResolveToplevelExternItem (const CanonicalPath &prefix)
 : ResolverBase (), prefix (prefix)
-- 
2.45.2



[PATCH 014/125] gccrs: libformat_parser: Send boxed values across FFI properly

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::~Pieces): Call libformat_parser's release
function in destructor.
* ast/rust-fmt.h (struct PieceSlice): Add capacity.
(destroy_pieces): New.
(struct Pieces): Add destructor.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Leak Boxes properly for C++ to
see them, add memory release function.
---
 gcc/rust/ast/rust-fmt.cc |  4 +-
 gcc/rust/ast/rust-fmt.h  |  9 +++
 libgrust/libformat_parser/src/lib.rs | 94 ++--
 3 files changed, 58 insertions(+), 49 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index a7c4341c52d..f6ee8a20913 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -34,8 +34,10 @@ Pieces::collect (const std::string &to_parse)
   // auto pieces = std::vector (piece_slice.base_ptr,
   //piece_slice.base_ptr + piece_slice.len);
 
-  return Pieces{};
+  return Pieces (piece_slice);
 }
 
+Pieces::~Pieces () { destroy_pieces (slice); }
+
 } // namespace Fmt
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 7ec9a2a199d..50aeff6433e 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -237,6 +237,7 @@ struct PieceSlice
 {
   const Piece *base_ptr;
   size_t len;
+  size_t cap;
 };
 
 extern "C" {
@@ -244,11 +245,19 @@ extern "C" {
 PieceSlice
 collect_pieces (const char *input);
 
+void destroy_pieces (PieceSlice);
+
 } // extern "C"
 
 struct Pieces
 {
   static Pieces collect (const std::string &to_parse);
+  ~Pieces ();
+
+private:
+  Pieces (PieceSlice slice) : slice (slice) {}
+
+  PieceSlice slice;
 };
 
 } // namespace Fmt
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index 4bbc468c755..9b2bffed05d 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -3,21 +3,17 @@
 // what's the plan? Have a function return something that can be constructed 
into a vector?
 // or an iterator?
 
-use std::ffi::CStr;
+use std::{ffi::CStr, mem};
 
-trait IntoFFI {
-type Output;
-
-fn into_ffi(&self) -> Self::Output;
+trait IntoFFI {
+fn into_ffi(self) -> T;
 }
 
-impl IntoFFI for Option
+impl IntoFFI<*const T> for Option
 where
 T: Sized,
 {
-type Output = *const T;
-
-fn into_ffi(&self) -> Self::Output {
+fn into_ffi(self) -> *const T {
 match self.as_ref() {
 None => std::ptr::null(),
 Some(r) => r as *const T,
@@ -40,12 +36,6 @@ mod ffi {
 pub end: usize,
 }
 
-// impl InnerSpan {
-// pub fn new(start: usize, end: usize) -> InnerSpan {
-// InnerSpan { start, end }
-// }
-// }
-
 /// The location and before/after width of a character whose width has 
changed from its source code
 /// representation
 #[derive(Copy, Clone, PartialEq, Eq)]
@@ -59,35 +49,27 @@ mod ffi {
 pub after: usize,
 }
 
-// impl InnerWidthMapping {
-// pub fn new(position: usize, before: usize, after: usize) -> 
InnerWidthMapping {
-// InnerWidthMapping {
-// position,
-// before,
-// after,
-// }
-// }
+// TODO: Not needed for now?
+// /// Whether the input string is a literal. If yes, it contains the 
inner width mappings.
+// #[derive(Clone, PartialEq, Eq)]
+// #[repr(C)]
+// enum InputStringKind {
+// NotALiteral,
+// Literal {
+// width_mappings: Vec,
+// },
 // }
 
-/// Whether the input string is a literal. If yes, it contains the inner 
width mappings.
-#[derive(Clone, PartialEq, Eq)]
-#[repr(C)]
-enum InputStringKind {
-NotALiteral,
-Literal {
-width_mappings: Vec,
-},
-}
-
-/// The type of format string that we are parsing.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-#[repr(C)]
-pub enum ParseMode {
-/// A normal format string as per `format_args!`.
-Format,
-/// An inline assembly template string for `asm!`.
-InlineAsm,
-}
+// TODO: Not needed for now?
+// /// The type of format string that we are parsing.
+// #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+// #[repr(C)]
+// pub enum ParseMode {
+// /// A normal format string as per `format_args!`.
+// Format,
+// /// An inline assembly template string for `asm!`.
+// InlineAsm,
+// }
 
 #[derive(Copy, Clone)]
 #[repr(C)]
@@ -102,7 +84,13 @@ mod ffi {
 String(&'a str),
 /// This describes that formatting should process the next argument (as
 /// specified inside) for emission.
-NextArgument(Box>),
+NextArgument(*const Argument<'a>),
+}
+
+impl<'a> Drop for Piece<'a> {
+fn drop(&mut self) {
+println!("dropping Piece

[PATCH 027/125] gccrs: Make DefaultResolver visit more of the AST

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc
(DefaultResolver::visit): Visit inner AST nodes of ClosureExprInner,
ClosureExprInnerTyped, IfExpr, IfExprConseqElse, MatchExpr,
PathInExpression, EnumItemTuple, EnumItemStruct, and
EnumItemDiscriminant.
* ast/rust-item.h
(EnumItemDiscriminant::has_expr): New function.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-item.h  |   2 +
 gcc/rust/resolve/rust-default-resolver.cc | 105 ++
 2 files changed, 91 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 0911719b716..44963ba386e 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -2081,6 +2081,8 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
+  bool has_expr () { return expression != nullptr; }
+
   // TODO: is this better? Or is a "vis_block" better?
   std::unique_ptr &get_expr ()
   {
diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 9f7fda4adaa..28f04a10839 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -177,12 +177,43 @@ DefaultResolver::visit (AST::StructExprFieldIndexValue &)
 {}
 
 void
-DefaultResolver::visit (AST::ClosureExprInner &)
-{}
+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);
+}
 
 void
-DefaultResolver::visit (AST::ClosureExprInnerTyped &)
-{}
+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::ContinueExpr &expr)
@@ -230,11 +261,18 @@ DefaultResolver::visit (AST::WhileLetLoopExpr &expr)
 
 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 &)
-{}
+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);
+}
 
 void
 DefaultResolver::visit (AST::IfLetExpr &expr)
@@ -246,7 +284,20 @@ DefaultResolver::visit (AST::IfLetExprConseqElse &)
 
 void
 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::AwaitExpr &expr)
@@ -277,8 +328,21 @@ DefaultResolver::visit (AST::ConstGenericParam &)
 {}
 
 void
-DefaultResolver::visit (AST::PathInExpression &)
-{}
+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::TypePathSegmentGeneric &)
@@ -373,16 +437,25 @@ DefaultResolver::visit (AST::EnumItem &)
 {}
 
 void
-DefaultResolver::visit (AST::EnumItemTuple &)
-{}
+DefaultResolver::visit (AST::EnumItemTuple &item)
+{
+  for (auto &field : item.get_tuple_fields ())
+field.get_field_type ()->accept_vis (*this);
+}
 
 void
-DefaultResolver::visit (AST::EnumItemStruct &)
-{}
+DefaultResolver::visit (AST::EnumItemStruct &item)
+{
+  for (auto &field : item.get_struct_fields ())
+field.get_field_type ()->accept_vis (*this);
+}
 
 void
-DefaultResolver::visit (AST::EnumItemDiscriminant &)
-{}
+DefaultResolver::visit (AST::EnumItemDiscriminant &item)
+{
+  if (item.has_expr ())
+item.get_expr ()->accept_vis (*this);
+}
 
 void
 DefaultResolver::visit (AST::ConstantItem &item)
-- 
2.45.2



[PATCH 023/125] gccrs: lang-items: Make lang items enum stronger, rename class, cleanup ns.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* util/rust-lang-item.h (class RustLangItem): Renamed to...
(class LangItem): ...this. Rename ItemType enum to Kind
* util/rust-lang-item.cc: Rename methods to use new class name.
* backend/rust-compile-expr.cc (CompileExpr::visit): Use new lang-item 
API.
(CompileExpr::resolve_operator_overload): Likewise.
* backend/rust-compile-expr.h: Likewise.
* hir/rust-ast-lower-base.cc 
(ASTLoweringBase::handle_lang_item_attribute): Likewise.
* typecheck/rust-autoderef.cc (Adjuster::try_deref_type): Likewise.
(AutoderefCycle::cycle): Likewise.
* typecheck/rust-autoderef.h: Likewise.
* typecheck/rust-hir-type-bounds.h: Likewise.
* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::get_marker_predicate): Likewise.
* typecheck/rust-hir-type-check-base.h: Likewise.
* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.
* typecheck/rust-hir-type-check-expr.h: Likewise.
* typecheck/rust-hir-type-check-type.cc 
(TypeResolveGenericParam::visit): Likewise.
* typecheck/rust-tyty-bounds.cc 
(TypeBoundsProbe::assemble_sized_builtin): Likewise.
(TypeBoundsProbe::assemble_builtin_candidate): Likewise.
(TypeCheckBase::get_predicate_from_bound): Likewise.
* typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): Likewise.
* util/rust-hir-map.cc (Mappings::get_lang_item): Likewise.
(Mappings::lookup_trait_item_lang_item): Likewise.
* util/rust-hir-map.h: Likewise.
---
 gcc/rust/backend/rust-compile-expr.cc |  24 +-
 gcc/rust/backend/rust-compile-expr.h  |   8 +-
 gcc/rust/hir/rust-ast-lower-base.cc   |   2 +-
 gcc/rust/typecheck/rust-autoderef.cc  |  22 +-
 gcc/rust/typecheck/rust-autoderef.h   |   5 +-
 gcc/rust/typecheck/rust-hir-type-bounds.h |   2 +-
 .../typecheck/rust-hir-type-check-base.cc |   3 +-
 gcc/rust/typecheck/rust-hir-type-check-base.h |   5 +-
 .../typecheck/rust-hir-type-check-expr.cc |  72 +++---
 gcc/rust/typecheck/rust-hir-type-check-expr.h |   7 +-
 .../typecheck/rust-hir-type-check-type.cc |   3 +-
 gcc/rust/typecheck/rust-tyty-bounds.cc|  12 +-
 gcc/rust/typecheck/rust-tyty.cc   |   5 +-
 gcc/rust/util/rust-hir-map.cc |   7 +-
 gcc/rust/util/rust-hir-map.h  |  13 +-
 gcc/rust/util/rust-lang-item.cc   | 218 +-
 gcc/rust/util/rust-lang-item.h|  31 ++-
 17 files changed, 213 insertions(+), 226 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 596b848849e..65de24bf9d8 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -150,7 +150,7 @@ CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
   if (is_op_overload)
 {
   auto lang_item_type
-   = Analysis::RustLangItem::OperatorToLangItem (expr.get_expr_type ());
+   = LangItem::OperatorToLangItem (expr.get_expr_type ());
   translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
  expr.get_lhs ().get (),
  expr.get_rhs ().get ());
@@ -193,9 +193,8 @@ CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type
-   = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
- expr.get_expr_type ());
+  auto lang_item_type = LangItem::CompoundAssignmentOperatorToLangItem (
+   expr.get_expr_type ());
   auto compound_assignment
= resolve_operator_overload (lang_item_type, expr, lhs, rhs,
 expr.get_lhs ().get (),
@@ -244,8 +243,7 @@ CompileExpr::visit (HIR::NegationExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type
-   = Analysis::RustLangItem::NegationOperatorToLangItem (op);
+  auto lang_item_type = LangItem::NegationOperatorToLangItem (op);
   translated
= resolve_operator_overload (lang_item_type, expr, negated_expr,
 nullptr, expr.get_expr ().get (), nullptr);
@@ -836,7 +834,7 @@ CompileExpr::visit (HIR::DereferenceExpr &expr)
 expr.get_mappings ().get_hirid (), &fntype);
   if (is_op_overload)
 {
-  auto lang_item_type = Analysis::RustLangItem::ItemType::DEREF;
+  auto lang_item_type = LangItem::Kind::DEREF;
   tree operator_overload_call
= resolve_operator_overload (lang_item_type, expr, main_expr, nullptr,
 expr.get_expr ().get (), nullptr);
@@ -1423,9 +1421,10 @@ CompileExpr::get_receiver_from_dyn (const 
TyTy::DynamicObjectType *dyn,
 }
 
 tree
-CompileExpr::resolve_operator_overload (
-  Analysis

[PATCH 034/125] gccrs: Add error emitting when we can't resolve id expr

2024-08-01 Thread Arthur Cohen
From: jjasmine 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add error 
emitting
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index f9731a451a3..8717c51e34a 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -130,7 +130,10 @@ Late::visit (AST::IdentifierExpr &expr)
 resolved = label;
   else if (value)
 resolved = value;
-  // TODO: else emit error?
+  else {
+  rust_error_at(expr.get_locus (), "could not resolve identifier 
expression: %qs", expr.get_ident ().as_string ().c_str ());
+  return;
+  }
 
   ctx.map_usage (expr.get_node_id (), *resolved);
 
-- 
2.45.2



[PATCH 013/125] gccrs: libformat_parser: Update header and remove old interface

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-fmt.cc (Pieces::collect): Use new Pieces API.
* ast/rust-fmt.h: Update interface with new FFI bindings.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Add IntoFFI trait.
* libformat_parser/libformat-parser.h: Removed.
---
 gcc/rust/ast/rust-fmt.cc |  10 +-
 gcc/rust/ast/rust-fmt.h  | 199 
 libgrust/libformat_parser/libformat-parser.h | 224 ---
 libgrust/libformat_parser/src/lib.rs |  56 +++--
 4 files changed, 200 insertions(+), 289 deletions(-)
 delete mode 100644 libgrust/libformat_parser/libformat-parser.h

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index 559b1c8b579..a7c4341c52d 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-fmt.h"
+#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace Fmt {
@@ -26,13 +27,12 @@ Pieces::collect (const std::string &to_parse)
 {
   auto piece_slice = collect_pieces (to_parse.c_str ());
 
-  rust_debug ("[ARTHUR] %p, %lu", (void *) piece_slice.ptr, piece_slice.len);
+  rust_debug ("[ARTHUR] %p, %lu", (const void *) piece_slice.base_ptr,
+ piece_slice.len);
 
   // this performs multiple copies, can we avoid them maybe?
-  auto pieces
-= std::vector (piece_slice.ptr, piece_slice.ptr + piece_slice.len);
-
-  rust_debug ("[ARTHUR] %p, %lu", (void *) pieces.data (), pieces.size ());
+  // auto pieces = std::vector (piece_slice.base_ptr,
+  //piece_slice.base_ptr + piece_slice.len);
 
   return Pieces{};
 }
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index 27c1c3625d3..7ec9a2a199d 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+// Copyright (C) 2023-2024 Free Software Foundation, Inc.
 
 // This file is part of GCC.
 
@@ -19,9 +19,10 @@
 #ifndef RUST_FMT_H
 #define RUST_FMT_H
 
-#include "rust-diagnostics.h"
 #include "rust-system.h"
 
+// FIXME: How to encode Option?
+
 namespace Rust {
 namespace Fmt {
 
@@ -30,116 +31,220 @@ struct RustHamster
   // hehe
 };
 
-struct InnerSpan
+/// Enum of alignments which are supported.
+enum class Alignment
 {
+  /// The value will be aligned to the left.
+  AlignLeft,
+  /// The value will be aligned to the right.
+  AlignRight,
+  /// The value will be aligned in the center.
+  AlignCenter,
+  /// The value will take on a default alignment.
+  AlignUnknown,
 };
 
-struct Count
+/// Enum for the debug hex flags.
+enum class DebugHex
 {
-  enum class Kind
-  {
-Is,
-IsName,
-IsParam,
-IsStar,
-Implied
-  } kind;
-
-  union
-  {
-size_t is;
-std::pair is_name;
-size_t is_param;
-size_t is_star;
-  } data;
+  /// The `x` flag in `{:x?}`.
+  Lower,
+  /// The `X` flag in `{:X?}`.
+  Upper,
 };
 
-struct DebugHex
+/// Enum for the sign flags.
+enum class Sign
 {
+  /// The `+` flag.
+  Plus,
+  /// The `-` flag.
+  Minus,
 };
 
-struct Sign
+/// Enum describing where an argument for a format can be located.
+struct Position
 {
-};
+  enum class Tag
+  {
+/// The argument is implied to be located at an index
+ArgumentImplicitlyIs,
+/// The argument is located at a specific index given in the format,
+ArgumentIs,
+/// The argument has a name.
+ArgumentNamed,
+  };
 
-struct Alignment
-{
+  struct ArgumentImplicitlyIs_Body
+  {
+size_t _0;
+  };
+
+  struct ArgumentIs_Body
+  {
+size_t _0;
+  };
+
+  struct ArgumentNamed_Body
+  {
+RustHamster _0;
+  };
+
+  Tag tag;
+  union
+  {
+ArgumentImplicitlyIs_Body argument_implicitly_is;
+ArgumentIs_Body argument_is;
+ArgumentNamed_Body argument_named;
+  };
 };
 
-struct RustString
+/// Range inside of a `Span` used for diagnostics when we only have access to
+/// relative positions.
+struct InnerSpan
 {
-  // hehe
+  size_t start;
+  size_t end;
 };
 
-struct Position
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+struct Count
 {
+  enum class Tag
+  {
+/// The count is specified explicitly.
+CountIs,
+/// The count is specified by the argument with the given name.
+CountIsName,
+/// The count is specified by the argument at the given index.
+CountIsParam,
+/// The count is specified by a star (like in `{:.*}`) that refers to the
+/// argument at the given index.
+CountIsStar,
+/// The count is implied and cannot be explicitly specified.
+CountImplied,
+  };
+
+  struct CountIs_Body
+  {
+size_t _0;
+  };
+
+  struct CountIsName_Body
+  {
+RustHamster _0;
+InnerSpan _1;
+  };
+
+  struct CountIsParam_Body
+  {
+size_t _0;
+  };
+
+  struct CountIsStar_Body
+  {
+size_t _0;
+  };
+
+  Tag tag;
+  union
+  {
+CountIs_Body count_is;
+CountIsName_Body count

[PATCH 016/125] gccrs: format_args: Parse entire token invocation

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Transform entire invocation token stream into string for the parser.
---
 gcc/rust/expand/rust-macro-builtins.cc | 40 ++
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 19ea9109453..2af05a5e377 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 
+#include "libproc_macro_internal/tokenstream.h"
+#include "rust-token-converter.h"
 #include "rust-system.h"
 #include "rust-macro-builtins.h"
 #include "rust-ast-fragment.h"
@@ -947,24 +949,26 @@ tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
   AST::MacroInvocData &invoc)
 {
-  auto fmt_expr
-= parse_single_string_literal (BuiltinMacro::FormatArgs,
-  invoc.get_delim_tok_tree (), invoc_locus,
-  invoc.get_expander ());
-
-  if (!fmt_expr)
-return AST::Fragment::create_error ();
-
-  // if it is not a literal, it's an eager macro invocation - return it
-  if (!fmt_expr->is_literal ())
-{
-  auto token_tree = invoc.get_delim_tok_tree ();
-  return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
-   token_tree.to_token_stream ());
-}
-
-  auto format_string = fmt_expr->as_string ();
-  auto pieces = Fmt::Pieces::collect (format_string);
+  auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
+  tokens.erase (tokens.begin ());
+  tokens.pop_back ();
+
+  std::stringstream stream;
+  for (const auto &tok : tokens)
+stream << tok->as_string () << ' ';
+
+  rust_debug ("[ARTHU]: `%s`", stream.str ().c_str ());
+
+  // FIXME: We need to handle this
+  // // if it is not a literal, it's an eager macro invocation - return it
+  // if (!fmt_expr->is_literal ())
+  //   {
+  // auto token_tree = invoc.get_delim_tok_tree ();
+  // return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
+  //   token_tree.to_token_stream ());
+  //   }
+
+  auto pieces = Fmt::Pieces::collect (stream.str ());
 
   return AST::Fragment::create_empty ();
 }
-- 
2.45.2



[PATCH 015/125] gccrs: format_args: Parse format string properly

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Construct string to parser properly.
---
 gcc/rust/expand/rust-macro-builtins.cc | 19 ++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 0e57406f10f..19ea9109453 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -947,7 +947,24 @@ tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
   AST::MacroInvocData &invoc)
 {
-  Fmt::Pieces::collect ("heyo this {is} what I {} want to {3}, {parse}");
+  auto fmt_expr
+= parse_single_string_literal (BuiltinMacro::FormatArgs,
+  invoc.get_delim_tok_tree (), invoc_locus,
+  invoc.get_expander ());
+
+  if (!fmt_expr)
+return AST::Fragment::create_error ();
+
+  // if it is not a literal, it's an eager macro invocation - return it
+  if (!fmt_expr->is_literal ())
+{
+  auto token_tree = invoc.get_delim_tok_tree ();
+  return AST::Fragment ({AST::SingleASTNode (std::move (fmt_expr))},
+   token_tree.to_token_stream ());
+}
+
+  auto format_string = fmt_expr->as_string ();
+  auto pieces = Fmt::Pieces::collect (format_string);
 
   return AST::Fragment::create_empty ();
 }
-- 
2.45.2



[PATCH 019/125] gccrs: format-parser: Add `is_some_and` method for Option

2024-08-01 Thread Arthur Cohen
Workaround for Ubuntu 18.04, since we still use it for the GCC 4.8 CI.
The default Rust package is 1.65 (and unlikely to change I assume?),
but the generic format parser library uses `is_some_and` which was
introduced in 1.70. So this is a simple reimplementation, directly taken
from the standard library sources.

libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Add IsSomeAnd
trait, impl it for Option.
---
 .../generic_format_parser/src/lib.rs | 16 
 1 file changed, 16 insertions(+)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index 6a366177f25..8062bf9e5ce 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -22,6 +22,22 @@ fn is_id_continue(c: char) -> bool {
 unicode_xid::UnicodeXID::is_xid_continue(c)
 }
 
+// Workaround for Ubuntu 18.04. The default Rust package is 1.65 (and unlikely 
to change I assume?), but the
+// generic format parser library uses `is_some_and` which was introduced in 
1.70. So this is a reimplementation,
+// directly taken from the standard library sources
+trait IsSomeAnd {
+fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool;
+}
+
+impl IsSomeAnd for Option {
+fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool {
+match self {
+None => false,
+Some(x) => f(x),
+}
+}
+}
+
 // use rustc_lexer::unescape;
 pub use Alignment::*;
 pub use Count::*;
-- 
2.45.2



[PATCH 043/125] gccrs: Placate clang-format re 'gcc/rust/backend/rust-tree.cc'

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

Reformat the upstream GCC commit f4a2ae2338962208b8039f154f5912402e94c378
"Change MODE_BITSIZE to MODE_PRECISION for MODE_VECTOR_BOOL" change to
'gcc/rust/backend/rust-tree.cc' to clang-format's liking.

gcc/rust/
* backend/rust-tree.cc (c_common_type_for_mode): Placate clang-format.
---
 gcc/rust/backend/rust-tree.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/backend/rust-tree.cc b/gcc/rust/backend/rust-tree.cc
index 2a5ffcbf895..cdb79095da8 100644
--- a/gcc/rust/backend/rust-tree.cc
+++ b/gcc/rust/backend/rust-tree.cc
@@ -5371,8 +5371,8 @@ c_common_type_for_mode (machine_mode mode, int unsignedp)
   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
   && valid_vector_subparts_p (GET_MODE_NUNITS (mode)))
 {
-  unsigned int elem_bits
-   = vector_element_size (GET_MODE_PRECISION (mode), GET_MODE_NUNITS 
(mode));
+  unsigned int elem_bits = vector_element_size (GET_MODE_PRECISION (mode),
+   GET_MODE_NUNITS (mode));
   tree bool_type = build_nonstandard_boolean_type (elem_bits);
   return build_vector_type_for_mode (bool_type, mode);
 }
-- 
2.45.2



[PATCH 040/125] gccrs: Unify ASTValidation::visit for ExternalFunctionItem and Function

2024-08-01 Thread Arthur Cohen
From: 0xn4utilus 

gcc/rust/ChangeLog:

* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
Add external function validation support. Add ErrorCode::E0130.
* parse/rust-parse-impl.h (Parser::parse_function): Parse
external functions from `parse_function`.
(Parser::parse_external_item): Clang format.
(Parser::parse_pattern): Clang format.
* parse/rust-parse.h: Add default parameter
`is_external` in `parse_function`.

Signed-off-by: 0xn4utilus 
---
 gcc/rust/checks/errors/rust-ast-validation.cc | 62 +++
 gcc/rust/parse/rust-parse-impl.h  |  9 +--
 gcc/rust/parse/rust-parse.h   |  3 +-
 3 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index bf70ca5d96f..f5a97b0d350 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -122,23 +122,61 @@ ASTValidation::visit (AST::Function &function)
   function.get_self_param ()->get_locus (),
   "% parameter is only allowed in associated functions");
 
-  if (!function.has_body ())
+  if (function.is_external ())
 {
-  if (context.back () == Context::INHERENT_IMPL
- || context.back () == Context::TRAIT_IMPL)
+  if (function.has_body ())
+   rust_error_at (function.get_locus (), "cannot have a body");
+
+  auto ¶ms = function.get_function_params ();
+
+  if (params.size () == 1 && function.is_variadic ())
rust_error_at (function.get_locus (),
-  "associated function in % without body");
-  else if (context.back () != Context::TRAIT)
-   rust_error_at (function.get_locus (), "free function without a body");
+  "C-variadic function must be declared with at least one "
+  "named argument");
+
+  for (auto it = params.begin (); it != params.end (); it++)
+   {
+ if (it->get ()->is_variadic () && it + 1 != params.end ())
+   rust_error_at (
+ it->get ()->get_locus (),
+ "%<...%> must be the last argument of a C-variadic function");
+
+ // if functional parameter
+ if (!it->get ()->is_self () && !it->get ()->is_variadic ())
+   {
+ auto param = static_cast (it->get ());
+ auto kind = param->get_pattern ()->get_pattern_kind ();
+
+ if (kind != AST::Pattern::Kind::Identifier
+ && kind != AST::Pattern::Kind::Wildcard)
+   rust_error_at (it->get ()->get_locus (), ErrorCode::E0130,
+  "pattern not allowed in foreign function");
+   }
+   }
 }
 
-  auto &function_params = function.get_function_params ();
-  for (auto it = function_params.begin (); it != function_params.end (); it++)
+  else
 {
-  if (it->get ()->is_variadic ())
-   rust_error_at (it->get ()->get_locus (),
-  "only foreign or % functions may "
-  "be C-variadic");
+  if (!function.has_body ())
+   {
+ if (context.back () == Context::INHERENT_IMPL
+ || context.back () == Context::TRAIT_IMPL)
+   rust_error_at (function.get_locus (),
+  "associated function in % without body");
+ else if (context.back () != Context::TRAIT)
+   rust_error_at (function.get_locus (),
+  "free function without a body");
+   }
+  auto &function_params = function.get_function_params ();
+  for (auto it = function_params.begin (); it != function_params.end ();
+  it++)
+   {
+ if (it->get ()->is_variadic ())
+   rust_error_at (
+ it->get ()->get_locus (),
+ "only foreign or % functions may "
+ "be C-variadic");
+   }
 }
 
   AST::ContextualASTVisitor::visit (function);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 9d9722e9714..c8a87a11766 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2908,7 +2908,8 @@ Parser::parse_use_tree ()
 template 
 std::unique_ptr
 Parser::parse_function (AST::Visibility vis,
-   AST::AttrVec outer_attrs)
+   AST::AttrVec outer_attrs,
+   bool is_external)
 {
   location_t locus = lexer.peek_token ()->get_locus ();
   // Get qualifiers for function if they exist
@@ -2992,7 +2993,7 @@ Parser::parse_function 
(AST::Visibility vis,
   std::move (generic_params), std::move (function_params),
   std::move (return_type), std::move (where_clause),
   std::move (body), std::move (vis),
-  std::move (outer_attrs), locus));
+  st

[PATCH 018/125] gccrs: libformat_parser: Fix Rust warnings.

2024-08-01 Thread Arthur Cohen
libgrust/ChangeLog:

* libformat_parser/generic_format_parser/src/lib.rs: Remove
unused deprecated attribute and unused import.
* libformat_parser/src/lib.rs: Remove unused import.
---
 libgrust/libformat_parser/generic_format_parser/src/lib.rs | 2 --
 libgrust/libformat_parser/src/lib.rs   | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/libgrust/libformat_parser/generic_format_parser/src/lib.rs 
b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
index 87a20dc18c5..6a366177f25 100644
--- a/libgrust/libformat_parser/generic_format_parser/src/lib.rs
+++ b/libgrust/libformat_parser/generic_format_parser/src/lib.rs
@@ -14,12 +14,10 @@
 // WARNING: We want to be able to build this crate with a stable compiler,
 //  so no `#![feature]` attributes should be added!
 
-#[deprecated(note = "Use a proper lexer function for this")]
 fn is_id_start(c: char) -> bool {
 c == '_' || unicode_xid::UnicodeXID::is_xid_start(c)
 }
 
-#[deprecated(note = "Use a proper lexer function for this")]
 fn is_id_continue(c: char) -> bool {
 unicode_xid::UnicodeXID::is_xid_continue(c)
 }
diff --git a/libgrust/libformat_parser/src/lib.rs 
b/libgrust/libformat_parser/src/lib.rs
index eb3e1060e5d..c164578a103 100644
--- a/libgrust/libformat_parser/src/lib.rs
+++ b/libgrust/libformat_parser/src/lib.rs
@@ -3,7 +3,7 @@
 // what's the plan? Have a function return something that can be constructed 
into a vector?
 // or an iterator?
 
-use std::{ffi::CStr, mem};
+use std::ffi::CStr;
 
 trait IntoFFI {
 fn into_ffi(self) -> T;
-- 
2.45.2



[PATCH 021/125] gccrs: Fix small FixMe task in rust macro builtins

2024-08-01 Thread Arthur Cohen
From: jjasmine 

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc: Change BuiltinMacro in
builtin_macro_from_string to tl::optional<>
* expand/rust-macro-builtins.h (enum class): Change BuiltinMacro
in builtin_macro_from_string to tl::optional<>
* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
Resolved wrong type dependency of builtin_macro_from_string

Signed-off-by: jjasmine 
---
 gcc/rust/expand/rust-macro-builtins.cc   | 3 +--
 gcc/rust/expand/rust-macro-builtins.h| 2 +-
 gcc/rust/resolve/rust-early-name-resolver.cc | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 2af05a5e377..f103759acdd 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -126,8 +126,7 @@ std::unordered_map
 {"Hash", MacroBuiltin::proc_macro_builtin},
 };
 
-// FIXME: This should return an tl::optional
-BuiltinMacro
+tl::optional
 builtin_macro_from_string (const std::string &identifier)
 {
   auto macro = MacroBuiltin::builtins.lookup (identifier);
diff --git a/gcc/rust/expand/rust-macro-builtins.h 
b/gcc/rust/expand/rust-macro-builtins.h
index f9ab3fc3698..1d6b30b5933 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -75,7 +75,7 @@ enum class BuiltinMacro
   Hash,
 };
 
-BuiltinMacro
+tl::optional
 builtin_macro_from_string (const std::string &identifier);
 
 /**
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index 422dd92e462..d70f9ca9806 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -497,7 +497,7 @@ EarlyNameResolver::visit (AST::MacroInvocation &invoc)
 {
   auto builtin_kind
= builtin_macro_from_string (rules_def->get_rule_name ().as_string ());
-  invoc.map_to_builtin (builtin_kind);
+  invoc.map_to_builtin (builtin_kind.value ());
 }
 
   auto attributes = rules_def->get_outer_attrs ();
-- 
2.45.2



[PATCH 029/125] gccrs: macro-builtins: Add newline generic format_args!() handler

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (format_args_maker): New function.
(try_expand_many_expr): Add comment about reworking function.
(MacroBuiltin::format_args_handler): Add newline parameter.
* expand/rust-macro-builtins.h: Likewise.
---
 gcc/rust/expand/rust-macro-builtins.cc | 69 +++---
 gcc/rust/expand/rust-macro-builtins.h  |  4 +-
 2 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index f103759acdd..9e6716c5975 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "libproc_macro_internal/tokenstream.h"
+#include "rust-ast-full-decls.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-token-converter.h"
 #include "rust-system.h"
 #include "rust-macro-builtins.h"
@@ -78,6 +80,14 @@ const BiMap 
MacroBuiltin::builtins = {{
 
 }};
 
+AST::MacroTranscriberFunc
+format_args_maker (AST::FormatArgs::Newline nl)
+{
+  return [nl] (location_t loc, AST::MacroInvocData &invoc) {
+return MacroBuiltin::format_args_handler (loc, invoc, nl);
+  };
+}
+
 std::unordered_map
   MacroBuiltin::builtin_transcribers = {
 {"assert", MacroBuiltin::assert_handler},
@@ -92,10 +102,10 @@ std::unordered_map
 {"env", MacroBuiltin::env_handler},
 {"cfg", MacroBuiltin::cfg_handler},
 {"include", MacroBuiltin::include_handler},
-{"format_args", MacroBuiltin::format_args_handler},
+{"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
+{"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
 /* Unimplemented macro builtins */
 {"option_env", MacroBuiltin::sorry},
-{"format_args_nl", MacroBuiltin::sorry},
 {"concat_idents", MacroBuiltin::sorry},
 {"module_path", MacroBuiltin::sorry},
 {"asm", MacroBuiltin::sorry},
@@ -286,6 +296,8 @@ try_expand_many_expr (Parser &parser,
and return the LiteralExpr for it. Allow for an optional trailing comma,
but otherwise enforce that these are the only tokens.  */
 
+// FIXME(Arthur): This function needs a rework - it should not emit errors, it
+// should probably be smaller
 std::unique_ptr
 parse_single_string_literal (BuiltinMacro kind,
 AST::DelimTokenTree &invoc_token_tree,
@@ -946,17 +958,31 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
 
 tl::optional
 MacroBuiltin::format_args_handler (location_t invoc_locus,
-  AST::MacroInvocData &invoc)
+  AST::MacroInvocData &invoc,
+  AST::FormatArgs::Newline nl)
 {
+  // Remove the delimiters from the macro invocation:
+  // the invoc data for `format_args!(fmt, arg1, arg2)` is `(fmt, arg1, arg2)`,
+  // so we pop the front and back to remove the parentheses (or curly brackets,
+  // or brackets)
   auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
   tokens.erase (tokens.begin ());
   tokens.pop_back ();
 
-  std::stringstream stream;
-  for (const auto &tok : tokens)
-stream << tok->as_string () << ' ';
+  auto append_newline = nl == AST::FormatArgs::Newline::Yes ? true : false;
+  auto fmt_arg
+= parse_single_string_literal (append_newline ? BuiltinMacro::FormatArgsNl
+ : BuiltinMacro::FormatArgs,
+  invoc.get_delim_tok_tree (), invoc_locus,
+  invoc.get_expander ());
 
-  rust_debug ("[ARTHU]: `%s`", stream.str ().c_str ());
+  if (!fmt_arg->is_literal ())
+{
+  rust_sorry_at (
+   invoc_locus,
+   "cannot yet use eager macro invocations as format strings");
+  return AST::Fragment::create_empty ();
+}
 
   // FIXME: We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
@@ -967,8 +993,37 @@ MacroBuiltin::format_args_handler (location_t invoc_locus,
   //   token_tree.to_token_stream ());
   //   }
 
+  auto fmt_str = static_cast (*fmt_arg.get ());
+
+  // Switch on the format string to know if the string is raw or cooked
+  switch (fmt_str.get_lit_type ())
+{
+// case AST::Literal::RAW_STRING:
+case AST::Literal::STRING:
+  break;
+case AST::Literal::CHAR:
+case AST::Literal::BYTE:
+case AST::Literal::BYTE_STRING:
+case AST::Literal::INT:
+case AST::Literal::FLOAT:
+case AST::Literal::BOOL:
+case AST::Literal::ERROR:
+  rust_unreachable ();
+}
+
+  std::stringstream stream;
+  for (const auto &tok : tokens)
+stream << tok->as_string () << ' ';
+
+  rust_debug ("[ARTHUR]: `%s`", stream.str ().c_str ());
+
   auto pieces = Fmt::Pieces::collect (stream.str ());
 
+  // TODO:
+  // do the transformation into an AST::FormatArgs node
+  // return that
+  // expand it during lowering
+
   return AST::F

[PATCH 026/125] gccrs: extern-types: Lower to HIR::ExternalTypeItem properly

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* hir/rust-ast-lower-extern.h: Lower to HIR::ExternalTypeItem nodes.
* hir/tree/rust-hir-item.h (class ExternalTypeItem): Create private
visibility by default as extern types have no visibility - add a comment
about the correctness of this.
---
 gcc/rust/hir/rust-ast-lower-extern.h |  9 -
 gcc/rust/hir/tree/rust-hir-item.h| 10 --
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index e495b16632d..f9e067c8e95 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -22,6 +22,7 @@
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-type.h"
 #include "rust-ast-lower.h"
+#include "rust-hir-full-decls.h"
 
 namespace Rust {
 namespace HIR {
@@ -116,7 +117,13 @@ public:
 
   void visit (AST::ExternalTypeItem &type) override
   {
-rust_sorry_at (type.get_locus (), "extern types are not implemented yet");
+auto crate_num = mappings->get_current_crate ();
+Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
+  mappings->get_next_hir_id (crate_num),
+  mappings->get_next_localdef_id (crate_num));
+
+translated = new HIR::ExternalTypeItem (mapping, type.get_identifier (),
+   type.get_locus ());
   }
 
 private:
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index 40093a2ad93..3bd0102d4dc 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -3152,16 +3152,20 @@ protected:
 
 class ExternalTypeItem : public ExternalItem
 {
+public:
   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
-   Visibility vis, AST::AttrVec outer_attrs, location_t locus)
+   location_t locus)
 : ExternalItem (std::move (mappings), std::move (item_name),
-   std::move (vis), std::move (outer_attrs), locus)
+   Visibility (Visibility::PRIVATE),
+   /* FIXME: Is that correct? */
+   {}, locus)
   {}
 
   ExternalTypeItem (ExternalTypeItem const &other) : ExternalItem (other) {}
 
   ExternalTypeItem (ExternalTypeItem &&other) = default;
   ExternalTypeItem &operator= (ExternalTypeItem &&other) = default;
+  ExternalTypeItem &operator= (ExternalTypeItem const &other) = default;
 
   std::string as_string () const override;
 
@@ -3171,6 +3175,8 @@ class ExternalTypeItem : public ExternalItem
   ExternKind get_extern_kind () override { return ExternKind::Type; }
 
 protected:
+  /* Use covariance to implement clone function as returning this object
+   * rather than base */
   ExternalTypeItem *clone_external_item_impl () const override
   {
 return new ExternalTypeItem (*this);
-- 
2.45.2



[PATCH 033/125] gccrs: format-args: Add documentation for future expansion of function

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler): Add
documentation regarding future tasks.
---
 gcc/rust/expand/rust-macro-builtins.cc | 26 +-
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index b42d1ec9367..e4ca0d8ba3b 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -1052,23 +1052,7 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
 {
   auto input = format_args_parse_arguments (invoc);
 
-  // auto fmt_arg
-  //   // FIXME: this eneds to be split up into a smaller function
-  //   = parse_single_string_literal (append_newline ?
-  //   BuiltinMacro::FormatArgsNl
-  // : BuiltinMacro::FormatArgs,
-  //  invoc.get_delim_tok_tree (), invoc_locus,
-  //  invoc.get_expander ());
-
-  //  if (!fmt_arg->is_literal ())
-  //{
-  //  rust_sorry_at (
-  // invoc_locus,
-  // "cannot yet use eager macro invocations as format strings");
-  //  return AST::Fragment::create_empty ();
-  //}
-
-  // FIXME: We need to handle this
+  // TODO(Arthur): We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
   // if (!fmt_expr->is_literal ())
   //   {
@@ -1077,10 +1061,10 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
   //   token_tree.to_token_stream ());
   //   }
 
-  // auto fmt_str = static_cast (*fmt_arg.get ());
-
-  // Switch on the format string to know if the string is raw or cooked
-  // switch (fmt_str.get_lit_type ())
+  // TODO(Arthur): Handle this as well - raw strings are special for the
+  // format_args parser auto fmt_str = static_cast
+  // (*fmt_arg.get ()); Switch on the format string to know if the string is 
raw
+  // or cooked switch (fmt_str.get_lit_type ())
   //   {
   //   // case AST::Literal::RAW_STRING:
   //   case AST::Literal::STRING:
-- 
2.45.2



[PATCH 032/125] gccrs: lower: Add base for lowering FormatArgs nodes

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* Make-lang.in: Compile the new source file.
* ast/rust-ast-collector.cc (TokenCollector::visit): Error out when
visiting FormatArgs nodes.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
* ast/rust-ast.cc (FormatArgs::get_locus): New.
* ast/rust-builtin-ast-nodes.h: Improve FormatArgs API.
* ast/rust-fmt.cc (Pieces::~Pieces): Cleanup.
(Pieces::Pieces): Likewise.
* ast/rust-fmt.h (struct Pieces): Add pieces_vector member.
* hir/rust-ast-lower-format-args.cc: New file.
* hir/rust-ast-lower-format-args.h: New file.
---
 gcc/rust/Make-lang.in  |  1 +
 gcc/rust/ast/rust-ast-collector.cc |  3 +-
 gcc/rust/ast/rust-ast.cc   |  2 +-
 gcc/rust/ast/rust-builtin-ast-nodes.h  | 32 +
 gcc/rust/ast/rust-fmt.cc   | 39 
 gcc/rust/ast/rust-fmt.h| 13 +--
 gcc/rust/hir/rust-ast-lower-expr.cc|  7 +++-
 gcc/rust/hir/rust-ast-lower-format-args.cc | 41 ++
 gcc/rust/hir/rust-ast-lower-format-args.h  | 40 +
 gcc/rust/resolve/rust-ast-resolve-base.cc  |  3 +-
 10 files changed, 127 insertions(+), 54 deletions(-)
 create mode 100644 gcc/rust/hir/rust-ast-lower-format-args.cc
 create mode 100644 gcc/rust/hir/rust-ast-lower-format-args.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index af5d775a3a6..f166b02340d 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -118,6 +118,7 @@ GRS_OBJS = \
 rust/rust-ast-lower-expr.o \
 rust/rust-ast-lower-type.o \
 rust/rust-ast-lower-stmt.o \
+rust/rust-ast-lower-format-args.o \
 rust/rust-rib.o \
 rust/rust-name-resolution-context.o \
 rust/rust-default-resolver.o \
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index b8ec62367bc..c0e8e774824 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2810,7 +2810,8 @@ TokenCollector::visit (BareFunctionType &type)
 void
 TokenCollector::visit (AST::FormatArgs &fmt)
 {
-  rust_sorry_at (0, "unimplemented format_args!() visitor");
+  rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
+__FILE__, __LINE__);
 }
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index f3dabc6cd0f..fbd795f6718 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -5065,7 +5065,7 @@ FormatArgs::as_string () const
 location_t
 FormatArgs::get_locus () const
 {
-  rust_unreachable ();
+  return loc;
 }
 
 bool
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 6e267173a55..780d1a9d4e9 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -184,48 +184,32 @@ public:
 
   FormatArgs (location_t loc, Fmt::Pieces &&template_str,
  FormatArguments &&arguments)
-: loc (loc), template_str (std::move (template_str)),
+: loc (loc), template_pieces (std::move (template_str)),
   arguments (std::move (arguments))
   {}
 
-  FormatArgs (FormatArgs &&other)
-: loc (std::move (other.loc)),
-  template_str (std::move (other.template_str)),
-  arguments (std::move (other.arguments))
-  {
-std::cerr << "[ARTHUR] moving FormatArgs" << std::endl;
-  }
-
-  // FIXME: This might be invalid - we are reusing the same memory allocated
-  // on the Rust side for `other`. This is probably valid as long as we only
-  // ever read that memory and never write to it.
-  FormatArgs (const FormatArgs &other)
-: loc (other.loc), template_str (other.template_str),
-  arguments (other.arguments)
-  {
-std::cerr << "[ARTHUR] copying FormatArgs" << std::endl;
-  }
-
-  // FormatArgs &operator= (const FormatArgs &other) = default;
-  //   : template_str (other.template_str), arguments (other.arguments)
-  // {}
+  FormatArgs (FormatArgs &&other) = default;
+  FormatArgs (const FormatArgs &other) = default;
+  FormatArgs &operator= (const FormatArgs &other) = default;
 
   void accept_vis (AST::ASTVisitor &vis) override;
 
+  const Fmt::Pieces &get_template () const { return template_pieces; }
+  virtual location_t get_locus () const override;
+
 private:
   location_t loc;
   // FIXME: This probably needs to be a separate type - it is one in rustc's
   // expansion of format_args!(). There is extra handling associated with it.
   // we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
   // transformation into something we can handle better
-  Fmt::Pieces template_str;
+  Fmt::Pieces template_pieces;
   FormatArguments arguments;
 
   bool marked_for_strip = false;
 
 protected:
   virtual std::string as_string () const override;
-  virtual location_t get_locus () 

[PATCH 031/125] gccrs: format-args: Fix Rust interface and add input parsing.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast.cc: Make FormatArgs inherit from AST::Expr
* ast/rust-builtin-ast-nodes.h: Improve FormatArg* nodes and helpers.
* ast/rust-fmt.cc (Pieces::collect): Fix interface to match FFI 
function.
* ast/rust-fmt.h (collect_pieces): Likewise.
(struct Pieces): Add append_newline parameter.
* expand/rust-macro-builtins.cc: Add proper parsing of format_args
input.
* hir/rust-ast-lower-base.cc: Include diagnostics header.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Switch interface to use more parser
parameters.
* libformat_parser/src/bin.rs: Use new interface.
---
 gcc/rust/ast/rust-ast.cc   |  51 +++
 gcc/rust/ast/rust-builtin-ast-nodes.h  | 133 --
 gcc/rust/ast/rust-fmt.cc   |  38 +-
 gcc/rust/ast/rust-fmt.h|  21 ++-
 gcc/rust/expand/rust-macro-builtins.cc | 182 +++--
 gcc/rust/hir/rust-ast-lower-base.cc|   1 +
 libgrust/libformat_parser/src/bin.rs   |   5 +-
 libgrust/libformat_parser/src/lib.rs   |  63 ++---
 8 files changed, 416 insertions(+), 78 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 5d571b46622..f3dabc6cd0f 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "rust-ast.h"
 #include "optional.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-system.h"
 #include "rust-ast-full.h"
 #include "rust-diagnostics.h"
@@ -5054,6 +5055,56 @@ FormatArgs::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
+std::string
+FormatArgs::as_string () const
+{
+  // FIXME(Arthur): Improve
+  return "FormatArgs";
+}
+
+location_t
+FormatArgs::get_locus () const
+{
+  rust_unreachable ();
+}
+
+bool
+FormatArgs::is_expr_without_block () const
+{
+  return false;
+}
+
+void
+FormatArgs::mark_for_strip ()
+{
+  marked_for_strip = true;
+}
+
+bool
+FormatArgs::is_marked_for_strip () const
+{
+  return marked_for_strip;
+}
+
+std::vector &
+FormatArgs::get_outer_attrs ()
+{
+  rust_unreachable ();
+}
+
+void FormatArgs::set_outer_attrs (std::vector)
+{
+  rust_unreachable ();
+}
+
+Expr *
+FormatArgs::clone_expr_impl () const
+{
+  std::cerr << "[ARTHUR] cloning FormatArgs! " << std::endl;
+
+  return new FormatArgs (*this);
+}
+
 } // namespace AST
 
 std::ostream &
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 3998fbfb4a7..6e267173a55 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -59,9 +59,17 @@ namespace AST {
 //  └─┘  └─┘
 //  positions (could be names, numbers, empty, or `*`)
 
+// FIXME: Merge with the class below this one?
 class FormatArgumentKind
 {
 public:
+  enum class Kind
+  {
+Normal,
+Named,
+Captured,
+  } kind;
+
   Identifier &get_ident ()
   {
 rust_assert (kind == Kind::Captured || kind == Kind::Named);
@@ -69,25 +77,90 @@ public:
 return ident.value ();
   }
 
-private:
-  enum class Kind
+  FormatArgumentKind (Kind kind, tl::optional ident)
+: kind (kind), ident (ident)
+  {}
+
+  FormatArgumentKind (const FormatArgumentKind &other)
   {
-Normal,
-Named,
-Captured,
-  } kind;
+kind = other.kind;
+ident = other.ident;
+  }
+
+  FormatArgumentKind operator= (const FormatArgumentKind &other)
+  {
+kind = other.kind;
+ident = other.ident;
 
+return *this;
+  }
+
+private:
   tl::optional ident;
 };
 
 class FormatArgument
 {
+public:
+  static FormatArgument normal (std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Normal, tl::nullopt,
+  std::move (expr));
+  }
+
+  static FormatArgument named (Identifier ident, std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Named, ident,
+  std::move (expr));
+  }
+
+  static FormatArgument captured (Identifier ident, std::unique_ptr expr)
+  {
+return FormatArgument (FormatArgumentKind::Kind::Captured, ident,
+  std::move (expr));
+  }
+
+  FormatArgument (const FormatArgument &other)
+: kind (other.kind), expr (other.expr->clone_expr ())
+  {}
+
+  FormatArgument operator= (const FormatArgument &other)
+  {
+kind = other.kind;
+expr = other.expr->clone_expr ();
+
+return *this;
+  }
+
+private:
+  FormatArgument (FormatArgumentKind::Kind kind, tl::optional 
ident,
+ std::unique_ptr expr)
+: kind (FormatArgumentKind (kind, ident)), expr (std::move (expr))
+  {}
+
   FormatArgumentKind kind;
   std::unique_ptr expr;
 };
 
 class FormatArguments
 {
+public:
+  FormatArguments () {}
+  FormatArguments (FormatArguments &&) = default;
+  FormatArguments (const FormatArguments &other)
+  {
+args = std::vector ();
+args.reserve (other.args.

[PATCH 035/125] gccrs: Add curly brackets, formatted clang

2024-08-01 Thread Arthur Cohen
From: jjasmine 

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add error 
emitting
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 17 -
 1 file changed, 12 insertions(+), 5 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 8717c51e34a..e5a4f234871 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -127,13 +127,20 @@ Late::visit (AST::IdentifierExpr &expr)
   auto value = ctx.values.get (expr.get_ident ());
 
   if (label)
-resolved = label;
+{
+  resolved = label;
+}
   else if (value)
-resolved = value;
-  else {
-  rust_error_at(expr.get_locus (), "could not resolve identifier 
expression: %qs", expr.get_ident ().as_string ().c_str ());
+{
+  resolved = value;
+}
+  else
+{
+  rust_error_at (expr.get_locus (),
+"could not resolve identifier expression: %qs",
+expr.get_ident ().as_string ().c_str ());
   return;
-  }
+}
 
   ctx.map_usage (expr.get_node_id (), *resolved);
 
-- 
2.45.2



[PATCH 038/125] gccrs: Add support for external functions

2024-08-01 Thread Arthur Cohen
From: 0xn4utilus 

gcc/rust/ChangeLog:

* ast/rust-ast.cc (Function::Function): Add `is_external_function` 
field.
(Function::operator=): Likewise.
* ast/rust-ast.h: New constructor for ExternalItem.
* ast/rust-item.h (class Function): Add `is_external_function`
field. Update `get_node_id`.
* ast/rust-macro.h: Update copy constructor.

Signed-off-by: 0xn4utilus 
---
 gcc/rust/ast/rust-ast.cc  |  9 ++---
 gcc/rust/ast/rust-ast.h   |  4 +++-
 gcc/rust/ast/rust-item.h  | 41 +++
 gcc/rust/ast/rust-macro.h |  9 +
 4 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index fbd795f6718..5d661989904 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1061,9 +1061,11 @@ Union::as_string () const
 }
 
 Function::Function (Function const &other)
-  : VisItem (other), qualifiers (other.qualifiers),
-function_name (other.function_name), where_clause (other.where_clause),
-locus (other.locus), is_default (other.is_default)
+  : VisItem (other), ExternalItem (other.get_node_id ()),
+qualifiers (other.qualifiers), function_name (other.function_name),
+where_clause (other.where_clause), locus (other.locus),
+is_default (other.is_default),
+is_external_function (other.is_external_function)
 {
   // guard to prevent null dereference (always required)
   if (other.return_type != nullptr)
@@ -1095,6 +1097,7 @@ Function::operator= (Function const &other)
   // outer_attrs = other.outer_attrs;
   locus = other.locus;
   is_default = other.is_default;
+  is_external_function = other.is_external_function;
 
   // guard to prevent null dereference (always required)
   if (other.return_type != nullptr)
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index c4d5858dd63..92faaf297f9 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1695,6 +1695,8 @@ class ExternalItem : public Visitable
 public:
   ExternalItem () : node_id (Analysis::Mappings::get ()->get_next_node_id ()) 
{}
 
+  ExternalItem (NodeId node_id) : node_id (node_id) {}
+
   virtual ~ExternalItem () {}
 
   // Unique pointer custom clone function
@@ -1708,7 +1710,7 @@ public:
   virtual void mark_for_strip () = 0;
   virtual bool is_marked_for_strip () const = 0;
 
-  NodeId get_node_id () const { return node_id; }
+  virtual NodeId get_node_id () const { return node_id; }
 
 protected:
   // Clone function implementation as pure virtual method
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 44963ba386e..573888bea5a 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1289,7 +1289,7 @@ protected:
 class LetStmt;
 
 // Rust function declaration AST node
-class Function : public VisItem, public AssociatedItem
+class Function : public VisItem, public AssociatedItem, public ExternalItem
 {
   FunctionQualifiers qualifiers;
   Identifier function_name;
@@ -1300,6 +1300,7 @@ class Function : public VisItem, public AssociatedItem
   tl::optional> function_body;
   location_t locus;
   bool is_default;
+  bool is_external_function;
 
 public:
   std::string as_string () const override;
@@ -1330,16 +1331,17 @@ public:
std::unique_ptr return_type, WhereClause where_clause,
tl::optional> function_body,
Visibility vis, std::vector outer_attrs,
-   location_t locus, bool is_default = false)
+   location_t locus, bool is_default = false,
+   bool is_external_function = false)
 : VisItem (std::move (vis), std::move (outer_attrs)),
-  qualifiers (std::move (qualifiers)),
+  ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)),
   function_name (std::move (function_name)),
   generic_params (std::move (generic_params)),
   function_params (std::move (function_params)),
   return_type (std::move (return_type)),
   where_clause (std::move (where_clause)),
   function_body (std::move (function_body)), locus (locus),
-  is_default (is_default)
+  is_default (is_default), is_external_function (is_external_function)
   {}
 
   // TODO: add constructor with less fields
@@ -1364,6 +1366,8 @@ public:
   && function_params.back ()->is_variadic ();
   }
 
+  bool is_external () const { return is_external_function; }
+
   // Invalid if block is null, so base stripping on that.
   void mark_for_strip () override { function_body = nullptr; }
   bool is_marked_for_strip () const override
@@ -1422,6 +1426,9 @@ public:
 return function_params[0];
   }
 
+  // ExternalItem::node_id is same as Stmt::node_id
+  NodeId get_node_id () const override { return Stmt::node_id; }
+
 protected:
   /* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1433,6 +1440,13 @@ protected:
   {
 return new Function (*this);
   }
+
+  /* Use covariance to implement clone 

[PATCH 028/125] gccrs: ast: Add base nodes for FormatArgs

2024-08-01 Thread Arthur Cohen
This commit adds a base for creating AST FormatArgs nodes after expanding
invocations of `format_args!()`. These nodes will then be expanded to
the proper runtime function calls (to core::fmt::rt) during the AST
lowering.

gcc/rust/ChangeLog:

* ast/rust-builtin-ast-nodes.h: New file.
* ast/rust-ast-full-decls.h (class FormatArgs): Declare new class.
* ast/rust-ast-collector.cc: Handle FormatArgs nodes properly.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-full.h: Likewise.
* ast/rust-ast-visitor.cc: Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-ast.cc: Likewise.
* ast/rust-ast.h: Likewise.
* expand/rust-derive.h: Likewise.
* hir/rust-ast-lower-base.cc: Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* hir/rust-ast-lower-expr.cc: Likewise.
* hir/rust-ast-lower-expr.h: Likewise.
* resolve/rust-ast-resolve-base.cc: Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
---
 gcc/rust/ast/rust-ast-collector.cc|   8 ++
 gcc/rust/ast/rust-ast-collector.h |   2 +
 gcc/rust/ast/rust-ast-full-decls.h|   3 +
 gcc/rust/ast/rust-ast-full.h  |   1 +
 gcc/rust/ast/rust-ast-visitor.cc  |   6 +
 gcc/rust/ast/rust-ast-visitor.h   |   5 +
 gcc/rust/ast/rust-ast.cc  |   6 +
 gcc/rust/ast/rust-ast.h   |   1 +
 gcc/rust/ast/rust-builtin-ast-nodes.h | 129 ++
 gcc/rust/expand/rust-derive.h |   1 +
 gcc/rust/hir/rust-ast-lower-base.cc   |   5 +
 gcc/rust/hir/rust-ast-lower-base.h|   3 +
 gcc/rust/hir/rust-ast-lower-expr.cc   |   8 ++
 gcc/rust/hir/rust-ast-lower-expr.h|   4 +
 gcc/rust/resolve/rust-ast-resolve-base.cc |   6 +
 gcc/rust/resolve/rust-ast-resolve-base.h  |   3 +
 16 files changed, 191 insertions(+)
 create mode 100644 gcc/rust/ast/rust-builtin-ast-nodes.h

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 181f1b100be..b8ec62367bc 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -16,6 +16,8 @@
 // along with GCC; see the file COPYING3.  If not see
 // .
 #include "rust-ast-collector.h"
+#include "rust-ast.h"
+#include "rust-diagnostics.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
 
@@ -2805,5 +2807,11 @@ TokenCollector::visit (BareFunctionType &type)
 }
 }
 
+void
+TokenCollector::visit (AST::FormatArgs &fmt)
+{
+  rust_sorry_at (0, "unimplemented format_args!() visitor");
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index cf97c185a26..ec695ef5b31 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -398,6 +398,8 @@ public:
   void visit (SliceType &type);
   void visit (InferredType &type);
   void visit (BareFunctionType &type);
+
+  void visit (FormatArgs &fmt);
 };
 } // namespace AST
 
diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index c96bbfb07d9..8d5c8dbc821 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -267,6 +267,9 @@ class SliceType;
 class InferredType;
 struct MaybeNamedParam;
 class BareFunctionType;
+
+// rust-builtin-ast-nodes.h
+class FormatArgs;
 } // namespace AST
 } // namespace Rust
 
diff --git a/gcc/rust/ast/rust-ast-full.h b/gcc/rust/ast/rust-ast-full.h
index f2152193a13..ebd38f2520c 100644
--- a/gcc/rust/ast/rust-ast-full.h
+++ b/gcc/rust/ast/rust-ast-full.h
@@ -28,5 +28,6 @@
 #include "rust-stmt.h"
 #include "rust-type.h"
 #include "rust-macro.h"
+#include "rust-builtin-ast-nodes.h"
 
 #endif
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 27b9aa47d99..c72e2d72f6d 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1395,6 +1395,12 @@ DefaultASTVisitor::visit (AST::BareFunctionType &type)
 visit (type.get_return_type ());
 }
 
+void
+DefaultASTVisitor::visit (AST::FormatArgs &)
+{
+  // FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
+}
+
 void
 DefaultASTVisitor::visit (AST::VariadicParam ¶m)
 {
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 6c9715eb077..c5c9a025ba6 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -229,6 +229,9 @@ public:
   virtual void visit (InferredType &type) = 0;
   virtual void visit (BareFunctionType &type) = 0;
 
+  // special AST nodes for certain builtin macros such as `asm!()`
+  virtual void visit (FormatArgs &fmt) = 0;
+
   // TODO: rust-cond-compilation.h visiting? not currently used
 };
 
@@ -390,6 +393,7 @@ protected:
   virtual void visit (AST::SelfParam &self) override;
   virtual void visit (AST::FunctionParam ¶m) override;
   virtual void visit (AST::Var

[PATCH 047/125] gccrs: format-args: Add base for expanding FormatArgs nodes

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* Make-lang.in: Add new object.
* hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Remove calls to
FormatArgsLowering.
* expand/rust-expand-format-args.cc: New file.
* expand/rust-expand-format-args.h: New file.
---
 gcc/rust/Make-lang.in  |  1 +
 gcc/rust/expand/rust-expand-format-args.cc | 43 ++
 gcc/rust/expand/rust-expand-format-args.h  | 32 
 gcc/rust/hir/rust-ast-lower-expr.cc|  4 --
 4 files changed, 76 insertions(+), 4 deletions(-)
 create mode 100644 gcc/rust/expand/rust-expand-format-args.cc
 create mode 100644 gcc/rust/expand/rust-expand-format-args.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index f166b02340d..cbb9da0fe43 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -205,6 +205,7 @@ GRS_OBJS = \
 rust/rust-unicode.o \
 rust/rust-punycode.o \
rust/rust-lang-item.o \
+   rust/rust-expand-format-args.o \
 $(END)
 # removed object files from here
 
diff --git a/gcc/rust/expand/rust-expand-format-args.cc 
b/gcc/rust/expand/rust-expand-format-args.cc
new file mode 100644
index 000..52249cb17e3
--- /dev/null
+++ b/gcc/rust/expand/rust-expand-format-args.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#include "rust-expand-format-args.h"
+#include "rust-builtin-ast-nodes.h"
+
+namespace Rust {
+
+tl::optional
+expand_format_args (AST::FormatArgs &fmt)
+{
+  for (const auto &node : fmt.get_template ().get_pieces ())
+{
+  switch (node.tag)
+   {
+   case Fmt::Piece::Tag::String:
+ // rust_debug ("[ARTHUR]: %s", node.string._0.c_str ());
+
+   case Fmt::Piece::Tag::NextArgument:
+ rust_debug ("[ARTHUR]: NextArgument");
+ break;
+   }
+}
+
+  return tl::nullopt;
+}
+
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-expand-format-args.h 
b/gcc/rust/expand/rust-expand-format-args.h
new file mode 100644
index 000..1481f3605ed
--- /dev/null
+++ b/gcc/rust/expand/rust-expand-format-args.h
@@ -0,0 +1,32 @@
+// Copyright (C) 2024 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// .
+
+#ifndef RUST_EXPAND_FORMAT_ARGS_H
+#define RUST_EXPAND_FORMAT_ARGS_H
+
+#include "optional.h"
+#include "rust-ast-fragment.h"
+
+namespace Rust {
+
+tl::optional
+expand_format_args (AST::FormatArgs &fmt);
+
+} // namespace Rust
+
+#endif //! RUST_EXPAND_FORMAT_ARGS_H
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 6944db9b9cc..c414643bb91 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -19,7 +19,6 @@
 #include "rust-ast-lower-expr.h"
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-block.h"
-#include "rust-ast-lower-format-args.h"
 #include "rust-ast-lower-struct-field-expr.h"
 #include "rust-ast-lower-pattern.h"
 #include "rust-ast-lower-type.h"
@@ -824,9 +823,6 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
 void
 ASTLoweringExpr::visit (AST::FormatArgs &fmt)
 {
-  // Lowering FormatArgs is complex, and this file is already very long
-  translated = FormatArgsLowering ().go (fmt);
-
   rust_sorry_at (fmt.get_locus (),
 "FormatArgs lowering is not implemented yet");
 }
-- 
2.45.2



[PATCH 036/125] gccrs: Ensure TupleStructPattern and TuplePattern have items

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

Note that instances of both classes which have been
moved from will have (items == nullptr).

gcc/rust/ChangeLog:

* ast/rust-pattern.h
(class TupleStructPattern): Assert that items != nullptr.
(class TuplePattern): Likewise.
(TupleStructPattern::has_items): Remove.
(TuplePattern::has_tuple_pattern_items): Likewise.
* parse/rust-parse-impl.h
(Parser::parse_ident_leading_pattern):
Prevent construction of TupleStructPattern with
(items == nullptr).
(Parser::parse_pattern_no_alt): Likewise.
* ast/rust-ast-collector.cc
(TokenCollector::visit): Remove usage of
TupleStructPattern::has_items.
* ast/rust-ast-visitor.cc
(DefaultASTVisitor::visit): Likewise.
* resolve/rust-early-name-resolver.cc
(EarlyNameResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/pattern-struct.rs: Fix test.

Signed-off-by: Owen Avery 
---
 gcc/rust/ast/rust-ast-collector.cc   |  3 +-
 gcc/rust/ast/rust-ast-visitor.cc |  3 +-
 gcc/rust/ast/rust-pattern.h  | 46 ++--
 gcc/rust/parse/rust-parse-impl.h | 16 ---
 gcc/rust/resolve/rust-early-name-resolver.cc | 10 -
 gcc/testsuite/rust/compile/pattern-struct.rs |  2 +-
 6 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index c0e8e774824..744d0eb9d28 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2503,8 +2503,7 @@ TokenCollector::visit (TupleStructPattern &pattern)
 {
   visit (pattern.get_path ());
   push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
-  if (pattern.has_items ())
-visit (pattern.get_items ());
+  visit (pattern.get_items ());
   push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
 }
 
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index c72e2d72f6d..697c2726309 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1225,8 +1225,7 @@ void
 DefaultASTVisitor::visit (AST::TupleStructPattern &pattern)
 {
   visit (pattern.get_path ());
-  if (pattern.has_items ())
-visit (pattern.get_items ());
+  visit (pattern.get_items ());
 }
 
 void
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 6a90b536175..96f09355fae 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -1123,22 +1123,22 @@ class TupleStructPattern : public Pattern
 public:
   std::string as_string () const override;
 
-  // Returns whether the pattern has tuple struct items.
-  bool has_items () const { return items != nullptr; }
-
   TupleStructPattern (PathInExpression tuple_struct_path,
  std::unique_ptr items)
 : path (std::move (tuple_struct_path)), items (std::move (items)),
   node_id (Analysis::Mappings::get ()->get_next_node_id ())
-  {}
+  {
+rust_assert (this->items != nullptr);
+  }
 
   // Copy constructor required to clone
   TupleStructPattern (TupleStructPattern const &other) : path (other.path)
   {
 // guard to protect from null dereference
+rust_assert (other.items != nullptr);
+
 node_id = other.node_id;
-if (other.items != nullptr)
-  items = other.items->clone_tuple_struct_items ();
+items = other.items->clone_tuple_struct_items ();
   }
 
   // Operator overload assignment operator to clone
@@ -1148,10 +1148,9 @@ public:
 node_id = other.node_id;
 
 // guard to protect from null dereference
-if (other.items != nullptr)
-  items = other.items->clone_tuple_struct_items ();
-else
-  items = nullptr;
+rust_assert (other.items != nullptr);
+
+items = other.items->clone_tuple_struct_items ();
 
 return *this;
   }
@@ -1164,7 +1163,11 @@ public:
 
   void accept_vis (ASTVisitor &vis) override;
 
-  std::unique_ptr &get_items () { return items; }
+  std::unique_ptr &get_items ()
+  {
+rust_assert (items != nullptr);
+return items;
+  }
 
   PathInExpression &get_path () { return path; }
   const PathInExpression &get_path () const { return path; }
@@ -1358,7 +1361,6 @@ protected:
 // AST node representing a tuple pattern
 class TuplePattern : public Pattern
 {
-  // bool has_tuple_pattern_items;
   std::unique_ptr items;
   location_t locus;
   NodeId node_id;
@@ -1366,21 +1368,21 @@ class TuplePattern : public Pattern
 public:
   std::string as_string () const override;
 
-  // Returns true if the tuple pattern has items
-  bool has_tuple_pattern_items () const { return items != nullptr; }
-
   TuplePattern (std::unique_ptr items, location_t locus)
 : items (std::move (items)), locus (locus),
   node_id (Analysis::Mappings::get ()->get_next_node_id ())
-  {}
+  {
+rust_assert (this->items != nullptr);
+  }
 
   // Copy constructor requires clone
   TuplePattern (TuplePattern con

[PATCH 030/125] gccrs: parser: Add peek(n) method to parser

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* parse/rust-parse.h: New method.
---
 gcc/rust/parse/rust-parse.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 1614d19e4a5..8c8bf96eb8d 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -725,6 +725,7 @@ public:
   const ManagedTokenSource &get_token_source () const { return lexer; }
 
   const_TokenPtr peek_current_token () { return lexer.peek_token (0); }
+  const_TokenPtr peek (int n) { return lexer.peek_token (n); }
 
 private:
   // The token source (usually lexer) associated with the parser.
-- 
2.45.2



[PATCH 048/125] gccrs: format-args: Start storing string in Rust memory

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-fmt.cc (ffi::RustHamster::to_string): New.
(Pieces::collect): Adapt to use new handle API.
(Pieces::~Pieces): Likewise.
(Pieces::Pieces): Likewise.
(Pieces::operator=): Likewise.
* ast/rust-fmt.h (struct RustString): Add members.
(struct FormatArgsHandle): New.
(clone_pieces): Adapt for new FFI API.
(destroy_pieces): Likewise.
(struct Pieces): Store new FormatArgsHandle type.
* expand/rust-expand-format-args.cc (expand_format_args): Use proper
namespace.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit): FormatArgs
nodes are already resolved, so do nothing.

libgrust/ChangeLog:

* libformat_parser/src/lib.rs: Use new Handle struct and expose it.
---
 gcc/rust/ast/rust-fmt.cc   |  32 ---
 gcc/rust/ast/rust-fmt.h|  46 ++---
 gcc/rust/expand/rust-expand-format-args.cc |   4 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc  |   5 +-
 libgrust/libformat_parser/src/lib.rs   | 105 -
 5 files changed, 133 insertions(+), 59 deletions(-)

diff --git a/gcc/rust/ast/rust-fmt.cc b/gcc/rust/ast/rust-fmt.cc
index b82e089fc41..fda02e530fd 100644
--- a/gcc/rust/ast/rust-fmt.cc
+++ b/gcc/rust/ast/rust-fmt.cc
@@ -22,44 +22,48 @@
 namespace Rust {
 namespace Fmt {
 
+std::string
+ffi::RustHamster::to_string () const
+{
+  return std::string (ptr, len);
+}
+
 Pieces
-Pieces::collect (std::string &&to_parse, bool append_newline)
+Pieces::collect (const std::string &to_parse, bool append_newline)
 {
-  auto piece_slice = collect_pieces (to_parse.c_str (), append_newline);
+  auto handle = ffi::collect_pieces (to_parse.c_str (), append_newline);
 
   // this performs multiple copies, can we avoid them maybe?
   // TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
   // should transform them into the proper C++ type which we can work with. so
   // transform all the strings into C++ strings? all the Option into
   // tl::optional?
-  auto pieces = std::vector (piece_slice.base_ptr,
-   piece_slice.base_ptr + piece_slice.len);
+  auto pieces_vector = std::vector (handle.piece_slice.base_ptr,
+   handle.piece_slice.base_ptr
+ + handle.piece_slice.len);
 
-  return Pieces (std::move (pieces), piece_slice, std::move (to_parse));
+  return Pieces (handle, std::move (pieces_vector));
 }
 
-Pieces::~Pieces () { destroy_pieces (slice); }
+Pieces::~Pieces () { ffi::destroy_pieces (handle); }
 
-Pieces::Pieces (const Pieces &other)
-  : pieces_vector (other.pieces_vector), to_parse (other.to_parse)
+Pieces::Pieces (const Pieces &other) : pieces_vector (other.pieces_vector)
 {
-  slice = clone_pieces (other.slice.base_ptr, other.slice.len, 
other.slice.cap);
+  handle = ffi::clone_pieces (other.handle);
 }
 
 Pieces &
 Pieces::operator= (const Pieces &other)
 {
-  slice = clone_pieces (other.slice.base_ptr, other.slice.len, 
other.slice.cap);
-  to_parse = other.to_parse;
+  handle = ffi::clone_pieces (other.handle);
+  pieces_vector = other.pieces_vector;
 
   return *this;
 }
 
 Pieces::Pieces (Pieces &&other)
   : pieces_vector (std::move (other.pieces_vector)),
-slice (
-  clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
-to_parse (std::move (other.to_parse))
+handle (clone_pieces (other.handle))
 {}
 
 } // namespace Fmt
diff --git a/gcc/rust/ast/rust-fmt.h b/gcc/rust/ast/rust-fmt.h
index ba412f9958c..6a0c116b841 100644
--- a/gcc/rust/ast/rust-fmt.h
+++ b/gcc/rust/ast/rust-fmt.h
@@ -20,15 +20,21 @@
 #define RUST_FMT_H
 
 #include "rust-system.h"
+#include 
 
 // FIXME: How to encode Option?
 
 namespace Rust {
 namespace Fmt {
 
+namespace ffi {
+
 struct RustHamster
 {
-  // hehe
+  const char *ptr;
+  size_t len;
+
+  std::string to_string () const;
 };
 
 /// Enum of alignments which are supported.
@@ -240,21 +246,36 @@ struct PieceSlice
   size_t cap;
 };
 
+struct RustString
+{
+  const unsigned char *ptr;
+  size_t len;
+  size_t cap;
+};
+
+struct FormatArgsHandle
+{
+  PieceSlice piece_slice;
+  RustString rust_string;
+};
+
 extern "C" {
 
-PieceSlice
+FormatArgsHandle
 collect_pieces (const char *input, bool append_newline);
 
-PieceSlice
-clone_pieces (const Piece *base_ptr, size_t len, size_t cap);
+FormatArgsHandle
+clone_pieces (const FormatArgsHandle &);
 
-void destroy_pieces (PieceSlice);
+void destroy_pieces (FormatArgsHandle);
 
 } // extern "C"
 
+} // namespace ffi
+
 struct Pieces
 {
-  static Pieces collect (std::string &&to_parse, bool append_newline);
+  static Pieces collect (const std::string &to_parse, bool append_newline);
   ~Pieces ();
 
   Pieces (const Pieces &other);
@@ -262,7 +283,7 @@ struct Pieces
 
   Pieces (Pieces &&other);
 
-  const std::vector &get_pieces () const { return pieces_vector; }
+  co

[PATCH 039/125] gccrs: Add get_pattern_kind to Pattern

2024-08-01 Thread Arthur Cohen
From: 0xn4utilus 

gcc/rust/ChangeLog:

* ast/rust-ast.h: Add Kind Enum to
Pattern.
* ast/rust-macro.h: Add get_pattern_kind().
* ast/rust-path.h: Likewise.
* ast/rust-pattern.h: Likewise.

Signed-off-by: 0xn4utilus 
---
 gcc/rust/ast/rust-ast.h | 20 
 gcc/rust/ast/rust-macro.h   |  5 +
 gcc/rust/ast/rust-path.h|  2 ++
 gcc/rust/ast/rust-pattern.h | 33 +
 4 files changed, 60 insertions(+)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 92faaf297f9..edf726b1ffe 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1360,12 +1360,32 @@ protected:
 class Pattern : public Visitable
 {
 public:
+  enum class Kind
+  {
+Literal,
+Identifier,
+Wildcard,
+Rest,
+Range,
+Reference,
+Struct,
+TupleStruct,
+Tuple,
+Grouped,
+Slice,
+Alt,
+Path,
+MacroInvocation,
+  };
+
   // Unique pointer custom clone function
   std::unique_ptr clone_pattern () const
   {
 return std::unique_ptr (clone_pattern_impl ());
   }
 
+  virtual Kind get_pattern_kind () = 0;
+
   // possible virtual methods: is_refutable()
 
   virtual ~Pattern () {}
diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index bfdebfc4203..5b9ff3f22c8 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -610,6 +610,11 @@ public:
 
   std::string as_string () const override;
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::MacroInvocation;
+  }
+
   /**
* The default constructor you should use. Whenever we parse a macro call, we
* cannot possibly know whether or not this call refers to a builtin macro or
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index ccac6303bb4..bd3012b1bed 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -578,6 +578,8 @@ public:
   // TODO: this seems kinda dodgy
   std::vector &get_segments () { return segments; }
   const std::vector &get_segments () const { return segments; 
}
+
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
 };
 
 /* AST node representing a path-in-expression pattern (path that allows
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 96f09355fae..365f3b7f69d 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -55,6 +55,8 @@ public:
 
   const Literal &get_literal () const { return lit; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Literal; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -149,6 +151,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::Identifier;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -177,6 +184,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Wildcard; 
}
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -204,6 +213,8 @@ public:
 
   NodeId get_node_id () const override final { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Rest; }
+
 protected:
   RestPattern *clone_pattern_impl () const override
   {
@@ -431,6 +442,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Range; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -499,6 +512,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::Reference;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -934,6 +952,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Struct; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1174,6 +1194,11 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override
+  {
+return Pattern::Kind::TupleStruct;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
* than base */
@@ -1411,6 +1436,8 @@ public:
 
   NodeId get_node_id () const override { return node_id; }
 
+  Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Tuple; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather

[PATCH 037/125] gccrs: Clean BiMap to use tl::optional for lookups

2024-08-01 Thread Arthur Cohen
From: Sourabh Jaiswal 

gcc/rust/Changelog:

* expand/rust-expand-visitor.cc
(ExpandVisitor::expand_inner_items): Adjust to use has_value ()
(ExpandVisitor::expand_inner_stmts): Likewise
* expand/rust-macro-builtins.cc (builtin_macro_from_string): Likewise
(make_macro_path_str): Likewise
* util/rust-hir-map.cc (Mappings::insert_macro_def): Likewise
* util/rust-lang-item.cc (LangItem::Parse): Adjust to return 
tl::optional
(LangItem::toString) Likewise
* util/rust-token-converter.cc (handle_suffix): Adjust to use value.or 
()
(from_literal) Likewise
* util/bi-map.h (BiMap::lookup): Adjust to use tl::optional for
lookups

Signed-off-by: Sourabh Jaiswal 
---
 gcc/rust/expand/rust-expand-visitor.cc |  8 
 gcc/rust/expand/rust-macro-builtins.cc |  8 
 gcc/rust/util/bi-map.h | 22 +++---
 gcc/rust/util/rust-hir-map.cc  |  2 +-
 gcc/rust/util/rust-lang-item.cc|  6 ++
 gcc/rust/util/rust-token-converter.cc  |  5 ++---
 6 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 6ca63115195..bd49fd91092 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -186,11 +186,11 @@ ExpandVisitor::expand_inner_items (
{
  auto maybe_builtin = MacroBuiltin::builtins.lookup (
to_derive.get ().as_string ());
- if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
+ if (maybe_builtin.has_value ())
{
  auto new_item
= builtin_derive_item (*item, current,
-  maybe_builtin->second);
+  maybe_builtin.value ());
  // this inserts the derive *before* the item - is it a
  // problem?
  it = items.insert (it, std::move (new_item));
@@ -272,11 +272,11 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
{
  auto maybe_builtin = MacroBuiltin::builtins.lookup (
to_derive.get ().as_string ());
- if (MacroBuiltin::builtins.is_iter_ok (maybe_builtin))
+ if (maybe_builtin.has_value ())
{
  auto new_item
= builtin_derive_item (item, current,
-  maybe_builtin->second);
+  maybe_builtin.value ());
  // this inserts the derive *before* the item - is it a
  // problem?
  it = stmts.insert (it, std::move (new_item));
diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index e4ca0d8ba3b..8cf32051c7a 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -142,9 +142,9 @@ tl::optional
 builtin_macro_from_string (const std::string &identifier)
 {
   auto macro = MacroBuiltin::builtins.lookup (identifier);
-  rust_assert (MacroBuiltin::builtins.is_iter_ok (macro));
+  rust_assert (macro.has_value ());
 
-  return macro->second;
+  return macro;
 }
 
 namespace {
@@ -152,9 +152,9 @@ std::string
 make_macro_path_str (BuiltinMacro kind)
 {
   auto str = MacroBuiltin::builtins.lookup (kind);
-  rust_assert (MacroBuiltin::builtins.is_iter_ok (str));
+  rust_assert (str.has_value ());
 
-  return str->second;
+  return str.value ();
 }
 
 static std::vector>
diff --git a/gcc/rust/util/bi-map.h b/gcc/rust/util/bi-map.h
index ff26c833811..bc4f5800fb1 100644
--- a/gcc/rust/util/bi-map.h
+++ b/gcc/rust/util/bi-map.h
@@ -24,9 +24,6 @@
 // very simple bi-directional hashmap
 template  class BiMap
 {
-  using v_iter = typename std::unordered_map::const_iterator;
-  using k_iter = typename std::unordered_map::const_iterator;
-
 public:
   BiMap (std::unordered_map &&original) : map (std::move (original))
   {
@@ -34,11 +31,22 @@ public:
   rmap.insert ({kv.second, kv.first});
   }
 
-  const v_iter lookup (const K &key) const { return map.find (key); }
-  const k_iter lookup (const V &key) const { return rmap.find (key); }
+  const tl::optional lookup (const K &key) const
+  {
+auto itr = map.find (key);
+if (itr == map.end ())
+  return tl::nullopt;
+
+return itr->second;
+  }
+  const tl::optional lookup (const V &key) const
+  {
+auto itr = rmap.find (key);
+if (itr == rmap.end ())
+  return tl::nullopt;
 
-  bool is_iter_ok (const v_iter &iter) const { return iter != map.end (); }
-  bool is_iter_ok (const k_iter &iter) const { return iter != rmap.end (); }
+ 

[PATCH 062/125] gccrs: session manager: Init Immutable name resolver.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Create an immutable
view of the name resolution context.
---
 gcc/rust/rust-session-manager.cc | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 64e0190f716..1c7e2766d71 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -18,6 +18,7 @@
 
 #include "rust-session-manager.h"
 #include "rust-diagnostics.h"
+#include "rust-immutable-name-resolution-context.h"
 #include "rust-unsafe-checker.h"
 #include "rust-lex.h"
 #include "rust-parse.h"
@@ -659,6 +660,9 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::TypeCheck)
 return;
 
+  // name resolution is done, we now freeze the name resolver for type checking
+  Resolver2_0::ImmutableNameResolutionContext::init (name_resolution_ctx);
+
   // type resolve
   Resolver::TypeResolution::Resolve (hir);
 
-- 
2.45.2



[PATCH 044/125] gccrs: Replace reference to unique pointer with reference

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Reference to unique pointers are a known anti pattern, only the element
shall be taken by reference instead of the whole wrapper.

gcc/rust/ChangeLog:

* ast/rust-item.h: Change getter function prototype to return a
reference directly instead of a reference to the wrapper type.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit): Fix
the code to accept references instead.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): Change
function implementation to return a reference.
* hir/rust-ast-lower-base.h: Accept a reference instead of a unique
pointer reference.
* resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Adapt the code
to a reference instead of a unique pointer.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/ast/rust-item.h  |  8 +++
 gcc/rust/checks/errors/rust-ast-validation.cc |  2 +-
 gcc/rust/hir/rust-ast-lower-base.cc   | 24 +--
 gcc/rust/hir/rust-ast-lower-base.h|  2 +-
 gcc/rust/resolve/rust-ast-resolve-item.cc | 19 +++
 5 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 573888bea5a..d09f4550062 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1415,15 +1415,15 @@ public:
 return return_type;
   }
 
-  std::unique_ptr &get_self_param ()
+  Param &get_self_param ()
   {
 rust_assert (has_self_param ());
-return function_params[0];
+return *function_params[0];
   }
-  const std::unique_ptr &get_self_param () const
+  const Param &get_self_param () const
   {
 rust_assert (has_self_param ());
-return function_params[0];
+return *function_params[0];
   }
 
   // ExternalItem::node_id is same as Stmt::node_id
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc 
b/gcc/rust/checks/errors/rust-ast-validation.cc
index d1edb890ae6..d5892087889 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -100,7 +100,7 @@ ASTValidation::visit (AST::Function &function)
   && context.back () != Context::INHERENT_IMPL
   && function.has_self_param ())
 rust_error_at (
-  function.get_self_param ()->get_locus (),
+  function.get_self_param ().get_locus (),
   "% parameter is only allowed in associated functions");
 
   if (function.is_external ())
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index ff6ef25a348..652530ae7a5 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -648,31 +648,31 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs 
&args)
 }
 
 HIR::SelfParam
-ASTLoweringBase::lower_self (std::unique_ptr ¶m)
+ASTLoweringBase::lower_self (AST::Param ¶m)
 {
-  rust_assert (param->is_self ());
+  rust_assert (param.is_self ());
 
-  auto self = static_cast (param.get ());
+  auto self = static_cast (param);
   auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, self->get_node_id (),
+  Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
 mappings->get_next_hir_id (crate_num),
 mappings->get_next_localdef_id (crate_num));
 
-  if (self->has_type ())
+  if (self.has_type ())
 {
-  HIR::Type *type = ASTLoweringType::translate (self->get_type ().get ());
+  HIR::Type *type = ASTLoweringType::translate (self.get_type ().get ());
   return HIR::SelfParam (mapping, std::unique_ptr (type),
-self->get_is_mut (), self->get_locus ());
+self.get_is_mut (), self.get_locus ());
 }
-  else if (!self->get_has_ref ())
+  else if (!self.get_has_ref ())
 {
   return HIR::SelfParam (mapping, std::unique_ptr (nullptr),
-self->get_is_mut (), self->get_locus ());
+self.get_is_mut (), self.get_locus ());
 }
 
-  AST::Lifetime l = self->get_lifetime ();
-  return HIR::SelfParam (mapping, lower_lifetime (l), self->get_is_mut (),
-self->get_locus ());
+  AST::Lifetime l = self.get_lifetime ();
+  return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
+self.get_locus ());
 }
 
 HIR::Type *
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index c19e9c03b5f..c01c7c85767 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -278,7 +278,7 @@ protected:
 
   HIR::GenericArgsBinding lower_binding (AST::GenericArgsBinding &binding);
 
-  HIR::SelfParam lower_self (std::unique_ptr &self);
+  HIR::SelfParam lower_self (AST::Param &self);
 
   HIR::Type *lower_type_no_bounds (AST::TypeNoBounds *type);
 
diff --git a/gcc/rust/resolve/rust-ast-

[PATCH 049/125] gccrs: format-args: Add basic expansion of unnamed Display::fmt arguments.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-ast-builder.h: Rename AST::AstBuilder -> AST::Builder
* ast/rust-ast-builder.cc: Likewise.
* expand/rust-derive.cc: Use new AST::Builder name.
* expand/rust-derive.h: Likewise.
* ast/rust-builtin-ast-nodes.h: Add required getters.
* expand/rust-expand-format-args.cc (format_arg): New.
(get_trait_name): New.
(expand_format_args): Properly expand basic format_args!() invocations.
* expand/rust-expand-format-args.h (expand_format_args): Fix signature.
* expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler):
Call into expand_format_args().
---
 gcc/rust/ast/rust-ast-builder.cc   |  66 -
 gcc/rust/ast/rust-ast-builder.h|  51 ++
 gcc/rust/ast/rust-builtin-ast-nodes.h  |   5 +
 gcc/rust/expand/rust-derive.cc |   2 +-
 gcc/rust/expand/rust-derive.h  |   2 +-
 gcc/rust/expand/rust-expand-format-args.cc | 107 +++--
 gcc/rust/expand/rust-expand-format-args.h  |   5 +-
 gcc/rust/expand/rust-macro-builtins.cc |  23 +++--
 8 files changed, 205 insertions(+), 56 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 0d5218c6381..1138d3dc2b2 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -17,53 +17,73 @@
 // .
 
 #include "rust-ast-builder.h"
+#include "rust-ast-full-decls.h"
 #include "rust-ast-full.h"
+#include "rust-expr.h"
+#include "rust-token.h"
+#include "rust-make-unique.h"
 
 namespace Rust {
 namespace AST {
 
 std::unique_ptr
-AstBuilder::call (std::unique_ptr &&path,
- std::vector> &&args)
+Builder::literal_string (std::string &&content) const
+{
+  return std::unique_ptr (
+new AST::LiteralExpr (std::move (content), Literal::LitType::STRING,
+ PrimitiveCoreType::CORETYPE_STR, {}, loc));
+}
+
+std::unique_ptr
+Builder::call (std::unique_ptr &&path,
+  std::vector> &&args) const
 {
   return std::unique_ptr (
 new CallExpr (std::move (path), std::move (args), {}, loc));
 }
 
 std::unique_ptr
-AstBuilder::identifier (std::string name)
+Builder::array (std::vector> &&members) const
+{
+  auto elts = Rust::make_unique (std::move (members), loc);
+
+  return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc));
+}
+
+std::unique_ptr
+Builder::identifier (std::string name) const
 {
   return std::unique_ptr (new IdentifierExpr (name, {}, loc));
 }
 
 std::unique_ptr
-AstBuilder::tuple_idx (std::string receiver, int idx)
+Builder::tuple_idx (std::string receiver, int idx) const
 {
   return std::unique_ptr (
 new TupleIndexExpr (identifier (receiver), idx, {}, loc));
 }
 
 FunctionQualifiers
-AstBuilder::fn_qualifiers ()
+Builder::fn_qualifiers () const
 {
   return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal);
 }
 
 PathExprSegment
-AstBuilder::path_segment (std::string seg)
+Builder::path_segment (std::string seg) const
 {
   return PathExprSegment (PathIdentSegment (seg, loc), loc);
 }
 
 std::unique_ptr
-AstBuilder::type_path_segment (std::string seg)
+Builder::type_path_segment (std::string seg) const
 {
   return std::unique_ptr (
 new TypePathSegment (seg, false, loc));
 }
 
 std::unique_ptr
-AstBuilder::single_type_path (std::string type)
+Builder::single_type_path (std::string type) const
 {
   auto segments = std::vector> ();
   segments.emplace_back (type_path_segment (type));
@@ -72,7 +92,7 @@ AstBuilder::single_type_path (std::string type)
 }
 
 PathInExpression
-AstBuilder::path_in_expression (std::vector &&segments)
+Builder::path_in_expression (std::vector &&segments) const
 {
   auto path_segments = std::vector ();
   for (auto &seg : segments)
@@ -82,8 +102,8 @@ AstBuilder::path_in_expression (std::vector 
&&segments)
 }
 
 std::unique_ptr
-AstBuilder::block (std::vector> &&stmts,
-  std::unique_ptr &&tail_expr)
+Builder::block (std::vector> &&stmts,
+   std::unique_ptr &&tail_expr) const
 {
   return std::unique_ptr (new BlockExpr (std::move (stmts),
   std::move (tail_expr), {}, {},
@@ -91,8 +111,8 @@ AstBuilder::block (std::vector> 
&&stmts,
 }
 
 std::unique_ptr
-AstBuilder::let (std::unique_ptr pattern, std::unique_ptr type,
-std::unique_ptr init)
+Builder::let (std::unique_ptr pattern, std::unique_ptr type,
+ std::unique_ptr init) const
 {
   return std::unique_ptr (new LetStmt (std::move (pattern),
 std::move (init), std::move (type),
@@ -100,28 +120,29 @@ AstBuilder::let (std::unique_ptr pattern, 
std::unique_ptr type,
 }
 
 std::unique_ptr
-AstBuilder::ref (std::unique_ptr &&of, bool mut)
+Builder::ref (std::unique_ptr &&of, bool mut) const
 {
   return std::unique_ptr (
 new BorrowExpr (std::move (of), mut, /* is dou

[PATCH 053/125] gccrs: TyTy: Variance analysis module

2024-08-01 Thread Arthur Cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* Make-lang.in: Add new .cc file.
* rust-session-manager.cc (Session::compile_crate): Run
analysis.
* typecheck/rust-tyty-variance-analysis-private.h: New file.
* typecheck/rust-tyty-variance-analysis.cc: New file.
* typecheck/rust-tyty-variance-analysis.h: New file.
* typecheck/rust-typecheck-context.cc
(TypeCheckContext::get_variance_analysis_ctx):
Variance analysis context.
* typecheck/rust-hir-type-check.h (TypeCheckItem::visit):
Variance analysis context.

Signed-off-by: Jakub Dupak 
---
 gcc/rust/Make-lang.in |   1 +
 gcc/rust/rust-session-manager.cc  |   3 +
 gcc/rust/typecheck/rust-hir-type-check.h  |   6 +
 gcc/rust/typecheck/rust-typecheck-context.cc  |   6 +
 .../rust-tyty-variance-analysis-private.h | 304 ++
 .../typecheck/rust-tyty-variance-analysis.cc  | 541 ++
 .../typecheck/rust-tyty-variance-analysis.h   | 114 
 7 files changed, 975 insertions(+)
 create mode 100644 gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
 create mode 100644 gcc/rust/typecheck/rust-tyty-variance-analysis.cc
 create mode 100644 gcc/rust/typecheck/rust-tyty-variance-analysis.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index cbb9da0fe43..67df843349f 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -147,6 +147,7 @@ GRS_OBJS = \
 rust/rust-tyty-util.o \
 rust/rust-tyty-call.o \
 rust/rust-tyty-subst.o \
+rust/rust-tyty-variance-analysis.o \
 rust/rust-typecheck-context.o \
 rust/rust-tyty-bounds.o \
 rust/rust-hir-trait-resolve.o \
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 62c47b2e6de..ea99d019f64 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -48,6 +48,7 @@
 #include "rust-attribute-values.h"
 #include "rust-borrow-checker.h"
 #include "rust-ast-validation.h"
+#include "rust-tyty-variance-analysis.h"
 
 #include "input.h"
 #include "selftest.h"
@@ -652,6 +653,8 @@ Session::compile_crate (const char *filename)
   // type resolve
   Resolver::TypeResolution::Resolve (hir);
 
+  Resolver::TypeCheckContext::get ()->get_variance_analysis_ctx ().solve ();
+
   if (saw_errors ())
 return;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h 
b/gcc/rust/typecheck/rust-hir-type-check.h
index 52c84fc4435..c32fa4e8487 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -24,6 +24,7 @@
 #include "rust-hir-trait-reference.h"
 #include "rust-autoderef.h"
 #include "rust-tyty-region.h"
+#include "rust-tyty-variance-analysis.h"
 
 #include 
 
@@ -233,6 +234,8 @@ public:
 
   void compute_inference_variables (bool error);
 
+  TyTy::VarianceAnalysis::CrateCtx &get_variance_analysis_ctx ();
+
 private:
   TypeCheckContext ();
 
@@ -272,6 +275,9 @@ private:
   std::set querys_in_progress;
   std::set trait_queries_in_progress;
 
+  // variance analysis
+  TyTy::VarianceAnalysis::CrateCtx variance_analysis_ctx;
+
   /** Used to resolve (interned) lifetime names to their bounding scope. */
   class LifetimeResolver
   {
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc 
b/gcc/rust/typecheck/rust-typecheck-context.cc
index 9059e0261b3..ab0093a273b 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -617,6 +617,12 @@ TypeCheckContext::compute_inference_variables (bool error)
   });
 }
 
+TyTy::VarianceAnalysis::CrateCtx &
+TypeCheckContext::get_variance_analysis_ctx ()
+{
+  return variance_analysis_ctx;
+}
+
 // TypeCheckContextItem
 
 TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h 
b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
new file mode 100644
index 000..ab8c039238e
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
@@ -0,0 +1,304 @@
+#ifndef RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
+#define RUST_TYTY_VARIANCE_ANALYSIS_PRIVATE_H
+
+#include "rust-tyty-variance-analysis.h"
+
+#include "rust-tyty-visitor.h"
+
+namespace Rust {
+namespace TyTy {
+namespace VarianceAnalysis {
+
+using SolutionIndex = uint32_t;
+
+/** Term descibing variance relations. */
+struct Term
+{
+  enum Kind : uint8_t
+  {
+CONST,
+REF,
+TRANSFORM,
+  };
+
+  Kind kind;
+  union
+  {
+struct
+{
+  Term *lhs;
+  Term *rhs;
+} transform;
+SolutionIndex ref;
+Variance const_val;
+  };
+
+  Term () {}
+
+  Term (Variance variance) : kind (CONST), const_val (variance) {}
+
+  WARN_UNUSED_RESULT bool is_const () const { return kind == CONST; }
+
+  static Term make_ref (SolutionIndex index);
+
+  static Term make_transform (Term lhs, Term rhs);
+};
+
+/** Variance constraint of a type parameter. */
+struct Constraint
+{

[PATCH 056/125] gccrs: Fix typo

2024-08-01 Thread Arthur Cohen
From: Guillaume Gomez 

gcc/rust/ChangeLog:

* expand/rust-derive.cc (DeriveVisitor::derive): Fix typo
---
 gcc/rust/expand/rust-derive.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 4177004eccf..e6778fea972 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -45,7 +45,7 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
 case BuiltinMacro::PartialOrd:
 case BuiltinMacro::Hash:
 default:
-  rust_sorry_at (attr.get_locus (), "uninmplemented builtin derive macro");
+  rust_sorry_at (attr.get_locus (), "unimplemented builtin derive macro");
   return nullptr;
 };
 }
-- 
2.45.2



[PATCH 042/125] gccrs: Remove dead code associated with `AST::ExternalFunctionItem`

2024-08-01 Thread Arthur Cohen
From: 0xn4utilus 

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit):
Remove dead code.
* ast/rust-ast-collector.h: Likewise.
* ast/rust-ast-full-decls.h (class ExternalFunctionItem):
Likewise.
* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
Likewise.
* ast/rust-ast-visitor.h: Likewise.
* ast/rust-ast.cc (ExternalFunctionItem::as_string): Likewise.
(ExternalFunctionItem::accept_vis): Likewise.
* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
Likewise.
* checks/errors/rust-ast-validation.h: Likewise.
* checks/errors/rust-feature-gate.h: Likewise.
* expand/rust-cfg-strip.cc (CfgStrip::visit):
Likewise.
* expand/rust-cfg-strip.h: Likewise.
* expand/rust-derive.h: Likewise.
* expand/rust-expand-visitor.cc (ExpandVisitor::visit):
Likewise.
* expand/rust-expand-visitor.h: Likewise.
* hir/rust-ast-lower-base.cc (ASTLoweringBase::visit):
Likewise.
* hir/rust-ast-lower-base.h: Likewise.
* metadata/rust-export-metadata.cc (ExportContext::emit_function):
Likewise.
* parse/rust-parse-impl.h: Likewise.
* parse/rust-parse.h: Likewise.
* resolve/rust-ast-resolve-base.cc (ResolverBase::visit):
Likewise.
* resolve/rust-ast-resolve-base.h: Likewise.
* resolve/rust-default-resolver.cc (DefaultResolver::visit):
Likewise.
* resolve/rust-default-resolver.h: Likewise.
* util/rust-attributes.cc (AttributeChecker::visit): Likewise.
* util/rust-attributes.h: Likewise.

gcc/testsuite/ChangeLog:

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

Signed-off-by: 0xn4utilus 
---
 gcc/rust/ast/rust-ast-collector.cc| 25 ---
 gcc/rust/ast/rust-ast-collector.h |  1 -
 gcc/rust/ast/rust-ast-full-decls.h|  1 -
 gcc/rust/ast/rust-ast-visitor.cc  | 18 -
 gcc/rust/ast/rust-ast-visitor.h   |  2 -
 gcc/rust/ast/rust-ast.cc  | 69 ---
 gcc/rust/checks/errors/rust-ast-validation.cc | 19 -
 gcc/rust/checks/errors/rust-ast-validation.h  |  1 -
 gcc/rust/checks/errors/rust-feature-gate.h|  1 -
 gcc/rust/expand/rust-cfg-strip.cc | 56 ---
 gcc/rust/expand/rust-cfg-strip.h  |  1 -
 gcc/rust/expand/rust-derive.h |  1 -
 gcc/rust/expand/rust-expand-visitor.cc| 17 -
 gcc/rust/expand/rust-expand-visitor.h |  1 -
 gcc/rust/hir/rust-ast-lower-base.cc   |  3 -
 gcc/rust/hir/rust-ast-lower-base.h|  1 -
 gcc/rust/metadata/rust-export-metadata.cc | 41 +--
 gcc/rust/parse/rust-parse-impl.h  | 62 -
 gcc/rust/parse/rust-parse.h   |  2 -
 gcc/rust/resolve/rust-ast-resolve-base.cc |  4 --
 gcc/rust/resolve/rust-ast-resolve-base.h  |  1 -
 gcc/rust/resolve/rust-default-resolver.cc |  4 --
 gcc/rust/resolve/rust-default-resolver.h  |  1 -
 gcc/rust/util/rust-attributes.cc  |  4 --
 gcc/rust/util/rust-attributes.h   |  1 -
 .../rust/compile/extern_func_with_body.rs |  5 ++
 26 files changed, 7 insertions(+), 335 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/extern_func_with_body.rs

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 744d0eb9d28..eb03dccaf84 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -2084,31 +2084,6 @@ TokenCollector::visit (ExternalStaticItem &item)
   push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
 }
 
-void
-TokenCollector::visit (ExternalFunctionItem &function)
-{
-  visit_items_as_lines (function.get_outer_attrs ());
-  visit (function.get_visibility ());
-
-  auto id = function.get_identifier ().as_string ();
-
-  push (Rust::Token::make (FN_KW, function.get_locus ()));
-  push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
-  if (function.has_generics ())
-visit (function.get_generic_params ());
-  push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
-
-  visit_items_joined_by_separator (function.get_function_params ());
-
-  push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
-  if (function.has_return_type ())
-{
-  push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
-  visit (function.get_return_type ());
-}
-  push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
-}
-
 void
 TokenCollector::visit (ExternBlock &block)
 {
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index ec695ef5b31..fdc99bb7086 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -333,7 +333,6 @@ public:
   void visit (TraitImpl &impl);
   void visit (ExternalTypeItem &item);
   void visit (ExternalStaticItem &item);

[PATCH 052/125] gccrs: TyTy: add common SubstitutionRef API

2024-08-01 Thread Arthur Cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_arg_at):
Add unified API.

Signed-off-by: Jakub Dupak 
---
 gcc/rust/typecheck/rust-tyty-subst.cc | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc 
b/gcc/rust/typecheck/rust-tyty-subst.cc
index 5a753566d48..71d41d6f796 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -589,6 +589,17 @@ SubstitutionRef::get_used_arguments () const
   return used_arguments;
 }
 
+tl::optional
+SubstitutionRef::get_arg_at (size_t i) const
+{
+  auto param_ty = get_substs ().at (i).get_param_ty ();
+  SubstitutionArg arg = SubstitutionArg::error ();
+  get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
+  if (arg.is_error ())
+return tl::nullopt;
+  return arg;
+}
+
 const RegionConstraints &
 SubstitutionRef::get_region_constraints () const
 {
-- 
2.45.2



[PATCH 063/125] gccrs: nr2.0: Add lookup of resolved nodes.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::lookup):
Add lookup function.
* resolve/rust-name-resolution-context.h: Include mappings and optional.
---
 gcc/rust/resolve/rust-name-resolution-context.cc | 13 +
 gcc/rust/resolve/rust-name-resolution-context.h  |  3 +++
 2 files changed, 16 insertions(+)

diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index f35db7e925e..9fd8d52968a 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -17,6 +17,8 @@
 // .
 
 #include "rust-name-resolution-context.h"
+#include "optional.h"
+#include "rust-mapping-common.h"
 
 namespace Rust {
 namespace Resolver2_0 {
@@ -52,6 +54,17 @@ NameResolutionContext::map_usage (NodeId usage, NodeId 
definition)
   rust_assert (inserted);
 }
 
+tl::optional
+NameResolutionContext::lookup (NodeId usage)
+{
+  auto it = resolved_nodes.find (usage);
+
+  if (it == resolved_nodes.end ())
+return tl::nullopt;
+
+  return it->second;
+}
+
 void
 NameResolutionContext::scoped (Rib rib, NodeId id,
   std::function lambda,
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index bc3c4bb5ddb..e896ca05360 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -19,6 +19,7 @@
 #ifndef RUST_NAME_RESOLVER_2_0_H
 #define RUST_NAME_RESOLVER_2_0_H
 
+#include "optional.h"
 #include "rust-forever-stack.h"
 #include "rust-hir-map.h"
 
@@ -180,7 +181,9 @@ public:
   Analysis::Mappings &mappings;
 
   // TODO: Rename
+  // TODO: Use newtype pattern for Usage and Definition
   void map_usage (NodeId usage, NodeId definition);
+  tl::optional lookup (NodeId usage);
 
 private:
   /* Map of "usage" nodes which have been resolved to a "definition" node */
-- 
2.45.2



[PATCH 070/125] gccrs: Change error message on unresolved import

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The error message did not match rustc's.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Change
error message.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 3 +--
 1 file changed, 1 insertion(+), 2 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 94cc3cb62d9..72c3560b9da 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -478,8 +478,7 @@ TopLevel::visit (AST::UseDeclaration &use)
   for (auto &path : paths)
 if (!handle_use_dec (path))
   rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
-"could not resolve import %qs",
-path.as_string ().c_str ());
+"unresolved import %qs", path.as_string ().c_str ());
 }
 
 } // namespace Resolver2_0
-- 
2.45.2



[PATCH 055/125] gccrs: Store visibility properly in ExternalTypeItem

2024-08-01 Thread Arthur Cohen
From: jjasmine 

Fix issue 2897

gcc/rust/ChangeLog:

* hir/rust-ast-lower-extern.h: Add translate_visiblity
* hir/tree/rust-hir-item.h: Fix constructor of ExternalTypeItem
---
 gcc/rust/hir/rust-ast-lower-extern.h | 4 +++-
 gcc/rust/hir/tree/rust-hir-item.h| 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index e92acdc44a1..bd889e244b0 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -133,8 +133,10 @@ public:
   mappings->get_next_hir_id (crate_num),
   mappings->get_next_localdef_id (crate_num));
 
+HIR::Visibility vis = translate_visibility (type.get_visibility ());
+
 translated = new HIR::ExternalTypeItem (mapping, type.get_identifier (),
-   type.get_locus ());
+   vis, type.get_locus ());
   }
 
 private:
diff --git a/gcc/rust/hir/tree/rust-hir-item.h 
b/gcc/rust/hir/tree/rust-hir-item.h
index 3bd0102d4dc..7e0c8c6ffca 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -3154,9 +3154,9 @@ class ExternalTypeItem : public ExternalItem
 {
 public:
   ExternalTypeItem (Analysis::NodeMapping mappings, Identifier item_name,
-   location_t locus)
+   Visibility vis, location_t locus)
 : ExternalItem (std::move (mappings), std::move (item_name),
-   Visibility (Visibility::PRIVATE),
+   Visibility (std::move (vis)),
/* FIXME: Is that correct? */
{}, locus)
   {}
-- 
2.45.2



[PATCH 078/125] gccrs: Add support for ambiguous use declarations

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Glob use declarations may lead to ambiguous situation where two
definitions with the same name are imported in a given scope. The
compiler now handles shadowable items inserted after non shadowable
items. An error is now thrown when multiple shadowable items are imported
and used in the same rib.

gcc/rust/ChangeLog:

* resolve/rust-early-name-resolver-2.0.cc (Early::visit): Adapt
resolved type to the new API.
(Early::visit_attributes): Retrieve the node id from the definition.
* resolve/rust-forever-stack.h: Change the return type of getter
functions. Those functions now return a definition type instead of a
node id.
* resolve/rust-forever-stack.hxx: Change member function implementation
in the forever stack to accomodate it's API changes.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Use internal
node id. Emit an error when resolving multiple ambiguous values.
* resolve/rust-rib.cc (Rib::Definition::Definition): Add a default
constructor.
(Rib::Definition::is_ambiguous): Add a new function to determine
whether a function definition is ambiguous or not.
(Rib::Definition::to_string): Add a member function to convert a given
definition to a string.
(Rib::insert): Add new rules for value insertion in a rib. Insertion
order does not impact the result anymore: inserting a shadowable value
after a non shadowable one does not trigger an error anymore. All
shadowable values inserted in a rib are kepts until being replaced by a
non shadowable one.
(Rib::get): Return a definition instead of a node id.
* resolve/rust-rib.h: Update function prototypes.
* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::handle_use_glob):
Update return value container to match the new function's prototype.
(TopLevel::handle_use_dec): Likewise.
(flatten_glob): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 18 ++---
 gcc/rust/resolve/rust-forever-stack.h | 10 +--
 gcc/rust/resolve/rust-forever-stack.hxx   | 39 ++-
 .../resolve/rust-late-name-resolver-2.0.cc| 17 +++--
 gcc/rust/resolve/rust-rib.cc  | 69 +++
 gcc/rust/resolve/rust-rib.h   | 19 -
 .../rust-toplevel-name-resolver-2.0.cc| 41 ++-
 7 files changed, 142 insertions(+), 71 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 982c696d2af..af148b0c1c0 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -152,9 +152,11 @@ Early::visit (AST::MacroInvocation &invoc)
 
   // 
https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
 
-  tl::optional definition = tl::nullopt;
+  tl::optional definition = tl::nullopt;
   if (path.get_segments ().size () == 1)
-definition = textual_scope.get (path.get_final_segment ().as_string ());
+definition
+  = textual_scope.get (path.get_final_segment ().as_string ())
+ .map ([] (NodeId id) { return Rib::Definition::NonShadowable (id); });
 
   // we won't have changed `definition` from `nullopt` if there are more
   // than one segments in our path
@@ -169,13 +171,13 @@ Early::visit (AST::MacroInvocation &invoc)
   return;
 }
 
-  insert_once (invoc, *definition);
+  insert_once (invoc, definition->get_node_id ());
 
   // now do we need to keep mappings or something? or insert "uses" into our
   // ForeverStack? can we do that? are mappings simpler?
   auto mappings = Analysis::Mappings::get ();
   AST::MacroRulesDefinition *rules_def = nullptr;
-  if (!mappings->lookup_macro_def (definition.value (), &rules_def))
+  if (!mappings->lookup_macro_def (definition->get_node_id (), &rules_def))
 {
   // Macro definition not found, maybe it is not expanded yet.
   return;
@@ -212,8 +214,8 @@ Early::visit_attributes (std::vector &attrs)
  continue;
}
 
- auto pm_def
-   = mappings->lookup_derive_proc_macro_def (definition.value ());
+ auto pm_def = mappings->lookup_derive_proc_macro_def (
+   definition->get_node_id ());
 
  rust_assert (pm_def.has_value ());
 
@@ -234,8 +236,8 @@ Early::visit_attributes (std::vector &attrs)
 "could not resolve attribute macro invocation");
  return;
}
- auto pm_def
-   = mappings->lookup_attribute_proc_macro_def (definition.value ());
+ auto pm_def = mappings->lookup_attribute_proc_macro_def (
+   definition->get_node_id ());
 
  rust_assert (pm_def.has_value ());
 
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/

[PATCH 051/125] gccrs: format-args: Only pass the format string to the parser.

2024-08-01 Thread Arthur Cohen
This fixes an issue we had where the generated code ended with more static
pieces than its rustc counterpart.

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (struct FormatArgsInput): Store the 
format_str
as a string instead of an AST::Expr.
(format_args_parse_arguments): Transform format_expr into a format 
string
properly - add note for handling eager macro invocations later on.
(MacroBuiltin::format_args_handler): Parse the correct input, append
newline to format_str if necessary.
---
 gcc/rust/expand/rust-macro-builtins.cc | 37 +++---
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
b/gcc/rust/expand/rust-macro-builtins.cc
index 112713a4f97..a33a57752da 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -18,6 +18,7 @@
 
 #include "expected.h"
 #include "libproc_macro_internal/tokenstream.h"
+#include "optional.h"
 #include "rust-ast-full-decls.h"
 #include "rust-builtin-ast-nodes.h"
 #include "rust-expand-format-args.h"
@@ -961,7 +962,7 @@ MacroBuiltin::stringify_handler (location_t invoc_locus,
 
 struct FormatArgsInput
 {
-  std::unique_ptr format_str;
+  std::string format_str;
   AST::FormatArguments args;
   // bool is_literal?
 };
@@ -985,12 +986,18 @@ format_args_parse_arguments (AST::MacroInvocData &invoc)
 
   auto args = AST::FormatArguments ();
   auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
-  std::unique_ptr format_str = nullptr;
+  std::unique_ptr format_expr = nullptr;
 
   // TODO: Handle the case where we're not parsing a string literal (macro
   // invocation for e.g.)
   if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
-format_str = parser.parse_literal_expr ();
+format_expr = parser.parse_literal_expr ();
+
+  // TODO(Arthur): Clean this up - if we haven't parsed a string literal but a
+  // macro invocation, what do we do here? return a tl::unexpected?
+  auto format_str = static_cast (*format_expr)
+ .get_literal ()
+ .as_string ();
 
   // TODO: Allow implicit captures ONLY if the the first arg is a string 
literal
   // and not a macro invocation
@@ -1053,6 +1060,13 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
 {
   auto input = format_args_parse_arguments (invoc);
 
+  if (!input)
+{
+  rust_error_at (invoc_locus,
+"could not parse arguments to %");
+  return tl::nullopt;
+}
+
   // TODO(Arthur): We need to handle this
   // // if it is not a literal, it's an eager macro invocation - return it
   // if (!fmt_expr->is_literal ())
@@ -1080,20 +1094,13 @@ MacroBuiltin::format_args_handler (location_t 
invoc_locus,
   // rust_unreachable ();
   //   }
 
-  // Remove the delimiters from the macro invocation:
-  // the invoc data for `format_args!(fmt, arg1, arg2)` is `(fmt, arg1, arg2)`,
-  // so we pop the front and back to remove the parentheses (or curly brackets,
-  // or brackets)
-  auto tokens = invoc.get_delim_tok_tree ().to_token_stream ();
-  tokens.erase (tokens.begin ());
-  tokens.pop_back ();
+  bool append_newline = nl == AST::FormatArgs::Newline::Yes;
 
-  std::stringstream stream;
-  for (const auto &tok : tokens)
-stream << tok->as_string () << ' ';
+  auto fmt_str = std::move (input->format_str);
+  if (append_newline)
+fmt_str += '\n';
 
-  auto append_newline = nl == AST::FormatArgs::Newline::Yes ? true : false;
-  auto pieces = Fmt::Pieces::collect (stream.str (), append_newline);
+  auto pieces = Fmt::Pieces::collect (fmt_str, append_newline);
 
   // TODO:
   // do the transformation into an AST::FormatArgs node
-- 
2.45.2



[PATCH 059/125] gccrs: nr2.0: Add new ImmutableNameResolutionCtx class.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* Make-lang.in: Compile it.
* resolve/rust-immutable-name-resolution-context.cc: New file.
* resolve/rust-immutable-name-resolution-context.h: New file.
---
 gcc/rust/Make-lang.in |  1 +
 .../rust-immutable-name-resolution-context.cc | 56 +++
 .../rust-immutable-name-resolution-context.h  | 55 ++
 3 files changed, 112 insertions(+)
 create mode 100644 gcc/rust/resolve/rust-immutable-name-resolution-context.cc
 create mode 100644 gcc/rust/resolve/rust-immutable-name-resolution-context.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 10af0814372..24229c02770 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -134,6 +134,7 @@ GRS_OBJS = \
 rust/rust-toplevel-name-resolver-2.0.o \
 rust/rust-early-name-resolver-2.0.o \
 rust/rust-late-name-resolver-2.0.o \
+   rust/rust-immutable-name-resolution-context.o \
 rust/rust-early-name-resolver.o \
 rust/rust-name-resolver.o \
 rust/rust-ast-resolve.o \
diff --git a/gcc/rust/resolve/rust-immutable-name-resolution-context.cc 
b/gcc/rust/resolve/rust-immutable-name-resolution-context.cc
new file mode 100644
index 000..3894e27cd20
--- /dev/null
+++ b/gcc/rust/resolve/rust-immutable-name-resolution-context.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2020-2023 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-immutable-name-resolution-context.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+static ImmutableNameResolutionContext *instance = nullptr;
+
+const ImmutableNameResolutionContext &
+ImmutableNameResolutionContext::init (const NameResolutionContext &ctx)
+{
+  rust_assert (!instance);
+
+  instance = new ImmutableNameResolutionContext (ctx);
+
+  return *instance;
+}
+
+const ImmutableNameResolutionContext &
+ImmutableNameResolutionContext::get ()
+{
+  rust_assert (instance);
+
+  return *instance;
+}
+
+const NameResolutionContext &
+ImmutableNameResolutionContext::resolver () const
+{
+  return ctx;
+}
+
+ImmutableNameResolutionContext::ImmutableNameResolutionContext (
+  const NameResolutionContext &ctx)
+  : ctx (ctx)
+{}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-immutable-name-resolution-context.h 
b/gcc/rust/resolve/rust-immutable-name-resolution-context.h
new file mode 100644
index 000..9f9e7764cd2
--- /dev/null
+++ b/gcc/rust/resolve/rust-immutable-name-resolution-context.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2020-2023 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_IMMUTABLE_NRCTX_H
+#define RUST_IMMUTABLE_NRCTX_H
+
+#include "rust-name-resolution-context.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+/**
+ * Once the name resolution pass is complete, the typechecker can access it
+ *
+ * FIXME: More documentation
+ */
+class ImmutableNameResolutionContext
+{
+public:
+  /** FIXME: Documentation */
+  static const ImmutableNameResolutionContext &
+  init (const NameResolutionContext &ctx);
+
+  /** FIXME: Documentation */
+  static const ImmutableNameResolutionContext &get ();
+
+  const NameResolutionContext &resolver () const;
+
+private:
+  ImmutableNameResolutionContext (const NameResolutionContext &ctx);
+  ImmutableNameResolutionContext (const ImmutableNameResolutionContext &other)
+= default;
+
+  const NameResolutionContext &ctx;
+};
+
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif //! RUST_IMMUTABLE_NRCTX_H
-- 
2.45.2



[PATCH 079/125] gccrs: Add tuple struct constructor to value namespace

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

A tuple struct constructor should be inserted in the value namespace
during name resolution in order to reject multiple definitions of the
function.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit): Add
the struct constructor to the value namespace.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 3 +++
 gcc/testsuite/rust/compile/name_resolution22.rs | 5 +
 2 files changed, 8 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/name_resolution22.rs

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 6929bdb641e..4134b9a4620 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -337,6 +337,9 @@ TopLevel::visit (AST::TupleStruct &tuple_struct)
 {
   insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
   Namespace::Types);
+
+  insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
+  Namespace::Values);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/name_resolution22.rs 
b/gcc/testsuite/rust/compile/name_resolution22.rs
new file mode 100644
index 000..c49331ef38c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution22.rs
@@ -0,0 +1,5 @@
+// { dg-options "-frust-name-resolution-2.0" }
+struct Marker;
+struct Foo(Marker);
+
+fn Foo(m: Marker) {} // { dg-error ".Foo. defined multiple times" }
-- 
2.45.2



[PATCH 087/125] gccrs: Change enum namespace from value to type

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The enum type shall be in type namespace, not value namespace.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::visit):
Change enum type namespace.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 2 +-
 1 file changed, 1 insertion(+), 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 820ba271ae0..b672d448151 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -95,7 +95,7 @@ GlobbingVisitor::visit (AST::Enum &enum_item)
 {
   if (enum_item.get_visibility ().is_public ())
 ctx.insert_shadowable (enum_item.get_identifier (),
-  enum_item.get_node_id (), Namespace::Values);
+  enum_item.get_node_id (), Namespace::Types);
 }
 
 void
-- 
2.45.2



[PATCH 054/125] gccrs: TyTy: Collect variance info from types

2024-08-01 Thread Arthur Cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit):
Collect variance info from types.

Signed-off-by: Jakub Dupak 
---
 gcc/rust/typecheck/rust-hir-type-check-item.cc | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 16b4906a356..4bbd28021a0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -25,6 +25,7 @@
 #include "rust-hir-trait-resolve.h"
 #include "rust-substitution-mapper.h"
 #include "rust-type-util.h"
+#include "rust-tyty-variance-analysis.h"
 
 namespace Rust {
 namespace Resolver {
@@ -204,7 +205,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *type = new TyTy::ADTType (
+  auto *type = new TyTy::ADTType (
 struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
@@ -215,6 +216,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -266,7 +269,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
 = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *type = new TyTy::ADTType (
+  auto *type = new TyTy::ADTType (
 struct_decl.get_mappings ().get_hirid (), mappings->get_next_hir_id (),
 struct_decl.get_identifier ().as_string (), ident,
 TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
@@ -277,6 +280,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -307,7 +312,7 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
   RustIdent ident{*canonical_path, enum_decl.get_locus ()};
 
   // multi variant ADT
-  TyTy::BaseType *type
+  auto *type
 = new TyTy::ADTType (enum_decl.get_mappings ().get_hirid (),
 mappings->get_next_hir_id (),
 enum_decl.get_identifier ().as_string (), ident,
@@ -316,6 +321,8 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
 
   context->insert_type (enum_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
@@ -363,7 +370,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
  TyTy::VariantDef::VariantType::STRUCT, nullptr,
  std::move (fields)));
 
-  TyTy::BaseType *type
+  auto *type
 = new TyTy::ADTType (union_decl.get_mappings ().get_hirid (),
 mappings->get_next_hir_id (),
 union_decl.get_identifier ().as_string (), ident,
@@ -372,6 +379,8 @@ TypeCheckItem::visit (HIR::Union &union_decl)
 
   context->insert_type (union_decl.get_mappings (), type);
   infered = type;
+
+  context->get_variance_analysis_ctx ().add_type_constraints (*type);
 }
 
 void
-- 
2.45.2



[PATCH 068/125] gccrs: Fix duplicate detection

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The resolver did report duplicate symbols when being run multiple times
even if the node id was the same. This commit adds an additional
condition, the error will only be reported if the existing node id is
different from the current node id.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::insert_or_error_out):
Add new constraint to duplicate errors.

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

diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 446a1c6a41b..407892bb7bb 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -47,11 +47,8 @@ TopLevel::insert_or_error_out (const Identifier &identifier,
 
   auto result = ctx.insert (identifier, node_id, ns);
 
-  if (!result)
+  if (!result && result.error ().existing != node_id)
 {
-  // can we do something like check if the node id is the same? if it is 
the
-  // same, it's not an error, just the resolver running multiple times?
-
   rich_location rich_loc (line_table, locus);
   rich_loc.add_range (node_locations[result.error ().existing]);
 
-- 
2.45.2



[PATCH 067/125] gccrs: late: Setup builtin types properly, change Rib API

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Start using Rib::Definition for
shadowable information.
* resolve/rust-late-name-resolver-2.0.cc (next_node_id): New.
(next_hir_id): New.
(Late::setup_builtin_types): Improve builtin type setup.
* resolve/rust-rib.cc (Rib::Definition::Definition): New constructor.
(Rib::Definition::Shadowable): Likewise.
(Rib::Definition::NonShadowable): Likewise.
(Rib::Rib): Fix general constructor.
(Rib::insert): Use Definition class.
(Rib::get): Likewise.
* resolve/rust-rib.h: New Definition class, new prototypes.
---
 gcc/rust/resolve/rust-forever-stack.hxx   | 22 +++--
 .../resolve/rust-late-name-resolver-2.0.cc| 84 +--
 gcc/rust/resolve/rust-rib.cc  | 38 +++--
 gcc/rust/resolve/rust-rib.h   | 30 +--
 4 files changed, 126 insertions(+), 48 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index 0aa9943191e..a2fdce98362 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -100,9 +100,9 @@ ForeverStack::pop ()
 }
 
 static tl::expected
-insert_inner (Rib &rib, std::string name, NodeId node, bool can_shadow)
+insert_inner (Rib &rib, std::string name, Rib::Definition definition)
 {
-  return rib.insert (name, node, can_shadow);
+  return rib.insert (name, definition);
 }
 
 template 
@@ -115,7 +115,8 @@ ForeverStack::insert (Identifier name, NodeId node)
   // pass, we might end up in a situation where it is okay to re-add new names.
   // Do we just ignore that here? Do we keep track of if the Rib is new or not?
   // should our cursor have info on the current node like "is it newly pushed"?
-  return insert_inner (innermost_rib, name.as_string (), node, false);
+  return insert_inner (innermost_rib, name.as_string (),
+  Rib::Definition::NonShadowable (node));
 }
 
 template 
@@ -126,7 +127,8 @@ ForeverStack::insert_at_root (Identifier name, NodeId 
node)
 
   // inserting in the root of the crate is never a shadowing operation, even 
for
   // macros
-  return insert_inner (root_rib, name.as_string (), node, false);
+  return insert_inner (root_rib, name.as_string (),
+  Rib::Definition::NonShadowable (node));
 }
 
 // Specialization for Macros and Labels - where we are allowed to shadow
@@ -135,14 +137,16 @@ template <>
 inline tl::expected
 ForeverStack::insert (Identifier name, NodeId node)
 {
-  return insert_inner (peek (), name.as_string (), node, true);
+  return insert_inner (peek (), name.as_string (),
+  Rib::Definition::Shadowable (node));
 }
 
 template <>
 inline tl::expected
 ForeverStack::insert (Identifier name, NodeId node)
 {
-  return insert_inner (peek (), name.as_string (), node, true);
+  return insert_inner (peek (), name.as_string (),
+  Rib::Definition::Shadowable (node));
 }
 
 template 
@@ -455,10 +459,10 @@ template 
 tl::optional::Node &, std::string>>
 ForeverStack::dfs (ForeverStack::Node &starting_point, NodeId to_find)
 {
-  auto &values = starting_point.rib.get_values ();
+  auto values = starting_point.rib.get_values ();
 
   for (auto &kv : values)
-if (kv.second == to_find)
+if (kv.second.id == to_find)
   return {{starting_point, kv.first}};
 
   for (auto &child : starting_point.children)
@@ -568,7 +572,7 @@ ForeverStack::stream_rib (std::stringstream &stream, 
const Rib &rib,
   stream << next << "rib: {\n";
 
   for (const auto &kv : rib.get_values ())
-stream << next_next << kv.first << ": " << kv.second << "\n";
+stream << next_next << kv.first << ": " << kv.second.id << "\n";
 
   stream << next << "},\n";
 }
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 50034073edf..3090bbeff2a 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -18,8 +18,10 @@
 
 #include "optional.h"
 #include "rust-ast-full.h"
+#include "rust-hir-map.h"
 #include "rust-late-name-resolver-2.0.h"
 #include "rust-default-resolver.h"
+#include "rust-name-resolution-context.h"
 #include "rust-path.h"
 #include "rust-tyty.h"
 #include "rust-hir-type-check.h"
@@ -29,41 +31,75 @@ namespace Resolver2_0 {
 
 Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {}
 
+static NodeId
+next_node_id ()
+{
+  return Analysis::Mappings::get ()->get_next_node_id ();
+};
+
+static HirId
+next_hir_id ()
+{
+  return Analysis::Mappings::get ()->get_next_hir_id ();
+};
+
 void
 Late::setup_builtin_types ()
 {
-  auto next_id = [this] () { return ctx.mappings.get_next_hir_id (); };
-
-  static const std::pair builtins[] = {
-{"u8", new TyTy::UintType (next_id (), TyTy::UintType::U8)},
-{"u16", new TyTy::UintType (next_id (), TyTy::UintType::U16)},
-{"u32"

[PATCH 090/125] gccrs: Remove extern block scoping

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Remove extern block scoping visit function, use the default visitor visit
function instead. We do not need scoping for extern block as their
element shall be visible from the extern block scope.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Remove
visitor implementation and scoping.
* resolve/rust-default-resolver.h: Remove function prototype.

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

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index f5546181b3c..291731be5b3 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -133,18 +133,6 @@ DefaultResolver::visit (AST::TraitImpl &impl)
   ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
 }
 
-void
-DefaultResolver::visit (AST::ExternBlock &block)
-{
-  auto inner_fn = [this, &block] () {
-for (auto &item : block.get_extern_items ())
-  item->accept_vis (*this);
-  };
-
-  ctx.scoped (Rib::Kind::Normal /* FIXME: Correct? */, block.get_node_id (),
- inner_fn);
-}
-
 void
 DefaultResolver::visit (AST::StructStruct &type)
 {
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index a19d70bc04d..0a6427ca6a6 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -49,7 +49,6 @@ public:
   void visit (AST::Trait &);
   void visit (AST::InherentImpl &);
   void visit (AST::TraitImpl &);
-  void visit (AST::ExternBlock &);
 
   // type dec nodes, which visit their fields or variants by default
   void visit (AST::StructStruct &);
-- 
2.45.2



[PATCH 075/125] gccrs: Shape up name resolver for normal direct calls

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Direct function calls did not work anymore due to the transition to the
new resolver.

gcc/rust/ChangeLog:

* checks/lints/rust-lint-marklive.cc (MarkLive::find_ref_node_id):
Add code path for the resolver 2.0
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Remove failing
label context resolve call.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/checks/lints/rust-lint-marklive.cc   | 23 +++
 .../resolve/rust-late-name-resolver-2.0.cc|  3 ++-
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc 
b/gcc/rust/checks/lints/rust-lint-marklive.cc
index 8787a9d8550..1a0a0a2b904 100644
--- a/gcc/rust/checks/lints/rust-lint-marklive.cc
+++ b/gcc/rust/checks/lints/rust-lint-marklive.cc
@@ -20,8 +20,10 @@
 // from live codes are live, and everything else is dead.
 
 #include "rust-lint-marklive.h"
+#include "options.h"
 #include "rust-hir-full.h"
 #include "rust-name-resolver.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Analysis {
@@ -270,12 +272,25 @@ MarkLive::mark_hir_id (HirId id)
 void
 MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
 {
-  if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+  if (flag_name_resolution_2_0)
 {
-  if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) {
+   ref_node_id = resolved;
+  });
+}
+  else
+{
+  if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- bool ok = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id);
- rust_assert (ok);
+ if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+   {
+ bool ok
+   = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id);
+ rust_assert (ok);
+   }
}
 }
 }
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 ee06c4efc2e..68eb88a1e4c 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -196,8 +196,9 @@ Late::visit (AST::PathInExpression &expr)
   // in a function item` error here?
   // do we emit it in `get`?
 
-  auto label = ctx.labels.resolve_path (expr.get_segments ());
   auto value = ctx.values.resolve_path (expr.get_segments ());
+
+  ctx.map_usage (Usage (expr.get_node_id ()), Definition (*value));
 }
 
 void
-- 
2.45.2



[PATCH 084/125] gccrs: Values shall be inserted in the value namespace

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Values were inserted in the label namespace instead of the value
namespace this lead to several bugs.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Change the
namespace for values from "label" to "values".

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

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 5c8d976b417..dc7cde1b323 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -151,7 +151,10 @@ Late::visit (AST::IdentifierPattern &identifier)
   // do we insert in labels or in values
   // but values does not allow shadowing... since functions cannot shadow
   // do we insert functions in labels as well?
-  new_label (identifier.get_ident (), identifier.get_node_id ());
+  auto ok
+= ctx.values.insert (identifier.get_ident (), identifier.get_node_id ());
+
+  rust_assert (ok);
 }
 
 void
-- 
2.45.2



[PATCH 097/125] gccrs: Add mappings for struct base and struct fields

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Definition/usage mapping during name resolution was missing.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add mapping
implementation.
* resolve/rust-late-name-resolver-2.0.h: Add function visitor prototype
override.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-late-name-resolver-2.0.cc| 21 +++
 .../resolve/rust-late-name-resolver-2.0.h |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index dc7cde1b323..f580c23377b 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -228,5 +228,26 @@ Late::visit (AST::TypePath &type)
 Definition (resolved->get_node_id ()));
 }
 
+void
+Late::visit (AST::StructExprStructBase &s)
+{
+  auto resolved = ctx.types.get (s.get_struct_name ().as_string ());
+
+  ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
+Definition (resolved->get_node_id ()));
+  DefaultResolver::visit (s);
+}
+
+void
+Late::visit (AST::StructExprStructFields &s)
+{
+  auto resolved = ctx.types.get (s.get_struct_name ().as_string ());
+
+  ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
+Definition (resolved->get_node_id ()));
+
+  DefaultResolver::visit (s);
+}
+
 } // 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 3a8a0060f5a..ee712b305d4 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -46,6 +46,8 @@ public:
   void visit (AST::IdentifierExpr &) override;
   void visit (AST::PathInExpression &) override;
   void visit (AST::TypePath &) override;
+  void visit (AST::StructExprStructBase &) override;
+  void visit (AST::StructExprStructFields &) override;
 
 private:
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
-- 
2.45.2



[PATCH 100/125] gccrs: nr2.0: Add new test cases.

2024-08-01 Thread Arthur Cohen
gcc/testsuite/ChangeLog:

* rust/compile/name_resolution13.rs: Add new module and remove compile
step.
* rust/compile/name_resolution14.rs: New test.
* rust/compile/name_resolution15.rs: New test.
* rust/compile/name_resolution16.rs: New test.
* rust/compile/name_resolution17.rs: New test.
* rust/compile/name_resolution18.rs: New test.
* rust/compile/name_resolution19.rs: New test.
* rust/compile/name_resolution20.rs: New test.
* rust/compile/name_resolution21.rs: New test.
---
 .../rust/compile/name_resolution13.rs |  6 +-
 .../rust/compile/name_resolution14.rs | 15 ++
 .../rust/compile/name_resolution15.rs | 20 +++
 .../rust/compile/name_resolution16.rs | 18 +
 .../rust/compile/name_resolution17.rs | 10 ++
 .../rust/compile/name_resolution18.rs | 15 ++
 .../rust/compile/name_resolution19.rs | 20 +++
 .../rust/compile/name_resolution20.rs | 11 ++
 .../rust/compile/name_resolution21.rs | 12 +++
 9 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/name_resolution14.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution15.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution16.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution17.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution18.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution19.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution20.rs
 create mode 100644 gcc/testsuite/rust/compile/name_resolution21.rs

diff --git a/gcc/testsuite/rust/compile/name_resolution13.rs 
b/gcc/testsuite/rust/compile/name_resolution13.rs
index 52a152bf51a..33edbf9312e 100644
--- a/gcc/testsuite/rust/compile/name_resolution13.rs
+++ b/gcc/testsuite/rust/compile/name_resolution13.rs
@@ -1,4 +1,8 @@
-// { dg-additional-options "-frust-name-resolution-2.0 
-frust-compile-until=lowering" }
+// { dg-options "-frust-name-resolution-2.0" }
+
+pub mod foo {
+pub macro bar() {}
+}
 
 fn foo() {
 let b = 10;
diff --git a/gcc/testsuite/rust/compile/name_resolution14.rs 
b/gcc/testsuite/rust/compile/name_resolution14.rs
new file mode 100644
index 000..eaef6a52f16
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution14.rs
@@ -0,0 +1,15 @@
+// { dg-options "-frust-name-resolution-2.0" }
+
+pub mod foo {
+pub macro bar() {}
+}
+
+use foo::biz; // { dg-error "unresolved import .foo::biz. .E0433." }
+
+use foo::{bar, baz, biz};
+// { dg-error "unresolved import .foo::baz. .E0433." "" { target *-*-* } .-1 }
+// { dg-error "unresolved import .foo::biz. .E0433." "" { target *-*-* } .-2 }
+
+fn main() {
+bar!();
+}
diff --git a/gcc/testsuite/rust/compile/name_resolution15.rs 
b/gcc/testsuite/rust/compile/name_resolution15.rs
new file mode 100644
index 000..45f38da768a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution15.rs
@@ -0,0 +1,20 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+#![feature(decl_macro)]
+
+pub mod foo {
+pub struct Foo {
+pub a: i32,
+}
+pub fn Foo() {}
+pub macro Foo() {{}}
+}
+
+pub use foo::Foo;
+
+use self::Foo as Fo;
+
+fn main() {
+let _a = Fo();
+let _b = Fo { a: 15 };
+let _c = Fo!();
+}
diff --git a/gcc/testsuite/rust/compile/name_resolution16.rs 
b/gcc/testsuite/rust/compile/name_resolution16.rs
new file mode 100644
index 000..230722ef819
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution16.rs
@@ -0,0 +1,18 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+#![feature(decl_macro)]
+
+pub mod foo {
+pub struct Foo {
+pub a: i32,
+}
+pub fn Foo() {}
+pub macro Foo() {{}}
+}
+
+pub use foo::Foo;
+
+fn main() {
+let _a = Foo();
+let _b = Foo { a: 15 };
+let _c = Foo!();
+}
diff --git a/gcc/testsuite/rust/compile/name_resolution17.rs 
b/gcc/testsuite/rust/compile/name_resolution17.rs
new file mode 100644
index 000..485947647a9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution17.rs
@@ -0,0 +1,10 @@
+// { dg-options "-frust-name-resolution-2.0" }
+
+struct Foo;
+fn Foo() {} // { dg-error ".Foo. defined multiple times" }
+
+struct Marker;
+struct Bar {
+a: Marker,
+}
+fn Bar() {} // ok, since `Bar` is not a value here
diff --git a/gcc/testsuite/rust/compile/name_resolution18.rs 
b/gcc/testsuite/rust/compile/name_resolution18.rs
new file mode 100644
index 000..5940149d3bb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution18.rs
@@ -0,0 +1,15 @@
+// { dg-options "-frust-name-resolution-2.0" }
+
+struct Marker;
+
+struct Foo {
+a: Marker,
+}
+
+pub mod foo {
+struct Foo {
+b: Marker,
+}
+}
+
+use foo::Foo; // { dg-error ".Foo. defined multiple times" }
diff --git a/gcc/testsuite

[PATCH 103/125] gccrs: Improve parsing of raw byte string literals

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* lex/rust-lex.cc
(Lexer::parse_raw_byte_string):
Bring handling of edge cases to par with parse_byte_string.

gcc/testsuite/ChangeLog:

* rust/compile/raw-byte-string-loc.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/lex/rust-lex.cc  | 23 +++
 .../rust/compile/raw-byte-string-loc.rs   |  6 +
 2 files changed, 25 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/raw-byte-string-loc.rs

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 9c2203160cd..7c37e83d6cb 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -1840,14 +1840,18 @@ Lexer::parse_raw_byte_string (location_t loc)
   int length = 1;
   int hash_count = 0;
 
+  const location_t string_begin_locus = get_current_location ();
+
   // get hash count at beginnning
   skip_input ();
   current_char = peek_input ();
   length++;
+  current_column++;
   while (current_char == '#')
 {
   hash_count++;
   length++;
+  current_column++;
 
   skip_input ();
   current_char = peek_input ();
@@ -1862,6 +1866,7 @@ Lexer::parse_raw_byte_string (location_t loc)
   skip_input ();
   current_char = peek_input ();
   length++;
+  current_column++;
 
   while (true)
 {
@@ -1884,27 +1889,37 @@ Lexer::parse_raw_byte_string (location_t loc)
  skip_input (hash_count);
  current_char = peek_input ();
  length += hash_count + 1;
+ current_column += hash_count + 1;
  break;
}
}
-
-  if (current_char.value > 127)
+  else if (current_char.value > 127)
{
  rust_error_at (get_current_location (),
 "character %<%s%> in raw byte string out of range",
 current_char.as_string ().c_str ());
  current_char = 0;
}
+  else if (current_char.is_eof ())
+   {
+ rust_error_at (string_begin_locus, "unended raw byte string literal");
+ return Token::make (END_OF_FILE, get_current_location ());
+   }
 
   length++;
+  current_column++;
+  if (current_char == '\n')
+   {
+ current_line++;
+ current_column = 1;
+ start_line (current_line, max_column_hint);
+   }
 
   str += current_char;
   skip_input ();
   current_char = peek_input ();
 }
 
-  current_column += length;
-
   loc += length - 1;
 
   str.shrink_to_fit ();
diff --git a/gcc/testsuite/rust/compile/raw-byte-string-loc.rs 
b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
new file mode 100644
index 000..f37d3f9694d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
@@ -0,0 +1,6 @@
+const X: &'static u8 = br#"12
+12"#;
+
+BREAK
+// { dg-error "unrecognised token" "" { target *-*-* } .-1 }
+// { dg-excess-errors "error 'failed to parse item' does not have location" }
-- 
2.45.2



[PATCH 107/125] gccrs: Improve parsing of raw string literals

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* lex/rust-lex.cc
(Lexer::parse_raw_string):
Bring handling of edge cases to par with parse_raw_byte_string.

gcc/testsuite/ChangeLog:

* rust/compile/raw-string-loc.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/lex/rust-lex.cc | 21 +---
 gcc/testsuite/rust/compile/raw-string-loc.rs |  6 ++
 2 files changed, 24 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/raw-string-loc.rs

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index 7c37e83d6cb..e5c9148976c 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -2152,6 +2152,9 @@ Lexer::parse_raw_string (location_t loc, int 
initial_hash_count)
   str.reserve (16); // some sensible default
 
   int length = 1 + initial_hash_count;
+  current_column += length;
+
+  const location_t string_begin_locus = get_current_location ();
 
   if (initial_hash_count > 0)
 skip_input (initial_hash_count - 1);
@@ -2162,10 +2165,11 @@ Lexer::parse_raw_string (location_t loc, int 
initial_hash_count)
 rust_error_at (get_current_location (), "raw string has no opening 
%<\"%>");
 
   length++;
+  current_column++;
   skip_input ();
   current_char = peek_input ();
 
-  while (!current_char.is_eof ())
+  while (true)
 {
   if (current_char.value == '"')
{
@@ -2186,19 +2190,30 @@ Lexer::parse_raw_string (location_t loc, int 
initial_hash_count)
  skip_input (initial_hash_count);
  current_char = peek_input ();
  length += initial_hash_count + 1;
+ current_column += initial_hash_count + 1;
  break;
}
}
+  else if (current_char.is_eof ())
+   {
+ rust_error_at (string_begin_locus, "unended raw string literal");
+ return Token::make (END_OF_FILE, get_current_location ());
+   }
 
   length++;
+  current_column++;
+  if (current_char == '\n')
+   {
+ current_line++;
+ current_column = 1;
+ start_line (current_line, max_column_hint);
+   }
 
   str += current_char.as_string ();
   skip_input ();
   current_char = peek_input ();
 }
 
-  current_column += length;
-
   loc += length - 1;
 
   str.shrink_to_fit ();
diff --git a/gcc/testsuite/rust/compile/raw-string-loc.rs 
b/gcc/testsuite/rust/compile/raw-string-loc.rs
new file mode 100644
index 000..70977510ba3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/raw-string-loc.rs
@@ -0,0 +1,6 @@
+const X: &'static str = r#"12
+12"#;
+
+BREAK
+// { dg-error "unrecognised token" "" { target *-*-* } .-1 }
+// { dg-excess-errors "error 'failed to parse item' does not have location" }
-- 
2.45.2



[PATCH 115/125] gccrs: borrowck: BIR: emit moves

2024-08-01 Thread Arthur Cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
(ExprStmtBuilder::visit): Emit moves.
* checks/errors/borrowck/rust-bir-builder-internal.h: Emit moves.
* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Emit moves.
* checks/errors/borrowck/rust-bir-dump.cc (Dump::visit_move_place): 
Emit moves.
(Dump::visit): Emit moves.
* checks/errors/borrowck/rust-bir-place.h (struct Place): Emit moves.
* checks/errors/borrowck/rust-bir-visitor.h: Emit moves.
* checks/errors/borrowck/rust-bir.h (enum class): Emit moves.
(class AbstractExpr): Emit moves.
(BasicBlock::is_terminated): Emit moves.

Signed-off-by: Jakub Dupak 
---
 .../borrowck/rust-bir-builder-expr-stmt.cc| 15 +++--
 .../borrowck/rust-bir-builder-internal.h  | 35 --
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |  2 +-
 .../checks/errors/borrowck/rust-bir-dump.cc   | 11 +++-
 .../checks/errors/borrowck/rust-bir-place.h   | 50 ++
 .../checks/errors/borrowck/rust-bir-visitor.h |  4 ++
 gcc/rust/checks/errors/borrowck/rust-bir.h| 66 +--
 7 files changed, 103 insertions(+), 80 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 89352d84f6b..922894cc5d5 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
@@ -84,7 +84,7 @@ ExprStmtBuilder::visit (HIR::ClosureExpr &expr)
 {
   captures.push_back (ctx.place_db.lookup_variable (capture));
 }
-  make_args (captures);
+  move_all (captures);
 
   // Note: Not a coercion site for captures.
   return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr));
@@ -96,7 +96,7 @@ ExprStmtBuilder::visit (HIR::StructExprStructFields &fields)
   auto struct_ty
 = lookup_type (fields)->as ()->get_variants ().at (0);
   auto init_values = StructBuilder (ctx, struct_ty).build (fields);
-  make_args (init_values);
+  move_all (init_values);
   return_expr (new InitializerExpr (std::move (init_values)),
   lookup_type (fields));
 }
@@ -141,7 +141,7 @@ void
 ExprStmtBuilder::visit (HIR::NegationExpr &expr)
 {
   PlaceId operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({make_arg (operand)}), lookup_type (expr));
+  return_expr (new Operator<1> ({move_place (operand)}), lookup_type (expr));
 }
 
 void
@@ -149,7 +149,7 @@ ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({make_arg (lhs), make_arg (rhs)}),
+  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
   lookup_type (expr));
 }
 
@@ -158,7 +158,7 @@ ExprStmtBuilder::visit (HIR::ComparisonExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({make_arg (lhs), make_arg (rhs)}),
+  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
   lookup_type (expr));
 }
 
@@ -208,7 +208,7 @@ ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
   case HIR::ArrayElems::VALUES: {
auto &elem_vals = (static_cast (*elems));
auto init_values = visit_list (elem_vals.get_values ());
-   make_args (init_values);
+   move_all (init_values);
return_expr (new InitializerExpr (std::move (init_values)),
 lookup_type (expr));
break;
@@ -264,6 +264,7 @@ ExprStmtBuilder::visit (HIR::CallExpr &expr)
   coercion_site (arguments[i], fn_type->get_param_type_at (i));
 }
 
+  move_all (arguments);
   return_expr (new CallExpr (fn, std::move (arguments)), lookup_type (expr),
   true);
 }
@@ -502,7 +503,7 @@ ExprStmtBuilder::visit (HIR::IfExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 {
-  push_switch (make_arg (visit_expr (*expr.get_if_condition (;
+  push_switch (move_place (visit_expr (*expr.get_if_condition (;
   BasicBlockId if_end_bb = ctx.current_bb;
 
   PlaceId result = take_or_create_return_place (lookup_type (expr));
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 55f00aa50ac..b421ba43fba 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -230,10 +230,15 @@ protected: // Helpers to add BIR statements
 push_assignment (tmp, rhs);
   }
 
+  void push_tmp_assignment (PlaceId rhs)
+  {
+push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty);
+  }
+
   void push_switch (PlaceId switch_val,
std::initializer_list destinations = {})
   {
-auto copy = make

[PATCH 069/125] gccrs: Emit error on identical use declarations

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The compiler did not emit any warning when a same target was declared
from different sources.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::handle_use_dec):
Use the new dict to track down already resolved use declarations.
* resolve/rust-toplevel-name-resolver-2.0.h: Add new dict to store
previous use declarations.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../rust-toplevel-name-resolver-2.0.cc| 76 ++-
 .../resolve/rust-toplevel-name-resolver-2.0.h |  4 +
 2 files changed, 46 insertions(+), 34 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 407892bb7bb..94cc3cb62d9 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -319,40 +319,48 @@ TopLevel::handle_use_dec (AST::SimplePath path)
 
   auto found = false;
 
-  auto resolve_and_insert = [this, &found, &declared_name,
-locus] (Namespace ns,
-const AST::SimplePath &path) {
-tl::optional resolved = tl::nullopt;
-
-// FIXME: resolve_path needs to return an `expected` so
-// that we can improve it with hints or location or w/ever. and maybe
-// only emit it the first time.
-switch (ns)
-  {
-  case Namespace::Values:
-   resolved = ctx.values.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Types:
-   resolved = ctx.types.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Macros:
-   resolved = ctx.macros.resolve_path (path.get_segments ());
-   break;
-  case Namespace::Labels:
-   // TODO: Is that okay?
-   rust_unreachable ();
-  }
-
-// FIXME: Ugly
-(void) resolved.map ([this, &found, &declared_name, locus, ns] (NodeId id) 
{
-  found = true;
-
-  // what do we do with the id?
-  insert_or_error_out (declared_name, locus, id, ns);
-
-  return id;
-});
-  };
+  auto resolve_and_insert
+= [this, &found, &declared_name, locus] (Namespace ns,
+const AST::SimplePath &path) {
+   tl::optional resolved = tl::nullopt;
+
+   // FIXME: resolve_path needs to return an `expected` so
+   // that we can improve it with hints or location or w/ever. and maybe
+   // only emit it the first time.
+   switch (ns)
+ {
+ case Namespace::Values:
+   resolved = ctx.values.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Types:
+   resolved = ctx.types.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Macros:
+   resolved = ctx.macros.resolve_path (path.get_segments ());
+   break;
+ case Namespace::Labels:
+   // TODO: Is that okay?
+   rust_unreachable ();
+ }
+
+   // FIXME: Ugly
+   (void) resolved.map (
+ [this, &found, &declared_name, locus, ns, path] (NodeId id) {
+   found = true;
+
+   // what do we do with the id?
+   insert_or_error_out (declared_name, locus, id, ns);
+   auto result = node_forwarding.find (id);
+   if (result != node_forwarding.cend ()
+   && result->second != path.get_node_id ())
+ rust_error_at (path.get_locus (), "%<%s%> defined multiple times",
+declared_name.c_str ());
+   else // No previous thing has inserted this into our scope
+ node_forwarding.insert ({id, path.get_node_id ()});
+
+   return id;
+ });
+  };
 
   // do this for all namespaces (even Labels?)
 
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 ac11f310370..0a766bab259 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -60,6 +60,10 @@ private:
   // FIXME: Do we move these to our mappings?
   std::unordered_map node_locations;
 
+  // Store node forwarding for use declaration, the link between a
+  // "new" local name and its definition.
+  std::unordered_map node_forwarding;
+
   void visit (AST::Module &module) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;
-- 
2.45.2



[PATCH 122/125] gccrs: borrowck: Remove block braces to satisfy GNU style

2024-08-01 Thread Arthur Cohen
From: Jakub Dupak 

gcc/rust/ChangeLog:

* checks/errors/borrowck/rust-bir-dump.cc (renumber_places):
Remove unecessary braces.
(Dump::go): Remove unecessary braces.
(Dump::visit): Remove unecessary braces.
(Dump::visit_scope): Remove unecessary braces.
* checks/errors/borrowck/rust-bir-fact-collector.h (class 
FactCollector):
Remove unecessary braces.
(points): Remove unecessary braces.
* checks/errors/borrowck/rust-bir-free-region.h: Remove unecessary 
braces.
* checks/errors/borrowck/rust-bir-place.h: Remove unecessary braces.
* checks/errors/borrowck/rust-borrow-checker.cc (BorrowChecker::go):
Remove unecessary braces.
* checks/errors/borrowck/rust-function-collector.h: Remove unecessary 
braces.

Signed-off-by: Jakub Dupak 
---
 .../checks/errors/borrowck/rust-bir-dump.cc   | 47 --
 .../errors/borrowck/rust-bir-fact-collector.h | 87 ++-
 .../errors/borrowck/rust-bir-free-region.h| 16 +---
 .../checks/errors/borrowck/rust-bir-place.h   | 17 ++--
 .../errors/borrowck/rust-borrow-checker.cc|  6 +-
 .../errors/borrowck/rust-function-collector.h |  4 +-
 6 files changed, 56 insertions(+), 121 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 51dd1436350..a39f145f8f9 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -42,13 +42,9 @@ renumber_places (const Function &func, std::vector 
&place_map)
 {
   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] = next_out_id++;
   else
-   {
- place_map[in_id] = INVALID_PLACE;
-   }
+   place_map[in_id] = INVALID_PLACE;
 }
 }
 
@@ -138,10 +134,9 @@ Dump::go (bool enable_simplify_cfg)
  stream << ";\n";
}
   if (!bb_terminated)
-   {
- stream << indentation << indentation << "goto -> bb"
-<< bb_fold_map[bb.successors.at (0)] << ";\t\t" << i++ << "\n";
-   }
+   stream << indentation << indentation << "goto -> bb"
+  << bb_fold_map[bb.successors.at (0)] << ";\t\t" << i++ << "\n";
+
   stream << indentation << "}\n";
 }
 
@@ -276,15 +271,13 @@ void
 Dump::visit (const CallExpr &expr)
 {
   stream << "Call(";
-  if (auto fn_type
-  = func.place_db[expr.get_callable ()].tyty->try_as ())
-{
-  stream << fn_type->get_identifier ();
-}
+  auto maybe_fn_type
+= func.place_db[expr.get_callable ()].tyty->try_as ();
+  if (maybe_fn_type)
+stream << maybe_fn_type->get_identifier ();
   else
-{
-  visit_move_place (expr.get_callable ());
-}
+visit_move_place (expr.get_callable ());
+
   stream << ")(";
   print_comma_separated (stream, expr.get_arguments (),
 [this] (PlaceId place_id) {
@@ -321,13 +314,9 @@ void
 Dump::visit (const Assignment &expr)
 {
   if (func.place_db[expr.get_rhs ()].is_rvalue ())
-{
-  visit_move_place (expr.get_rhs ());
-}
+visit_move_place (expr.get_rhs ());
   else
-{
-  visit_place (expr.get_rhs ());
-}
+visit_place (expr.get_rhs ());
 }
 
 std::ostream &
@@ -346,9 +335,8 @@ Dump::visit_scope (ScopeId id, size_t depth)
 return;
 
   if (id > 1)
-{
-  indent (depth) << "scope " << id - 1 << " {\n";
-}
+indent (depth) << "scope " << id - 1 << " {\n";
+
   for (auto &local : scope.locals)
 {
   indent (depth + 1) << "let _";
@@ -357,9 +345,8 @@ 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 >= 1) ? depth + 1 : depth);
+
   if (id > 1)
 indent (depth) << "}\n";
 }
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 17c198e0fa7..527ae65606c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-fact-collector.h
@@ -67,9 +67,8 @@ class FactCollector : public Visitor
   {
 std::vector free_regions;
 for (size_t i = 0; i < size; i++)
-  {
-   free_regions.push_back (region_binder.get_next_free_region ());
-  }
+  free_regions.push_back (region_binder.get_next_free_region ());
+
 return FreeRegions (std::move (free_regions));
   }
 
@@ -129,9 +128,8 @@ protected: // Main collection entry points (for different 
categories).
  case Place::TEMPORARY:
facts.path_is_var.emplace_back (place_id, place_id);
for (auto ®ion : place.regions)
- {
-   facts.use_of_var_derefs_origin.emplace_back (place_id, re

[PATCH 125/125] gccrs: Add a test for inherent impl type name resolve

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

A previous bug with name resolution 2.0 was caused by an incorrectly
resolved inherent impl name. This test shall highlight the behavior
and prevent regression.

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/testsuite/rust/compile/name_resolution25.rs 
b/gcc/testsuite/rust/compile/name_resolution25.rs
new file mode 100644
index 000..3cacac7f64b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/name_resolution25.rs
@@ -0,0 +1,5 @@
+// { dg-options "-frust-name-resolution-2.0" }
+
+struct Test; // { dg-warning "struct is never constructed: .Test." }
+
+impl Test {}
-- 
2.45.2



[PATCH 071/125] gccrs: Prevent error emission on resolver reentry

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The resolver was emitting an error when meeting the same symbol twice.
What is important here is the origin of the resolved symbol, we should
emit an error when the name is similar but the symbol isn't be not when
the resolver is simply meeting the exact same symbol.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (insert_macros): Add
constraint over the ast node id.
(TopLevel::visit): Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 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 72c3560b9da..3b1ccc1d3c5 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -91,7 +91,7 @@ insert_macros (std::vector ¯os, 
NameResolutionContext &ctx)
 {
   auto res = ctx.macros.insert (macro.get_name (), macro.get_node_id ());
 
-  if (!res)
+  if (!res && res.error ().existing != macro.get_node_id ())
{
  rust_error_at (UNKNOWN_LOCATION, ErrorCode::E0428,
 "macro %qs defined multiple times",
@@ -167,7 +167,7 @@ TopLevel::visit (AST::MacroRulesDefinition ¯o)
 {
   auto res = ctx.macros.insert_at_root (macro.get_rule_name (),
macro.get_node_id ());
-  if (!res)
+  if (!res && res.error ().existing != macro.get_node_id ())
{
  // TODO: Factor this
  rich_location rich_loc (line_table, macro.get_locus ());
-- 
2.45.2



[PATCH 058/125] gccrs: Placate clang-format re 'gcc/rust/lex/rust-lex.cc'

2024-08-01 Thread Arthur Cohen
From: Thomas Schwinge 

Reformat the upstream GCC commit 61644aea34c4623d16273ff705f8b8b1ff2d87f0
"gccrs: tokenize Unicode identifiers" change to 'gcc/rust/lex/rust-lex.cc'
to clang-format's liking.

gcc/rust/
* lex/rust-lex.cc (is_identifier_start): Placate clang-format.
---
 gcc/rust/lex/rust-lex.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index bf6bf4c8446..9c2203160cd 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -128,7 +128,8 @@ is_non_decimal_int_literal_separator (uint32_t character)
 bool
 is_identifier_start (uint32_t codepoint)
 {
-  return (cpp_check_xid_property (codepoint) & CPP_XID_START) || codepoint == 
'_';
+  return (cpp_check_xid_property (codepoint) & CPP_XID_START)
+|| codepoint == '_';
 }
 
 bool
-- 
2.45.2



[PATCH 099/125] gccrs: compile: resolve-path-ref: properly resolve nodeId with nr2.0

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-compile-resolve-path.cc: Attempt to resolve names
also using new name resolution context.
* backend/rust-compile-resolve-path.h: Add new declaration.
---
 gcc/rust/backend/rust-compile-resolve-path.cc | 112 +++---
 gcc/rust/backend/rust-compile-resolve-path.h  |   6 +
 2 files changed, 74 insertions(+), 44 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc 
b/gcc/rust/backend/rust-compile-resolve-path.cc
index 366de59865e..3bb45a53750 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -17,14 +17,17 @@
 // .
 
 #include "rust-compile-resolve-path.h"
+#include "options.h"
 #include "rust-compile-intrinsic.h"
 #include "rust-compile-item.h"
 #include "rust-compile-implitem.h"
 #include "rust-compile-expr.h"
+#include "rust-hir-map.h"
 #include "rust-hir-trait-resolve.h"
 #include "rust-hir-path-probe.h"
 #include "rust-compile-extern.h"
 #include "rust-constexpr.h"
+#include "rust-tyty.h"
 
 namespace Rust {
 namespace Compile {
@@ -43,6 +46,50 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
  expr.get_mappings (), expr.get_locus (), false);
 }
 
+tree
+ResolvePathRef::attempt_constructor_expression_lookup (
+  TyTy::BaseType *lookup, Context *ctx, const Analysis::NodeMapping &mappings,
+  location_t expr_locus)
+{
+  // it might be an enum data-less enum variant
+  if (lookup->get_kind () != TyTy::TypeKind::ADT)
+return error_mark_node;
+
+  TyTy::ADTType *adt = static_cast (lookup);
+  if (adt->is_unit ())
+return unit_expression (ctx, expr_locus);
+
+  if (!adt->is_enum ())
+return error_mark_node;
+
+  HirId variant_id;
+  if (!ctx->get_tyctx ()->lookup_variant_definition (mappings.get_hirid (),
+&variant_id))
+return error_mark_node;
+
+  int union_disriminator = -1;
+  TyTy::VariantDef *variant = nullptr;
+  if (!adt->lookup_variant_by_id (variant_id, &variant, &union_disriminator))
+return error_mark_node;
+
+  // this can only be for discriminant variants the others are built up
+  // using call-expr or struct-init
+  rust_assert (variant->get_variant_type ()
+  == TyTy::VariantDef::VariantType::NUM);
+
+  // we need the actual gcc type
+  tree compiled_adt_type = TyTyResolveCompile::compile (ctx, adt);
+
+  // make the ctor for the union
+  HIR::Expr *discrim_expr = variant->get_discriminant ();
+  tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
+  tree folded_discrim_expr = fold_expr (discrim_expr_node);
+  tree qualifier = folded_discrim_expr;
+
+  return Backend::constructor_expression (compiled_adt_type, true, {qualifier},
+ union_disriminator, expr_locus);
+}
+
 tree
 ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
 const Analysis::NodeMapping &mappings,
@@ -53,52 +100,29 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment 
&final_segment,
   rust_assert (ok);
 
   // need to look up the reference for this identifier
+
+  // this can fail because it might be a Constructor for something
+  // in that case the caller should attempt ResolvePathType::Compile
   NodeId ref_node_id = UNKNOWN_NODEID;
-  if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
-  &ref_node_id))
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto resolved = nr_ctx.lookup (mappings.get_nodeid ());
+
+  if (!resolved)
+   return attempt_constructor_expression_lookup (lookup, ctx, mappings,
+ expr_locus);
+
+  ref_node_id = *resolved;
+}
+  else
 {
-  // this can fail because it might be a Constructor for something
-  // in that case the caller should attempt ResolvePathType::Compile
-
-  // it might be an enum data-less enum variant
-  if (lookup->get_kind () != TyTy::TypeKind::ADT)
-   return error_mark_node;
-
-  TyTy::ADTType *adt = static_cast (lookup);
-  if (adt->is_unit ())
-   return unit_expression (ctx, expr_locus);
-
-  if (!adt->is_enum ())
-   return error_mark_node;
-
-  HirId variant_id;
-  if (!ctx->get_tyctx ()->lookup_variant_definition (mappings.get_hirid (),
-&variant_id))
-   return error_mark_node;
-
-  int union_disriminator = -1;
-  TyTy::VariantDef *variant = nullptr;
-  if (!adt->lookup_variant_by_id (variant_id, &variant,
- &union_disriminator))
-   return error_mark_node;
-
-  // this can only be for discriminant variants the others are built up
-  // using call-expr or struct-init
-  rust_assert (var

[PATCH 076/125] gccrs: Add call to globbing visitor

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Globbing visitor did not visit subitems.

gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add a check
for missing item.
* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::go):
Add a new function in the visitor to dispatch the visitor to items in
the given module.
(TopLevel::handle_use_glob): Change call to visitor to use the pointer.
* resolve/rust-toplevel-name-resolver-2.0.h: Add prototype for new
member function.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 2 ++
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 -
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h  | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 68eb88a1e4c..d8bd9ac524f 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -197,6 +197,8 @@ Late::visit (AST::PathInExpression &expr)
   // do we emit it in `get`?
 
   auto value = ctx.values.resolve_path (expr.get_segments ());
+  if (!value.has_value ())
+rust_unreachable (); // Should have been resolved earlier
 
   ctx.map_usage (Usage (expr.get_node_id ()), Definition (*value));
 }
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 3122d41412f..501204174f2 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -25,6 +25,13 @@
 namespace Rust {
 namespace Resolver2_0 {
 
+void
+GlobbingVisitor::go (AST::Module *module)
+{
+  for (auto &i : module->get_items ())
+visit (i);
+}
+
 void
 GlobbingVisitor::visit (AST::Module &module)
 {
@@ -399,7 +406,7 @@ TopLevel::handle_use_glob (AST::SimplePath glob)
 return false;
 
   GlobbingVisitor gvisitor (ctx);
-  gvisitor.visit (*result.value ());
+  gvisitor.go (result.value ());
 
   return true;
 }
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 31535a9b22e..f5e224fa049 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -33,6 +33,7 @@ class GlobbingVisitor : public AST::DefaultASTVisitor
 public:
   GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
 
+  void go (AST::Module *module);
   void visit (AST::Module &module) override;
   void visit (AST::MacroRulesDefinition ¯o) override;
   void visit (AST::Function &function) override;
-- 
2.45.2



[PATCH 060/125] gccrs: sesh: Add late name resolution 2.0

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-session-manager.cc (Session::compile_crate): Create name 
resolution
context for Session::expansion and subsequent name resolution passes.
(Session::expansion): Take name resolution context as a parameter
instead.
* rust-session-manager.h (Session::expansion): Fix declaration.
---
 gcc/rust/rust-session-manager.cc | 14 +-
 gcc/rust/rust-session-manager.h  |  3 ++-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index ea99d019f64..40adeb20de4 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -42,6 +42,7 @@
 #include "rust-early-name-resolver.h"
 #include "rust-name-resolution-context.h"
 #include "rust-early-name-resolver-2.0.h"
+#include "rust-late-name-resolver-2.0.h"
 #include "rust-cfg-strip.h"
 #include "rust-expand-visitor.h"
 #include "rust-unicode.h"
@@ -591,8 +592,10 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::Expansion)
 return;
 
+  auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
   // expansion pipeline stage
-  expansion (parsed_crate);
+
+  expansion (parsed_crate, name_resolution_ctx);
   rust_debug ("\033[0;31mSUCCESSFULLY FINISHED EXPANSION \033[0m");
   if (options.dump_option_enabled (CompileOptions::EXPANSION_DUMP))
 {
@@ -617,7 +620,10 @@ Session::compile_crate (const char *filename)
 return;
 
   // resolution pipeline stage
-  Resolver::NameResolution::Resolve (parsed_crate);
+  if (flag_name_resolution_2_0)
+Resolver2_0::Late (name_resolution_ctx).go (parsed_crate);
+  else
+Resolver::NameResolution::Resolve (parsed_crate);
 
   if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
 {
@@ -881,7 +887,7 @@ Session::injection (AST::Crate &crate)
 }
 
 void
-Session::expansion (AST::Crate &crate)
+Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx)
 {
   rust_debug ("started expansion");
 
@@ -908,8 +914,6 @@ Session::expansion (AST::Crate &crate)
   if (saw_errors ())
break;
 
-  auto ctx = Resolver2_0::NameResolutionContext ();
-
   if (flag_name_resolution_2_0)
{
  Resolver2_0::Early early (ctx);
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 41aad607905..9a5691f45ee 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -24,6 +24,7 @@
 #include "rust-backend.h"
 #include "rust-hir-map.h"
 #include "safe-ctype.h"
+#include "rust-name-resolution-context.h"
 
 #include "config.h"
 #include "rust-system.h"
@@ -413,7 +414,7 @@ private:
   /* Expansion pipeline stage. TODO maybe move to another object? Expands all
* macros, maybe build test harness in future, AST validation, maybe create
* macro crate (if not rustdoc).*/
-  void expansion (AST::Crate &crate);
+  void expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx);
 
   // handle cfg_option
   bool handle_cfg_option (std::string &data);
-- 
2.45.2



[PATCH 041/125] gccrs: Update resolver to use `AST::Function` instead of `AST::ExternalFunctionItem`

2024-08-01 Thread Arthur Cohen
From: 0xn4utilus 

gcc/rust/ChangeLog:

* checks/errors/rust-feature-gate.cc (FeatureGate::visit):
Check if function is_external or not.
* hir/rust-ast-lower-extern.h: Use AST::Function
instead of AST::ExternalFunctionItem.
* parse/rust-parse-impl.h (Parser::parse_external_item):
Likewise.
(Parser::parse_pattern): Fix clang format.
* resolve/rust-ast-resolve-implitem.h: Likewise.
* resolve/rust-ast-resolve-item.cc (ResolveExternItem::visit):
Likewise.
* resolve/rust-ast-resolve-item.h: Likewise.
* resolve/rust-default-resolver.cc (DefaultResolver::visit):
Check if param has_pattern before using get_pattern.

Signed-off-by: 0xn4utilus 
---
 gcc/rust/checks/errors/rust-feature-gate.cc  |  3 ++-
 gcc/rust/hir/rust-ast-lower-extern.h | 23 +++-
 gcc/rust/parse/rust-parse-impl.h |  7 +++---
 gcc/rust/resolve/rust-ast-resolve-implitem.h |  4 ++--
 gcc/rust/resolve/rust-ast-resolve-item.cc| 16 +-
 gcc/rust/resolve/rust-ast-resolve-item.h |  2 +-
 gcc/rust/resolve/rust-default-resolver.cc|  3 ++-
 7 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 3c943022f05..33bbfa1ec51 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -131,7 +131,8 @@ FeatureGate::visit (AST::MacroRulesDefinition &rules_def)
 void
 FeatureGate::visit (AST::Function &function)
 {
-  check_rustc_attri (function.get_outer_attrs ());
+  if (!function.is_external ())
+check_rustc_attri (function.get_outer_attrs ());
 }
 
 void
diff --git a/gcc/rust/hir/rust-ast-lower-extern.h 
b/gcc/rust/hir/rust-ast-lower-extern.h
index f9e067c8e95..ad7d75422d6 100644
--- a/gcc/rust/hir/rust-ast-lower-extern.h
+++ b/gcc/rust/hir/rust-ast-lower-extern.h
@@ -65,7 +65,7 @@ public:
   item.get_outer_attrs (), item.get_locus ());
   }
 
-  void visit (AST::ExternalFunctionItem &function) override
+  void visit (AST::Function &function) override
   {
 std::vector > where_clause_items;
 HIR::WhereClause where_clause (std::move (where_clause_items));
@@ -88,12 +88,25 @@ public:
 std::vector function_params;
 for (auto it = begin; it != end; it++)
   {
+   auto param = static_cast (it->get ());
+
+   if (param->is_variadic () || param->is_self ())
+ continue;
+   auto param_kind = param->get_pattern ()->get_pattern_kind ();
+
+   rust_assert (param_kind == AST::Pattern::Kind::Identifier
+|| param_kind == AST::Pattern::Kind::Wildcard);
+   auto param_ident = static_cast (
+ param->get_pattern ().get ());
+   Identifier param_name = param_kind == AST::Pattern::Kind::Identifier
+ ? param_ident->get_ident ()
+ : std::string ("_");
+
HIR::Type *param_type
- = ASTLoweringType::translate (it->get_type ().get ());
-   Identifier param_name = it->get_name ();
+ = ASTLoweringType::translate (param->get_type ().get ());
 
auto crate_num = mappings->get_current_crate ();
-   Analysis::NodeMapping mapping (crate_num, it->get_node_id (),
+   Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
   mappings->get_next_hir_id (crate_num),
   mappings->get_next_localdef_id (
 crate_num));
@@ -109,7 +122,7 @@ public:
   mappings->get_next_localdef_id (crate_num));
 
 translated = new HIR::ExternalFunctionItem (
-  mapping, function.get_identifier (), std::move (generic_params),
+  mapping, function.get_function_name (), std::move (generic_params),
   std::unique_ptr (return_type), std::move (where_clause),
   std::move (function_params), is_variadic, std::move (vis),
   function.get_outer_attrs (), function.get_locus ());
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c8a87a11766..26b24150f7a 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -6165,8 +6165,7 @@ Parser::parse_external_item ()
   std::move (outer_attrs), locus));
   }
 case FN_KW:
-  return parse_external_function_item (std::move (vis),
-  std::move (outer_attrs));
+  return parse_function (std::move (vis), std::move (outer_attrs), true);
 
 case TYPE:
   return parse_external_type_item (std::move (vis),
@@ -10476,7 +10475,9 @@ Parser::parse_pattern ()
 {
   lexer.skip_token ();
   alts.push_back (parse_pattern_no_alt ());
-  } while (lexer.peek_token ()->get_id () == PIPE);
+}
+
+  while (lexer.peek_token ()->get_id () == PIPE);
 
   /* alter

[PATCH 080/125] gccrs: Change error message to match test

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Error message did not match the test from the previous name resolver when
a given path cannot be resolved.

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_root_path):
Change error message to match old resolver and test case.

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

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index cdb506dacbe..b0e52c454e9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -266,8 +266,10 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression 
&expr, size_t *offset,
{
  if (is_root)
{
- rust_error_at (seg.get_locus (),
-"failed to resolve root segment");
+ rust_error_at (expr.get_locus (), ErrorCode::E0425,
+"cannot find value %qs in this scope",
+expr.as_simple_path ().as_string ().c_str ());
+
  return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
  return root_tyty;
-- 
2.45.2



[PATCH 061/125] gccrs: session-manager: Dump name resolution pass.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* rust-session-manager.cc: Add files for dumping name resolution, call
name resolution dump function.
(Session::dump_name_resolution): New.
* rust-session-manager.h: New declaration.
---
 gcc/rust/rust-session-manager.cc | 30 +++---
 gcc/rust/rust-session-manager.h  |  1 +
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 40adeb20de4..64e0190f716 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -69,6 +69,10 @@ const char *kASTDumpFile = "gccrs.ast.dump";
 const char *kASTPrettyDumpFile = "gccrs.ast-pretty.dump";
 const char *kASTPrettyDumpFileExpanded = "gccrs.ast-pretty-expanded.dump";
 const char *kASTExpandedDumpFile = "gccrs.ast-expanded.dump";
+const char *kASTmacroResolutionDumpFile = "gccrs.ast-macro-resolution.dump";
+const char *kASTlabelResolutionDumpFile = "gccrs.ast-label-resolution.dump";
+const char *kASTtypeResolutionDumpFile = "gccrs.ast-type-resolution.dump";
+const char *kASTvalueResolutionDumpFile = "gccrs.ast-value-resolution.dump";
 const char *kHIRDumpFile = "gccrs.hir.dump";
 const char *kHIRPrettyDumpFile = "gccrs.hir-pretty.dump";
 const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump";
@@ -86,6 +90,7 @@ Session::get_instance ()
 
 static std::string
 infer_crate_name (const std::string &filename)
+
 {
   if (filename == "-")
 return kDefaultCrateName;
@@ -626,9 +631,7 @@ Session::compile_crate (const char *filename)
 Resolver::NameResolution::Resolve (parsed_crate);
 
   if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP))
-{
-  // TODO: what do I dump here? resolved names? AST with resolved names?
-}
+dump_name_resolution (name_resolution_ctx);
 
   if (saw_errors ())
 return;
@@ -982,6 +985,27 @@ Session::dump_ast_pretty (AST::Crate &crate, bool 
expanded) const
   out.close ();
 }
 
+void
+Session::dump_name_resolution (Resolver2_0::NameResolutionContext &ctx) const
+{
+  // YES this is ugly but NO GCC 4.8 does not allow us to make it fancier :(
+  std::string types_content = ctx.types.as_debug_string ();
+  std::ofstream types_stream{kASTtypeResolutionDumpFile};
+  types_stream << types_content;
+
+  std::string macros_content = ctx.macros.as_debug_string ();
+  std::ofstream macros_stream{kASTmacroResolutionDumpFile};
+  macros_stream << macros_content;
+
+  std::string labels_content = ctx.labels.as_debug_string ();
+  std::ofstream labels_stream{kASTlabelResolutionDumpFile};
+  labels_stream << labels_content;
+
+  std::string values_content = ctx.values.as_debug_string ();
+  std::ofstream values_stream{kASTvalueResolutionDumpFile};
+  values_stream << values_content;
+}
+
 void
 Session::dump_hir (HIR::Crate &crate) const
 {
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 9a5691f45ee..845b53ab6db 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -396,6 +396,7 @@ private:
 
   void dump_lex (Parser &parser) const;
   void dump_ast_pretty (AST::Crate &crate, bool expanded = false) const;
+  void dump_name_resolution (Resolver2_0::NameResolutionContext &ctx) const;
   void dump_hir (HIR::Crate &crate) const;
   void dump_hir_pretty (HIR::Crate &crate) const;
 
-- 
2.45.2



[PATCH 081/125] gccrs: Visit function return type in default resolver

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Function return type was not properly visited in the default resolver
visitor pattern.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Visit
function return type.

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

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index e2609d13c9a..d805bc9a511 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -79,6 +79,9 @@ DefaultResolver::visit (AST::Function &function)
  }
   }
 
+if (function.has_return_type ())
+  visit (function.get_return_type ());
+
 if (function.has_body ())
   function.get_definition ().value ()->accept_vis (*this);
   };
-- 
2.45.2



[PATCH 065/125] gccrs: backend: Use new name resolver where necessary

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* backend/rust-compile-base.cc: Use new ImmutableNrCtx.
* backend/rust-compile-context.h: Likewise.
* backend/rust-compile-expr.cc: Likewise.
* backend/rust-compile-item.cc: Likewise.
---
 gcc/rust/backend/rust-compile-base.cc   |  1 +
 gcc/rust/backend/rust-compile-context.h |  1 +
 gcc/rust/backend/rust-compile-expr.cc   | 22 ++
 gcc/rust/backend/rust-compile-item.cc   | 31 -
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index 4d6f0275b00..584d6a03ea9 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -31,6 +31,7 @@
 #include "rust-type-util.h"
 #include "rust-compile-implitem.h"
 #include "rust-attribute-values.h"
+#include "rust-immutable-name-resolution-context.h"
 
 #include "fold-const.h"
 #include "stringpool.h"
diff --git a/gcc/rust/backend/rust-compile-context.h 
b/gcc/rust/backend/rust-compile-context.h
index 36a36e79f68..671aee196c2 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -27,6 +27,7 @@
 #include "rust-hir-full.h"
 #include "rust-mangle.h"
 #include "rust-tree.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 65de24bf9d8..6a9bb73ffe0 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2311,11 +2311,23 @@ CompileExpr::generate_closure_function 
(HIR::ClosureExpr &expr,
   if (is_block_expr)
 {
   auto body_mappings = function_body->get_mappings ();
-  Resolver::Rib *rib = nullptr;
-  bool ok
-   = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
-  &rib);
-  rust_assert (ok);
+  if (flag_name_resolution_2_0)
+   {
+ auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+ auto candidate = nr_ctx.values.to_rib (body_mappings.get_nodeid ());
+
+ rust_assert (candidate.has_value ());
+   }
+  else
+   {
+ Resolver::Rib *rib = nullptr;
+ bool ok
+   = ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
+  &rib);
+ rust_assert (ok);
+   }
 }
 
   tree enclosing_scope = NULL_TREE;
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index 234ad2aa59c..8feed51efa4 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -19,6 +19,7 @@
 #include "rust-compile-item.h"
 #include "rust-compile-implitem.h"
 #include "rust-compile-extern.h"
+#include "rust-immutable-name-resolution-context.h"
 
 namespace Rust {
 namespace Compile {
@@ -149,12 +150,30 @@ CompileItem::visit (HIR::Function &function)
}
 }
 
-  const Resolver::CanonicalPath *canonical_path = nullptr;
-  bool ok = ctx->get_mappings ()->lookup_canonical_path (
-function.get_mappings ().get_nodeid (), &canonical_path);
-  rust_assert (ok);
+  Resolver::CanonicalPath canonical_path
+= Resolver::CanonicalPath::create_empty ();
+
+  if (flag_name_resolution_2_0)
+{
+  auto nr_ctx
+   = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
+
+  auto path = nr_ctx.values.to_canonical_path (
+   function.get_mappings ().get_nodeid ());
+
+  canonical_path = path.value ();
+}
+  else
+{
+  const Resolver::CanonicalPath *path = nullptr;
+  bool ok = ctx->get_mappings ()->lookup_canonical_path (
+   function.get_mappings ().get_nodeid (), &path);
+  rust_assert (ok);
+
+  canonical_path = *path;
+}
 
-  const std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
+  const std::string asm_name = ctx->mangle_item (fntype, canonical_path);
 
   // items can be forward compiled which means we may not need to invoke this
   // code. We might also have already compiled this generic function as well.
@@ -181,7 +200,7 @@ CompileItem::visit (HIR::Function &function)
function.get_function_params (),
function.get_qualifiers (), function.get_visibility (),
function.get_outer_attrs (), function.get_locus (),
-   function.get_definition ().get (), canonical_path,
+   function.get_definition ().get (), &canonical_path,
fntype);
   reference = address_expression (fndecl, ref_locus);
 
-- 
2.45.2



[PATCH 066/125] gccrs: nr2.0: Start using newtype pattern for Usage and Declaration

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::map_usage):
Use newtype pattern.
(NameResolutionContext::lookup): Likewise.
* resolve/rust-name-resolution-context.h (class Usage): New class.
(class Definition): Likewise.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Create instances
of Usage and Definition.
---
 .../resolve/rust-late-name-resolver-2.0.cc|  4 +--
 .../resolve/rust-name-resolution-context.cc   |  6 ++---
 .../resolve/rust-name-resolution-context.h| 27 +--
 3 files changed, 30 insertions(+), 7 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 e5a4f234871..50034073edf 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -142,7 +142,7 @@ Late::visit (AST::IdentifierExpr &expr)
   return;
 }
 
-  ctx.map_usage (expr.get_node_id (), *resolved);
+  ctx.map_usage (Usage (expr.get_node_id ()), Definition (*resolved));
 
   // in the old resolver, resolutions are kept in the resolver, not the 
mappings
   // :/ how do we deal with that?
@@ -173,7 +173,7 @@ Late::visit (AST::TypePath &type)
 
   auto resolved = ctx.types.get (type.get_segments ().back ()->as_string ());
 
-  ctx.map_usage (type.get_node_id (), *resolved);
+  ctx.map_usage (Usage (type.get_node_id ()), Definition (*resolved));
 }
 
 } // namespace Resolver2_0
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 9fd8d52968a..0340d28f127 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -46,7 +46,7 @@ NameResolutionContext::insert (Identifier name, NodeId id, 
Namespace ns)
 }
 
 void
-NameResolutionContext::map_usage (NodeId usage, NodeId definition)
+NameResolutionContext::map_usage (Usage usage, Definition definition)
 {
   auto inserted = resolved_nodes.emplace (usage, definition).second;
 
@@ -57,12 +57,12 @@ NameResolutionContext::map_usage (NodeId usage, NodeId 
definition)
 tl::optional
 NameResolutionContext::lookup (NodeId usage)
 {
-  auto it = resolved_nodes.find (usage);
+  auto it = resolved_nodes.find (Usage (usage));
 
   if (it == resolved_nodes.end ())
 return tl::nullopt;
 
-  return it->second;
+  return it->second.id;
 }
 
 void
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index e896ca05360..8702900d0f3 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -133,6 +133,28 @@ change?
 correct
 */
 
+// FIXME: Documentation
+class Usage
+{
+public:
+  explicit Usage (NodeId id) : id (id) {}
+
+  // TODO: move to name-resolution-ctx.cc
+  // storing it as a key in a map
+  bool operator< (const Usage other) const { return other.id < id; }
+
+  NodeId id;
+};
+
+// FIXME: Documentation
+class Definition
+{
+public:
+  explicit Definition (NodeId id) : id (id) {}
+
+  NodeId id;
+};
+
 // Now our resolver, which keeps track of all the `ForeverStack`s we could want
 class NameResolutionContext
 {
@@ -182,12 +204,13 @@ public:
 
   // TODO: Rename
   // TODO: Use newtype pattern for Usage and Definition
-  void map_usage (NodeId usage, NodeId definition);
+  void map_usage (Usage usage, Definition definition);
+
   tl::optional lookup (NodeId usage);
 
 private:
   /* Map of "usage" nodes which have been resolved to a "definition" node */
-  std::map resolved_nodes;
+  std::map resolved_nodes;
 };
 
 } // namespace Resolver2_0
-- 
2.45.2



[PATCH 046/125] gccrs: macro: Use MacroInvocation's node_id in ExternalItem constructor.

2024-08-01 Thread Arthur Cohen
gcc/rust/ChangeLog:

* ast/rust-macro.h: Use proper node id instead of the one in the base
Expr class - which is uninitialized.
---
 gcc/rust/ast/rust-macro.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h
index 5b9ff3f22c8..507e595e379 100644
--- a/gcc/rust/ast/rust-macro.h
+++ b/gcc/rust/ast/rust-macro.h
@@ -727,7 +727,7 @@ private:
   {}
 
   MacroInvocation (const MacroInvocation &other)
-: TraitItem (other.locus), ExternalItem (Expr::node_id),
+: TraitItem (other.locus), ExternalItem (other.node_id),
   outer_attrs (other.outer_attrs), locus (other.locus),
   node_id (other.node_id), invoc_data (other.invoc_data),
   is_semi_coloned (other.is_semi_coloned), kind (other.kind),
-- 
2.45.2



[PATCH 085/125] gccrs: Unit struct constructor shall be resolved

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Unit struct have a special constructor that should be added to the struct
namespace in order to be resolved later when called. As it is a function
it should be added in the value namespace.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::visit):
Add the struct constructor when the struct is a unit.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +++--
 1 file changed, 7 insertions(+), 2 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 4134b9a4620..75d9bb82131 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -68,8 +68,13 @@ void
 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::Values);
+{
+  ctx.insert_shadowable (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);
+}
 }
 
 void
-- 
2.45.2



[PATCH 050/125] gccrs: format-args: Add basic test case

2024-08-01 Thread Arthur Cohen
gcc/testsuite/ChangeLog:

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

diff --git a/gcc/testsuite/rust/compile/format_args_basic_expansion.rs 
b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
new file mode 100644
index 000..40bcd3c1433
--- /dev/null
+++ b/gcc/testsuite/rust/compile/format_args_basic_expansion.rs
@@ -0,0 +1,47 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! format_args {
+() => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+pub mod core {
+pub mod fmt {
+pub struct Formatter;
+pub struct Result;
+
+pub struct Arguments<'a>;
+
+impl<'a> Arguments<'a> {
+pub fn new_v1(_: &'a [&'static str], _: &'a [ArgumentV1<'a>]) -> 
Arguments<'a> {
+Arguments
+}
+}
+
+pub struct ArgumentV1<'a>;
+
+impl<'a> ArgumentV1<'a> {
+pub fn new<'b, T>(_: &'b T, _: fn(&T, &mut Formatter) -> Result) 
-> ArgumentV1 {
+ArgumentV1
+}
+}
+
+pub trait Display {
+fn fmt(&self, _: &mut Formatter) -> Result;
+}
+
+impl Display for i32 {
+fn fmt(&self, _: &mut Formatter) -> Result {
+// { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+Result
+}
+}
+}
+}
+
+fn main() {
+let _formatted = format_args!("hello {}", 15);
+}
-- 
2.45.2



[PATCH 094/125] gccrs: Update assignment operator with cratenum

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Crate number was not assigned with the other fields in the assignment
operator overload of a CannonicalPath.

gcc/rust/ChangeLog:

* util/rust-canonical-path.h: Also assign crate number.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/util/rust-canonical-path.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/rust/util/rust-canonical-path.h 
b/gcc/rust/util/rust-canonical-path.h
index f2865eba9ae..969ac7f7cc1 100644
--- a/gcc/rust/util/rust-canonical-path.h
+++ b/gcc/rust/util/rust-canonical-path.h
@@ -51,6 +51,7 @@ public:
   CanonicalPath &operator= (const CanonicalPath &other)
   {
 segs = other.segs;
+crate_num = other.crate_num;
 return *this;
   }
 
-- 
2.45.2



[PATCH 077/125] gccrs: Make globbing definition shadowable by default

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Elements from glob use declaration shall be shadowable by default.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.h: Add a new function prototype to insert
a shadowable definition.
* resolve/rust-forever-stack.hxx: Add the new insert_shadowable
function to insert shadowable definition into the forever stack.
* resolve/rust-name-resolution-context.cc 
(NameResolutionContext::insert_shadowable):
Likewise with the name resolution context.
* resolve/rust-name-resolution-context.h: Add name resolution context
insert_shadowable member function prototype.
* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::visit):
Insert shadowable definition into the forever stack for glob use
declaration.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-forever-stack.h | 15 
 gcc/rust/resolve/rust-forever-stack.hxx   | 10 ++
 .../resolve/rust-name-resolution-context.cc   | 19 ++
 .../resolve/rust-name-resolution-context.h|  3 ++
 .../rust-toplevel-name-resolver-2.0.cc| 35 ++-
 5 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 01371fc7bcd..bba5875d435 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -437,6 +437,21 @@ public:
*/
   tl::expected insert (Identifier name, NodeId id);
 
+  /**
+   * Insert a new shadowable definition in the innermost `Rib` in this stack
+   *
+   * @param name The name of the definition
+   * @param id Its NodeId
+   *
+   * @return `DuplicateNameError` if that node was already present in the Rib,
+   * the node's `NodeId` otherwise.
+   *
+   * @aborts if there are no `Rib`s inserted in the current map, this function
+   * aborts the program.
+   */
+  tl::expected insert_shadowable (Identifier name,
+ NodeId id);
+
   /**
* Insert a new definition at the root of this stack
*
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index a2fdce98362..008adff4676 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -119,6 +119,16 @@ ForeverStack::insert (Identifier name, NodeId node)
   Rib::Definition::NonShadowable (node));
 }
 
+template 
+tl::expected
+ForeverStack::insert_shadowable (Identifier name, NodeId node)
+{
+  auto &innermost_rib = peek ();
+
+  return insert_inner (innermost_rib, name.as_string (),
+  Rib::Definition::Shadowable (node));
+}
+
 template 
 tl::expected
 ForeverStack::insert_at_root (Identifier name, NodeId node)
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc 
b/gcc/rust/resolve/rust-name-resolution-context.cc
index 0340d28f127..e8529b70bcb 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -45,6 +45,25 @@ NameResolutionContext::insert (Identifier name, NodeId id, 
Namespace ns)
 }
 }
 
+tl::expected
+NameResolutionContext::insert_shadowable (Identifier name, NodeId id,
+ Namespace ns)
+{
+  switch (ns)
+{
+case Namespace::Values:
+  return values.insert_shadowable (name, id);
+case Namespace::Types:
+  return types.insert_shadowable (name, id);
+case Namespace::Macros:
+  return macros.insert_shadowable (name, id);
+case Namespace::Labels:
+default:
+  // return labels.insert (name, id);
+  rust_unreachable ();
+}
+}
+
 void
 NameResolutionContext::map_usage (Usage usage, Definition definition)
 {
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h 
b/gcc/rust/resolve/rust-name-resolution-context.h
index 8702900d0f3..74f110d54de 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -171,6 +171,9 @@ public:
   tl::expected insert (Identifier name, NodeId id,
   Namespace ns);
 
+  tl::expected
+  insert_shadowable (Identifier name, NodeId id, Namespace ns);
+
   /**
* Run a lambda in a "scoped" context, meaning that a new `Rib` will be 
pushed
* before executing the lambda and then popped. This is useful for all kinds
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 501204174f2..7f4169a4d8e 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -36,71 +36,72 @@ void
 GlobbingVisitor::visit (AST::Module &module)
 {
   if (module.get_visibility ().is_public ())
-ctx.insert (module.get_name (), module.get_node_id (), Namespace::Types);
+ctx.insert_shadowable (module.

[PATCH 109/125] gccrs: unify: Always coerce `!` to the target type.

2024-08-01 Thread Arthur Cohen
Never can... never... exist, so it should always be coerced to the type
it is being matched against. This is useful for breaking off of a loop
from inside a match, or an if condition, for example.

gcc/rust/ChangeLog:

* typecheck/rust-unify.cc (UnifyRules::go): Always unify to `ltype` if
we are matching against a `Never` in `rtype`.
(UnifyRules::expect_never): Always unify to the expected type.

gcc/testsuite/ChangeLog:

* rust/compile/match-never-ltype.rs: New test.
* rust/compile/match-never-rtype.rs: New test.
---
 gcc/rust/typecheck/rust-unify.cc  | 36 ++-
 .../rust/compile/match-never-ltype.rs | 17 +
 .../rust/compile/match-never-rtype.rs | 17 +
 3 files changed, 45 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/match-never-ltype.rs
 create mode 100644 gcc/testsuite/rust/compile/match-never-rtype.rs

diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 8b43380cc59..7d1042d8e63 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-unify.h"
+#include "rust-tyty.h"
 
 namespace Rust {
 namespace Resolver {
@@ -237,6 +238,15 @@ UnifyRules::go ()
}
 }
 
+  // The never type should always get coerced to the type it's being matched
+  // against, so in that case, ltype. This avoids doing the same check in all
+  // the `expect_*` functions.
+  // However, this does not work if we have an annoying ltype - like INFER.
+  // TODO: Is ltype == Infer the only special case here? What about 
projections?
+  // references?
+  if (rtype->get_kind () == TyTy::NEVER && ltype->get_kind () != TyTy::INFER)
+return ltype->clone ();
+
   switch (ltype->get_kind ())
 {
 case TyTy::INFER:
@@ -1536,32 +1546,8 @@ UnifyRules::expect_never (TyTy::NeverType *ltype, 
TyTy::BaseType *rtype)
   }
   break;
 
-case TyTy::NEVER:
+default:
   return rtype->clone ();
-
-case TyTy::PLACEHOLDER:
-case TyTy::PROJECTION:
-case TyTy::DYNAMIC:
-case TyTy::CLOSURE:
-case TyTy::SLICE:
-case TyTy::PARAM:
-case TyTy::POINTER:
-case TyTy::STR:
-case TyTy::ADT:
-case TyTy::REF:
-case TyTy::ARRAY:
-case TyTy::FNDEF:
-case TyTy::FNPTR:
-case TyTy::TUPLE:
-case TyTy::BOOL:
-case TyTy::CHAR:
-case TyTy::INT:
-case TyTy::UINT:
-case TyTy::FLOAT:
-case TyTy::USIZE:
-case TyTy::ISIZE:
-case TyTy::ERROR:
-  return new TyTy::ErrorType (0);
 }
   return new TyTy::ErrorType (0);
 }
diff --git a/gcc/testsuite/rust/compile/match-never-ltype.rs 
b/gcc/testsuite/rust/compile/match-never-ltype.rs
new file mode 100644
index 000..6516ab3c1ea
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-never-ltype.rs
@@ -0,0 +1,17 @@
+fn foo() {}
+
+enum Foo {
+A,
+B,
+}
+
+fn main() {
+let a = Foo::A;
+
+loop {
+match a {
+Foo::A => break,
+Foo::B => foo(),
+}
+}
+}
diff --git a/gcc/testsuite/rust/compile/match-never-rtype.rs 
b/gcc/testsuite/rust/compile/match-never-rtype.rs
new file mode 100644
index 000..6e4e7638f67
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-never-rtype.rs
@@ -0,0 +1,17 @@
+fn foo() {}
+
+enum Foo {
+A,
+B,
+}
+
+fn main() {
+let a = Foo::A;
+
+loop {
+match a {
+Foo::B => foo(),
+Foo::A => break,
+}
+}
+}
-- 
2.45.2



[PATCH 082/125] gccrs: Visit constant item type in default resolver

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

The type of constant item expression was not properly visited in the
default resolver.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Visit
constant item's types.

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

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index d805bc9a511..0c2576f6e75 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -464,7 +464,10 @@ DefaultResolver::visit (AST::EnumItemDiscriminant &item)
 void
 DefaultResolver::visit (AST::ConstantItem &item)
 {
-  auto expr_vis = [this, &item] () { item.get_expr ().accept_vis (*this); };
+  auto expr_vis = [this, &item] () {
+item.get_expr ().accept_vis (*this);
+visit (item.get_type ());
+  };
 
   // FIXME: Why do we need a Rib here?
   ctx.scoped (Rib::Kind::Item, item.get_node_id (), expr_vis);
-- 
2.45.2



[PATCH 083/125] gccrs: Raw pointer type visitor didn't require overload

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

This overload did not dispatch the visitor to sub members of a raw
pointer like the default one. It is therefore useless as pointed type
shall be visited to be resolved correctly.

gcc/rust/ChangeLog:

* resolve/rust-default-resolver.cc (DefaultResolver::visit): Remove
function implementation.
* resolve/rust-default-resolver.h: Remove function prototype.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.cc | 4 
 gcc/rust/resolve/rust-default-resolver.h  | 1 -
 2 files changed, 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 0c2576f6e75..f5546181b3c 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -630,10 +630,6 @@ void
 DefaultResolver::visit (AST::TupleType &)
 {}
 
-void
-DefaultResolver::visit (AST::RawPointerType &)
-{}
-
 void
 DefaultResolver::visit (AST::ReferenceType &)
 {}
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 97ad6d78be3..a19d70bc04d 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -151,7 +151,6 @@ public:
   void visit (AST::ImplTraitTypeOneBound &);
   void visit (AST::TraitObjectTypeOneBound &);
   void visit (AST::TupleType &);
-  void visit (AST::RawPointerType &);
   void visit (AST::ReferenceType &);
   void visit (AST::ArrayType &);
   void visit (AST::SliceType &);
-- 
2.45.2



[PATCH 086/125] gccrs: Add tuple struct to the type namespace

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Only tuple struct constructor was added to the resolver.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc (GlobbingVisitor::visit):
Add tuple struct type to the resolver's context.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc | 9 +++--
 1 file changed, 7 insertions(+), 2 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 75d9bb82131..820ba271ae0 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -81,8 +81,13 @@ void
 GlobbingVisitor::visit (AST::TupleStruct &tuple_struct)
 {
   if (tuple_struct.get_visibility ().is_public ())
-ctx.insert_shadowable (tuple_struct.get_identifier (),
-  tuple_struct.get_node_id (), Namespace::Values);
+{
+  ctx.insert_shadowable (tuple_struct.get_identifier (),
+tuple_struct.get_node_id (), Namespace::Types);
+
+  ctx.insert_shadowable (tuple_struct.get_identifier (),
+tuple_struct.get_node_id (), Namespace::Values);
+}
 }
 
 void
-- 
2.45.2



[PATCH 091/125] gccrs: Remove unsafe block empty visit function

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

We need to visit subcomponents in unsafe elements, this means we can
leverage the default ast visitor's code instead of duplicating it.

gcc/rust/ChangeLog:

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

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/rust/resolve/rust-default-resolver.cc | 4 
 gcc/rust/resolve/rust-default-resolver.h  | 1 -
 2 files changed, 5 deletions(-)

diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 291731be5b3..393994808ee 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -235,10 +235,6 @@ void
 DefaultResolver::visit (AST::ReturnExpr &expr)
 {}
 
-void
-DefaultResolver::visit (AST::UnsafeBlockExpr &expr)
-{}
-
 void
 DefaultResolver::visit (AST::LoopExpr &expr)
 {}
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 0a6427ca6a6..547b5376bfc 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -66,7 +66,6 @@ public:
   void visit (AST::RangeFromToInclExpr &);
   void visit (AST::RangeToInclExpr &);
   void visit (AST::ReturnExpr &);
-  void visit (AST::UnsafeBlockExpr &);
   void visit (AST::LoopExpr &);
   void visit (AST::WhileLoopExpr &);
   void visit (AST::WhileLetLoopExpr &);
-- 
2.45.2



[PATCH 098/125] gccrs: Fix use rebind name resolution.

2024-08-01 Thread Arthur Cohen
From: Pierre-Emmanuel Patry 

Name resolution for rebind were missing.

gcc/rust/ChangeLog:

* resolve/rust-toplevel-name-resolver-2.0.cc 
(TopLevel::handle_use_glob):
Change function prototype to use a reference instead.
(TopLevel::handle_use_dec): Likewise.
(TopLevel::handle_rebind): Add name resolution on rebind use
declarations.
(flatten_rebind): Change prototype to accept a pair of path/alias.
(flatten_list): Adapt call to flatten_rebind.
(flatten): Adapt call to flatten_rebind.
(flatten_glob): Remove unused part.
(TopLevel::visit): Add rebind resolution.
* resolve/rust-toplevel-name-resolver-2.0.h: Adapt function prototypes.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../rust-toplevel-name-resolver-2.0.cc| 194 +-
 .../resolve/rust-toplevel-name-resolver-2.0.h |   5 +-
 2 files changed, 151 insertions(+), 48 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 e6da8db850c..4593c67c5d3 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-toplevel-name-resolver-2.0.h"
+#include "input.h"
 #include "optional.h"
 #include "rust-ast-full.h"
 #include "rust-hir-map.h"
@@ -434,7 +435,7 @@ TopLevel::visit (AST::ConstantItem &const_item)
 }
 
 bool
-TopLevel::handle_use_glob (AST::SimplePath glob)
+TopLevel::handle_use_glob (AST::SimplePath &glob)
 {
   auto resolved = ctx.types.resolve_path (glob.get_segments ());
   if (!resolved.has_value ())
@@ -453,7 +454,7 @@ TopLevel::handle_use_glob (AST::SimplePath glob)
 }
 
 bool
-TopLevel::handle_use_dec (AST::SimplePath path)
+TopLevel::handle_use_dec (AST::SimplePath &path)
 {
   auto locus = path.get_final_segment ().get_locus ();
   auto declared_name = path.get_final_segment ().as_string ();
@@ -508,6 +509,97 @@ TopLevel::handle_use_dec (AST::SimplePath path)
});
   };
 
+  resolve_and_insert (Namespace::Values, path);
+  resolve_and_insert (Namespace::Types, path);
+  resolve_and_insert (Namespace::Macros, path);
+
+  return found;
+}
+
+bool
+TopLevel::handle_rebind (std::pair 
&rebind)
+{
+  auto &path = rebind.first;
+
+  location_t locus = UNKNOWN_LOCATION;
+  std::string declared_name;
+
+  switch (rebind.second.get_new_bind_type ())
+{
+case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+  declared_name = rebind.second.get_identifier ().as_string ();
+  locus = rebind.second.get_identifier ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::NONE:
+  declared_name = path.get_final_segment ().as_string ();
+  locus = path.get_final_segment ().get_locus ();
+  break;
+case AST::UseTreeRebind::NewBindType::WILDCARD:
+  rust_unreachable ();
+  break;
+}
+
+  // in what namespace do we perform path resolution? All
+  // of them? see which one matches? Error out on
+  // ambiguities? so, apparently, for each one that
+  // matches, add it to the proper namespace
+  // :(
+  auto found = false;
+
+  auto resolve_and_insert = [this, &found, &declared_name,
+locus] (Namespace ns,
+const AST::SimplePath &path) {
+tl::optional resolved = tl::nullopt;
+tl::optional resolved_bind = tl::nullopt;
+
+std::vector declaration_v
+  = {AST::SimplePathSegment (declared_name, locus)};
+// FIXME: resolve_path needs to return an `expected` so
+// that we can improve it with hints or location or w/ever. and maybe
+// only emit it the first time.
+switch (ns)
+  {
+  case Namespace::Values:
+   resolved = ctx.values.resolve_path (path.get_segments ());
+   resolved_bind = ctx.values.resolve_path (declaration_v);
+   break;
+  case Namespace::Types:
+   resolved = ctx.types.resolve_path (path.get_segments ());
+   resolved_bind = ctx.types.resolve_path (declaration_v);
+   break;
+  case Namespace::Macros:
+   resolved = ctx.macros.resolve_path (path.get_segments ());
+   resolved_bind = ctx.macros.resolve_path (declaration_v);
+   break;
+  case Namespace::Labels:
+   // TODO: Is that okay?
+   rust_unreachable ();
+  }
+
+resolved.map ([this, &found, &declared_name, locus, ns, path,
+  &resolved_bind] (Rib::Definition def) {
+  found = true;
+
+  insert_or_error_out (declared_name, locus, def.get_node_id (), ns);
+  if (resolved_bind.has_value ())
+   {
+ auto bind_def = resolved_bind.value ();
+ // what do we do with the id?
+ auto result = node_forwarding.find (bind_def.get_node_id ());
+ if (result != node_forwarding.cend ()
+ && result->second != path.get_node_id ())
+   rust_error_at (path.get_locus (), "%qs defined

[PATCH 104/125] gccrs: Recognize rustc_deprecated as a builtin attribute

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* util/rust-attribute-values.h
(Attributes::RUSTC_DEPRECATED): New.
* util/rust-attributes.cc
(__definitions): Add Attributes::RUSTC_DEPRECATED.

gcc/testsuite/ChangeLog:

* rust/compile/deprecated-fn.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/util/rust-attribute-values.h   | 1 +
 gcc/rust/util/rust-attributes.cc| 1 +
 gcc/testsuite/rust/compile/deprecated-fn.rs | 4 
 3 files changed, 6 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/deprecated-fn.rs

diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index e284cec1a16..04aef99be68 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -48,6 +48,7 @@ public:
   static constexpr auto &TARGET_FEATURE = "target_feature";
   // From now on, these are reserved by the compiler and gated through
   // #![feature(rustc_attrs)]
+  static constexpr auto &RUSTC_DEPRECATED = "rustc_deprecated";
   static constexpr auto &RUSTC_INHERIT_OVERFLOW_CHECKS
 = "rustc_inherit_overflow_checks";
   static constexpr auto &STABLE = "stable";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index eac29808299..e10918b2f8d 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -58,6 +58,7 @@ static const BuiltinAttrDefinition __definitions[]
  {Attrs::TARGET_FEATURE, CODE_GENERATION},
  // From now on, these are reserved by the compiler and gated through
  // #![feature(rustc_attrs)]
+ {Attrs::RUSTC_DEPRECATED, STATIC_ANALYSIS},
  {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
  {Attrs::STABLE, STATIC_ANALYSIS}};
 
diff --git a/gcc/testsuite/rust/compile/deprecated-fn.rs 
b/gcc/testsuite/rust/compile/deprecated-fn.rs
new file mode 100644
index 000..4083593b30b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/deprecated-fn.rs
@@ -0,0 +1,4 @@
+#![feature(rustc_attrs)]
+
+#[rustc_deprecated(since = "right now", reason = "a whim")]
+pub fn foo() {}
-- 
2.45.2



[PATCH 106/125] gccrs: Avoid parsing const unsafe/extern functions as async

2024-08-01 Thread Arthur Cohen
From: Owen Avery 

gcc/rust/ChangeLog:

* parse/rust-parse-impl.h
(Parser::parse_vis_item):
Call parse_function instead of parse_async_item when finding
UNSAFE or EXTERN_KW during lookahead.

gcc/testsuite/ChangeLog:

* rust/compile/func-const-unsafe.rs: New test.

Signed-off-by: Owen Avery 
---
 gcc/rust/parse/rust-parse-impl.h| 4 ++--
 gcc/testsuite/rust/compile/func-const-unsafe.rs | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/func-const-unsafe.rs

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index b6c2ca3fc0c..263ca634ea5 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -1382,10 +1382,10 @@ Parser::parse_vis_item 
(AST::AttrVec outer_attrs)
case IDENTIFIER:
case UNDERSCORE:
  return parse_const_item (std::move (vis), std::move (outer_attrs));
-   case UNSAFE:
-   case EXTERN_KW:
case ASYNC:
  return parse_async_item (std::move (vis), std::move (outer_attrs));
+   case UNSAFE:
+   case EXTERN_KW:
case FN_KW:
  return parse_function (std::move (vis), std::move (outer_attrs));
default:
diff --git a/gcc/testsuite/rust/compile/func-const-unsafe.rs 
b/gcc/testsuite/rust/compile/func-const-unsafe.rs
new file mode 100644
index 000..9c932bd1cb5
--- /dev/null
+++ b/gcc/testsuite/rust/compile/func-const-unsafe.rs
@@ -0,0 +1 @@
+pub const unsafe fn foo() {}
-- 
2.45.2



[PATCH 108/125] gccrs: raw-strings: Remove dg-excess-error directive

2024-08-01 Thread Arthur Cohen
The error is actually expected and uses the correct location.

gcc/testsuite/ChangeLog:

* rust/compile/raw-byte-string-loc.rs: Use dg-error instead of
dg-excess-error.
* rust/compile/raw-string-loc.rs: Likewise.
---
 gcc/testsuite/rust/compile/raw-byte-string-loc.rs | 2 +-
 gcc/testsuite/rust/compile/raw-string-loc.rs  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/rust/compile/raw-byte-string-loc.rs 
b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
index f37d3f9694d..b71b6e5aded 100644
--- a/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
+++ b/gcc/testsuite/rust/compile/raw-byte-string-loc.rs
@@ -3,4 +3,4 @@ const X: &'static u8 = br#"12
 
 BREAK
 // { dg-error "unrecognised token" "" { target *-*-* } .-1 }
-// { dg-excess-errors "error 'failed to parse item' does not have location" }
+// { dg-error "failed to parse item" "" { target *-*-* } .-2 }
diff --git a/gcc/testsuite/rust/compile/raw-string-loc.rs 
b/gcc/testsuite/rust/compile/raw-string-loc.rs
index 70977510ba3..26331eafa44 100644
--- a/gcc/testsuite/rust/compile/raw-string-loc.rs
+++ b/gcc/testsuite/rust/compile/raw-string-loc.rs
@@ -3,4 +3,4 @@ const X: &'static str = r#"12
 
 BREAK
 // { dg-error "unrecognised token" "" { target *-*-* } .-1 }
-// { dg-excess-errors "error 'failed to parse item' does not have location" }
+// { dg-error "failed to parse item" "" { target *-*-* } .-2 }
-- 
2.45.2



  1   2   >