public inbox for gcc-rust@gcc.gnu.org
 help / color / mirror / Atom feed
* [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly
@ 2024-02-07 11:43 arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 02/25] gccrs: Implement quick-check for Unicode arthur.cohen
                   ` (23 more replies)
  0 siblings, 24 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

Fixes #2812

gcc/rust/ChangeLog:

	* parse/rust-parse-impl.h (Parser::parse_function):
	Skip token if its a COMMA.

gcc/testsuite/ChangeLog:

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

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/parse/rust-parse-impl.h         | 4 ++--
 gcc/testsuite/rust/compile/issue-2812.rs | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2812.rs

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c622ed7bc97..89e3731a898 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2946,8 +2946,8 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis,
       && initial_param.error () != ParseSelfError::NOT_SELF)
     return nullptr;
 
-  if (initial_param.has_value ())
-    skip_token (COMMA);
+  if (initial_param.has_value () && lexer.peek_token ()->get_id () == COMMA)
+    skip_token ();
 
   // parse function parameters (only if next token isn't right paren)
   std::vector<std::unique_ptr<AST::Param>> function_params;
diff --git a/gcc/testsuite/rust/compile/issue-2812.rs b/gcc/testsuite/rust/compile/issue-2812.rs
new file mode 100644
index 00000000000..173259b1291
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2812.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-frust-compile-until=astvalidation" }
+fn foo_1(&self);
+fn foo_1(&mut self);
+fn foo_1(self);
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 02/25] gccrs: Implement quick-check for Unicode
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 03/25] gccrs: Typecheck: lifetime interning and resolution tool arthur.cohen
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Raiki Tamura

From: Raiki Tamura <tamaron1203@gmail.com>

gcc/rust/ChangeLog:

	* rust-lang.cc (run_rust_tests): Add test.
	* rust-system.h: Add <algorithm>.
	* util/make-rust-unicode.py: Output NFC_Quick_Check table.
	* util/rust-codepoint.h (struct Codepoint): Add is_supplementary
	method.
	* util/rust-unicode-data.h: Generated.
	* util/rust-unicode.cc (binary_search_sorted_array): Removed.
	(lookup_cc): Remove namespace.
	(is_alphabetic): Use std::binary_search
	(nfc_quick_check): New function.
	(nfc_normalize): Use nfc_quick_check.
	(is_nfc_qc_maybe): New function.
	(is_nfc_qc_no): New function.
	(rust_nfc_qc_test): New test.
	* util/rust-unicode.h (is_nfc_qc_no): New function.
	(is_nfc_qc_maybe): New function.
	(enum class): New enum class.
	(nfc_quick_check): New function.
	(rust_nfc_qc_test): New test.

Signed-off-by: Raiki Tamura <tamaron1203@gmail.com>
---
 gcc/rust/rust-lang.cc              |   1 +
 gcc/rust/rust-system.h             |   1 +
 gcc/rust/util/make-rust-unicode.py |  39 +++++--
 gcc/rust/util/rust-codepoint.h     |   1 +
 gcc/rust/util/rust-unicode-data.h  | 158 ++++++++++++++++++++++++++++-
 gcc/rust/util/rust-unicode.cc      | 143 +++++++++++++-------------
 gcc/rust/util/rust-unicode.h       |  19 ++++
 7 files changed, 280 insertions(+), 82 deletions(-)

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index 8b76ba28ea2..4c2ef108bce 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -438,6 +438,7 @@ run_rust_tests ()
 {
   // Call tests for the rust frontend here
   rust_input_source_test ();
+  rust_nfc_qc_test ();
   rust_utf8_normalize_test ();
   rust_punycode_encode_test ();
   rust_cfg_parser_test ();
diff --git a/gcc/rust/rust-system.h b/gcc/rust/rust-system.h
index 88d6c1095e6..d8a42181700 100644
--- a/gcc/rust/rust-system.h
+++ b/gcc/rust/rust-system.h
@@ -44,6 +44,7 @@
 #include <utility>
 #include <fstream>
 #include <array>
+#include <algorithm>
 
 // Rust frontend requires C++11 minimum, so will have unordered_map and set
 #include <unordered_map>
diff --git a/gcc/rust/util/make-rust-unicode.py b/gcc/rust/util/make-rust-unicode.py
index 5303440fd25..f6f04ebdf5b 100644
--- a/gcc/rust/util/make-rust-unicode.py
+++ b/gcc/rust/util/make-rust-unicode.py
@@ -250,6 +250,30 @@ def write_numeric() -> None:
     print("}};")
 
 
+def write_nfc_qc():
+    print(
+        "const std::array<std::pair<uint32_t, uint32_t>, {}> NFC_QC_NO_RANGES = {{{{".format(
+            len(nfc_qc_no_ranges)
+        )
+    )
+    print("  // clang-format off")
+    for r in nfc_qc_no_ranges:
+        print("  {{{:#06x}, {:#06x}}},".format(r[0], r[1]))
+    print("  // clang-format on")
+    print("}};")
+
+    print(
+        "const std::array<std::pair<uint32_t, uint32_t>, {}> NFC_QC_MAYBE_RANGES = {{{{".format(
+            len(nfc_qc_maybe_ranges)
+        )
+    )
+    print("  // clang-format off")
+    for r in nfc_qc_maybe_ranges:
+        print("  {{{:#06x}, {:#06x}}},".format(r[0], r[1]))
+    print("  // clang-format on")
+    print("}};")
+
+
 def main() -> None:
     if len(sys.argv) != 4:
         print("too few arguments", file=sys.stderr)
@@ -265,13 +289,12 @@ def main() -> None:
     print(COPYRIGHT)
     print()
 
-    print('#include "rust-system.h"')
-    print()
-    print("namespace Rust {")
-    print()
+    print('#include "rust-system.h"\n')
+    print("namespace Rust {\n")
     print("const uint32_t NUM_ALPHABETIC_RANGES = {};".format(len(alphabetic_ranges)))
-    print("const uint32_t NUM_NUMERIC_CODEPOINTS = {};".format(len(numeric_codepoints)))
-    print()
+    print(
+        "const uint32_t NUM_NUMERIC_CODEPOINTS = {};\n".format(len(numeric_codepoints))
+    )
 
     write_decomposition()
     print()
@@ -283,8 +306,8 @@ def main() -> None:
     print()
     write_numeric()
     print()
-
-    # TODO: write NFC_QC table
+    write_nfc_qc()
+    print()
 
     print("} // namespace Rust")
 
diff --git a/gcc/rust/util/rust-codepoint.h b/gcc/rust/util/rust-codepoint.h
index a75e99e7c0c..2c5fece9d3e 100644
--- a/gcc/rust/util/rust-codepoint.h
+++ b/gcc/rust/util/rust-codepoint.h
@@ -40,6 +40,7 @@ struct Codepoint
   static Codepoint eof () { return Codepoint (UINT32_MAX); }
   bool is_eof () const { return value == UINT32_MAX; }
   bool is_ascii () const { return value <= MAX_ASCII_CODEPOINT; }
+  bool is_supplementary_character () const { return value > 0xFFFF; }
 
   // Returns a C++ string containing string value of codepoint.
   std::string as_string ();
diff --git a/gcc/rust/util/rust-unicode-data.h b/gcc/rust/util/rust-unicode-data.h
index c42460f4541..e07752a4f63 100644
--- a/gcc/rust/util/rust-unicode-data.h
+++ b/gcc/rust/util/rust-unicode-data.h
@@ -20,7 +20,7 @@
 
 namespace Rust {
 
-const uint32_t NUM_ALPHABETIC_RANGES = 1117;
+const uint32_t NUM_ALPHABETIC_RANGES = 1141;
 const uint32_t NUM_NUMERIC_CODEPOINTS = 1831;
 
 const std::map<uint32_t, std::vector<uint32_t>> DECOMPOSITION_MAP = {
@@ -4167,6 +4167,7 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x0bd7, 0x0bd8},
   {0x0c00, 0x0c01},
   {0x0c01, 0x0c04},
+  {0x0c04, 0x0c05},
   {0x0c05, 0x0c0d},
   {0x0c0e, 0x0c11},
   {0x0c12, 0x0c29},
@@ -4202,6 +4203,7 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x0ce0, 0x0ce2},
   {0x0ce2, 0x0ce4},
   {0x0cf1, 0x0cf3},
+  {0x0cf3, 0x0cf4},
   {0x0d00, 0x0d02},
   {0x0d02, 0x0d04},
   {0x0d04, 0x0d0d},
@@ -4257,7 +4259,7 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x0f49, 0x0f6d},
   {0x0f71, 0x0f7f},
   {0x0f7f, 0x0f80},
-  {0x0f80, 0x0f82},
+  {0x0f80, 0x0f84},
   {0x0f88, 0x0f8d},
   {0x0f8d, 0x0f98},
   {0x0f99, 0x0fbd},
@@ -4758,6 +4760,7 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x11071, 0x11073},
   {0x11073, 0x11075},
   {0x11075, 0x11076},
+  {0x11080, 0x11082},
   {0x11082, 0x11083},
   {0x11083, 0x110b0},
   {0x110b0, 0x110b3},
@@ -4794,6 +4797,8 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x11234, 0x11235},
   {0x11237, 0x11238},
   {0x1123e, 0x1123f},
+  {0x1123f, 0x11241},
+  {0x11241, 0x11242},
   {0x11280, 0x11287},
   {0x11288, 0x11289},
   {0x1128a, 0x1128e},
@@ -4948,12 +4953,22 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x11ee0, 0x11ef3},
   {0x11ef3, 0x11ef5},
   {0x11ef5, 0x11ef7},
+  {0x11f00, 0x11f02},
+  {0x11f02, 0x11f03},
+  {0x11f03, 0x11f04},
+  {0x11f04, 0x11f11},
+  {0x11f12, 0x11f34},
+  {0x11f34, 0x11f36},
+  {0x11f36, 0x11f3b},
+  {0x11f3e, 0x11f40},
+  {0x11f40, 0x11f41},
   {0x11fb0, 0x11fb1},
   {0x12000, 0x1239a},
   {0x12400, 0x1246f},
   {0x12480, 0x12544},
   {0x12f90, 0x12ff1},
-  {0x13000, 0x1342f},
+  {0x13000, 0x13430},
+  {0x13441, 0x13447},
   {0x14400, 0x14647},
   {0x16800, 0x16a39},
   {0x16a40, 0x16a5f},
@@ -4980,7 +4995,9 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x1aff5, 0x1affc},
   {0x1affd, 0x1afff},
   {0x1b000, 0x1b123},
+  {0x1b132, 0x1b133},
   {0x1b150, 0x1b153},
+  {0x1b155, 0x1b156},
   {0x1b164, 0x1b168},
   {0x1b170, 0x1b2fc},
   {0x1bc00, 0x1bc6b},
@@ -5021,16 +5038,21 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x1df00, 0x1df0a},
   {0x1df0a, 0x1df0b},
   {0x1df0b, 0x1df1f},
+  {0x1df25, 0x1df2b},
   {0x1e000, 0x1e007},
   {0x1e008, 0x1e019},
   {0x1e01b, 0x1e022},
   {0x1e023, 0x1e025},
   {0x1e026, 0x1e02b},
+  {0x1e030, 0x1e06e},
+  {0x1e08f, 0x1e090},
   {0x1e100, 0x1e12d},
   {0x1e137, 0x1e13e},
   {0x1e14e, 0x1e14f},
   {0x1e290, 0x1e2ae},
   {0x1e2c0, 0x1e2ec},
+  {0x1e4d0, 0x1e4eb},
+  {0x1e4eb, 0x1e4ec},
   {0x1e7e0, 0x1e7e7},
   {0x1e7e8, 0x1e7ec},
   {0x1e7ed, 0x1e7ef},
@@ -5076,12 +5098,14 @@ const std::array<std::pair<uint32_t, uint32_t>, NUM_ALPHABETIC_RANGES>
   {0x1f150, 0x1f16a},
   {0x1f170, 0x1f18a},
   {0x20000, 0x2a6e0},
-  {0x2a700, 0x2b739},
+  {0x2a700, 0x2b73a},
   {0x2b740, 0x2b81e},
   {0x2b820, 0x2cea2},
   {0x2ceb0, 0x2ebe1},
+  {0x2ebf0, 0x2ee5e},
   {0x2f800, 0x2fa1e},
   {0x30000, 0x3134b},
+  {0x31350, 0x323b0},
     // clang-format on
   }};
 
@@ -5205,4 +5229,130 @@ const std::array<uint32_t, NUM_NUMERIC_CODEPOINTS> NUMERIC_CODEPOINTS = {{
   // clang-format on
 }};
 
+const std::array<std::pair<uint32_t, uint32_t>, 74> NFC_QC_NO_RANGES = {{
+  // clang-format off
+  {0x0340, 0x0342},
+  {0x0343, 0x0345},
+  {0x0374, 0x0375},
+  {0x037e, 0x037f},
+  {0x0387, 0x0388},
+  {0x0958, 0x0960},
+  {0x09dc, 0x09de},
+  {0x09df, 0x09e0},
+  {0x0a33, 0x0a34},
+  {0x0a36, 0x0a37},
+  {0x0a59, 0x0a5c},
+  {0x0a5e, 0x0a5f},
+  {0x0b5c, 0x0b5e},
+  {0x0f43, 0x0f44},
+  {0x0f4d, 0x0f4e},
+  {0x0f52, 0x0f53},
+  {0x0f57, 0x0f58},
+  {0x0f5c, 0x0f5d},
+  {0x0f69, 0x0f6a},
+  {0x0f73, 0x0f74},
+  {0x0f75, 0x0f77},
+  {0x0f78, 0x0f79},
+  {0x0f81, 0x0f82},
+  {0x0f93, 0x0f94},
+  {0x0f9d, 0x0f9e},
+  {0x0fa2, 0x0fa3},
+  {0x0fa7, 0x0fa8},
+  {0x0fac, 0x0fad},
+  {0x0fb9, 0x0fba},
+  {0x1f71, 0x1f72},
+  {0x1f73, 0x1f74},
+  {0x1f75, 0x1f76},
+  {0x1f77, 0x1f78},
+  {0x1f79, 0x1f7a},
+  {0x1f7b, 0x1f7c},
+  {0x1f7d, 0x1f7e},
+  {0x1fbb, 0x1fbc},
+  {0x1fbe, 0x1fbf},
+  {0x1fc9, 0x1fca},
+  {0x1fcb, 0x1fcc},
+  {0x1fd3, 0x1fd4},
+  {0x1fdb, 0x1fdc},
+  {0x1fe3, 0x1fe4},
+  {0x1feb, 0x1fec},
+  {0x1fee, 0x1ff0},
+  {0x1ff9, 0x1ffa},
+  {0x1ffb, 0x1ffc},
+  {0x1ffd, 0x1ffe},
+  {0x2000, 0x2002},
+  {0x2126, 0x2127},
+  {0x212a, 0x212c},
+  {0x2329, 0x232a},
+  {0x232a, 0x232b},
+  {0x2adc, 0x2add},
+  {0xf900, 0xfa0e},
+  {0xfa10, 0xfa11},
+  {0xfa12, 0xfa13},
+  {0xfa15, 0xfa1f},
+  {0xfa20, 0xfa21},
+  {0xfa22, 0xfa23},
+  {0xfa25, 0xfa27},
+  {0xfa2a, 0xfa6e},
+  {0xfa70, 0xfada},
+  {0xfb1d, 0xfb1e},
+  {0xfb1f, 0xfb20},
+  {0xfb2a, 0xfb37},
+  {0xfb38, 0xfb3d},
+  {0xfb3e, 0xfb3f},
+  {0xfb40, 0xfb42},
+  {0xfb43, 0xfb45},
+  {0xfb46, 0xfb4f},
+  {0x1d15e, 0x1d165},
+  {0x1d1bb, 0x1d1c1},
+  {0x2f800, 0x2fa1e},
+  // clang-format on
+}};
+const std::array<std::pair<uint32_t, uint32_t>, 43> NFC_QC_MAYBE_RANGES = {{
+  // clang-format off
+  {0x0300, 0x0305},
+  {0x0306, 0x030d},
+  {0x030f, 0x0310},
+  {0x0311, 0x0312},
+  {0x0313, 0x0315},
+  {0x031b, 0x031c},
+  {0x0323, 0x0329},
+  {0x032d, 0x032f},
+  {0x0330, 0x0332},
+  {0x0338, 0x0339},
+  {0x0342, 0x0343},
+  {0x0345, 0x0346},
+  {0x0653, 0x0656},
+  {0x093c, 0x093d},
+  {0x09be, 0x09bf},
+  {0x09d7, 0x09d8},
+  {0x0b3e, 0x0b3f},
+  {0x0b56, 0x0b57},
+  {0x0b57, 0x0b58},
+  {0x0bbe, 0x0bbf},
+  {0x0bd7, 0x0bd8},
+  {0x0c56, 0x0c57},
+  {0x0cc2, 0x0cc3},
+  {0x0cd5, 0x0cd7},
+  {0x0d3e, 0x0d3f},
+  {0x0d57, 0x0d58},
+  {0x0dca, 0x0dcb},
+  {0x0dcf, 0x0dd0},
+  {0x0ddf, 0x0de0},
+  {0x102e, 0x102f},
+  {0x1161, 0x1176},
+  {0x11a8, 0x11c3},
+  {0x1b35, 0x1b36},
+  {0x3099, 0x309b},
+  {0x110ba, 0x110bb},
+  {0x11127, 0x11128},
+  {0x1133e, 0x1133f},
+  {0x11357, 0x11358},
+  {0x114b0, 0x114b1},
+  {0x114ba, 0x114bb},
+  {0x114bd, 0x114be},
+  {0x115af, 0x115b0},
+  {0x11930, 0x11931},
+  // clang-format on
+}};
+
 } // namespace Rust
diff --git a/gcc/rust/util/rust-unicode.cc b/gcc/rust/util/rust-unicode.cc
index 999ecb042ca..6bd2db550a1 100644
--- a/gcc/rust/util/rust-unicode.cc
+++ b/gcc/rust/util/rust-unicode.cc
@@ -39,75 +39,27 @@ const uint32_t L_COUNT = 19, V_COUNT = 21, T_COUNT = 28;
 const uint32_t N_COUNT = V_COUNT * T_COUNT;
 const uint32_t S_COUNT = L_COUNT * N_COUNT;
 
+// Check if the codepoint is in any of the ranges (half-open intervals [a,b)).
 template <std::size_t SIZE>
-int64_t
+bool
 binary_search_ranges (
-  // FIXME: use binray search function from <algorithm>
   const std::array<std::pair<uint32_t, uint32_t>, SIZE> &ranges,
   uint32_t target_cp)
 {
-  if (SIZE == 0)
-    return -1;
-
-  uint32_t low, high, mid;
-  uint32_t start, end;
-  low = 0;
-  high = SIZE - 1;
-  mid = (low + high) / 2;
-  while (high - low > 1)
-    {
-      start = ranges[mid].first;
-      end = ranges[mid].second;
-      if (start <= target_cp && target_cp < end)
-	{
-	  return mid;
-	}
-      else if (end <= target_cp)
-	low = mid + 1;
-      else
-	high = mid - 1;
-      mid = (low + high) / 2;
-    }
-
-  if (ranges[mid].first <= target_cp && target_cp < ranges[mid].second)
-    return mid;
-  else
-    return -1;
-}
-
-template <std::size_t SIZE>
-int64_t
-binary_search_sorted_array (const std::array<uint32_t, SIZE> &array,
-			    uint32_t target)
-{
-  // FIXME: use binray search function from <algorithm>
-  if (SIZE == 0)
-    return -1;
-
-  uint32_t low, high, mid;
-  low = 0;
-  high = SIZE;
-  mid = (low + high) / 2;
-  while (high - low > 1)
-    {
-      if (array[mid] <= target)
-	low = mid;
-      else
-	high = mid;
-      mid = (low + high) / 2;
-    }
-
-  if (array[mid] == target)
-    return mid;
+  auto it = std::lower_bound (ranges.begin (), ranges.end (), target_cp,
+			      [] (const std::pair<uint32_t, uint32_t> &a,
+				  uint32_t b) { return a.second <= b; });
+  if (it == ranges.end ())
+    return false;
   else
-    return -1;
+    return it->first <= target_cp && target_cp < it->second;
 }
 
 int
 lookup_cc (codepoint_t c)
 {
-  auto it = Rust::CCC_TABLE.find (c.value);
-  if (it != Rust::CCC_TABLE.end ())
+  auto it = CCC_TABLE.find (c.value);
+  if (it != CCC_TABLE.end ())
     return it->second;
   else
     // Starter. Returns zero.
@@ -289,10 +241,44 @@ recomp (string_t s)
   return buf;
 }
 
+// see https://unicode.org/reports/tr15/#Detecting_Normalization_Forms
+QuickCheckResult
+nfc_quick_check (const string_t &s)
+{
+  int last_canonical_class = 0;
+  QuickCheckResult res = QuickCheckResult::YES;
+
+  for (unsigned long i = 0; i < s.size (); i++)
+    {
+      codepoint_t c = s[i];
+
+      if (c.is_supplementary_character ())
+	i++;
+
+      int canonical_class = lookup_cc (c);
+      if (last_canonical_class > canonical_class && canonical_class != 0)
+	return QuickCheckResult::NO;
+
+      if (is_nfc_qc_no (c.value))
+	return QuickCheckResult::NO;
+
+      if (is_nfc_qc_maybe (c.value))
+	res = QuickCheckResult::MAYBE;
+
+      last_canonical_class = canonical_class;
+    }
+  return res;
+}
+
 string_t
-nfc_normalize (string_t s)
+nfc_normalize (const string_t &s)
 {
-  // TODO: Quick Check
+  if (nfc_quick_check (s) == QuickCheckResult::YES)
+    return s;
+
+  // TODO: optimize normalization.
+  // i.e. only normalize a limited area around MAYBE character, instead of
+  // performing complete normlization of the entire string
 
   // decompose
   string_t d = decomp_cano (s);
@@ -312,21 +298,26 @@ Utf8String::nfc_normalize () const
 bool
 is_alphabetic (uint32_t codepoint)
 {
-  int64_t res = binary_search_ranges (ALPHABETIC_RANGES, codepoint);
-  if (res < 0)
-    return false;
-  else
-    return true;
+  return binary_search_ranges (ALPHABETIC_RANGES, codepoint);
 }
 
 bool
 is_numeric (uint32_t codepoint)
 {
-  int64_t res = binary_search_sorted_array (NUMERIC_CODEPOINTS, codepoint);
-  if (res < 0)
-    return false;
-  else
-    return true;
+  return std::binary_search (NUMERIC_CODEPOINTS.begin (),
+			     NUMERIC_CODEPOINTS.end (), codepoint);
+}
+
+bool
+is_nfc_qc_maybe (uint32_t codepoint)
+{
+  return binary_search_ranges (NFC_QC_MAYBE_RANGES, codepoint);
+}
+
+bool
+is_nfc_qc_no (uint32_t codepoint)
+{
+  return binary_search_ranges (NFC_QC_NO_RANGES, codepoint);
 }
 
 bool
@@ -344,6 +335,18 @@ is_ascii_only (const std::string &str)
 
 namespace selftest {
 
+void
+rust_nfc_qc_test ()
+{
+  ASSERT_EQ (Rust::nfc_quick_check ({0x1e0a /* NFC_QC_YES */}),
+	     Rust::QuickCheckResult::YES);
+  ASSERT_EQ (Rust::nfc_quick_check (
+	       {0x1e0a /* NFC_QC_YES */, 0x0323 /* NFC_QC_MAYBE */}),
+	     Rust::QuickCheckResult::MAYBE);
+  ASSERT_EQ (Rust::nfc_quick_check ({0x0340 /* NFC_QC_NO */}),
+	     Rust::QuickCheckResult::NO);
+}
+
 void
 assert_normalize (const std::vector<Rust::Codepoint> origin,
 		  const std::vector<Rust::Codepoint> expected)
diff --git a/gcc/rust/util/rust-unicode.h b/gcc/rust/util/rust-unicode.h
index 2538436797f..aa7bd8a5632 100644
--- a/gcc/rust/util/rust-unicode.h
+++ b/gcc/rust/util/rust-unicode.h
@@ -68,12 +68,31 @@ is_ascii_only (const std::string &str);
 bool
 is_numeric (uint32_t codepoint);
 
+bool
+is_nfc_qc_no (uint32_t codepoint);
+
+bool
+is_nfc_qc_maybe (uint32_t codepoint);
+
+enum class QuickCheckResult
+{
+  YES,
+  NO,
+  MAYBE
+};
+
+QuickCheckResult
+nfc_quick_check (const std::vector<Codepoint> &s);
+
 } // namespace Rust
 
 #if CHECKING_P
 
 namespace selftest {
 
+void
+rust_nfc_qc_test ();
+
 void
 rust_utf8_normalize_test ();
 
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 03/25] gccrs: Typecheck: lifetime interning and resolution tool
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 02/25] gccrs: Implement quick-check for Unicode arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 04/25] gccrs: TyTy: Region (lifetime) representation arthur.cohen
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check.h (class Lifetime): add interned lifetime class
	* typecheck/rust-typecheck-context.cc (TypeCheckContext::TypeCheckContext): add
	resolution tool
	(TypeCheckContext::intern_lifetime): add method to intern lifetime from tyctx
	(TypeCheckContext::lookup_lifetime): add method to lookup lifetime from tyctx
	(TypeCheckContext::intern_and_insert_lifetime): add a helper method

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/typecheck/rust-hir-type-check.h     | 225 +++++++++++++++++++
 gcc/rust/typecheck/rust-typecheck-context.cc |  55 ++++-
 2 files changed, 279 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 7dd4dda5b93..0d74ae11a2c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -24,6 +24,8 @@
 #include "rust-hir-trait-reference.h"
 #include "rust-autoderef.h"
 
+#include <stack>
+
 namespace Rust {
 namespace Resolver {
 
@@ -79,6 +81,49 @@ private:
   Item item;
 };
 
+/**
+ * Interned lifetime representation in TyTy
+ *
+ * On the HIR->TyTy boundary HIR::Lifetime is interned into this struct.
+ */
+class Lifetime
+{
+  uint32_t interner_index;
+
+public:
+  explicit constexpr Lifetime (uint32_t interner_index)
+    : interner_index (interner_index)
+  {}
+
+  Lifetime () = default;
+
+  WARN_UNUSED_RESULT bool is_static () const { return interner_index == 0; }
+
+  WARN_UNUSED_RESULT static constexpr Lifetime static_lifetime ()
+  {
+    return Lifetime (0);
+  }
+
+  WARN_UNUSED_RESULT static constexpr Lifetime anonymous_lifetime ()
+  {
+    return Lifetime (1);
+  }
+
+  static constexpr uint32_t FIRST_NAMED_LIFETIME = 2;
+
+  friend bool operator== (const Lifetime &lhs, const Lifetime &rhs)
+  {
+    return lhs.interner_index == rhs.interner_index;
+  }
+
+  friend bool operator!= (const Lifetime &lhs, const Lifetime &rhs)
+  {
+    return !(lhs == rhs);
+  }
+
+  WARN_UNUSED_RESULT Lifetime next () { return Lifetime (interner_index++); }
+};
+
 class TypeCheckContext
 {
 public:
@@ -173,6 +218,12 @@ public:
   void trait_query_completed (DefId id);
   bool trait_query_in_progress (DefId id) const;
 
+  Lifetime intern_lifetime (const HIR::Lifetime &name);
+  WARN_UNUSED_RESULT tl::optional<Lifetime>
+  lookup_lifetime (const HIR::Lifetime &lifetime) const;
+
+  void intern_and_insert_lifetime (const HIR::Lifetime &lifetime);
+
 private:
   TypeCheckContext ();
 
@@ -211,6 +262,180 @@ private:
   // query context lookups
   std::set<HirId> querys_in_progress;
   std::set<DefId> trait_queries_in_progress;
+
+  /** Used to resolve (interned) lifetime names to their bounding scope. */
+  class LifetimeResolver
+  {
+    /**
+     * The level of nested scopes, where the lifetime was declared.
+     *
+     * Index 0 is used for `impl` blocks and is skipped if not explicitly
+     * requested.
+     * Index 1 for the top-level of declarations of items.
+     * Index >1 is used for late-bound lifetimes.
+     */
+    using ScopeIndex = size_t;
+
+    static constexpr ScopeIndex IMPL_SCOPE = 0;
+    static constexpr ScopeIndex ITEM_SCOPE = 1;
+
+    /**
+     * A reference to a lifetime binder.
+     *
+     * This is used to resolve lifetimes to their scope.
+     */
+    struct LifetimeBinderRef
+    {
+      uint32_t scope; //> Depth of the scope where the lifetime was declared.
+      uint32_t index; //> Index of the lifetime in the scope.
+    };
+
+    /**
+     * A stack of the number of lifetimes declared in each scope.
+     *
+     * Used to pop the correct number of lifetimes when leaving a scope.
+     */
+    std::stack<uint32_t> binder_size_stack;
+
+    /**
+     * Merged stack of all lifetimes declared in all scopes.
+     *
+     * Use `binder_size_stack` to determine the number of lifetimes in each
+     * scope.
+     */
+    std::vector<std::pair<Lifetime, LifetimeBinderRef>> lifetime_lookup;
+
+    /**
+     * Whether the current scope is a function body.
+     *
+     * In function header, lifetimes are resolved as early-bound, in the body as
+     * named. This is because the header can be also used in call position.
+     */
+    bool is_body = false;
+
+    /** Return the number of the current scope. */
+    WARN_UNUSED_RESULT uint32_t get_current_scope () const
+    {
+      return binder_size_stack.size () - 1;
+    }
+
+  public:
+    /** Add new declaration of a lifetime. */
+    void insert_mapping (Lifetime placeholder)
+    {
+      lifetime_lookup.push_back (
+	{placeholder, {get_current_scope (), binder_size_stack.top ()++}});
+    }
+
+    /** Only to be used by the guard. */
+    void push_binder () { binder_size_stack.push (0); }
+    /** Only to be used by the guard. */
+    void pop_binder () { binder_size_stack.pop (); }
+
+    /**
+     * Switch from resolving a function header to a function body.
+     */
+    void switch_to_fn_body () { this->is_body = true; }
+
+    size_t get_num_bound_regions () const { return binder_size_stack.top (); }
+  };
+
+  // lifetime resolving
+  std::unordered_map<std::string, Lifetime> lifetime_name_interner;
+  Lifetime next_lifetime_index = Lifetime (Lifetime::FIRST_NAMED_LIFETIME);
+
+  /**
+   * Stack of lifetime resolvers.
+   *
+   * Due to the contruction of the type checker, it is possible to start
+   * resolution of a new type in the middle of resolving another type. This
+   * stack isolates the conexts in such cases.
+   */
+  std::stack<LifetimeResolver> lifetime_resolver_stack;
+
+public:
+  WARN_UNUSED_RESULT LifetimeResolver &get_lifetime_resolver ()
+  {
+    rust_assert (!lifetime_resolver_stack.empty ());
+    return lifetime_resolver_stack.top ();
+  }
+
+  WARN_UNUSED_RESULT const LifetimeResolver &get_lifetime_resolver () const
+  {
+    rust_assert (!lifetime_resolver_stack.empty ());
+    return lifetime_resolver_stack.top ();
+  }
+
+  /**
+   * A guard that pushes a new lifetime resolver on the stack and pops it
+   * when it goes out of scope.
+   */
+  class LifetimeResolverGuard
+  {
+  public:
+    /** The kind of scope that is being pushed. */
+    enum ScopeKind
+    {
+      IMPL_BLOCK_RESOLVER, //> A new `impl` block scope.
+      RESOLVER,		   //> A new scope for a function body.
+      BINDER,		   //> A new scope for late-bound lifetimes.
+    };
+
+  private:
+    TypeCheckContext &ctx;
+    ScopeKind kind;
+
+  public:
+    LifetimeResolverGuard (TypeCheckContext &ctx, ScopeKind kind)
+      : ctx (ctx), kind (kind)
+    {
+      if (kind == IMPL_BLOCK_RESOLVER)
+	{
+	  ctx.lifetime_resolver_stack.push (LifetimeResolver ());
+	}
+
+      if (kind == RESOLVER)
+	{
+	  ctx.lifetime_resolver_stack.push (LifetimeResolver ());
+	  // Skip the `impl` block scope.
+	  ctx.lifetime_resolver_stack.top ().push_binder ();
+	}
+      rust_assert (!ctx.lifetime_resolver_stack.empty ());
+      ctx.lifetime_resolver_stack.top ().push_binder ();
+    }
+
+    ~LifetimeResolverGuard ()
+    {
+      rust_assert (!ctx.lifetime_resolver_stack.empty ());
+      ctx.lifetime_resolver_stack.top ().pop_binder ();
+      if (kind == RESOLVER)
+	{
+	  ctx.lifetime_resolver_stack.pop ();
+	}
+    }
+  };
+
+  /** Start new late bound lifetime scope. */
+  WARN_UNUSED_RESULT LifetimeResolverGuard push_lifetime_binder ()
+  {
+    return LifetimeResolverGuard (*this, LifetimeResolverGuard::BINDER);
+  }
+
+  /** Start new function body scope. */
+  WARN_UNUSED_RESULT LifetimeResolverGuard
+  push_clean_lifetime_resolver (bool is_impl_block = false)
+  {
+    return LifetimeResolverGuard (*this,
+				  is_impl_block
+				    ? LifetimeResolverGuard::IMPL_BLOCK_RESOLVER
+				    : LifetimeResolverGuard::RESOLVER);
+  }
+
+  /** Switch from resolving a function header to a function body. */
+  void switch_to_fn_body ()
+  {
+    this->lifetime_resolver_stack.top ().switch_to_fn_body ();
+  }
 };
 
 class TypeResolution
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 46954683875..c6840c8b1a9 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -31,7 +31,7 @@ TypeCheckContext::get ()
   return instance;
 }
 
-TypeCheckContext::TypeCheckContext () {}
+TypeCheckContext::TypeCheckContext () { lifetime_resolver_stack.emplace (); }
 
 TypeCheckContext::~TypeCheckContext () {}
 
@@ -496,6 +496,59 @@ TypeCheckContext::trait_query_in_progress (DefId id) const
 	 != trait_queries_in_progress.end ();
 }
 
+Lifetime
+TypeCheckContext::intern_lifetime (const HIR::Lifetime &lifetime)
+{
+  if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
+    {
+      auto maybe_interned = lookup_lifetime (lifetime);
+      if (maybe_interned)
+	return *maybe_interned;
+
+      auto interned = next_lifetime_index.next ();
+      lifetime_name_interner[lifetime.get_name ()] = interned;
+      return interned;
+    }
+  if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
+    {
+      return next_lifetime_index.next ();
+    }
+  if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
+    {
+      return Lifetime::static_lifetime ();
+    }
+  rust_unreachable ();
+}
+
+tl::optional<Lifetime>
+TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
+{
+  if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED)
+    {
+      rust_assert (lifetime.get_name () != "static");
+      const auto name = lifetime.get_name ();
+      auto it = lifetime_name_interner.find (name);
+      if (it == lifetime_name_interner.end ())
+	return tl::nullopt;
+      return it->second;
+    }
+  if (lifetime.get_lifetime_type () == AST::Lifetime::WILDCARD)
+    {
+      return Lifetime::anonymous_lifetime ();
+    }
+  if (lifetime.get_lifetime_type () == AST::Lifetime::STATIC)
+    {
+      return Lifetime::static_lifetime ();
+    }
+  rust_unreachable ();
+}
+
+void
+TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
+{
+  get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
+}
+
 // TypeCheckContextItem
 
 TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 04/25] gccrs: TyTy: Region (lifetime) representation
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 02/25] gccrs: Implement quick-check for Unicode arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 03/25] gccrs: Typecheck: lifetime interning and resolution tool arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 05/25] gccrs: HIR: Add mising getter arthur.cohen
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-tyty-region.h: New file.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/typecheck/rust-tyty-region.h | 110 ++++++++++++++++++++++++++
 1 file changed, 110 insertions(+)
 create mode 100644 gcc/rust/typecheck/rust-tyty-region.h

diff --git a/gcc/rust/typecheck/rust-tyty-region.h b/gcc/rust/typecheck/rust-tyty-region.h
new file mode 100644
index 00000000000..b34a2115e7a
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-region.h
@@ -0,0 +1,110 @@
+#ifndef RUST_TYTY_REGION_H
+#define RUST_TYTY_REGION_H
+
+namespace Rust {
+namespace TyTy {
+
+class Region
+{
+  enum Variant : uint8_t
+  {
+    UNRESOLVED,
+    STATIC,
+    EARLY_BOUND,
+    LATE_BOUND,
+    NAMED,
+    ANONYMOUS,
+    ERASED,
+  };
+
+  uint32_t index;
+  uint16_t debruijn_index;
+  Variant variant;
+
+public:
+  Region () : Region (UNRESOLVED) {}
+  Region (const Region &other)
+    : index (other.index), debruijn_index (other.debruijn_index),
+      variant (other.variant)
+  {}
+  Region (Region &&other) noexcept
+    : index (other.index), debruijn_index (other.debruijn_index),
+      variant (other.variant)
+  {}
+  Region &operator= (const Region &other)
+  {
+    if (this == &other)
+      return *this;
+    index = other.index;
+    debruijn_index = other.debruijn_index;
+    variant = other.variant;
+    return *this;
+  }
+  Region &operator= (Region &&other) noexcept
+  {
+    if (this == &other)
+      return *this;
+    index = other.index;
+    debruijn_index = other.debruijn_index;
+    variant = other.variant;
+    return *this;
+  }
+
+  static Region make_static () { return Region (STATIC); }
+  static Region make_early_bound (uint32_t index)
+  {
+    return Region (EARLY_BOUND, index);
+  }
+  static Region make_late_bound (uint32_t index, uint16_t debruijn_index)
+  {
+    return Region (LATE_BOUND, index, debruijn_index);
+  }
+  static Region make_named (uint32_t index) { return Region (NAMED, index); }
+  static Region make_anonymous () { return Region (ANONYMOUS); }
+  static Region make_erased () { return Region (ERASED); }
+
+  size_t get_index () const { return index; }
+
+  bool is_static () const { return variant == STATIC; }
+  bool is_early_bound () const { return variant == EARLY_BOUND; }
+  bool is_late_bound () const { return variant == LATE_BOUND; }
+  bool is_named () const { return variant == NAMED; }
+  bool is_anonymous () const { return variant == ANONYMOUS; }
+
+  void shift_down () { debruijn_index++; }
+
+  WARN_UNUSED_RESULT std::string as_string () const
+  {
+    switch (variant)
+      {
+      case UNRESOLVED:
+	return "'unresolved";
+      case STATIC:
+	return "'static";
+      case EARLY_BOUND:
+	return "'early(" + std::to_string (index) + ")";
+      case LATE_BOUND:
+	return "'late(" + std::to_string (debruijn_index) + ", "
+	       + std::to_string (index) + ")";
+      case NAMED:
+	return "'named(" + std::to_string (index) + "";
+      case ANONYMOUS:
+	return "'_";
+      case ERASED:
+	return "'erased";
+      }
+
+    rust_unreachable ();
+  }
+
+private:
+  explicit Region (Variant variant, uint32_t index = 0,
+		   uint16_t debruijn_index = 0)
+    : index (index), debruijn_index (debruijn_index), variant (variant)
+  {}
+};
+
+} // namespace TyTy
+} // namespace Rust
+
+#endif // RUST_TYTY_REGION_H
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 05/25] gccrs: HIR: Add mising getter
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (2 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 04/25] gccrs: TyTy: Region (lifetime) representation arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 06/25] gccrs: Typecheck: add regions (lifetimes) to TyTy arthur.cohen
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* hir/tree/rust-hir-item.h: Add missing getter

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/hir/tree/rust-hir-item.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 74450786e89..1d067fca5be 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -3062,6 +3062,11 @@ public:
   // Returns whether item has a where clause.
   bool has_where_clause () const { return !where_clause.is_empty (); }
 
+  WARN_UNUSED_RESULT const WhereClause &get_where_clause () const
+  {
+    return where_clause;
+  }
+
   ExternalFunctionItem (
     Analysis::NodeMapping mappings, Identifier item_name,
     std::vector<std::unique_ptr<GenericParam>> generic_params,
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 06/25] gccrs: Typecheck: add regions (lifetimes) to TyTy
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (3 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 05/25] gccrs: HIR: Add mising getter arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 07/25] gccrs: TyTy: Store region constraints arthur.cohen
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-trait-resolve.cc: add regions
	* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::resolve_literal):
	add regions, resolve generic lifetimes
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): add regions
	* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
	add regions, resolve lifetimes
	(TypeCheckImplItem::visit): add regions, resove lifetimes
	* typecheck/rust-hir-type-check-implitem.h: add default value for result
	* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::visit): add regions,
	resove lifetimes
	(TypeCheckItem::resolve_impl_block_substitutions): add regions, resove lifetimes
	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): add regions,
	resove lifetimes
	(TypeCheckExpr::resolve_root_path): add regions, resove lifetimes
	(TypeCheckExpr::resolve_segments): add regions, resove lifetimes
	* typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): add regions,
	resove lifetimes
	(TypeCheckType::resolve_root_path): add regions, resove lifetimes
	(ResolveWhereClauseItem::Resolve): add regions, resove lifetimes
	(ResolveWhereClauseItem::visit): add regions, resove lifetimes
	* typecheck/rust-hir-type-check.cc (TypeCheckContext::LifetimeResolver::resolve):
	add regions, resolve lifetimes
	(TraitItemReference::get_type_from_fn): add regions, resove lifetimes
	* typecheck/rust-hir-type-check.h: add regions, resove lifetimes
	* typecheck/rust-substitution-mapper.cc (SubstMapper::SubstMapper): add regions,
	resove lifetimes
	(SubstMapper::Resolve): add regions, resove lifetimes
	(SubstMapper::InferSubst): add regions, resove lifetimes
	(SubstMapper::visit): add regions, resove lifetimes
	* typecheck/rust-substitution-mapper.h: add regions, resove lifetimes
	* typecheck/rust-typecheck-context.cc (TypeCheckContext::TypeCheckContext):
	lifetime resolution
	(TypeCheckContext::regions_from_generic_args): lifetime resolution helper
	* typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::TypeBoundPredicate):
	add regions, resove lifetimes
	(TypeBoundPredicate::operator=): add regions, resove lifetimes
	(TypeBoundPredicate::apply_generic_arguments): add regions, resove lifetimes
	(TypeBoundPredicateItem::get_tyty_for_receiver): add regions, resove lifetimes
	* typecheck/rust-tyty-subst.cc (SubstitutionArgumentMappings::get_regions):
	add regions, resove lifetimes
	(SubstitutionArgumentMappings::get_mut_regions): getter
	(SubstitutionArgumentMappings::error): split error and empty
	(SubstitutionArgumentMappings::empty): split error and empty
	(SubstitutionArgumentMappings::find_symbol): helper
	(SubstitutionRef::get_num_lifetime_params): getter
	(SubstitutionRef::get_num_type_params): getter
	(SubstitutionRef::needs_substitution): extend to regions
	(SubstitutionRef::get_mappings_from_generic_args): helper
	(SubstitutionRef::infer_substitions): add regions
	* typecheck/rust-tyty-subst.h (class RegionParamList): region param handler
	* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): add regions, resove lifetimes
	(InferType::default_type): add regions, resove lifetimes
	(FnType::clone): add regions, resove lifetimes
	(ReferenceType::ReferenceType): add regions
	(ReferenceType::get_region): getter
	(ReferenceType::clone): add regions
	* typecheck/rust-tyty.h: add regions, resove

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  |  11 +-
 .../typecheck/rust-hir-type-check-base.cc     |  23 ++--
 .../typecheck/rust-hir-type-check-expr.cc     |  24 ++--
 .../typecheck/rust-hir-type-check-implitem.cc |  78 +++++++++----
 .../typecheck/rust-hir-type-check-implitem.h  |   2 +-
 .../typecheck/rust-hir-type-check-item.cc     | 101 ++++++++++-------
 .../typecheck/rust-hir-type-check-path.cc     |  16 ++-
 .../typecheck/rust-hir-type-check-type.cc     | 106 ++++++++++++++++--
 gcc/rust/typecheck/rust-hir-type-check.cc     |  90 ++++++++++++---
 gcc/rust/typecheck/rust-hir-type-check.h      |  10 ++
 .../typecheck/rust-substitution-mapper.cc     |  19 ++--
 gcc/rust/typecheck/rust-substitution-mapper.h |   8 +-
 gcc/rust/typecheck/rust-typecheck-context.cc  |  27 +++++
 gcc/rust/typecheck/rust-tyty-bounds.cc        |   8 +-
 gcc/rust/typecheck/rust-tyty-subst.cc         |  95 +++++++++++-----
 gcc/rust/typecheck/rust-tyty-subst.h          |  94 +++++++++++++++-
 gcc/rust/typecheck/rust-tyty.cc               |  29 +++--
 gcc/rust/typecheck/rust-tyty.h                |  21 +++-
 18 files changed, 585 insertions(+), 177 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 1d6a9fbdd37..a300cecae31 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -520,9 +520,10 @@ AssociatedImplTrait::setup_associated_types (
 	}
     }
 
-  TyTy::SubstitutionArgumentMappings infer_arguments (std::move (subst_args),
-						      {}, locus,
-						      param_subst_cb);
+  TyTy::SubstitutionArgumentMappings infer_arguments (
+    std::move (subst_args), {},
+    TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (args),
+    locus, param_subst_cb);
   TyTy::BaseType *impl_self_infer
     = (!associated_self->is_concrete ())
 	? SubstMapperInternal::Resolve (associated_self, infer_arguments)
@@ -613,7 +614,9 @@ AssociatedImplTrait::setup_associated_types (
     }
 
   TyTy::SubstitutionArgumentMappings associated_type_args (
-    std::move (associated_arguments), {}, locus);
+    std::move (associated_arguments), {},
+    TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (args),
+    locus);
 
   auto &impl_items = impl->get_impl_items ();
   for (auto &impl_item : impl_items)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 871b8920572..b9b4f91ac9f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -225,7 +225,8 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
 
 	infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
 					   TyTy::TyVar (base->get_ref ()),
-					   Mutability::Imm);
+					   Mutability::Imm,
+					   TyTy::Region::make_static ());
       }
       break;
 
@@ -271,7 +272,8 @@ TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
 
 	infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
 					   TyTy::TyVar (array->get_ref ()),
-					   Mutability::Imm);
+					   Mutability::Imm,
+					   TyTy::Region::make_static ());
       }
       break;
 
@@ -352,16 +354,23 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
 
 void
 TypeCheckBase::resolve_generic_params (
-  const std::vector<std::unique_ptr<HIR::GenericParam> > &generic_params,
+  const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
   std::vector<TyTy::SubstitutionParamMapping> &substitutions)
 {
   for (auto &generic_param : generic_params)
     {
-      switch (generic_param.get ()->get_kind ())
+      switch (generic_param->get_kind ())
 	{
-	case HIR::GenericParam::GenericKind::LIFETIME:
-	  // FIXME: Skipping Lifetime completely until better
-	  // handling.
+	  case HIR::GenericParam::GenericKind::LIFETIME: {
+	    auto lifetime_param
+	      = static_cast<HIR::LifetimeParam &> (*generic_param);
+	    auto lifetime = lifetime_param.get_lifetime ();
+	    rust_assert (lifetime.get_lifetime_type ()
+			 == AST::Lifetime::LifetimeType::NAMED);
+	    context->get_lifetime_resolver ().insert_mapping (
+	      context->intern_lifetime (lifetime));
+	  }
+
 	  break;
 
 	  case HIR::GenericParam::GenericKind::CONST: {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 43d183f7a59..9f5042a4ece 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -674,8 +674,9 @@ TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
   const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
   subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
 
-  TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
-					    expr.get_locus ());
+  TyTy::SubstitutionArgumentMappings subst (
+    subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+    expr.get_locus ());
   infered = SubstMapperInternal::Resolve (adt, subst);
 }
 
@@ -721,8 +722,9 @@ TypeCheckExpr::visit (HIR::RangeFromExpr &expr)
   const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
   subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
 
-  TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
-					    expr.get_locus ());
+  TyTy::SubstitutionArgumentMappings subst (
+    subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+    expr.get_locus ());
   infered = SubstMapperInternal::Resolve (adt, subst);
 }
 
@@ -767,8 +769,9 @@ TypeCheckExpr::visit (HIR::RangeToExpr &expr)
   const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
   subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, from_ty));
 
-  TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
-					    expr.get_locus ());
+  TyTy::SubstitutionArgumentMappings subst (
+    subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+    expr.get_locus ());
   infered = SubstMapperInternal::Resolve (adt, subst);
 }
 
@@ -851,8 +854,9 @@ TypeCheckExpr::visit (HIR::RangeFromToInclExpr &expr)
   const TyTy::SubstitutionParamMapping *param_ref = &adt->get_substs ().at (0);
   subst_mappings.push_back (TyTy::SubstitutionArg (param_ref, unified));
 
-  TyTy::SubstitutionArgumentMappings subst (subst_mappings, {},
-					    expr.get_locus ());
+  TyTy::SubstitutionArgumentMappings subst (
+    subst_mappings, {}, adt->get_substitution_arguments ().get_regions (),
+    expr.get_locus ());
   infered = SubstMapperInternal::Resolve (adt, subst);
 }
 
@@ -1193,7 +1197,9 @@ TypeCheckExpr::visit (HIR::MethodCallExpr &expr)
 
   if (resolved_candidate.is_impl_candidate ())
     {
-      auto infer_arguments = TyTy::SubstitutionArgumentMappings::error ();
+      auto infer_arguments = TyTy::SubstitutionArgumentMappings::empty ();
+      infer_arguments.get_mut_regions ()
+	= fn->get_used_arguments ().get_regions ();
       HIR::ImplBlock &impl = *resolved_candidate.item.impl.parent;
       TyTy::BaseType *impl_self_infer
 	= TypeCheckItem::ResolveImplBlockSelfWithInference (impl,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 5fb6fa3190e..0ca59dea899 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -62,6 +62,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalStaticItem &item)
 void
 TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 {
+  auto binder_pin = context->push_clean_lifetime_resolver ();
+
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
     {
@@ -70,6 +72,11 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 	  switch (generic_param.get ()->get_kind ())
 	    {
 	    case HIR::GenericParam::GenericKind::LIFETIME:
+	      context->intern_and_insert_lifetime (
+		static_cast<HIR::LifetimeParam &> (*generic_param)
+		  .get_lifetime ());
+	      // TODO: handle bounds
+	      break;
 	    case HIR::GenericParam::GenericKind::CONST:
 	      // FIXME: Skipping Lifetime and Const completely until better
 	      // handling.
@@ -153,11 +160,13 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 			    function.get_item_name ().as_string ()),
     function.get_locus ()};
 
-  auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
-				  function.get_mappings ().get_defid (),
-				  function.get_item_name ().as_string (), ident,
-				  flags, parent.get_abi (), std::move (params),
-				  ret_type, std::move (substitutions));
+  auto fnType = new TyTy::FnType (
+    function.get_mappings ().get_hirid (),
+    function.get_mappings ().get_defid (),
+    function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
+    std::move (params), ret_type, std::move (substitutions),
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
 
   context->insert_type (function.get_mappings (), fnType);
   resolved = fnType;
@@ -192,6 +201,8 @@ TypeCheckImplItem::Resolve (
 void
 TypeCheckImplItem::visit (HIR::Function &function)
 {
+  auto binder_pin = context->push_lifetime_binder ();
+
   if (function.has_generics ())
     resolve_generic_params (function.get_generic_params (), substitutions);
 
@@ -254,16 +265,36 @@ TypeCheckImplItem::visit (HIR::Function &function)
 	      self_type = self->clone ();
 	      break;
 
-	    case HIR::SelfParam::IMM_REF:
-	      self_type = new TyTy::ReferenceType (
-		self_param.get_mappings ().get_hirid (),
-		TyTy::TyVar (self->get_ref ()), Mutability::Imm);
+	      case HIR::SelfParam::IMM_REF: {
+		auto region = context->lookup_and_resolve_lifetime (
+		  self_param.get_lifetime ());
+		if (!region.has_value ())
+		  {
+		    rust_inform (self_param.get_locus (),
+				 "failed to resolve lifetime");
+		    region = TyTy::Region::make_anonymous (); // FIXME
+		  }
+		self_type = new TyTy::ReferenceType (
+		  self_param.get_mappings ().get_hirid (),
+		  TyTy::TyVar (self->get_ref ()), Mutability::Imm,
+		  region.value ());
+	      }
 	      break;
 
-	    case HIR::SelfParam::MUT_REF:
-	      self_type = new TyTy::ReferenceType (
-		self_param.get_mappings ().get_hirid (),
-		TyTy::TyVar (self->get_ref ()), Mutability::Mut);
+	      case HIR::SelfParam::MUT_REF: {
+		auto region = context->lookup_and_resolve_lifetime (
+		  self_param.get_lifetime ());
+		if (!region.has_value ())
+		  {
+		    rust_error_at (self_param.get_locus (),
+				   "failed to resolve lifetime");
+		    return;
+		  }
+		self_type = new TyTy::ReferenceType (
+		  self_param.get_mappings ().get_hirid (),
+		  TyTy::TyVar (self->get_ref ()), Mutability::Mut,
+		  region.value ());
+	      }
 	      break;
 
 	    default:
@@ -295,15 +326,15 @@ TypeCheckImplItem::visit (HIR::Function &function)
   rust_assert (ok);
 
   RustIdent ident{*canonical_path, function.get_locus ()};
-  auto fnType
-    = new TyTy::FnType (function.get_mappings ().get_hirid (),
-			function.get_mappings ().get_defid (),
-			function.get_function_name ().as_string (), ident,
-			function.is_method ()
-			  ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
+  auto fnType = new TyTy::FnType (
+    function.get_mappings ().get_hirid (),
+    function.get_mappings ().get_defid (),
+    function.get_function_name ().as_string (), ident,
+    function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
-			ABI::RUST, std::move (params), ret_type,
-			std::move (substitutions));
+    ABI::RUST, std::move (params), ret_type, std::move (substitutions),
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
 
   context->insert_type (function.get_mappings (), fnType);
   result = fnType;
@@ -348,6 +379,11 @@ TypeCheckImplItem::visit (HIR::ConstantItem &constant)
 void
 TypeCheckImplItem::visit (HIR::TypeAlias &alias)
 {
+  auto binder_pin = context->push_lifetime_binder ();
+
+  if (alias.has_generics ())
+    resolve_generic_params (alias.get_generic_params (), substitutions);
+
   TyTy::BaseType *actual_type
     = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 7db06c0a89f..067465ec77a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -61,7 +61,7 @@ protected:
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
 
-  TyTy::BaseType *result;
+  TyTy::BaseType *result = nullptr;
 };
 
 class TypeCheckImplItemWithTrait : public TypeCheckBase,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 0bf4d709990..eb2698ead28 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -113,8 +113,11 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (
     }
 
   // create argument mappings
-  *infer_arguments
-    = TyTy::SubstitutionArgumentMappings (std::move (args), {}, locus);
+  *infer_arguments = TyTy::SubstitutionArgumentMappings (
+    std::move (args), {},
+    TyTy::SubstitutionArgumentMappings::regions_from_nullable_args (
+      infer_arguments),
+    locus);
 
   TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments);
 
@@ -139,7 +142,7 @@ TypeCheckItem::visit (HIR::TypeAlias &alias)
 
   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
   infered = actual_type;
 }
@@ -147,13 +150,15 @@ TypeCheckItem::visit (HIR::TypeAlias &alias)
 void
 TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 {
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
+
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -162,7 +167,7 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
     {
       TyTy::BaseType *field_type
 	= TypeCheckType::Resolve (field.get_field_type ().get ());
-      TyTy::StructFieldType *ty_field
+      auto *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     std::to_string (idx), field_type,
 				     field.get_locus ());
@@ -192,12 +197,13 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
     = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *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), std::move (substitutions), repr);
+  TyTy::BaseType *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),
+    std::move (substitutions), repr,
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -206,13 +212,15 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
 void
 TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 {
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
+
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -220,7 +228,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
     {
       TyTy::BaseType *field_type
 	= TypeCheckType::Resolve (field.get_field_type ().get ());
-      TyTy::StructFieldType *ty_field
+      auto *ty_field
 	= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
 				     field.get_field_name ().as_string (),
 				     field_type, field.get_locus ());
@@ -249,12 +257,13 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   TyTy::ADTType::ReprOptions repr
     = parse_repr_options (attrs, struct_decl.get_locus ());
 
-  TyTy::BaseType *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), std::move (substitutions), repr);
+  TyTy::BaseType *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),
+    std::move (substitutions), repr,
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -263,6 +272,7 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
 void
 TypeCheckItem::visit (HIR::Enum &enum_decl)
 {
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (enum_decl.has_generics ())
     resolve_generic_params (enum_decl.get_generic_params (), substitutions);
@@ -301,13 +311,14 @@ TypeCheckItem::visit (HIR::Enum &enum_decl)
 void
 TypeCheckItem::visit (HIR::Union &union_decl)
 {
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (union_decl.has_generics ())
     resolve_generic_params (union_decl.get_generic_params (), substitutions);
 
   for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -315,7 +326,7 @@ TypeCheckItem::visit (HIR::Union &union_decl)
     {
       TyTy::BaseType *variant_type
 	= TypeCheckType::Resolve (variant.get_field_type ().get ());
-      TyTy::StructFieldType *ty_variant
+      auto *ty_variant
 	= new TyTy::StructFieldType (variant.get_mappings ().get_hirid (),
 				     variant.get_field_name ().as_string (),
 				     variant_type, variant.get_locus ());
@@ -387,6 +398,8 @@ TypeCheckItem::visit (HIR::ConstantItem &constant)
 void
 TypeCheckItem::visit (HIR::ImplBlock &impl_block)
 {
+  auto binder_pin = context->push_clean_lifetime_resolver (true);
+
   bool failed_flag = false;
   std::vector<TyTy::SubstitutionParamMapping> substitutions
     = resolve_impl_block_substitutions (impl_block, failed_flag);
@@ -429,13 +442,14 @@ TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
 void
 TypeCheckItem::visit (HIR::Function &function)
 {
+  auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
     resolve_generic_params (function.get_generic_params (), substitutions);
 
   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
 
   TyTy::BaseType *ret_type = nullptr;
@@ -463,8 +477,7 @@ TypeCheckItem::visit (HIR::Function &function)
     {
       // get the name as well required for later on
       auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-      params.push_back (std::pair<HIR::Pattern *, TyTy::BaseType *> (
-	param.get_param_name ().get (), param_tyty));
+      params.emplace_back (param.get_param_name ().get (), param_tyty);
 
       context->insert_type (param.get_mappings (), param_tyty);
       TypeCheckPattern::Resolve (param.get_param_name ().get (), param_tyty);
@@ -477,21 +490,25 @@ TypeCheckItem::visit (HIR::Function &function)
   rust_assert (ok);
 
   RustIdent ident{*canonical_path, function.get_locus ()};
-  auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
-				  function.get_mappings ().get_defid (),
-				  function.get_function_name ().as_string (),
-				  ident, TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
-				  ABI::RUST, std::move (params), ret_type,
-				  std::move (substitutions));
 
-  context->insert_type (function.get_mappings (), fnType);
+  auto fn_type = new TyTy::FnType (
+    function.get_mappings ().get_hirid (),
+    function.get_mappings ().get_defid (),
+    function.get_function_name ().as_string (), ident,
+    TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
+    std::move (substitutions),
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
+
+  context->insert_type (function.get_mappings (), fn_type);
 
   // need to get the return type from this
-  TyTy::FnType *resolved_fn_type = fnType;
+  TyTy::FnType *resolved_fn_type = fn_type;
   auto expected_ret_tyty = resolved_fn_type->get_return_type ();
   context->push_return_type (TypeCheckContextItem (&function),
 			     expected_ret_tyty);
 
+  context->switch_to_fn_body ();
   auto block_expr_ty
     = TypeCheckExpr::Resolve (function.get_definition ().get ());
 
@@ -505,14 +522,14 @@ TypeCheckItem::visit (HIR::Function &function)
 
   context->pop_return_type ();
 
-  infered = fnType;
+  infered = fn_type;
 }
 
 void
 TypeCheckItem::visit (HIR::Module &module)
 {
   for (auto &item : module.get_items ())
-    TypeCheckItem::Resolve (*item.get ());
+    TypeCheckItem::Resolve (*item);
 }
 
 void
@@ -551,7 +568,7 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
 
   for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item);
     }
 
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
@@ -559,13 +576,13 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   if (impl_block.has_trait_ref ())
     {
       std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
-      trait_reference = TraitResolver::Resolve (*ref.get ());
+      trait_reference = TraitResolver::Resolve (*ref);
       rust_assert (!trait_reference->is_error ());
 
       // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
       // for example
       specified_bound
-	= get_predicate_from_bound (*ref.get (), impl_block.get_type ().get ());
+	= get_predicate_from_bound (*ref, impl_block.get_type ().get ());
     }
 
   TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ().get ());
@@ -596,13 +613,13 @@ TypeCheckItem::validate_trait_impl_block (
   if (impl_block.has_trait_ref ())
     {
       std::unique_ptr<HIR::TypePath> &ref = impl_block.get_trait_ref ();
-      trait_reference = TraitResolver::Resolve (*ref.get ());
+      trait_reference = TraitResolver::Resolve (*ref);
       rust_assert (!trait_reference->is_error ());
 
       // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
       // for example
       specified_bound
-	= get_predicate_from_bound (*ref.get (), impl_block.get_type ().get ());
+	= get_predicate_from_bound (*ref, impl_block.get_type ().get ());
     }
 
   bool is_trait_impl_block = !trait_reference->is_error ();
@@ -637,17 +654,17 @@ TypeCheckItem::validate_trait_impl_block (
 	      std::string trait_item_name = trait_item_ref.get_identifier ();
 	      std::string impl_item_name
 		= implemented_trait_item->get_identifier ();
-	      found = trait_item_name.compare (impl_item_name) == 0;
+	      found = trait_item_name == impl_item_name;
 	      if (found)
 		break;
 	    }
 
 	  bool is_required_trait_item = !trait_item_ref.is_optional ();
 	  if (!found && is_required_trait_item)
-	    missing_trait_items.push_back (trait_item_ref);
+	    missing_trait_items.emplace_back (trait_item_ref);
 	}
 
-      if (missing_trait_items.size () > 0)
+      if (!missing_trait_items.empty ())
 	{
 	  std::string missing_items_buf;
 	  rich_location r (line_table, impl_block.get_locus ());
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 7dfa9368729..ea7d8422980 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -141,8 +141,12 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
 	  infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
 	  return;
 	}
+      std::vector<TyTy::Region> regions;
+
       infered = SubstMapper::Resolve (infered, expr.get_locus (),
-				      &item_seg.get_generic_args ());
+				      &item_seg.get_generic_args (),
+				      context->regions_from_generic_args (
+					item_seg.get_generic_args ()));
     }
 
   // continue on as a path-in-expression
@@ -298,7 +302,9 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
       if (seg.has_generic_args ())
 	{
 	  lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
-					 &seg.get_generic_args ());
+					 &seg.get_generic_args (),
+					 context->regions_from_generic_args (
+					   seg.get_generic_args ()));
 	  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
 	    return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
 	}
@@ -471,8 +477,10 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 
       if (seg.has_generic_args ())
 	{
-	  tyseg = SubstMapper::Resolve (tyseg, expr_locus,
-					&seg.get_generic_args ());
+	  tyseg
+	    = SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
+				    context->regions_from_generic_args (
+				      seg.get_generic_args ()));
 	  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
 	    return;
 	}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 951920138cb..e7a86b9eee1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -70,6 +70,12 @@ TypeCheckType::Resolve (HIR::Type *type)
 void
 TypeCheckType::visit (HIR::BareFunctionType &fntype)
 {
+  auto binder_pin = context->push_lifetime_binder ();
+  for (auto &lifetime_param : fntype.get_for_lifetimes ())
+    {
+      context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+    }
+
   TyTy::BaseType *return_type;
   if (fntype.has_return_type ())
     {
@@ -292,8 +298,11 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
 		= new TyTy::ErrorType (path.get_mappings ().get_hirid ());
 	      return;
 	    }
-	  translated = SubstMapper::Resolve (translated, path.get_locus (),
-					     &generic_seg.get_generic_args ());
+	  translated
+	    = SubstMapper::Resolve (translated, path.get_locus (),
+				    &generic_seg.get_generic_args (),
+				    context->regions_from_generic_args (
+				      generic_seg.get_generic_args ()));
 	}
     }
 
@@ -425,8 +434,11 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
 	  HIR::TypePathSegmentGeneric *generic_segment
 	    = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
 
+	  auto regions = context->regions_from_generic_args (
+	    generic_segment->get_generic_args ());
 	  lookup = SubstMapper::Resolve (lookup, path.get_locus (),
-					 &generic_segment->get_generic_args ());
+					 &generic_segment->get_generic_args (),
+					 regions);
 	  if (lookup->get_kind () == TyTy::TypeKind::ERROR)
 	    return new TyTy::ErrorType (seg->get_mappings ().get_hirid ());
 	}
@@ -434,7 +446,9 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
 	{
 	  HIR::GenericArgs empty
 	    = HIR::GenericArgs::create_empty (path.get_locus ());
-	  lookup = SubstMapper::Resolve (lookup, path.get_locus (), &empty);
+	  lookup
+	    = SubstMapper::Resolve (lookup, path.get_locus (), &empty,
+				    context->regions_from_generic_args (empty));
 	}
 
       *root_resolved_node_id = ref_node_id;
@@ -532,11 +546,26 @@ TypeCheckType::resolve_segments (
 
       if (seg->is_generic_segment ())
 	{
-	  HIR::TypePathSegmentGeneric *generic_segment
+	  auto *generic_segment
 	    = static_cast<HIR::TypePathSegmentGeneric *> (seg.get ());
 
+	  std::vector<TyTy::Region> regions;
+	  for (auto &lifetime :
+	       generic_segment->get_generic_args ().get_lifetime_args ())
+	    {
+	      auto region = context->lookup_and_resolve_lifetime (lifetime);
+	      if (!region.has_value ())
+		{
+		  rust_error_at (lifetime.get_locus (),
+				 "failed to resolve lifetime");
+		  return new TyTy::ErrorType (expr_id);
+		}
+	      regions.push_back (region.value ());
+	    }
+
 	  tyseg = SubstMapper::Resolve (tyseg, expr_locus,
-					&generic_segment->get_generic_args ());
+					&generic_segment->get_generic_args (),
+					regions);
 	  if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
 	    return new TyTy::ErrorType (expr_id);
 	}
@@ -607,6 +636,12 @@ TypeCheckType::visit (HIR::TraitObjectType &type)
       HIR::TypeParamBound &b = *bound.get ();
       HIR::TraitBound &trait_bound = static_cast<HIR::TraitBound &> (b);
 
+      auto binder_pin = context->push_lifetime_binder ();
+      for (auto &lifetime_param : trait_bound.get_for_lifetimes ())
+	{
+	  context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+	}
+
       TyTy::TypeBoundPredicate predicate = get_predicate_from_bound (
 	trait_bound.get_path (),
 	nullptr /*this will setup a PLACEHOLDER for self*/);
@@ -660,10 +695,18 @@ void
 TypeCheckType::visit (HIR::ReferenceType &type)
 {
   TyTy::BaseType *base = TypeCheckType::Resolve (type.get_base_type ().get ());
-  translated
-    = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
-			       TyTy::TyVar (base->get_ref ()), type.get_mut ());
-}
+  rust_assert (type.has_lifetime ());
+  auto region = context->lookup_and_resolve_lifetime (type.get_lifetime ());
+  if (!region.has_value ())
+    {
+      rust_error_at (type.get_locus (), "failed to resolve lifetime");
+      translated = new TyTy::ErrorType (type.get_mappings ().get_hirid ());
+      return;
+    }
+  translated = new TyTy::ReferenceType (type.get_mappings ().get_hirid (),
+					TyTy::TyVar (base->get_ref ()),
+					type.get_mut (), region.value ());
+} // namespace Resolver
 
 void
 TypeCheckType::visit (HIR::RawPointerType &type)
@@ -849,6 +892,9 @@ void
 ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item)
 {
   ResolveWhereClauseItem resolver;
+
+  auto binder_pin = resolver.context->push_lifetime_binder ();
+
   switch (item.get_item_type ())
     {
     case HIR::WhereClauseItem::LIFETIME:
@@ -863,11 +909,34 @@ ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item)
 
 void
 ResolveWhereClauseItem::visit (HIR::LifetimeWhereClauseItem &item)
-{}
+{
+  auto lhs = context->lookup_and_resolve_lifetime (item.get_lifetime ());
+  if (!lhs.has_value ())
+    {
+      rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
+    }
+  for (auto &lifetime : item.get_lifetime_bounds ())
+    {
+      auto rhs_i = context->lookup_and_resolve_lifetime (lifetime);
+      if (!rhs_i.has_value ())
+	{
+	  rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
+	}
+    }
+}
 
 void
 ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 {
+  auto binder_pin = context->push_lifetime_binder ();
+  if (item.has_for_lifetimes ())
+    {
+      for (auto &lifetime_param : item.get_for_lifetimes ())
+	{
+	  context->intern_and_insert_lifetime (lifetime_param.get_lifetime ());
+	}
+    }
+
   auto &binding_type_path = item.get_bound_type ();
   TyTy::BaseType *binding = TypeCheckType::Resolve (binding_type_path.get ());
 
@@ -879,7 +948,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
       switch (bound->get_bound_type ())
 	{
 	  case HIR::TypeParamBound::BoundType::TRAITBOUND: {
-	    HIR::TraitBound *b = static_cast<HIR::TraitBound *> (bound.get ());
+	    auto *b = static_cast<HIR::TraitBound *> (bound.get ());
 
 	    TyTy::TypeBoundPredicate predicate
 	      = get_predicate_from_bound (b->get_path (),
@@ -888,6 +957,19 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 	      specified_bounds.push_back (std::move (predicate));
 	  }
 	  break;
+	  case HIR::TypeParamBound::BoundType::LIFETIME: {
+	    if (binding->is<TyTy::ParamType> ())
+	      {
+		auto *b = static_cast<HIR::Lifetime *> (bound.get ());
+		auto region = context->lookup_and_resolve_lifetime (*b);
+		if (!region.has_value ())
+		  {
+		    rust_error_at (UNKNOWN_LOCATION,
+				   "failed to resolve lifetime");
+		  }
+	      }
+	  }
+	  break;
 
 	default:
 	  break;
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index c8e223d56dd..68d9681485a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -30,6 +30,39 @@ saw_errors (void);
 namespace Rust {
 namespace Resolver {
 
+tl::optional<TyTy::Region>
+TypeCheckContext::LifetimeResolver::resolve (const Lifetime &placeholder) const
+{
+  if (placeholder.is_static ())
+    return TyTy::Region::make_static ();
+
+  if (placeholder == Lifetime::anonymous_lifetime ())
+    return TyTy::Region::make_anonymous ();
+
+  for (auto it = lifetime_lookup.rbegin (); it != lifetime_lookup.rend (); ++it)
+    {
+      if (it->first == placeholder)
+	{
+	  if (it->second.scope <= ITEM_SCOPE)
+	    {
+	      // It is useful to have the static lifetime and named
+	      // lifetimed disjoint so we add the +1 here.
+	      return (is_body)
+		       ? TyTy::Region::make_named (it->second.index + 1)
+		       : TyTy::Region::make_early_bound (it->second.index);
+	    }
+	  else
+	    {
+	      return TyTy::Region::make_late_bound (get_current_scope ()
+						      - it->second.scope,
+						    it->second.index);
+	    }
+	}
+    }
+
+  return tl::nullopt;
+}
+
 void
 TypeResolution::Resolve (HIR::Crate &crate)
 {
@@ -151,6 +184,8 @@ TraitItemReference::get_type_from_constant (
 TyTy::BaseType *
 TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 {
+  auto binder_pin = context->push_clean_lifetime_resolver ();
+
   std::vector<TyTy::SubstitutionParamMapping> substitutions
     = inherited_substitutions;
 
@@ -161,7 +196,15 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 	{
 	  switch (generic_param.get ()->get_kind ())
 	    {
-	    case HIR::GenericParam::GenericKind::LIFETIME:
+	      case HIR::GenericParam::GenericKind::LIFETIME: {
+		auto lifetime_param
+		  = static_cast<HIR::LifetimeParam &> (*generic_param);
+
+		context->intern_and_insert_lifetime (
+		  lifetime_param.get_lifetime ());
+		// TODO: Handle lifetime bounds
+	      }
+	      break;
 	    case HIR::GenericParam::GenericKind::CONST:
 	      // FIXME: Skipping Lifetime and Const completely until better
 	      // handling.
@@ -234,15 +277,27 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 	      break;
 
 	    case HIR::SelfParam::IMM_REF:
-	      self_type = new TyTy::ReferenceType (
-		self_param.get_mappings ().get_hirid (),
-		TyTy::TyVar (self->get_ref ()), Mutability::Imm);
-	      break;
-
-	    case HIR::SelfParam::MUT_REF:
-	      self_type = new TyTy::ReferenceType (
-		self_param.get_mappings ().get_hirid (),
-		TyTy::TyVar (self->get_ref ()), Mutability::Mut);
+	      case HIR::SelfParam::MUT_REF: {
+		auto mutability
+		  = self_param.get_self_kind () == HIR::SelfParam::IMM_REF
+		      ? Mutability::Imm
+		      : Mutability::Mut;
+		rust_assert (self_param.has_lifetime ());
+
+		auto maybe_region = context->lookup_and_resolve_lifetime (
+		  self_param.get_lifetime ());
+
+		if (!maybe_region.has_value ())
+		  {
+		    rust_error_at (self_param.get_locus (),
+				   "failed to resolve lifetime");
+		    return get_error ();
+		  }
+		self_type = new TyTy::ReferenceType (
+		  self_param.get_mappings ().get_hirid (),
+		  TyTy::TyVar (self->get_ref ()), mutability,
+		  maybe_region.value ());
+	      }
 	      break;
 
 	    default:
@@ -274,15 +329,14 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
   rust_assert (ok);
 
   RustIdent ident{*canonical_path, fn.get_locus ()};
-  auto resolved
-    = new TyTy::FnType (fn.get_mappings ().get_hirid (),
-			fn.get_mappings ().get_defid (),
-			function.get_function_name ().as_string (), ident,
-			function.is_method ()
-			  ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
+  auto resolved = new TyTy::FnType (
+    fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (),
+    function.get_function_name ().as_string (), ident,
+    function.is_method () ? TyTy::FnType::FNTYPE_IS_METHOD_FLAG
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
-			ABI::RUST, std::move (params), ret_type, substitutions);
-
+    ABI::RUST, std::move (params), ret_type, substitutions,
+    TyTy::SubstitutionArgumentMappings::empty (
+      context->get_lifetime_resolver ().get_num_bound_regions ()));
   context->insert_type (fn.get_mappings (), resolved);
   return resolved;
 }
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 0d74ae11a2c..3d66e29052f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -23,6 +23,7 @@
 #include "rust-tyty.h"
 #include "rust-hir-trait-reference.h"
 #include "rust-autoderef.h"
+#include "rust-tyty-region.h"
 
 #include <stack>
 
@@ -222,8 +223,14 @@ public:
   WARN_UNUSED_RESULT tl::optional<Lifetime>
   lookup_lifetime (const HIR::Lifetime &lifetime) const;
 
+  WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+  lookup_and_resolve_lifetime (const HIR::Lifetime &lifetime) const;
+
   void intern_and_insert_lifetime (const HIR::Lifetime &lifetime);
 
+  WARN_UNUSED_RESULT std::vector<TyTy::Region>
+  regions_from_generic_args (const HIR::GenericArgs &args) const;
+
 private:
   TypeCheckContext ();
 
@@ -327,6 +334,9 @@ private:
 	{placeholder, {get_current_scope (), binder_size_stack.top ()++}});
     }
 
+    WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+    resolve (const Lifetime &placeholder) const;
+
     /** Only to be used by the guard. */
     void push_binder () { binder_size_stack.push (0); }
     /** Only to be used by the guard. */
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
index b2d58c44acc..394dfe40db4 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.cc
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -23,15 +23,18 @@ namespace Rust {
 namespace Resolver {
 
 SubstMapper::SubstMapper (HirId ref, HIR::GenericArgs *generics,
+			  const std::vector<TyTy::Region> &regions,
 			  location_t locus)
-  : resolved (new TyTy::ErrorType (ref)), generics (generics), locus (locus)
+  : resolved (new TyTy::ErrorType (ref)), generics (generics),
+    regions (regions), locus (locus)
 {}
 
 TyTy::BaseType *
 SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
-		      HIR::GenericArgs *generics)
+		      HIR::GenericArgs *generics,
+		      const std::vector<TyTy::Region> &regions)
 {
-  SubstMapper mapper (base->get_ref (), generics, locus);
+  SubstMapper mapper (base->get_ref (), generics, regions, locus);
   base->accept_vis (mapper);
   rust_assert (mapper.resolved != nullptr);
   return mapper.resolved;
@@ -40,7 +43,7 @@ SubstMapper::Resolve (TyTy::BaseType *base, location_t locus,
 TyTy::BaseType *
 SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus)
 {
-  return SubstMapper::Resolve (base, locus, nullptr);
+  return SubstMapper::Resolve (base, locus, nullptr, {});
 }
 
 bool
@@ -62,7 +65,7 @@ SubstMapper::visit (TyTy::FnType &type)
   else
     {
       TyTy::SubstitutionArgumentMappings mappings
-	= type.get_mappings_from_generic_args (*generics);
+	= type.get_mappings_from_generic_args (*generics, regions);
       if (mappings.is_error ())
 	return;
 
@@ -86,7 +89,7 @@ SubstMapper::visit (TyTy::ADTType &type)
   else
     {
       TyTy::SubstitutionArgumentMappings mappings
-	= type.get_mappings_from_generic_args (*generics);
+	= type.get_mappings_from_generic_args (*generics, regions);
       if (mappings.is_error ())
 	return;
 
@@ -101,7 +104,7 @@ void
 SubstMapper::visit (TyTy::PlaceholderType &type)
 {
   rust_assert (type.can_resolve ());
-  resolved = SubstMapper::Resolve (type.resolve (), locus, generics);
+  resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions);
 }
 
 void
@@ -117,7 +120,7 @@ SubstMapper::visit (TyTy::ProjectionType &type)
   else
     {
       TyTy::SubstitutionArgumentMappings mappings
-	= type.get_mappings_from_generic_args (*generics);
+	= type.get_mappings_from_generic_args (*generics, regions);
       if (mappings.is_error ())
 	return;
 
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 0a816c738dd..13487cf002d 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -29,7 +29,9 @@ class SubstMapper : public TyTy::TyVisitor
 {
 public:
   static TyTy::BaseType *Resolve (TyTy::BaseType *base, location_t locus,
-				  HIR::GenericArgs *generics = nullptr);
+				  HIR::GenericArgs *generics = nullptr,
+				  const std::vector<TyTy::Region> &regions
+				  = {});
 
   static TyTy::BaseType *InferSubst (TyTy::BaseType *base, location_t locus);
 
@@ -63,10 +65,12 @@ public:
   void visit (TyTy::ClosureType &) override { rust_unreachable (); }
 
 private:
-  SubstMapper (HirId ref, HIR::GenericArgs *generics, location_t locus);
+  SubstMapper (HirId ref, HIR::GenericArgs *generics,
+	       const std::vector<TyTy::Region> &regions, location_t locus);
 
   TyTy::BaseType *resolved;
   HIR::GenericArgs *generics;
+  const std::vector<TyTy::Region> &regions;
   location_t locus;
 };
 
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index c6840c8b1a9..1f4a5a35626 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -543,12 +543,39 @@ TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const
   rust_unreachable ();
 }
 
+WARN_UNUSED_RESULT tl::optional<TyTy::Region>
+TypeCheckContext::lookup_and_resolve_lifetime (
+  const HIR::Lifetime &lifetime) const
+{
+  auto maybe_interned = lookup_lifetime (lifetime);
+  if (!maybe_interned)
+    return tl::nullopt;
+
+  return get_lifetime_resolver ().resolve (maybe_interned.value ());
+}
 void
 TypeCheckContext::intern_and_insert_lifetime (const HIR::Lifetime &lifetime)
 {
   get_lifetime_resolver ().insert_mapping (intern_lifetime (lifetime));
 }
 
+WARN_UNUSED_RESULT std::vector<TyTy::Region>
+TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
+{
+  std::vector<TyTy::Region> regions;
+  for (const auto &lifetime : args.get_lifetime_args ())
+    {
+      auto resolved = lookup_and_resolve_lifetime (lifetime);
+      if (!resolved)
+	{
+	  rust_error_at (lifetime.get_locus (), "unresolved lifetime");
+	  return {};
+	}
+      regions.push_back (*resolved);
+    }
+  return regions;
+}
+
 // TypeCheckContextItem
 
 TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 6a87c05dbf4..066fe4781ed 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -375,6 +375,7 @@ TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
 
   used_arguments
     = SubstitutionArgumentMappings (copied_arg_mappings, {},
+				    other.used_arguments.get_regions (),
 				    other.used_arguments.get_locus ());
 }
 
@@ -415,6 +416,7 @@ TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
 
   used_arguments
     = SubstitutionArgumentMappings (copied_arg_mappings, {},
+				    other.used_arguments.get_regions (),
 				    other.used_arguments.get_locus ());
 
   return *this;
@@ -482,7 +484,10 @@ TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
     }
 
   // now actually perform a substitution
-  used_arguments = get_mappings_from_generic_args (*generic_args);
+  used_arguments = get_mappings_from_generic_args (
+    *generic_args,
+    Resolver::TypeCheckContext::get ()->regions_from_generic_args (
+      *generic_args));
 
   error_flag |= used_arguments.is_error ();
   auto &subst_mappings = used_arguments;
@@ -590,6 +595,7 @@ TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
     }
 
   SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
+					 gargs.get_regions (),
 					 gargs.get_locus (),
 					 gargs.get_subst_cb (),
 					 true /* trait-mode-flag */);
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index b71c9183110..fcb09d507a8 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -17,6 +17,8 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-tyty-subst.h"
+
+#include <utility>
 #include "rust-tyty.h"
 #include "rust-hir-type-check.h"
 #include "rust-substitution-mapper.h"
@@ -243,21 +245,34 @@ SubstitutionArg::as_string () const
 	 + (argument != nullptr ? ":" + argument->as_string () : "");
 }
 
+const RegionParamList &
+SubstitutionArgumentMappings::get_regions () const
+{
+  return regions;
+}
+
+RegionParamList &
+SubstitutionArgumentMappings::get_mut_regions ()
+{
+  return regions;
+}
+
 // SubstitutionArgumentMappings
 
 SubstitutionArgumentMappings::SubstitutionArgumentMappings (
   std::vector<SubstitutionArg> mappings,
-  std::map<std::string, BaseType *> binding_args, location_t locus,
-  ParamSubstCb param_subst_cb, bool trait_item_flag, bool error_flag)
-  : mappings (mappings), binding_args (binding_args), locus (locus),
-    param_subst_cb (param_subst_cb), trait_item_flag (trait_item_flag),
-    error_flag (error_flag)
+  std::map<std::string, BaseType *> binding_args, RegionParamList regions,
+  location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
+  bool error_flag)
+  : mappings (std::move (mappings)), binding_args (binding_args),
+    regions (regions), locus (locus), param_subst_cb (param_subst_cb),
+    trait_item_flag (trait_item_flag), error_flag (error_flag)
 {}
 
 SubstitutionArgumentMappings::SubstitutionArgumentMappings (
   const SubstitutionArgumentMappings &other)
   : mappings (other.mappings), binding_args (other.binding_args),
-    locus (other.locus), param_subst_cb (nullptr),
+    regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
     trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
 {}
 
@@ -267,6 +282,7 @@ SubstitutionArgumentMappings::operator= (
 {
   mappings = other.mappings;
   binding_args = other.binding_args;
+  regions = other.regions;
   locus = other.locus;
   param_subst_cb = nullptr;
   trait_item_flag = other.trait_item_flag;
@@ -278,15 +294,15 @@ SubstitutionArgumentMappings::operator= (
 SubstitutionArgumentMappings
 SubstitutionArgumentMappings::error ()
 {
-  return SubstitutionArgumentMappings ({}, {}, UNDEF_LOCATION, nullptr, false,
-				       true);
+  return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
+				       false, true);
 }
 
 SubstitutionArgumentMappings
-SubstitutionArgumentMappings::empty ()
+SubstitutionArgumentMappings::empty (size_t num_regions)
 {
-  return SubstitutionArgumentMappings ({}, {}, UNDEF_LOCATION, nullptr, false,
-				       false);
+  return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
+				       nullptr, false, false);
 }
 
 bool
@@ -297,12 +313,12 @@ SubstitutionArgumentMappings::is_error () const
 
 bool
 SubstitutionArgumentMappings::get_argument_for_symbol (
-  const ParamType *param_to_find, SubstitutionArg *argument)
+  const ParamType *param_to_find, SubstitutionArg *argument) const
 {
-  for (auto &mapping : mappings)
+  for (const auto &mapping : mappings)
     {
       const ParamType *p = mapping.get_param_ty ();
-      if (p->get_symbol ().compare (param_to_find->get_symbol ()) == 0)
+      if (p->get_symbol () == param_to_find->get_symbol ())
 	{
 	  *argument = mapping;
 	  return true;
@@ -310,6 +326,18 @@ SubstitutionArgumentMappings::get_argument_for_symbol (
     }
   return false;
 }
+tl::optional<size_t>
+SubstitutionArgumentMappings::find_symbol (const ParamType &param_to_find) const
+{
+  auto it = std::find_if (mappings.begin (), mappings.end (),
+			  [param_to_find] (const SubstitutionArg &arg) {
+			    return arg.get_param_ty ()->get_symbol ()
+				   == param_to_find.get_symbol ();
+			  });
+  if (it == mappings.end ())
+    return tl::nullopt;
+  return std::distance (mappings.begin (), it);
+}
 
 bool
 SubstitutionArgumentMappings::get_argument_at (size_t index,
@@ -461,6 +489,16 @@ SubstitutionRef::get_num_substitutions () const
 {
   return substitutions.size ();
 }
+size_t
+SubstitutionRef::get_num_lifetime_params () const
+{
+  return used_arguments.get_regions ().size ();
+}
+size_t
+SubstitutionRef::get_num_type_params () const
+{
+  return get_num_substitutions ();
+}
 
 std::vector<SubstitutionParamMapping> &
 SubstitutionRef::get_substs ()
@@ -497,12 +535,9 @@ SubstitutionRef::override_context ()
 bool
 SubstitutionRef::needs_substitution () const
 {
-  for (auto &sub : substitutions)
-    {
-      if (sub.need_substitution ())
-	return true;
-    }
-  return false;
+  return std::any_of (substitutions.begin (), substitutions.end (),
+		      std::mem_fn (
+			&SubstitutionParamMapping::needs_substitution));
 }
 
 bool
@@ -547,14 +582,15 @@ SubstitutionRef::min_required_substitutions () const
   return n;
 }
 
-SubstitutionArgumentMappings
+const SubstitutionArgumentMappings &
 SubstitutionRef::get_used_arguments () const
 {
   return used_arguments;
 }
 
 SubstitutionArgumentMappings
-SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
+SubstitutionRef::get_mappings_from_generic_args (
+  HIR::GenericArgs &args, const std::vector<Region> &regions)
 {
   std::map<std::string, BaseType *> binding_arguments;
   if (args.get_binding_args ().size () > 0)
@@ -672,9 +708,9 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
 	  // this resolved default might already contain default parameters
 	  if (!resolved->is_concrete ())
 	    {
-	      SubstitutionArgumentMappings intermediate (mappings,
-							 binding_arguments,
-							 args.get_locus ());
+	      SubstitutionArgumentMappings intermediate (
+		mappings, binding_arguments,
+		{used_arguments.get_regions ().size ()}, args.get_locus ());
 	      resolved = Resolver::SubstMapperInternal::Resolve (resolved,
 								 intermediate);
 
@@ -687,8 +723,10 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
 	}
     }
 
-  return SubstitutionArgumentMappings (mappings, binding_arguments,
-				       args.get_locus ());
+  return {mappings, binding_arguments,
+	  RegionParamList::from_subst (used_arguments.get_regions ().size (),
+				       regions),
+	  args.get_locus ()};
 }
 
 BaseType *
@@ -727,6 +765,7 @@ SubstitutionRef::infer_substitions (location_t locus)
 
   SubstitutionArgumentMappings infer_arguments (std::move (args),
 						{} /* binding_arguments */,
+						used_arguments.get_regions (),
 						locus);
   return handle_substitions (infer_arguments);
 }
@@ -773,6 +812,7 @@ SubstitutionRef::adjust_mappings_for_this (
 
   return SubstitutionArgumentMappings (resolved_mappings,
 				       mappings.get_binding_args (),
+				       mappings.get_regions (),
 				       mappings.get_locus (),
 				       mappings.get_subst_cb (),
 				       mappings.trait_item_mode ());
@@ -840,6 +880,7 @@ SubstitutionRef::solve_mappings_from_receiver_for_self (
 
   return SubstitutionArgumentMappings (resolved_mappings,
 				       mappings.get_binding_args (),
+				       mappings.get_regions (),
 				       mappings.get_locus ());
 }
 
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index d9d179d426f..dbabff3d449 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -23,6 +23,9 @@
 #include "rust-location.h"
 #include "rust-hir-full-decls.h"
 #include "rust-tyty-bounds.h"
+#include "rust-tyty-region.h"
+
+#include <optional.h>
 
 namespace Rust {
 namespace TyTy {
@@ -69,6 +72,61 @@ private:
   ParamType *param;
 };
 
+/**
+ * Represents the part of the parameter list that contains lifetime
+ * parameters.
+ *
+ * ```
+ * Foo<'a, 'b, i32, 8>
+ *     ^^^^^^
+ * ```
+ *
+ * It has fixed size based on the number of lifetime parameters and they are
+ * indexed based on their order.
+ *
+ * All regions are initially set to unresolved. When type instantiation is
+ * encountered, all explicitly mentioned lifetimes are resolved to bound
+ * lifetimes. The remaining unresolved lifetimes are set to anonymous. During
+ * BIR construction, all lifetimes are replaced with free region variables.
+ * Inference of anonymous regions happens automatically using BIR subtyping
+ * pass.
+ */
+class RegionParamList
+{
+  std::vector<Region> regions;
+
+public:
+  RegionParamList (size_t num_regions) : regions (num_regions) {}
+
+  Region *begin () { return regions.data (); }
+  Region *end () { return regions.data () + regions.size (); }
+  Region &operator[] (size_t index) { return regions.at (index); }
+  const Region &operator[] (size_t index) const { return regions.at (index); }
+  WARN_UNUSED_RESULT const Region *begin () const { return regions.data (); }
+  WARN_UNUSED_RESULT const Region *end () const
+  {
+    return regions.data () + regions.size ();
+  }
+  size_t size () const { return regions.size (); }
+
+  /**
+   * Takes regions from the `subst` parameter and fills the rest with anonymous
+   * regions.
+   */
+  static RegionParamList from_subst (size_t num_regions,
+				     std::vector<Region> subst)
+  {
+    RegionParamList list (num_regions);
+    for (size_t i = 0; i < subst.size (); i++)
+      list.regions.at (i) = subst.at (i);
+    for (size_t i = subst.size (); i < num_regions; i++)
+      {
+	list.regions.at (i) = Region::make_anonymous ();
+      }
+    return list;
+  }
+};
+
 class SubstitutionArg
 {
 public:
@@ -110,7 +168,7 @@ class SubstitutionArgumentMappings
 public:
   SubstitutionArgumentMappings (std::vector<SubstitutionArg> mappings,
 				std::map<std::string, BaseType *> binding_args,
-				location_t locus,
+				RegionParamList regions, location_t locus,
 				ParamSubstCb param_subst_cb = nullptr,
 				bool trait_item_flag = false,
 				bool error_flag = false);
@@ -124,12 +182,26 @@ public:
     = default;
 
   static SubstitutionArgumentMappings error ();
-  static SubstitutionArgumentMappings empty ();
+
+  /** Creates empty substitution argument mappings with unresolved regions */
+  static SubstitutionArgumentMappings empty (size_t num_regions = 0);
+
+  static RegionParamList
+  regions_from_nullable_args (SubstitutionArgumentMappings *args)
+  {
+    if (args == nullptr)
+      return RegionParamList (0);
+
+    return args->get_regions ();
+  }
 
   bool is_error () const;
 
   bool get_argument_for_symbol (const ParamType *param_to_find,
-				SubstitutionArg *argument);
+				SubstitutionArg *argument) const;
+
+  /** Return type parameter index for symbol */
+  tl::optional<size_t> find_symbol (const ParamType &param_to_find) const;
 
   bool get_argument_at (size_t index, SubstitutionArg *argument);
 
@@ -152,6 +224,9 @@ public:
 
   const std::map<std::string, BaseType *> &get_binding_args () const;
 
+  const RegionParamList &get_regions () const;
+  RegionParamList &get_mut_regions ();
+
   std::string as_string () const;
 
   void on_param_subst (const ParamType &p, const SubstitutionArg &a) const;
@@ -163,6 +238,7 @@ public:
 private:
   std::vector<SubstitutionArg> mappings;
   std::map<std::string, BaseType *> binding_args;
+  RegionParamList regions;
   location_t locus;
   ParamSubstCb param_subst_cb;
   bool trait_item_flag;
@@ -193,6 +269,10 @@ public:
 
   size_t get_num_substitutions () const;
 
+  size_t get_num_lifetime_params () const;
+
+  size_t get_num_type_params () const;
+
   std::vector<SubstitutionParamMapping> &get_substs ();
 
   const std::vector<SubstitutionParamMapping> &get_substs () const;
@@ -221,7 +301,8 @@ public:
   // the substitions we have here define X,Y but the arguments have no bindings
   // so its a matter of ordering
   SubstitutionArgumentMappings
-  get_mappings_from_generic_args (HIR::GenericArgs &args);
+  get_mappings_from_generic_args (HIR::GenericArgs &args,
+				  const std::vector<Region> &regions);
 
   // Recursive substitutions
   // Foo <A,B> { a:A, b: B}; Bar <X,Y,Z>{a:X, b: Foo<Y,Z>}
@@ -318,7 +399,10 @@ public:
   virtual BaseType *handle_substitions (SubstitutionArgumentMappings &mappings)
     = 0;
 
-  SubstitutionArgumentMappings get_used_arguments () const;
+  WARN_UNUSED_RESULT const SubstitutionArgumentMappings &
+  get_used_arguments () const;
+
+  WARN_UNUSED_RESULT tl::optional<SubstitutionArg> get_arg_at (size_t i) const;
 
 protected:
   std::vector<SubstitutionParamMapping> substitutions;
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index f1789f008a0..890d079d67f 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -572,7 +572,8 @@ BaseType::monomorphized_clone () const
     {
       TyVar elm = ref->get_var_element_type ().monomorphized_clone ();
       return new ReferenceType (ref->get_ref (), ref->get_ty_ref (), elm,
-				ref->mutability (), ref->get_combined_refs ());
+				ref->mutability (), ref->get_region (),
+				ref->get_combined_refs ());
     }
   else if (auto tuple = x->try_as<const TupleType> ())
     {
@@ -594,7 +595,8 @@ BaseType::monomorphized_clone () const
       return new FnType (fn->get_ref (), fn->get_ty_ref (), fn->get_id (),
 			 fn->get_identifier (), fn->ident, fn->get_flags (),
 			 fn->get_abi (), std::move (cloned_params), retty,
-			 fn->clone_substs (), fn->get_combined_refs ());
+			 fn->clone_substs (), fn->get_substitution_arguments (),
+			 fn->get_combined_refs ());
     }
   else if (auto fn = x->try_as<const FnPtr> ())
     {
@@ -977,6 +979,7 @@ InferType::default_type (BaseType **type) const
   auto context = Resolver::TypeCheckContext::get ();
   bool ok = false;
 
+  // NOTE: Calling this error is misleading.
   if (default_hint.kind == TypeKind::ERROR)
     {
       switch (infer_kind)
@@ -1955,7 +1958,7 @@ FnType::clone () const
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
 		     ident, flags, abi, std::move (cloned_params),
 		     get_return_type ()->clone (), clone_substs (),
-		     get_combined_refs ());
+		     get_substitution_arguments (), get_combined_refs ());
 }
 
 FnType *
@@ -2848,19 +2851,20 @@ CharType::clone () const
 // Reference Type
 
 ReferenceType::ReferenceType (HirId ref, TyVar base, Mutability mut,
-			      std::set<HirId> refs)
+			      Region region, std::set<HirId> refs)
   : BaseType (ref, ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
-	      refs),
-    base (base), mut (mut)
+	      std::move (refs)),
+    base (base), mut (mut), region (region)
 {}
 
 ReferenceType::ReferenceType (HirId ref, HirId ty_ref, TyVar base,
-			      Mutability mut, std::set<HirId> refs)
+			      Mutability mut, Region region,
+			      std::set<HirId> refs)
   : BaseType (ref, ty_ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
-	      refs),
-    base (base), mut (mut)
+	      std::move (refs)),
+    base (base), mut (mut), region (region)
 {}
 
 Mutability
@@ -2874,6 +2878,11 @@ ReferenceType::is_mutable () const
 {
   return mut == Mutability::Mut;
 }
+Region
+ReferenceType::get_region () const
+{
+  return region;
+}
 
 bool
 ReferenceType::is_dyn_object () const
@@ -2982,7 +2991,7 @@ BaseType *
 ReferenceType::clone () const
 {
   return new ReferenceType (get_ref (), get_ty_ref (), base, mutability (),
-			    get_combined_refs ());
+			    get_region (), get_combined_refs ());
 }
 
 ReferenceType *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index b04048f400d..7384c402f4e 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -26,6 +26,9 @@
 #include "rust-tyty-bounds.h"
 #include "rust-tyty-util.h"
 #include "rust-tyty-subst.h"
+#include "rust-tyty-region.h"
+
+#include <limits>
 
 namespace Rust {
 
@@ -770,10 +773,10 @@ public:
 	  uint8_t flags, ABI abi,
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+	  SubstitutionArgumentMappings substitution_argument_mappings,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
       params (std::move (params)), type (type), flags (flags),
       identifier (identifier), id (id), abi (abi)
   {
@@ -785,10 +788,10 @@ public:
 	  RustIdent ident, uint8_t flags, ABI abi,
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
+	  SubstitutionArgumentMappings substitution_argument_mappings,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
       params (params), type (type), flags (flags), identifier (identifier),
       id (id), abi (abi)
   {
@@ -977,7 +980,7 @@ public:
 	       = std::vector<TypeBoundPredicate> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()),
+		       SubstitutionArgumentMappings::error ()), // TODO
       parameters (parameters), result_type (std::move (result_type)), id (id),
       captures (captures)
   {
@@ -1365,11 +1368,13 @@ public:
 class ReferenceType : public BaseType
 {
 public:
-  static constexpr auto KIND = TypeKind::REF;
+  static constexpr auto KIND = REF;
 
   ReferenceType (HirId ref, TyVar base, Mutability mut,
+		 Region region = Region::make_anonymous (),
 		 std::set<HirId> refs = std::set<HirId> ());
   ReferenceType (HirId ref, HirId ty_ref, TyVar base, Mutability mut,
+		 Region region = Region::make_anonymous (),
 		 std::set<HirId> refs = std::set<HirId> ());
 
   BaseType *get_base () const;
@@ -1393,6 +1398,9 @@ public:
   Mutability mutability () const;
   bool is_mutable () const;
 
+  WARN_UNUSED_RESULT Region get_region () const;
+  void set_region (Region region);
+
   bool is_dyn_object () const;
   bool is_dyn_slice_type (const TyTy::SliceType **slice = nullptr) const;
   bool is_dyn_str_type (const TyTy::StrType **str = nullptr) const;
@@ -1401,6 +1409,7 @@ public:
 private:
   TyVar base;
   Mutability mut;
+  Region region;
 };
 
 class PointerType : public BaseType
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 07/25] gccrs: TyTy: Store region constraints
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (4 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 06/25] gccrs: Typecheck: add regions (lifetimes) to TyTy arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 15:26   ` Bernhard Reutner-Fischer
  2024-02-07 11:43 ` [COMMITTED 08/25] gccrs: TyTy: Store reference to type before any substitutions arthur.cohen
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
	Add region constraints.
	(TypeCheckImplItem::visit): Add region constraints.
	* typecheck/rust-hir-type-check-implitem.h: Add region constraints.
	* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelf):
	Add region constraints.
	(TypeCheckItem::visit): Add region constraints.
	(TypeCheckItem::resolve_impl_item): Add region constraints.
	(TypeCheckItem::resolve_impl_block_substitutions): Add region constraints.
	* typecheck/rust-hir-type-check-item.h: Add region constraints.
	* typecheck/rust-hir-type-check-type.cc (ResolveWhereClauseItem::Resolve):
	Add region constraints.
	(ResolveWhereClauseItem::visit): Add region constraints.
	* typecheck/rust-hir-type-check-type.h (class ResolveWhereClauseItem):
	Add region constraints.
	* typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
	Add region constraints.
	* typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::TypeBoundPredicate):
	Add region constraints.
	* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_region_constraints):
	Add region constraints.
	* typecheck/rust-tyty-subst.h (class BaseType): Add region constraints.
	(struct RegionConstraints): Add region constraints.
	* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): Add region constraints.
	(ADTType::clone): Add region constraints.
	(FnType::clone): Add region constraints.
	(ProjectionType::clone): Add region constraints.
	* typecheck/rust-tyty.h: Add region constraints.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 .../typecheck/rust-hir-type-check-implitem.cc | 24 ++++++--
 .../typecheck/rust-hir-type-check-implitem.h  |  1 +
 .../typecheck/rust-hir-type-check-item.cc     | 58 +++++++++++++------
 gcc/rust/typecheck/rust-hir-type-check-item.h |  3 +-
 .../typecheck/rust-hir-type-check-type.cc     | 11 +++-
 gcc/rust/typecheck/rust-hir-type-check-type.h | 10 +++-
 gcc/rust/typecheck/rust-hir-type-check.cc     | 11 +++-
 gcc/rust/typecheck/rust-tyty-bounds.cc        |  8 +--
 gcc/rust/typecheck/rust-tyty-subst.cc         | 11 +++-
 gcc/rust/typecheck/rust-tyty-subst.h          | 17 +++++-
 gcc/rust/typecheck/rust-tyty.cc               | 23 +++++---
 gcc/rust/typecheck/rust-tyty.h                | 27 ++++++---
 12 files changed, 151 insertions(+), 53 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 0ca59dea899..6b4141a4270 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -96,6 +96,16 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 	}
     }
 
+  TyTy::RegionConstraints region_constraints;
+  if (function.has_where_clause ())
+    {
+      for (auto &where_clause_item : function.get_where_clause ().get_items ())
+	{
+	  ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+					   region_constraints);
+	}
+    }
+
   TyTy::BaseType *ret_type = nullptr;
   if (!function.has_return_type ())
     ret_type
@@ -166,7 +176,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
     function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
     std::move (params), ret_type, std::move (substitutions),
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fnType);
   resolved = fnType;
@@ -206,9 +217,11 @@ TypeCheckImplItem::visit (HIR::Function &function)
   if (function.has_generics ())
     resolve_generic_params (function.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+				       region_constraints);
     }
 
   TyTy::BaseType *ret_type = nullptr;
@@ -334,7 +347,8 @@ TypeCheckImplItem::visit (HIR::Function &function)
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     ABI::RUST, std::move (params), ret_type, std::move (substitutions),
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fnType);
   result = fnType;
@@ -389,9 +403,11 @@ TypeCheckImplItem::visit (HIR::TypeAlias &alias)
 
   context->insert_type (alias.get_mappings (), actual_type);
   result = actual_type;
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+				       region_constraints);
     }
 }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 067465ec77a..4d178440775 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -97,6 +97,7 @@ private:
   HIR::ImplBlock *parent;
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
+  TyTy::RegionConstraints region_costraints;
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index eb2698ead28..16b4906a356 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -63,12 +63,15 @@ TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
   TypeCheckItem resolver;
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
+  auto result
     = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   return resolver.resolve_impl_block_self (impl_block);
 }
@@ -81,12 +84,14 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (
   TypeCheckItem resolver;
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolver.resolve_impl_block_substitutions (impl, failed_flag);
+  auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   // now that we have the param mappings we need to query the self type
   TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
@@ -140,9 +145,10 @@ TypeCheckItem::visit (HIR::TypeAlias &alias)
 
   context->insert_type (alias.get_mappings (), actual_type);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
   infered = actual_type;
 }
@@ -156,9 +162,10 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -203,7 +210,8 @@ TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
     TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
     std::move (substitutions), repr,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -218,9 +226,10 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -263,7 +272,8 @@ TypeCheckItem::visit (HIR::StructStruct &struct_decl)
     TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
     std::move (substitutions), repr,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -316,9 +326,10 @@ TypeCheckItem::visit (HIR::Union &union_decl)
   if (union_decl.has_generics ())
     resolve_generic_params (union_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -401,13 +412,15 @@ TypeCheckItem::visit (HIR::ImplBlock &impl_block)
   auto binder_pin = context->push_clean_lifetime_resolver (true);
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolve_impl_block_substitutions (impl_block, failed_flag);
+  auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
       return;
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
 
@@ -427,13 +440,16 @@ TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
 				  HIR::ImplItem &item)
 {
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolve_impl_block_substitutions (impl_block, failed_flag);
+  auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     }
 
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
+
   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
 
   return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
@@ -445,11 +461,13 @@ TypeCheckItem::visit (HIR::Function &function)
   auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
-    resolve_generic_params (function.get_generic_params (), substitutions);
+    resolve_generic_params (function.get_generic_params (),
+			    substitutions); // TODO resolve constraints
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   TyTy::BaseType *ret_type = nullptr;
@@ -498,7 +516,8 @@ TypeCheckItem::visit (HIR::Function &function)
     TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
     std::move (substitutions),
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fn_type);
 
@@ -558,7 +577,7 @@ TypeCheckItem::visit (HIR::ExternBlock &extern_block)
     }
 }
 
-std::vector<TyTy::SubstitutionParamMapping>
+std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
 TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
 						 bool &failure_flag)
 {
@@ -566,9 +585,10 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   if (impl_block.has_generics ())
     resolve_generic_params (impl_block.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
@@ -600,7 +620,7 @@ TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   failure_flag = check_for_unconstrained (substitutions, trait_constraints,
 					  impl_constraints, self);
 
-  return substitutions;
+  return {substitutions, region_constraints};
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 73cf9ded1fd..8a90ba051eb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -57,7 +57,8 @@ public:
   void visit (HIR::UseDeclaration &) override {}
 
 protected:
-  std::vector<TyTy::SubstitutionParamMapping>
+  std::pair<std::vector<TyTy::SubstitutionParamMapping>,
+	    TyTy::RegionConstraints>
   resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
 				    bool &failure_flag);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index e7a86b9eee1..0d108c3959c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -889,9 +889,10 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
 }
 
 void
-ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item)
+ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item,
+				 TyTy::RegionConstraints &region_constraints)
 {
-  ResolveWhereClauseItem resolver;
+  ResolveWhereClauseItem resolver (region_constraints);
 
   auto binder_pin = resolver.context->push_lifetime_binder ();
 
@@ -922,6 +923,8 @@ ResolveWhereClauseItem::visit (HIR::LifetimeWhereClauseItem &item)
 	{
 	  rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
 	}
+      region_constraints.region_region.emplace_back (lhs.value (),
+						     rhs_i.value ());
     }
 }
 
@@ -958,7 +961,7 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 	  }
 	  break;
 	  case HIR::TypeParamBound::BoundType::LIFETIME: {
-	    if (binding->is<TyTy::ParamType> ())
+	    if (auto param = binding->try_as<TyTy::ParamType> ())
 	      {
 		auto *b = static_cast<HIR::Lifetime *> (bound.get ());
 		auto region = context->lookup_and_resolve_lifetime (*b);
@@ -967,6 +970,8 @@ ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 		    rust_error_at (UNKNOWN_LOCATION,
 				   "failed to resolve lifetime");
 		  }
+		region_constraints.type_region.emplace_back (param,
+							     region.value ());
 	      }
 	  }
 	  break;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 31b486958f4..3083a94f97b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -115,15 +115,21 @@ private:
 
 class ResolveWhereClauseItem : public TypeCheckBase
 {
+  // pair(a, b) => a: b
+  TyTy::RegionConstraints &region_constraints;
+
 public:
-  static void Resolve (HIR::WhereClauseItem &item);
+  static void Resolve (HIR::WhereClauseItem &item,
+		       TyTy::RegionConstraints &region_constraints);
 
 protected:
   void visit (HIR::LifetimeWhereClauseItem &item);
   void visit (HIR::TypeBoundWhereClauseItem &item);
 
 private:
-  ResolveWhereClauseItem () : TypeCheckBase () {}
+  ResolveWhereClauseItem (TyTy::RegionConstraints &region_constraints)
+    : region_constraints (region_constraints)
+  {}
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 68d9681485a..2b7868685d4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -189,6 +189,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
   std::vector<TyTy::SubstitutionParamMapping> substitutions
     = inherited_substitutions;
 
+  TyTy::RegionConstraints region_constraints;
   HIR::TraitFunctionDecl &function = fn.get_decl ();
   if (function.has_generics ())
     {
@@ -224,6 +225,13 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 	}
     }
 
+  if (function.has_where_clause ())
+    {
+      for (auto &where_clause_item : function.get_where_clause ().get_items ())
+	ResolveWhereClauseItem::Resolve (*where_clause_item,
+					 region_constraints);
+    }
+
   TyTy::BaseType *ret_type = nullptr;
   if (!function.has_return_type ())
     ret_type = TyTy::TupleType::get_unit_type (fn.get_mappings ().get_hirid ());
@@ -336,7 +344,8 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     ABI::RUST, std::move (params), ret_type, substitutions,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
   context->insert_type (fn.get_mappings (), resolved);
   return resolved;
 }
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 066fe4781ed..f37cf50d53c 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -306,7 +306,7 @@ namespace TyTy {
 TypeBoundPredicate::TypeBoundPredicate (
   const Resolver::TraitReference &trait_reference, BoundPolarity polarity,
   location_t locus)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
     error_flag (false), polarity (polarity)
 {
@@ -324,7 +324,7 @@ TypeBoundPredicate::TypeBoundPredicate (
 TypeBoundPredicate::TypeBoundPredicate (
   DefId reference, std::vector<SubstitutionParamMapping> subst,
   BoundPolarity polarity, location_t locus)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (reference), locus (locus), error_flag (false),
     polarity (polarity)
 {
@@ -340,13 +340,13 @@ TypeBoundPredicate::TypeBoundPredicate (
 }
 
 TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (UNKNOWN_DEFID), locus (UNDEF_LOCATION), error_flag (true),
     polarity (BoundPolarity::RegularBound)
 {}
 
 TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (other.reference), locus (other.locus),
     error_flag (other.error_flag), polarity (other.polarity)
 {
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index fcb09d507a8..0a8340e317d 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -440,8 +440,9 @@ SubstitutionArgumentMappings::trait_item_mode () const
 
 SubstitutionRef::SubstitutionRef (
   std::vector<SubstitutionParamMapping> substitutions,
-  SubstitutionArgumentMappings arguments)
-  : substitutions (substitutions), used_arguments (arguments)
+  SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
+  : substitutions (substitutions), used_arguments (arguments),
+    region_constraints (region_constraints)
 {}
 
 bool
@@ -588,6 +589,12 @@ SubstitutionRef::get_used_arguments () const
   return used_arguments;
 }
 
+const RegionConstraints &
+SubstitutionRef::get_region_constraints () const
+{
+  return region_constraints;
+}
+
 SubstitutionArgumentMappings
 SubstitutionRef::get_mappings_from_generic_args (
   HIR::GenericArgs &args, const std::vector<Region> &regions)
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index dbabff3d449..562267cd059 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -30,8 +30,17 @@
 namespace Rust {
 namespace TyTy {
 
-class BaseType;
 class ParamType;
+
+struct RegionConstraints
+{
+  /** 'a: 'b */
+  std::vector<std::pair<Region, Region>> region_region;
+  /** T: 'a */
+  std::vector<std::pair<ParamType *, Region>> type_region;
+};
+
+class BaseType;
 class SubstitutionArgumentMappings;
 class SubstitutionParamMapping
 {
@@ -249,7 +258,8 @@ class SubstitutionRef
 {
 public:
   SubstitutionRef (std::vector<SubstitutionParamMapping> substitutions,
-		   SubstitutionArgumentMappings arguments);
+		   SubstitutionArgumentMappings arguments,
+		   RegionConstraints region_constraints);
 
   bool has_substitutions () const;
 
@@ -404,9 +414,12 @@ public:
 
   WARN_UNUSED_RESULT tl::optional<SubstitutionArg> get_arg_at (size_t i) const;
 
+  const RegionConstraints &get_region_constraints () const;
+
 protected:
   std::vector<SubstitutionParamMapping> substitutions;
   SubstitutionArgumentMappings used_arguments;
+  RegionConstraints region_constraints;
 };
 
 } // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 890d079d67f..a8d358161fc 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -596,6 +596,7 @@ BaseType::monomorphized_clone () const
 			 fn->get_identifier (), fn->ident, fn->get_flags (),
 			 fn->get_abi (), std::move (cloned_params), retty,
 			 fn->clone_substs (), fn->get_substitution_arguments (),
+			 fn->get_region_constraints (),
 			 fn->get_combined_refs ());
     }
   else if (auto fn = x->try_as<const FnPtr> ())
@@ -620,6 +621,7 @@ BaseType::monomorphized_clone () const
 			  adt->get_adt_kind (), cloned_variants,
 			  adt->clone_substs (), adt->get_repr_options (),
 			  adt->get_used_arguments (),
+			  adt->get_region_constraints (),
 			  adt->get_combined_refs ());
     }
   else
@@ -1639,7 +1641,7 @@ ADTType::clone () const
   return new ADTType (get_ref (), get_ty_ref (), identifier, ident,
 		      get_adt_kind (), cloned_variants, clone_substs (),
 		      get_repr_options (), used_arguments,
-		      get_combined_refs ());
+		      get_region_constraints (), get_combined_refs ());
 }
 
 static bool
@@ -1958,7 +1960,8 @@ FnType::clone () const
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
 		     ident, flags, abi, std::move (cloned_params),
 		     get_return_type ()->clone (), clone_substs (),
-		     get_substitution_arguments (), get_combined_refs ());
+		     get_substitution_arguments (), get_region_constraints (),
+		     get_combined_refs ());
 }
 
 FnType *
@@ -3573,11 +3576,13 @@ PlaceholderType::is_equal (const BaseType &other) const
 ProjectionType::ProjectionType (
   HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item,
   std::vector<SubstitutionParamMapping> subst_refs,
-  SubstitutionArgumentMappings generic_arguments, std::set<HirId> refs)
+  SubstitutionArgumentMappings generic_arguments,
+  RegionConstraints region_constraints, std::set<HirId> refs)
   : BaseType (ref, ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
-	      refs),
-    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+	      std::move (refs)),
+    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		     std::move (region_constraints)),
     base (base), trait (trait), item (item)
 {}
 
@@ -3585,11 +3590,13 @@ ProjectionType::ProjectionType (
   HirId ref, HirId ty_ref, BaseType *base,
   const Resolver::TraitReference *trait, DefId item,
   std::vector<SubstitutionParamMapping> subst_refs,
-  SubstitutionArgumentMappings generic_arguments, std::set<HirId> refs)
+  SubstitutionArgumentMappings generic_arguments,
+  RegionConstraints region_constraints, std::set<HirId> refs)
   : BaseType (ref, ty_ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
 	      refs),
-    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		     std::move (region_constraints)),
     base (base), trait (trait), item (item)
 {}
 
@@ -3640,7 +3647,7 @@ ProjectionType::clone () const
 {
   return new ProjectionType (get_ref (), get_ty_ref (), base->clone (), trait,
 			     item, clone_substs (), used_arguments,
-			     get_combined_refs ());
+			     region_constraints, get_combined_refs ());
 }
 
 ProjectionType *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 7384c402f4e..570a57bff01 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -650,9 +650,11 @@ public:
 	   std::vector<SubstitutionParamMapping> subst_refs,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind)
   {}
 
@@ -661,9 +663,11 @@ public:
 	   std::vector<SubstitutionParamMapping> subst_refs,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind)
   {}
 
@@ -672,9 +676,11 @@ public:
 	   std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind),
       repr (repr)
   {}
@@ -774,9 +780,11 @@ public:
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
 	  SubstitutionArgumentMappings substitution_argument_mappings,
+	  RegionConstraints region_constraints,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
+		       region_constraints),
       params (std::move (params)), type (type), flags (flags),
       identifier (identifier), id (id), abi (abi)
   {
@@ -789,9 +797,11 @@ public:
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
 	  SubstitutionArgumentMappings substitution_argument_mappings,
+	  RegionConstraints region_constraints,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
+		       region_constraints),
       params (params), type (type), flags (flags), identifier (identifier),
       id (id), abi (abi)
   {
@@ -962,7 +972,8 @@ public:
 	       = std::vector<TypeBoundPredicate> ())
     : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()),
+		       SubstitutionArgumentMappings::error (),
+		       {}), // TODO: check region constraints
       parameters (parameters), result_type (std::move (result_type)), id (id),
       captures (captures)
   {
@@ -980,7 +991,7 @@ public:
 	       = std::vector<TypeBoundPredicate> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()), // TODO
+		       SubstitutionArgumentMappings::error (), {}), // TODO
       parameters (parameters), result_type (std::move (result_type)), id (id),
       captures (captures)
   {
@@ -1534,6 +1545,7 @@ public:
 		  std::vector<SubstitutionParamMapping> subst_refs,
 		  SubstitutionArgumentMappings generic_arguments
 		  = SubstitutionArgumentMappings::error (),
+		  RegionConstraints region_constraints = {},
 		  std::set<HirId> refs = std::set<HirId> ());
 
   ProjectionType (HirId ref, HirId ty_ref, BaseType *base,
@@ -1541,6 +1553,7 @@ public:
 		  std::vector<SubstitutionParamMapping> subst_refs,
 		  SubstitutionArgumentMappings generic_arguments
 		  = SubstitutionArgumentMappings::error (),
+		  RegionConstraints region_constraints = {},
 		  std::set<HirId> refs = std::set<HirId> ());
 
   void accept_vis (TyVisitor &vis) override;
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 08/25] gccrs: TyTy: Store reference to type before any substitutions
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (5 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 07/25] gccrs: TyTy: Store region constraints arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 09/25] gccrs: Set the default ABI to C for extern blocks and extern functions arthur.cohen
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Jakub Dupak

From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-tyty.cc (BaseType::BaseType): Store orig ref.
	(BaseType::get_orig_ref): Add getter.
	* typecheck/rust-tyty.h: Store orig ref.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 gcc/rust/typecheck/rust-tyty.cc | 10 ++++++++--
 gcc/rust/typecheck/rust-tyty.h  |  3 +++
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index a8d358161fc..d81311eed6e 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -140,14 +140,15 @@ is_primitive_type_kind (TypeKind kind)
 BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
 		    std::set<HirId> refs)
   : TypeBoundsMappings ({}), kind (kind), ref (ref), ty_ref (ty_ref),
-    combined (refs), ident (ident), mappings (Analysis::Mappings::get ())
+    orig_ref (ref), combined (refs), ident (ident),
+    mappings (Analysis::Mappings::get ())
 {}
 
 BaseType::BaseType (HirId ref, HirId ty_ref, TypeKind kind, RustIdent ident,
 		    std::vector<TypeBoundPredicate> specified_bounds,
 		    std::set<HirId> refs)
   : TypeBoundsMappings (specified_bounds), kind (kind), ref (ref),
-    ty_ref (ty_ref), combined (refs), ident (ident),
+    ty_ref (ty_ref), orig_ref (ref), combined (refs), ident (ident),
     mappings (Analysis::Mappings::get ())
 {}
 
@@ -178,6 +179,11 @@ BaseType::set_ty_ref (HirId id)
 {
   ty_ref = id;
 }
+HirId
+BaseType::get_orig_ref () const
+{
+  return orig_ref;
+}
 
 bool
 BaseType::is_equal (const BaseType &other) const
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 570a57bff01..5d4eab42a91 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -99,6 +99,8 @@ public:
   HirId get_ty_ref () const;
   void set_ty_ref (HirId id);
 
+  HirId get_orig_ref () const;
+
   virtual void accept_vis (TyVisitor &vis) = 0;
   virtual void accept_vis (TyConstVisitor &vis) const = 0;
 
@@ -243,6 +245,7 @@ protected:
   TypeKind kind;
   HirId ref;
   HirId ty_ref;
+  const HirId orig_ref;
   std::set<HirId> combined;
   RustIdent ident;
 
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 09/25] gccrs: Set the default ABI to C for extern blocks and extern functions
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (6 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 08/25] gccrs: TyTy: Store reference to type before any substitutions arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 10/25] gccrs: add testcase to prove issue has already been fixed arthur.cohen
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Nobel Singh

From: Nobel Singh <nobel2073@gmail.com>

Previously, the default ABI was set to Rust, which is not correct for
extern blocks and extern functions. This patch changes the default
ABI to C for these cases.

gcc/rust/ChangeLog:

	* hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_qualifiers):
	Change default ABI to C for extern functions
	(ASTLoweringBase::lower_extern_block): Likewise

Signed-off-by: Nobel Singh <nobel2073@gmail.com>
---
 gcc/rust/hir/rust-ast-lower-base.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 748cec74829..19f20885209 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -718,8 +718,8 @@ ASTLoweringBase::lower_qualifiers (const AST::FunctionQualifiers &qualifiers)
   Unsafety unsafety
     = qualifiers.is_unsafe () ? Unsafety::Unsafe : Unsafety::Normal;
   bool has_extern = qualifiers.is_extern ();
+  ABI abi = has_extern ? ABI::C : ABI::RUST;
 
-  ABI abi = ABI::RUST;
   if (qualifiers.has_abi ())
     {
       const std::string &extern_abi = qualifiers.get_extern_abi ();
@@ -965,7 +965,7 @@ ASTLoweringBase::lower_extern_block (AST::ExternBlock &extern_block)
       extern_items.push_back (std::unique_ptr<HIR::ExternalItem> (lowered));
     }
 
-  ABI abi = ABI::RUST;
+  ABI abi = ABI::C;
   if (extern_block.has_abi ())
     {
       const std::string &extern_abi = extern_block.get_abi ();
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 10/25] gccrs: add testcase to prove issue has already been fixed
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (7 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 09/25] gccrs: Set the default ABI to C for extern blocks and extern functions arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 11/25] gccrs: add test cases to prove type inference is working arthur.cohen
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

Fixes #1483

gcc/testsuite/ChangeLog:

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

diff --git a/gcc/testsuite/rust/compile/issue-1483.rs b/gcc/testsuite/rust/compile/issue-1483.rs
new file mode 100644
index 00000000000..eda7e139283
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1483.rs
@@ -0,0 +1,28 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub fn takes_fn_generic<F: FnOnce(i32) -> i32>(a: i32, f: F) -> i32 {
+    f(a)
+}
+
+pub fn takes_fn_generic_where<F>(a: i32, f: F) -> i32
+where
+    F: FnOnce(i32) -> i32,
+{
+    f(a)
+}
+
+pub fn test() {
+    let foo = |x: i32| -> i32 { x + 1 };
+
+    takes_fn_generic(1, foo);
+    takes_fn_generic_where(2, foo);
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 11/25] gccrs: add test cases to prove type inference is working
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (8 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 10/25] gccrs: add testcase to prove issue has already been fixed arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 12/25] gccrs: Fix ICE accessing empty vector without check arthur.cohen
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

Fixes #2772

gcc/testsuite/ChangeLog:

	* rust/compile/issue-2772-1.rs: New test.
	* rust/compile/issue-2772-2.rs: New test.
---
 gcc/testsuite/rust/compile/issue-2772-1.rs | 20 ++++++++++++++++++++
 gcc/testsuite/rust/compile/issue-2772-2.rs | 20 ++++++++++++++++++++
 2 files changed, 40 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-2772-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2772-2.rs

diff --git a/gcc/testsuite/rust/compile/issue-2772-1.rs b/gcc/testsuite/rust/compile/issue-2772-1.rs
new file mode 100644
index 00000000000..69977db0bfb
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2772-1.rs
@@ -0,0 +1,20 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Pair<'a, T, U>
+where
+    T: 'a,
+    U: 'a,
+{
+    left: T,
+    right: U,
+}
+
+pub fn test<'a>() {
+    let a: i32 = 50;
+    let x = Pair {
+        left: &&a,
+        right: &a,
+    };
+}
diff --git a/gcc/testsuite/rust/compile/issue-2772-2.rs b/gcc/testsuite/rust/compile/issue-2772-2.rs
new file mode 100644
index 00000000000..b05f2b1dc2b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2772-2.rs
@@ -0,0 +1,20 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Pair<'a, T, U>
+where
+    T: 'a,
+    U: 'a,
+{
+    left: T,
+    right: U,
+}
+
+pub fn test<'a>() {
+    let a: i32 = 50;
+    let x = Pair::<&'_ _, &'_ _> {
+        left: &&a,
+        right: &a,
+    };
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 12/25] gccrs: Fix ICE accessing empty vector without check
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (9 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 11/25] gccrs: add test cases to prove type inference is working arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-07 11:43 ` [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg arthur.cohen
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

Fixes #2747

gcc/rust/ChangeLog:

	* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_mappings_from_generic_args): fix

gcc/testsuite/ChangeLog:

	* rust/compile/issue-2747.rs: New test.
---
 gcc/rust/typecheck/rust-tyty-subst.cc    |  3 ++-
 gcc/testsuite/rust/compile/issue-2747.rs | 31 ++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2747.rs

diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index 0a8340e317d..5a753566d48 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -660,7 +660,8 @@ SubstitutionRef::get_mappings_from_generic_args (
   if (args.get_type_args ().size () + offs > substitutions.size ())
     {
       rich_location r (line_table, args.get_locus ());
-      r.add_range (substitutions.front ().get_param_locus ());
+      if (!substitutions.empty ())
+	r.add_range (substitutions.front ().get_param_locus ());
 
       rust_error_at (
 	r,
diff --git a/gcc/testsuite/rust/compile/issue-2747.rs b/gcc/testsuite/rust/compile/issue-2747.rs
new file mode 100644
index 00000000000..a9c09e7372f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2747.rs
@@ -0,0 +1,31 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    #[lang = "fn_once_output"]
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+struct Foo<'a, 'b: 'a> {
+    x: &'a i32,
+    y: &'a i32,
+    a: &'b i32,
+    q: &'a [&'b i32],
+}
+
+pub fn test<'x, 'y>(f: Foo<'x, 'y, ()>) {
+    // { dg-error "generic item takes at most 0 type arguments but 1 were supplied" "" { target *-*-* } .-1 }
+    let x = 5;
+    let y = 6;
+    let z = 7;
+    type F<'a, 'b> = fn(&'a i32, &'b i32) -> i32;
+    let f = Foo {
+        x: &x,
+        y: &y,
+        a: &z,
+        q: &[&x, &y],
+    };
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (10 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 12/25] gccrs: Fix ICE accessing empty vector without check arthur.cohen
@ 2024-02-07 11:43 ` arthur.cohen
  2024-02-09 10:03   ` Jakub Jelinek
  2024-02-07 11:44 ` [COMMITTED 14/25] gccrs: remove similar hack in type paths as we had in path expressions arthur.cohen
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

This patch introduces one regression because generics are getting better
understood over time. The code here used to apply generics with the same
symbol from previous segments which was a bit of a hack with out limited
inference variable support. The regression looks like it will be related
to another issue which needs to default integer inference variables much
more aggresivly to default integer.

Fixes #2723

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): remove hack

gcc/testsuite/ChangeLog:

	* rust/compile/issue-1773.rs: Moved to...
	* rust/compile/issue-1773.rs.bak: ...here.
	* rust/compile/issue-2723-1.rs: New test.
	* rust/compile/issue-2723-2.rs: New test.
---
 .../typecheck/rust-hir-type-check-path.cc     | 21 ++-----------------
 .../{issue-1773.rs => issue-1773.rs.bak}      |  0
 gcc/testsuite/rust/compile/issue-2723-1.rs    | 14 +++++++++++++
 gcc/testsuite/rust/compile/issue-2723-2.rs    | 14 +++++++++++++
 4 files changed, 30 insertions(+), 19 deletions(-)
 rename gcc/testsuite/rust/compile/{issue-1773.rs => issue-1773.rs.bak} (100%)
 create mode 100644 gcc/testsuite/rust/compile/issue-2723-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-2723-2.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index ea7d8422980..ad31fb74a80 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -456,27 +456,10 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 	    }
 	}
 
-      if (tyseg->needs_generic_substitutions ())
-	{
-	  if (!prev_segment->needs_generic_substitutions ())
-	    {
-	      auto used_args_in_prev_segment
-		= GetUsedSubstArgs::From (prev_segment);
-
-	      if (!used_args_in_prev_segment.is_error ())
-		{
-		  if (SubstMapperInternal::mappings_are_bound (
-			tyseg, used_args_in_prev_segment))
-		    {
-		      tyseg = SubstMapperInternal::Resolve (
-			tyseg, used_args_in_prev_segment);
-		    }
-		}
-	    }
-	}
-
       if (seg.has_generic_args ())
 	{
+	  rust_debug_loc (seg.get_locus (), "applying segment generics: %s",
+			  tyseg->as_string ().c_str ());
 	  tyseg
 	    = SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
 				    context->regions_from_generic_args (
diff --git a/gcc/testsuite/rust/compile/issue-1773.rs b/gcc/testsuite/rust/compile/issue-1773.rs.bak
similarity index 100%
rename from gcc/testsuite/rust/compile/issue-1773.rs
rename to gcc/testsuite/rust/compile/issue-1773.rs.bak
diff --git a/gcc/testsuite/rust/compile/issue-2723-1.rs b/gcc/testsuite/rust/compile/issue-2723-1.rs
new file mode 100644
index 00000000000..261956de42e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2723-1.rs
@@ -0,0 +1,14 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+struct S<T>(T);
+
+impl S<i32> {
+    fn f<S>(t: S) -> S {
+        t
+    }
+}
+
+pub fn main() {
+    S::<i32>::f::<i32>(0);
+}
diff --git a/gcc/testsuite/rust/compile/issue-2723-2.rs b/gcc/testsuite/rust/compile/issue-2723-2.rs
new file mode 100644
index 00000000000..c7609d1e14d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2723-2.rs
@@ -0,0 +1,14 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+struct S<T1, T2>(T1, T2);
+
+impl S<i32, i32> {
+    fn f<S>(t: S) -> S {
+        t
+    }
+}
+
+pub fn main() {
+    S::<i32, i32>::f::<i32>(0);
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 14/25] gccrs: remove similar hack in type paths as we had in path expressions
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (11 preceding siblings ...)
  2024-02-07 11:43 ` [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 15/25] gccrs: refactor inference variable computation into a seperate method arthur.cohen
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

This keeps the resolution code in line with paths.

Addresses #2723

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-type.cc: remove hack
---
 gcc/rust/typecheck/rust-hir-type-check-type.cc | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 0d108c3959c..74a12c4b011 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -572,22 +572,6 @@ TypeCheckType::resolve_segments (
     }
 
   context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
-  if (tyseg->needs_generic_substitutions ())
-    {
-      // location_t locus = segments.back ()->get_locus ();
-      if (!prev_segment->needs_generic_substitutions ())
-	{
-	  auto used_args_in_prev_segment
-	    = GetUsedSubstArgs::From (prev_segment);
-	  if (!used_args_in_prev_segment.is_error ())
-	    tyseg
-	      = SubstMapperInternal::Resolve (tyseg, used_args_in_prev_segment);
-	}
-
-      if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
-	return new TyTy::ErrorType (expr_id);
-    }
-
   rust_assert (resolved_node_id != UNKNOWN_NODEID);
 
   // lookup if the name resolver was able to canonically resolve this or not
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 15/25] gccrs: refactor inference variable computation into a seperate method
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (12 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 14/25] gccrs: remove similar hack in type paths as we had in path expressions arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 16/25] gccrs: Move the Implementation of implitem lowering into its own file arthur.cohen
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check.cc (TypeResolution::Resolve): refactor
	* typecheck/rust-hir-type-check.h: new prototype
	* typecheck/rust-typecheck-context.cc (TypeCheckContext::compute_inference_variables): x
---
 gcc/rust/typecheck/rust-hir-type-check.cc    | 34 +---------------
 gcc/rust/typecheck/rust-hir-type-check.h     |  2 +
 gcc/rust/typecheck/rust-typecheck-context.cc | 41 ++++++++++++++++++++
 3 files changed, 44 insertions(+), 33 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 2b7868685d4..0bc72d3f73f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -76,40 +76,8 @@ TypeResolution::Resolve (HIR::Crate &crate)
   if (saw_errors ())
     return;
 
-  auto mappings = Analysis::Mappings::get ();
   auto context = TypeCheckContext::get ();
-
-  // default inference variables if possible
-  context->iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
-    // nothing to do
-    if (ty->get_kind () != TyTy::TypeKind::INFER)
-      return true;
-
-    TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
-    TyTy::BaseType *default_type;
-    bool ok = infer_var->default_type (&default_type);
-    if (!ok)
-      {
-	rust_error_at (mappings->lookup_location (id), ErrorCode::E0282,
-		       "type annotations needed");
-	return true;
-      }
-    else
-      {
-	auto result
-	  = unify_site (id, TyTy::TyWithLocation (ty),
-			TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
-	rust_assert (result);
-	rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
-	result->set_ref (id);
-	context->insert_type (
-	  Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
-				 UNKNOWN_LOCAL_DEFID),
-	  result);
-      }
-
-    return true;
-  });
+  context->compute_inference_variables (true);
 }
 
 // rust-hir-trait-ref.h
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 3d66e29052f..52c84fc4435 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -231,6 +231,8 @@ public:
   WARN_UNUSED_RESULT std::vector<TyTy::Region>
   regions_from_generic_args (const HIR::GenericArgs &args) const;
 
+  void compute_inference_variables (bool error);
+
 private:
   TypeCheckContext ();
 
diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc
index 1f4a5a35626..9059e0261b3 100644
--- a/gcc/rust/typecheck/rust-typecheck-context.cc
+++ b/gcc/rust/typecheck/rust-typecheck-context.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-hir-type-check.h"
+#include "rust-type-util.h"
 
 namespace Rust {
 namespace Resolver {
@@ -576,6 +577,46 @@ TypeCheckContext::regions_from_generic_args (const HIR::GenericArgs &args) const
   return regions;
 }
 
+void
+TypeCheckContext::compute_inference_variables (bool error)
+{
+  auto mappings = Analysis::Mappings::get ();
+
+  // default inference variables if possible
+  iterate ([&] (HirId id, TyTy::BaseType *ty) mutable -> bool {
+    // nothing to do
+    if (ty->get_kind () != TyTy::TypeKind::INFER)
+      return true;
+
+    TyTy::InferType *infer_var = static_cast<TyTy::InferType *> (ty);
+    TyTy::BaseType *default_type;
+
+    rust_debug_loc (mappings->lookup_location (id),
+		    "trying to default infer-var: %s",
+		    infer_var->as_string ().c_str ());
+    bool ok = infer_var->default_type (&default_type);
+    if (!ok)
+      {
+	if (error)
+	  rust_error_at (mappings->lookup_location (id), ErrorCode::E0282,
+			 "type annotations needed");
+	return true;
+      }
+
+    auto result
+      = unify_site (id, TyTy::TyWithLocation (ty),
+		    TyTy::TyWithLocation (default_type), UNDEF_LOCATION);
+    rust_assert (result);
+    rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
+    result->set_ref (id);
+    insert_type (Analysis::NodeMapping (mappings->get_current_crate (), 0, id,
+					UNKNOWN_LOCAL_DEFID),
+		 result);
+
+    return true;
+  });
+}
+
 // TypeCheckContextItem
 
 TypeCheckContextItem::Item::Item (HIR::Function *item) : item (item) {}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 16/25] gccrs: Move the Implementation of implitem lowering into its own file.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (13 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 15/25] gccrs: refactor inference variable computation into a seperate method arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 17/25] gccrs: Add testcase to show issue is already fixed arthur.cohen
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Nobel Singh, Nobel Singh

From: Nobel Singh <nobel2073@gmail.com>

This patch moves the implementation of the implitem lowering
from rust-ast-lower-implitem.h into the rust-ast-lower-implitem.cc
file.

gcc/rust/ChangeLog:

	* Make-lang.in: Add rust-ast-lower-implitem.cc to list of objects.
	* hir/rust-ast-lower-implitem.h (RUST_AST_LOWER_IMPLITEM_H): Remove
	implementation.
	* hir/rust-ast-lower-implitem.cc: Copy implementation from header.

Signed-off-by: Nobel Singh <Nobel2073@gmail.com>
---
 gcc/rust/Make-lang.in                   |   1 +
 gcc/rust/hir/rust-ast-lower-implitem.cc | 428 ++++++++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-implitem.h  | 406 +---------------------
 3 files changed, 439 insertions(+), 396 deletions(-)
 create mode 100644 gcc/rust/hir/rust-ast-lower-implitem.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index bdaef41c419..4d646018792 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -111,6 +111,7 @@ GRS_OBJS = \
     rust/rust-ast-lower-base.o \
     rust/rust-ast-lower-pattern.o \
     rust/rust-ast-lower-item.o \
+    rust/rust-ast-lower-implitem.o \
     rust/rust-ast-lower-expr.o \
     rust/rust-ast-lower-type.o \
     rust/rust-ast-lower-stmt.o \
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
new file mode 100644
index 00000000000..98db1dccd7c
--- /dev/null
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -0,0 +1,428 @@
+// 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
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-lower-implitem.h"
+#include "rust-ast-lower.h"
+#include "rust-ast-lower-type.h"
+#include "rust-ast-lower-expr.h"
+#include "rust-ast-lower-pattern.h"
+#include "rust-ast-lower-block.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace HIR {
+
+HIR::ImplItem *
+ASTLowerImplItem::translate (AST::AssociatedItem *item, HirId parent_impl_id)
+{
+  ASTLowerImplItem resolver;
+  item->accept_vis (resolver);
+
+  if (resolver.translated != nullptr)
+    {
+      rust_assert (resolver.item_cast != nullptr);
+
+      auto id = resolver.translated->get_impl_mappings ().get_hirid ();
+      auto defid = resolver.translated->get_impl_mappings ().get_defid ();
+      auto locus = resolver.translated->get_locus ();
+
+      resolver.handle_outer_attributes (*resolver.item_cast);
+      resolver.mappings->insert_hir_implitem (parent_impl_id,
+					      resolver.translated);
+      resolver.mappings->insert_location (id, locus);
+      resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
+    }
+
+  return resolver.translated;
+}
+
+void
+ASTLowerImplItem::visit (AST::TypeAlias &alias)
+{
+  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+  HIR::WhereClause where_clause (std::move (where_clause_items));
+  HIR::Visibility vis = translate_visibility (alias.get_visibility ());
+
+  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+  if (alias.has_generics ())
+    generic_params = lower_generic_params (alias.get_generic_params ());
+
+  HIR::Type *existing_type
+    = ASTLoweringType::translate (alias.get_type_aliased ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, alias.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  auto type_alias
+    = new HIR::TypeAlias (mapping, alias.get_new_type_name (),
+			  std::move (generic_params), std::move (where_clause),
+			  std::unique_ptr<HIR::Type> (existing_type),
+			  std::move (vis), alias.get_outer_attrs (),
+			  alias.get_locus ());
+
+  translated = type_alias;
+  item_cast = type_alias;
+}
+
+void
+ASTLowerImplItem::visit (AST::ConstantItem &constant)
+{
+  HIR::Visibility vis = translate_visibility (constant.get_visibility ());
+
+  HIR::Type *type
+    = ASTLoweringType::translate (constant.get_type ().get (), true);
+  HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  auto translated_constant
+    = new HIR::ConstantItem (mapping, constant.get_identifier (), vis,
+			     std::unique_ptr<HIR::Type> (type),
+			     std::unique_ptr<HIR::Expr> (expr),
+			     constant.get_outer_attrs (),
+			     constant.get_locus ());
+
+  translated = translated_constant;
+  item_cast = translated_constant;
+}
+
+void
+ASTLowerImplItem::visit (AST::Function &function)
+{
+  // ignore for now and leave empty
+  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+  for (auto &item : function.get_where_clause ().get_items ())
+    {
+      HIR::WhereClauseItem *i
+	= ASTLowerWhereClauseItem::translate (*item.get ());
+      where_clause_items.push_back (std::unique_ptr<HIR::WhereClauseItem> (i));
+    }
+
+  HIR::WhereClause where_clause (std::move (where_clause_items));
+  HIR::FunctionQualifiers qualifiers
+    = lower_qualifiers (function.get_qualifiers ());
+  HIR::Visibility vis = translate_visibility (function.get_visibility ());
+
+  // need
+  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+  if (function.has_generics ())
+    {
+      generic_params = lower_generic_params (function.get_generic_params ());
+    }
+  Identifier function_name = function.get_function_name ();
+  location_t locus = function.get_locus ();
+
+  HIR::SelfParam self_param = HIR::SelfParam::error ();
+  if (function.has_self_param ())
+    self_param = lower_self (function.get_self_param ());
+
+  std::unique_ptr<HIR::Type> return_type
+    = function.has_return_type () ? std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (function.get_return_type ().get ()))
+				  : nullptr;
+
+  std::vector<HIR::FunctionParam> function_params;
+  for (auto &p : function.get_function_params ())
+    {
+      if (p->is_self () || p->is_variadic ())
+	continue;
+      auto param = static_cast<AST::FunctionParam *> (p.get ());
+
+      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
+	ASTLoweringPattern::translate (param->get_pattern ().get ()));
+      auto translated_type = std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (param->get_type ().get ()));
+
+      auto crate_num = mappings->get_current_crate ();
+      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
+				     mappings->get_next_hir_id (crate_num),
+				     UNKNOWN_LOCAL_DEFID);
+
+      auto hir_param
+	= HIR::FunctionParam (mapping, std::move (translated_pattern),
+			      std::move (translated_type), param->get_locus ());
+      function_params.push_back (std::move (hir_param));
+    }
+
+  bool terminated = false;
+  std::unique_ptr<HIR::BlockExpr> function_body
+    = std::unique_ptr<HIR::BlockExpr> (
+      ASTLoweringBlock::translate (function.get_definition ()->get (),
+				   &terminated));
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  mappings->insert_location (function_body->get_mappings ().get_hirid (),
+			     function.get_locus ());
+
+  auto fn
+    = new HIR::Function (mapping, std::move (function_name),
+			 std::move (qualifiers), std::move (generic_params),
+			 std::move (function_params), std::move (return_type),
+			 std::move (where_clause), std::move (function_body),
+			 std::move (vis), function.get_outer_attrs (),
+			 std::move (self_param), locus);
+
+  if (!fn->get_self_param ().is_error ())
+    {
+      // insert mappings for self
+      mappings->insert_hir_self_param (&fn->get_self_param ());
+      mappings->insert_location (
+	fn->get_self_param ().get_mappings ().get_hirid (),
+	fn->get_self_param ().get_locus ());
+    }
+
+  // add the mappings for the function params at the end
+  for (auto &param : fn->get_function_params ())
+    {
+      mappings->insert_hir_param (&param);
+      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
+    }
+
+  translated = fn;
+  item_cast = fn;
+}
+
+HIR::TraitItem *
+ASTLowerTraitItem::translate (AST::AssociatedItem *item)
+{
+  ASTLowerTraitItem resolver;
+  item->accept_vis (resolver);
+
+  if (resolver.translated != nullptr)
+    {
+      auto id = resolver.translated->get_mappings ().get_hirid ();
+      auto defid = resolver.translated->get_mappings ().get_defid ();
+      auto locus = resolver.translated->get_trait_locus ();
+
+      resolver.handle_outer_attributes (*resolver.translated);
+      resolver.mappings->insert_hir_trait_item (resolver.translated);
+      resolver.mappings->insert_location (id, locus);
+      resolver.mappings->insert_defid_mapping (defid, resolver.translated);
+    }
+
+  return resolver.translated;
+}
+
+void
+ASTLowerTraitItem::visit (AST::TraitItemFunc &func)
+{
+  AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();
+  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+  HIR::WhereClause where_clause (std::move (where_clause_items));
+  HIR::FunctionQualifiers qualifiers
+    = lower_qualifiers (func.get_trait_function_decl ().get_qualifiers ());
+
+  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+  if (ref.has_generics ())
+    {
+      generic_params = lower_generic_params (ref.get_generic_params ());
+    }
+
+  std::unique_ptr<HIR::Type> return_type
+    = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (ref.get_return_type ().get ()))
+			     : nullptr;
+
+  std::vector<HIR::FunctionParam> function_params;
+  for (auto &p : ref.get_function_params ())
+    {
+      if (p->is_variadic () || p->is_self ())
+	continue;
+
+      auto param = static_cast<AST::FunctionParam *> (p.get ());
+
+      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
+	ASTLoweringPattern::translate (param->get_pattern ().get ()));
+      auto translated_type = std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (param->get_type ().get ()));
+
+      auto crate_num = mappings->get_current_crate ();
+      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
+				     mappings->get_next_hir_id (crate_num),
+				     UNKNOWN_LOCAL_DEFID);
+
+      auto hir_param
+	= HIR::FunctionParam (mapping, std::move (translated_pattern),
+			      std::move (translated_type), param->get_locus ());
+      function_params.push_back (std::move (hir_param));
+    }
+
+  HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
+			       std::move (generic_params),
+			       HIR::SelfParam::error (),
+			       std::move (function_params),
+			       std::move (return_type),
+			       std::move (where_clause));
+  bool terminated = false;
+  std::unique_ptr<HIR::BlockExpr> block_expr
+    = func.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
+	ASTLoweringBlock::translate (func.get_definition ().get (),
+				     &terminated))
+			     : nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, func.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  HIR::TraitItemFunc *trait_item
+    = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr),
+			      func.get_outer_attrs (), func.get_locus ());
+  translated = trait_item;
+
+  // add the mappings for the function params at the end
+  for (auto &param : trait_item->get_decl ().get_function_params ())
+    {
+      mappings->insert_hir_param (&param);
+      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
+    }
+}
+
+void
+ASTLowerTraitItem::visit (AST::TraitItemMethod &method)
+{
+  AST::TraitMethodDecl &ref = method.get_trait_method_decl ();
+
+  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+  HIR::WhereClause where_clause (std::move (where_clause_items));
+  HIR::FunctionQualifiers qualifiers
+    = lower_qualifiers (method.get_trait_method_decl ().get_qualifiers ());
+
+  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+  if (ref.has_generics ())
+    {
+      generic_params = lower_generic_params (ref.get_generic_params ());
+    }
+
+  std::unique_ptr<HIR::Type> return_type
+    = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (ref.get_return_type ().get ()))
+			     : nullptr;
+
+  HIR::SelfParam self_param = lower_self (ref.get_self_param ());
+
+  std::vector<HIR::FunctionParam> function_params;
+  for (auto &p : ref.get_function_params ())
+    {
+      if (p->is_variadic () || p->is_self ())
+	continue;
+
+      auto param = static_cast<AST::FunctionParam *> (p.get ());
+
+      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
+	ASTLoweringPattern::translate (param->get_pattern ().get ()));
+      auto translated_type = std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (param->get_type ().get ()));
+
+      auto crate_num = mappings->get_current_crate ();
+      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
+				     mappings->get_next_hir_id (crate_num),
+				     UNKNOWN_LOCAL_DEFID);
+
+      auto hir_param
+	= HIR::FunctionParam (mapping, std::move (translated_pattern),
+			      std::move (translated_type), param->get_locus ());
+      function_params.push_back (hir_param);
+    }
+
+  HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
+			       std::move (generic_params),
+			       std::move (self_param),
+			       std::move (function_params),
+			       std::move (return_type),
+			       std::move (where_clause));
+
+  bool terminated = false;
+  std::unique_ptr<HIR::BlockExpr> block_expr
+    = method.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
+	ASTLoweringBlock::translate (method.get_definition ().get (),
+				     &terminated))
+			       : nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  HIR::TraitItemFunc *trait_item
+    = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr),
+			      method.get_outer_attrs (), method.get_locus ());
+  translated = trait_item;
+
+  // insert mappings for self
+  mappings->insert_hir_self_param (&self_param);
+  mappings->insert_location (self_param.get_mappings ().get_hirid (),
+			     self_param.get_locus ());
+
+  // add the mappings for the function params at the end
+  for (auto &param : trait_item->get_decl ().get_function_params ())
+    {
+      mappings->insert_hir_param (&param);
+      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
+    }
+}
+
+void
+ASTLowerTraitItem::visit (AST::TraitItemConst &constant)
+{
+  HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
+  HIR::Expr *expr = constant.has_expression ()
+		      ? ASTLoweringExpr::translate (constant.get_expr ().get ())
+		      : nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  HIR::TraitItemConst *trait_item
+    = new HIR::TraitItemConst (mapping, constant.get_identifier (),
+			       std::unique_ptr<HIR::Type> (type),
+			       std::unique_ptr<HIR::Expr> (expr),
+			       constant.get_outer_attrs (),
+			       constant.get_locus ());
+  translated = trait_item;
+}
+
+void
+ASTLowerTraitItem::visit (AST::TraitItemType &type)
+{
+  std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
+  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));
+
+  HIR::TraitItemType *trait_item
+    = new HIR::TraitItemType (mapping, type.get_identifier (),
+			      std::move (type_param_bounds),
+			      type.get_outer_attrs (), type.get_locus ());
+  translated = trait_item;
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 81dae14cdca..3a266b41ed4 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -19,11 +19,7 @@
 #ifndef RUST_AST_LOWER_IMPLITEM_H
 #define RUST_AST_LOWER_IMPLITEM_H
 
-#include "rust-ast-lower-type.h"
-#include "rust-ast-lower-expr.h"
-#include "rust-ast-lower-pattern.h"
-#include "rust-ast-lower-block.h"
-#include "rust-item.h"
+#include "rust-ast-lower-base.h"
 
 namespace Rust {
 namespace HIR {
@@ -34,179 +30,10 @@ class ASTLowerImplItem : public ASTLoweringBase
 
 public:
   static HIR::ImplItem *translate (AST::AssociatedItem *item,
-				   HirId parent_impl_id)
-  {
-    ASTLowerImplItem resolver;
-    item->accept_vis (resolver);
-
-    if (resolver.translated != nullptr)
-      {
-	rust_assert (resolver.item_cast != nullptr);
-
-	auto id = resolver.translated->get_impl_mappings ().get_hirid ();
-	auto defid = resolver.translated->get_impl_mappings ().get_defid ();
-	auto locus = resolver.translated->get_locus ();
-
-	resolver.handle_outer_attributes (*resolver.item_cast);
-	resolver.mappings->insert_hir_implitem (parent_impl_id,
-						resolver.translated);
-	resolver.mappings->insert_location (id, locus);
-	resolver.mappings->insert_defid_mapping (defid, resolver.item_cast);
-      }
-
-    return resolver.translated;
-  }
-
-  void visit (AST::TypeAlias &alias) override
-  {
-    std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-    HIR::WhereClause where_clause (std::move (where_clause_items));
-    HIR::Visibility vis = translate_visibility (alias.get_visibility ());
-
-    std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-    if (alias.has_generics ())
-      generic_params = lower_generic_params (alias.get_generic_params ());
-
-    HIR::Type *existing_type
-      = ASTLoweringType::translate (alias.get_type_aliased ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, alias.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    auto type_alias = new HIR::TypeAlias (
-      mapping, alias.get_new_type_name (), std::move (generic_params),
-      std::move (where_clause), std::unique_ptr<HIR::Type> (existing_type),
-      std::move (vis), alias.get_outer_attrs (), alias.get_locus ());
-
-    translated = type_alias;
-    item_cast = type_alias;
-  }
-
-  void visit (AST::ConstantItem &constant) override
-  {
-    HIR::Visibility vis = translate_visibility (constant.get_visibility ());
-
-    HIR::Type *type
-      = ASTLoweringType::translate (constant.get_type ().get (), true);
-    HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    auto translated_constant
-      = new HIR::ConstantItem (mapping, constant.get_identifier (), vis,
-			       std::unique_ptr<HIR::Type> (type),
-			       std::unique_ptr<HIR::Expr> (expr),
-			       constant.get_outer_attrs (),
-			       constant.get_locus ());
-    translated = translated_constant;
-    item_cast = translated_constant;
-  }
-
-  void visit (AST::Function &function) override
-  {
-    // ignore for now and leave empty
-    std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-    for (auto &item : function.get_where_clause ().get_items ())
-      {
-	HIR::WhereClauseItem *i
-	  = ASTLowerWhereClauseItem::translate (*item.get ());
-	where_clause_items.push_back (
-	  std::unique_ptr<HIR::WhereClauseItem> (i));
-      }
-
-    HIR::WhereClause where_clause (std::move (where_clause_items));
-    HIR::FunctionQualifiers qualifiers
-      = lower_qualifiers (function.get_qualifiers ());
-    HIR::Visibility vis = translate_visibility (function.get_visibility ());
-
-    // need
-    std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-    if (function.has_generics ())
-      {
-	generic_params = lower_generic_params (function.get_generic_params ());
-      }
-    Identifier function_name = function.get_function_name ();
-    location_t locus = function.get_locus ();
-
-    HIR::SelfParam self_param = HIR::SelfParam::error ();
-    if (function.has_self_param ())
-      self_param = lower_self (function.get_self_param ());
-
-    std::unique_ptr<HIR::Type> return_type
-      = function.has_return_type () ? std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (function.get_return_type ().get ()))
-				    : nullptr;
-
-    std::vector<HIR::FunctionParam> function_params;
-    for (auto &p : function.get_function_params ())
-      {
-	if (p->is_self () || p->is_variadic ())
-	  continue;
-	auto param = static_cast<AST::FunctionParam *> (p.get ());
-
-	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-	  ASTLoweringPattern::translate (param->get_pattern ().get ()));
-	auto translated_type = std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (param->get_type ().get ()));
-
-	auto crate_num = mappings->get_current_crate ();
-	Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
-				       mappings->get_next_hir_id (crate_num),
-				       UNKNOWN_LOCAL_DEFID);
-
-	auto hir_param
-	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
-				std::move (translated_type),
-				param->get_locus ());
-	function_params.push_back (std::move (hir_param));
-      }
-
-    bool terminated = false;
-    std::unique_ptr<HIR::BlockExpr> function_body
-      = std::unique_ptr<HIR::BlockExpr> (
-	ASTLoweringBlock::translate (function.get_definition ()->get (),
-				     &terminated));
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    mappings->insert_location (function_body->get_mappings ().get_hirid (),
-			       function.get_locus ());
-
-    auto fn
-      = new HIR::Function (mapping, std::move (function_name),
-			   std::move (qualifiers), std::move (generic_params),
-			   std::move (function_params), std::move (return_type),
-			   std::move (where_clause), std::move (function_body),
-			   std::move (vis), function.get_outer_attrs (),
-			   std::move (self_param), locus);
-
-    if (!fn->get_self_param ().is_error ())
-      {
-	// insert mappings for self
-	mappings->insert_hir_self_param (&fn->get_self_param ());
-	mappings->insert_location (
-	  fn->get_self_param ().get_mappings ().get_hirid (),
-	  fn->get_self_param ().get_locus ());
-      }
-
-    // add the mappings for the function params at the end
-    for (auto &param : fn->get_function_params ())
-      {
-	mappings->insert_hir_param (&param);
-	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-      }
-
-    translated = fn;
-    item_cast = fn;
-  }
+				   HirId parent_impl_id);
+  void visit (AST::TypeAlias &alias) override;
+  void visit (AST::ConstantItem &constant) override;
+  void visit (AST::Function &function) override;
 
 private:
   ASTLowerImplItem () : translated (nullptr), item_cast (nullptr) {}
@@ -220,224 +47,11 @@ class ASTLowerTraitItem : public ASTLoweringBase
   using Rust::HIR::ASTLoweringBase::visit;
 
 public:
-  static HIR::TraitItem *translate (AST::AssociatedItem *item)
-  {
-    ASTLowerTraitItem resolver;
-    item->accept_vis (resolver);
-
-    if (resolver.translated != nullptr)
-      {
-	auto id = resolver.translated->get_mappings ().get_hirid ();
-	auto defid = resolver.translated->get_mappings ().get_defid ();
-	auto locus = resolver.translated->get_trait_locus ();
-
-	resolver.handle_outer_attributes (*resolver.translated);
-	resolver.mappings->insert_hir_trait_item (resolver.translated);
-	resolver.mappings->insert_location (id, locus);
-	resolver.mappings->insert_defid_mapping (defid, resolver.translated);
-      }
-
-    return resolver.translated;
-  }
-
-  void visit (AST::TraitItemFunc &func) override
-  {
-    AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();
-
-    std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-    HIR::WhereClause where_clause (std::move (where_clause_items));
-    HIR::FunctionQualifiers qualifiers
-      = lower_qualifiers (func.get_trait_function_decl ().get_qualifiers ());
-
-    std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-    if (ref.has_generics ())
-      {
-	generic_params = lower_generic_params (ref.get_generic_params ());
-      }
-
-    std::unique_ptr<HIR::Type> return_type
-      = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (ref.get_return_type ().get ()))
-			       : nullptr;
-
-    std::vector<HIR::FunctionParam> function_params;
-    for (auto &p : ref.get_function_params ())
-      {
-	if (p->is_variadic () || p->is_self ())
-	  continue;
-
-	auto param = static_cast<AST::FunctionParam *> (p.get ());
-
-	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-	  ASTLoweringPattern::translate (param->get_pattern ().get ()));
-	auto translated_type = std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (param->get_type ().get ()));
-
-	auto crate_num = mappings->get_current_crate ();
-	Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
-				       mappings->get_next_hir_id (crate_num),
-				       UNKNOWN_LOCAL_DEFID);
-
-	auto hir_param
-	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
-				std::move (translated_type),
-				param->get_locus ());
-	function_params.push_back (std::move (hir_param));
-      }
-
-    HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
-				 std::move (generic_params),
-				 HIR::SelfParam::error (),
-				 std::move (function_params),
-				 std::move (return_type),
-				 std::move (where_clause));
-    bool terminated = false;
-    std::unique_ptr<HIR::BlockExpr> block_expr
-      = func.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
-	  ASTLoweringBlock::translate (func.get_definition ().get (),
-				       &terminated))
-			       : nullptr;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, func.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    HIR::TraitItemFunc *trait_item
-      = new HIR::TraitItemFunc (mapping, std::move (decl),
-				std::move (block_expr), func.get_outer_attrs (),
-				func.get_locus ());
-    translated = trait_item;
-
-    // add the mappings for the function params at the end
-    for (auto &param : trait_item->get_decl ().get_function_params ())
-      {
-	mappings->insert_hir_param (&param);
-	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-      }
-  }
-
-  void visit (AST::TraitItemMethod &method) override
-  {
-    AST::TraitMethodDecl &ref = method.get_trait_method_decl ();
-
-    std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-    HIR::WhereClause where_clause (std::move (where_clause_items));
-    HIR::FunctionQualifiers qualifiers
-      = lower_qualifiers (method.get_trait_method_decl ().get_qualifiers ());
-
-    std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-    if (ref.has_generics ())
-      {
-	generic_params = lower_generic_params (ref.get_generic_params ());
-      }
-
-    std::unique_ptr<HIR::Type> return_type
-      = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (ref.get_return_type ().get ()))
-			       : nullptr;
-
-    HIR::SelfParam self_param = lower_self (ref.get_self_param ());
-
-    std::vector<HIR::FunctionParam> function_params;
-    for (auto &p : ref.get_function_params ())
-      {
-	if (p->is_variadic () || p->is_self ())
-	  continue;
-
-	auto param = static_cast<AST::FunctionParam *> (p.get ());
-
-	auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-	  ASTLoweringPattern::translate (param->get_pattern ().get ()));
-	auto translated_type = std::unique_ptr<HIR::Type> (
-	  ASTLoweringType::translate (param->get_type ().get ()));
-
-	auto crate_num = mappings->get_current_crate ();
-	Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
-				       mappings->get_next_hir_id (crate_num),
-				       UNKNOWN_LOCAL_DEFID);
-
-	auto hir_param
-	  = HIR::FunctionParam (mapping, std::move (translated_pattern),
-				std::move (translated_type),
-				param->get_locus ());
-	function_params.push_back (hir_param);
-      }
-
-    HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
-				 std::move (generic_params),
-				 std::move (self_param),
-				 std::move (function_params),
-				 std::move (return_type),
-				 std::move (where_clause));
-    bool terminated = false;
-    std::unique_ptr<HIR::BlockExpr> block_expr
-      = method.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
-	  ASTLoweringBlock::translate (method.get_definition ().get (),
-				       &terminated))
-				 : nullptr;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    HIR::TraitItemFunc *trait_item
-      = new HIR::TraitItemFunc (mapping, std::move (decl),
-				std::move (block_expr),
-				method.get_outer_attrs (), method.get_locus ());
-    translated = trait_item;
-
-    // insert mappings for self
-    mappings->insert_hir_self_param (&self_param);
-    mappings->insert_location (self_param.get_mappings ().get_hirid (),
-			       self_param.get_locus ());
-
-    // add the mappings for the function params at the end
-    for (auto &param : trait_item->get_decl ().get_function_params ())
-      {
-	mappings->insert_hir_param (&param);
-	mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-      }
-  }
-
-  void visit (AST::TraitItemConst &constant) override
-  {
-    HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
-    HIR::Expr *expr
-      = constant.has_expression ()
-	  ? ASTLoweringExpr::translate (constant.get_expr ().get ())
-	  : nullptr;
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
-				   mappings->get_next_hir_id (crate_num),
-				   mappings->get_next_localdef_id (crate_num));
-
-    HIR::TraitItemConst *trait_item
-      = new HIR::TraitItemConst (mapping, constant.get_identifier (),
-				 std::unique_ptr<HIR::Type> (type),
-				 std::unique_ptr<HIR::Expr> (expr),
-				 constant.get_outer_attrs (),
-				 constant.get_locus ());
-    translated = trait_item;
-  }
-
-  void visit (AST::TraitItemType &type) override
-  {
-    std::vector<std::unique_ptr<HIR::TypeParamBound> > type_param_bounds;
-
-    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));
-
-    HIR::TraitItemType *trait_item
-      = new HIR::TraitItemType (mapping, type.get_identifier (),
-				std::move (type_param_bounds),
-				type.get_outer_attrs (), type.get_locus ());
-    translated = trait_item;
-  }
+  static HIR::TraitItem *translate (AST::AssociatedItem *item);
+  void visit (AST::TraitItemFunc &func) override;
+  void visit (AST::TraitItemMethod &method) override;
+  void visit (AST::TraitItemConst &constant) override;
+  void visit (AST::TraitItemType &type) override;
 
 private:
   ASTLowerTraitItem () : translated (nullptr) {}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 17/25] gccrs: Add testcase to show issue is already fixed
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (14 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 16/25] gccrs: Move the Implementation of implitem lowering into its own file arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 18/25] gccrs: fix bug in pattern check for tuples arthur.cohen
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

Fixes #2782

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/testsuite/rust/compile/issue-2782.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-2782.rs

diff --git a/gcc/testsuite/rust/compile/issue-2782.rs b/gcc/testsuite/rust/compile/issue-2782.rs
new file mode 100644
index 00000000000..e199c882c86
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2782.rs
@@ -0,0 +1,12 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+struct S<T>(T);
+
+impl S<u8> {
+    fn foo<U>() {}
+}
+
+fn main() {
+    S::foo::<i32>();
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 18/25] gccrs: fix bug in pattern check for tuples
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (15 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 17/25] gccrs: Add testcase to show issue is already fixed arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 19/25] gccrs: Use AssociatedItem in place of TraitItem arthur.cohen
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Philip Herron

From: Philip Herron <herron.philip@googlemail.com>

We can point to generic parent types which means we need to do the shallow
resolve thing that rustc does. We have destructure which is similar to get
what the parameter type points to.

Fixes #2775

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): use destructure

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc |  6 ++++--
 gcc/testsuite/rust/compile/issue-2775.rs          | 11 +++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-2775.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 19f742f2154..c7f29e28b2d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -302,7 +302,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
 	  = *static_cast<HIR::TuplePatternItemsMultiple *> (
 	    pattern.get_items ().get ());
 
-	if (parent->get_kind () != TyTy::TUPLE)
+	auto resolved_parent = parent->destructure ();
+	if (resolved_parent->get_kind () != TyTy::TUPLE)
 	  {
 	    rust_error_at (pattern.get_locus (), "expected %s, found tuple",
 			   parent->as_string ().c_str ());
@@ -312,7 +313,8 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
 	const auto &patterns = ref.get_patterns ();
 	size_t nitems_to_resolve = patterns.size ();
 
-	TyTy::TupleType &par = *static_cast<TyTy::TupleType *> (parent);
+	TyTy::TupleType &par
+	  = *static_cast<TyTy::TupleType *> (resolved_parent);
 	if (patterns.size () != par.get_fields ().size ())
 	  {
 	    emit_pattern_size_error (pattern, par.get_fields ().size (),
diff --git a/gcc/testsuite/rust/compile/issue-2775.rs b/gcc/testsuite/rust/compile/issue-2775.rs
new file mode 100644
index 00000000000..3ad7085785e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2775.rs
@@ -0,0 +1,11 @@
+// { dg-options "-w" }
+#[lang = "sized"]
+pub trait Sized {}
+
+struct Ref<'a, T> {
+    x: &'a T,
+}
+
+pub fn test<'a, 'b, 'c>() {
+    let (_, &&Ref::<(&'_ i32, i32)> { x: &(a, b) }): (i32, &'_ &'b Ref<'b, (&'c i32, i32)>);
+}
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 19/25] gccrs: Use AssociatedItem in place of TraitItem
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (16 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 18/25] gccrs: fix bug in pattern check for tuples arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 20/25] gccrs: Add checks for Trait functions arthur.cohen
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

gcc/rust/ChangeLog:

	* ast/rust-ast.h: Replace TraitItem with AssociatedItem.
	* ast/rust-item.h (class Trait): Likewise.
	* expand/rust-expand-visitor.cc (ExpandVisitor::visit):
	Likewise.
	* parse/rust-parse-impl.h (Parser::parse_trait): Likewise.
	* parse/rust-parse.h: Likewise.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/ast/rust-ast.h                |  6 +++---
 gcc/rust/ast/rust-item.h               | 16 ++++++++--------
 gcc/rust/expand/rust-expand-visitor.cc |  3 ++-
 gcc/rust/parse/rust-parse-impl.h       |  6 +++---
 gcc/rust/parse/rust-parse.h            |  2 +-
 5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index e96ac349733..1422d77eade 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1907,11 +1907,11 @@ public:
     return std::move (item);
   }
 
-  std::unique_ptr<TraitItem> take_trait_item ()
+  std::unique_ptr<AssociatedItem> take_trait_item ()
   {
     rust_assert (!is_error ());
-    return std::unique_ptr<TraitItem> (
-      static_cast<TraitItem *> (assoc_item.release ()));
+    return std::unique_ptr<AssociatedItem> (
+      static_cast<AssociatedItem *> (assoc_item.release ()));
   }
 
   std::unique_ptr<ExternalItem> take_external_item ()
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 1553f29ad2d..1defecc4452 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -3140,7 +3140,7 @@ class Trait : public VisItem
   std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds;
   WhereClause where_clause;
   std::vector<Attribute> inner_attrs;
-  std::vector<std::unique_ptr<TraitItem>> trait_items;
+  std::vector<std::unique_ptr<AssociatedItem>> trait_items;
   location_t locus;
 
 public:
@@ -3171,9 +3171,9 @@ public:
 	 std::vector<std::unique_ptr<GenericParam>> generic_params,
 	 std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds,
 	 WhereClause where_clause,
-	 std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis,
-	 std::vector<Attribute> outer_attrs, std::vector<Attribute> inner_attrs,
-	 location_t locus)
+	 std::vector<std::unique_ptr<AssociatedItem>> trait_items,
+	 Visibility vis, std::vector<Attribute> outer_attrs,
+	 std::vector<Attribute> inner_attrs, location_t locus)
     : VisItem (std::move (vis), std::move (outer_attrs)),
       has_unsafe (is_unsafe), has_auto (is_auto), name (std::move (name)),
       generic_params (std::move (generic_params)),
@@ -3199,7 +3199,7 @@ public:
 
     trait_items.reserve (other.trait_items.size ());
     for (const auto &e : other.trait_items)
-      trait_items.push_back (e->clone_trait_item ());
+      trait_items.push_back (e->clone_associated_item ());
   }
 
   // Overloaded assignment operator with vector clone
@@ -3223,7 +3223,7 @@ public:
 
     trait_items.reserve (other.trait_items.size ());
     for (const auto &e : other.trait_items)
-      trait_items.push_back (e->clone_trait_item ());
+      trait_items.push_back (e->clone_associated_item ());
 
     return *this;
   }
@@ -3244,11 +3244,11 @@ public:
   const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; }
   std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
 
-  const std::vector<std::unique_ptr<TraitItem>> &get_trait_items () const
+  const std::vector<std::unique_ptr<AssociatedItem>> &get_trait_items () const
   {
     return trait_items;
   }
-  std::vector<std::unique_ptr<TraitItem>> &get_trait_items ()
+  std::vector<std::unique_ptr<AssociatedItem>> &get_trait_items ()
   {
     return trait_items;
   }
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index dad2417eac4..bc0149ca99d 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -903,7 +903,8 @@ ExpandVisitor::visit (AST::Trait &trait)
 
   expander.push_context (MacroExpander::ContextType::TRAIT);
 
-  std::function<std::unique_ptr<AST::TraitItem> (AST::SingleASTNode)> extractor
+  std::function<std::unique_ptr<AST::AssociatedItem> (AST::SingleASTNode)>
+    extractor
     = [] (AST::SingleASTNode node) { return node.take_trait_item (); };
 
   expand_macro_children (MacroExpander::ContextType::TRAIT,
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 89e3731a898..a7de948006b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -5045,12 +5045,12 @@ Parser<ManagedTokenSource>::parse_trait (AST::Visibility vis,
   AST::AttrVec inner_attrs = parse_inner_attributes ();
 
   // parse trait items
-  std::vector<std::unique_ptr<AST::TraitItem>> trait_items;
+  std::vector<std::unique_ptr<AST::AssociatedItem>> trait_items;
 
   const_TokenPtr t = lexer.peek_token ();
   while (t->get_id () != RIGHT_CURLY)
     {
-      std::unique_ptr<AST::TraitItem> trait_item = parse_trait_item ();
+      std::unique_ptr<AST::AssociatedItem> trait_item = parse_trait_item ();
 
       if (trait_item == nullptr)
 	{
@@ -5082,7 +5082,7 @@ Parser<ManagedTokenSource>::parse_trait (AST::Visibility vis,
 
 // Parses a trait item used inside traits (not trait, the Item).
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::TraitItem>
+std::unique_ptr<AST::AssociatedItem>
 Parser<ManagedTokenSource>::parse_trait_item ()
 {
   // parse outer attributes (if they exist)
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 34397540321..1614d19e4a5 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -169,7 +169,7 @@ public:
 					 = ParseRestrictions ());
   std::unique_ptr<AST::Type> parse_type (bool save_errors = true);
   std::unique_ptr<AST::ExternalItem> parse_external_item ();
-  std::unique_ptr<AST::TraitItem> parse_trait_item ();
+  std::unique_ptr<AST::AssociatedItem> parse_trait_item ();
   std::unique_ptr<AST::AssociatedItem> parse_inherent_impl_item ();
   std::unique_ptr<AST::AssociatedItem> parse_trait_impl_item ();
   AST::PathInExpression parse_path_in_expression ();
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 20/25] gccrs: Add checks for Trait functions
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (17 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 19/25] gccrs: Use AssociatedItem in place of TraitItem arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 21/25] gccrs: Add missing visitors for AST::Function arthur.cohen
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

Since we want to use AST::Function class for trait functions as well, we
need to check against specific conditions in ASTValidation phase.

gcc/rust/ChangeLog:

	* checks/errors/rust-ast-validation.cc (ASTValidation::visit):
	Add checks for Trait functions.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/checks/errors/rust-ast-validation.cc | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc
index ccb071f74b0..d1c8273a0b3 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -95,24 +95,28 @@ ASTValidation::visit (AST::Union &item)
 void
 ASTValidation::visit (AST::Function &function)
 {
-  std::set<Context> valid_context
-    = {Context::INHERENT_IMPL, Context::TRAIT_IMPL};
-
   const auto &qualifiers = function.get_qualifiers ();
   if (qualifiers.is_async () && qualifiers.is_const ())
     rust_error_at (function.get_locus (),
 		   "functions cannot be both %<const%> and %<async%>");
 
-  if (qualifiers.is_const () && context.back () == Context::TRAIT_IMPL)
+  if (qualifiers.is_const ()
+      && (context.back () == Context::TRAIT_IMPL
+	  || context.back () == Context::TRAIT))
     rust_error_at (function.get_locus (), ErrorCode::E0379,
-		   "functions in traits cannot be declared const");
+		   "functions in traits cannot be declared %<const%>");
 
   // may change soon
-  if (qualifiers.is_async () && context.back () == Context::TRAIT_IMPL)
+  if (qualifiers.is_async ()
+      && (context.back () == Context::TRAIT_IMPL
+	  || context.back () == Context::TRAIT))
     rust_error_at (function.get_locus (), ErrorCode::E0706,
 		   "functions in traits cannot be declared %<async%>");
 
-  if (valid_context.find (context.back ()) == valid_context.end ()
+  // if not an associated function but has a self parameter
+  if (context.back () != Context::TRAIT
+      && context.back () != Context::TRAIT_IMPL
+      && context.back () != Context::INHERENT_IMPL
       && function.has_self_param ())
     rust_error_at (
       function.get_self_param ()->get_locus (),
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 21/25] gccrs: Add missing visitors for AST::Function.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (18 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 20/25] gccrs: Add checks for Trait functions arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 22/25] gccrs: Fix inconsistent formatting arthur.cohen
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

To use AST::Function instead of AST::TraitItemFunc and
AST::TraitItemMethod, we need to provide similar visitors during
lowering and resolving phase.

gcc/rust/ChangeLog:

	* hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit):
	Provide visitor for AST::Function.
	* hir/rust-ast-lower-implitem.h:
	Likewise.
	* resolve/rust-ast-resolve-implitem.h:
	Likewise.
	* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
	Likewise.
	* resolve/rust-ast-resolve-item.h:
	Likewise.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/hir/rust-ast-lower-implitem.cc      | 86 +++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-implitem.h       |  1 +
 gcc/rust/resolve/rust-ast-resolve-implitem.h | 20 +++++
 gcc/rust/resolve/rust-ast-resolve-item.cc    | 88 ++++++++++++++++++++
 gcc/rust/resolve/rust-ast-resolve-item.h     |  1 +
 5 files changed, 196 insertions(+)

diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 98db1dccd7c..77230e7a8bf 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -227,6 +227,92 @@ ASTLowerTraitItem::translate (AST::AssociatedItem *item)
   return resolver.translated;
 }
 
+void
+ASTLowerTraitItem::visit (AST::Function &func)
+{
+  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+  HIR::WhereClause where_clause (std::move (where_clause_items));
+  HIR::FunctionQualifiers qualifiers
+    = lower_qualifiers (func.get_qualifiers ());
+
+  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+  if (func.has_generics ())
+    generic_params = lower_generic_params (func.get_generic_params ());
+
+  std::unique_ptr<HIR::Type> return_type
+    = func.has_return_type () ? std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (func.get_return_type ().get ()))
+			      : nullptr;
+
+  // set self parameter to error if this is a method
+  // else lower to hir
+  HIR::SelfParam self_param = func.has_self_param ()
+				? lower_self (func.get_self_param ())
+				: HIR::SelfParam::error ();
+
+  std::vector<HIR::FunctionParam> function_params;
+  for (auto &p : func.get_function_params ())
+    {
+      if (p->is_variadic () || p->is_self ())
+	continue;
+
+      auto param = static_cast<AST::FunctionParam *> (p.get ());
+
+      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
+	ASTLoweringPattern::translate (param->get_pattern ().get ()));
+      auto translated_type = std::unique_ptr<HIR::Type> (
+	ASTLoweringType::translate (param->get_type ().get ()));
+
+      auto crate_num = mappings->get_current_crate ();
+      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
+				     mappings->get_next_hir_id (crate_num),
+				     UNKNOWN_LOCAL_DEFID);
+
+      auto hir_param
+	= HIR::FunctionParam (mapping, std::move (translated_pattern),
+			      std::move (translated_type), param->get_locus ());
+      function_params.push_back (hir_param);
+    }
+
+  HIR::TraitFunctionDecl decl (func.get_function_name (),
+			       std::move (qualifiers),
+			       std::move (generic_params),
+			       std::move (self_param),
+			       std::move (function_params),
+			       std::move (return_type),
+			       std::move (where_clause));
+  bool terminated = false;
+  std::unique_ptr<HIR::BlockExpr> block_expr
+    = func.has_body () ? std::unique_ptr<HIR::BlockExpr> (
+	ASTLoweringBlock::translate (func.get_definition ()->get (),
+				     &terminated))
+		       : nullptr;
+
+  auto crate_num = mappings->get_current_crate ();
+  Analysis::NodeMapping mapping (crate_num, func.get_node_id (),
+				 mappings->get_next_hir_id (crate_num),
+				 mappings->get_next_localdef_id (crate_num));
+
+  auto *trait_item
+    = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr),
+			      func.get_outer_attrs (), func.get_locus ());
+  translated = trait_item;
+  if (func.has_self_param ())
+    {
+      // insert mappings for self
+      mappings->insert_hir_self_param (&self_param);
+      mappings->insert_location (self_param.get_mappings ().get_hirid (),
+				 self_param.get_locus ());
+    }
+
+  // add the mappings for the function params at the end
+  for (auto &param : trait_item->get_decl ().get_function_params ())
+    {
+      mappings->insert_hir_param (&param);
+      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
+    }
+}
+
 void
 ASTLowerTraitItem::visit (AST::TraitItemFunc &func)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 3a266b41ed4..b9d12cc4a56 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -48,6 +48,7 @@ class ASTLowerTraitItem : public ASTLoweringBase
 
 public:
   static HIR::TraitItem *translate (AST::AssociatedItem *item);
+  void visit (AST::Function &func) override;
   void visit (AST::TraitItemFunc &func) override;
   void visit (AST::TraitItemMethod &method) override;
   void visit (AST::TraitItemConst &constant) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 365bdd6135f..d9c9bcb28c9 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -110,6 +110,26 @@ public:
     item->accept_vis (resolver);
   };
 
+  void visit (AST::Function &function) override
+  {
+    auto decl
+      = CanonicalPath::new_seg (function.get_node_id (),
+				function.get_function_name ().as_string ());
+    auto path = prefix.append (decl);
+    auto cpath = canonical_prefix.append (decl);
+
+    resolver->get_name_scope ().insert (
+      path, function.get_node_id (), function.get_locus (), false,
+      Rib::ItemType::Function,
+      [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
+	rich_location r (line_table, function.get_locus ());
+	r.add_range (locus);
+	rust_error_at (r, "redefined multiple times");
+      });
+
+    mappings->insert_canonical_path (function.get_node_id (), cpath);
+  }
+
   void visit (AST::TraitItemFunc &function) override
   {
     auto decl = CanonicalPath::new_seg (
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 60eca5b13c7..6037fe59f5b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -45,6 +45,94 @@ ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix,
   item->accept_vis (resolver);
 }
 
+void
+ResolveTraitItems::visit (AST::Function &function)
+{
+  auto decl
+    = CanonicalPath::new_seg (function.get_node_id (),
+			      function.get_function_name ().as_string ());
+  auto path = prefix.append (decl);
+  auto cpath = canonical_prefix.append (decl);
+  mappings->insert_canonical_path (function.get_node_id (), cpath);
+
+  NodeId scope_node_id = function.get_node_id ();
+  resolver->get_name_scope ().push (scope_node_id);
+  resolver->get_type_scope ().push (scope_node_id);
+  resolver->get_label_scope ().push (scope_node_id);
+  resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+  resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
+
+  if (function.has_generics ())
+    for (auto &generic : function.get_generic_params ())
+      ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
+
+  if (function.has_return_type ())
+    ResolveType::go (function.get_return_type ().get ());
+
+  // self turns into (self: Self) as a function param
+  std::vector<PatternBinding> bindings
+    = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
+
+  // we make a new scope so the names of parameters are resolved and shadowed
+  // correctly
+  for (auto &p : function.get_function_params ())
+    {
+      if (p->is_variadic ())
+	{
+	  auto param = static_cast<AST::VariadicParam *> (p.get ());
+	  PatternDeclaration::go (param->get_pattern ().get (),
+				  Rib::ItemType::Param, bindings);
+	}
+      else if (p->is_self ())
+	{
+	  auto param = static_cast<AST::SelfParam *> (p.get ());
+	  // FIXME: which location should be used for Rust::Identifier `self`?
+	  AST::IdentifierPattern self_pattern (
+	    param->get_node_id (), {"self"}, param->get_locus (),
+	    param->get_has_ref (), param->get_is_mut (),
+	    std::unique_ptr<AST::Pattern> (nullptr));
+
+	  PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
+
+	  if (param->has_type ())
+	    {
+	      // This shouldn't happen the parser should already error for this
+	      rust_assert (!param->get_has_ref ());
+	      ResolveType::go (param->get_type ().get ());
+	    }
+	  else
+	    {
+	      // here we implicitly make self have a type path of Self
+	      std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
+	      segments.push_back (std::unique_ptr<AST::TypePathSegment> (
+		new AST::TypePathSegment ("Self", false, param->get_locus ())));
+
+	      AST::TypePath self_type_path (std::move (segments),
+					    param->get_locus ());
+	      ResolveType::go (&self_type_path);
+	    }
+	}
+      else
+	{
+	  auto param = static_cast<AST::FunctionParam *> (p.get ());
+	  ResolveType::go (param->get_type ().get ());
+	  PatternDeclaration::go (param->get_pattern ().get (),
+				  Rib::ItemType::Param, bindings);
+	}
+    }
+
+  if (function.has_where_clause ())
+    ResolveWhereClause::Resolve (function.get_where_clause ());
+
+  // trait items have an optional body
+  if (function.has_body ())
+    ResolveExpr::go (function.get_definition ()->get (), path, cpath);
+
+  resolver->get_name_scope ().pop ();
+  resolver->get_type_scope ().pop ();
+  resolver->get_label_scope ().pop ();
+}
 void
 ResolveTraitItems::visit (AST::TraitItemType &type)
 {
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 712fe62336f..33a78e21957 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -35,6 +35,7 @@ public:
   static void go (AST::AssociatedItem *item, const CanonicalPath &prefix,
 		  const CanonicalPath &canonical_prefix);
 
+  void visit (AST::Function &type) override;
   void visit (AST::TraitItemType &type) override;
   void visit (AST::TraitItemFunc &func) override;
   void visit (AST::TraitItemMethod &func) override;
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 22/25] gccrs: Fix inconsistent formatting.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (19 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 21/25] gccrs: Add missing visitors for AST::Function arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 23/25] gccrs: Parse trait functions as `AST::Function` arthur.cohen
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

gcc/testsuite/ChangeLog:

	* rust/compile/issue-2040.rs:
	Enclose 'const' in single quotes.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/testsuite/rust/compile/issue-2040.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/rust/compile/issue-2040.rs b/gcc/testsuite/rust/compile/issue-2040.rs
index fbac168b9f3..89895420a4d 100644
--- a/gcc/testsuite/rust/compile/issue-2040.rs
+++ b/gcc/testsuite/rust/compile/issue-2040.rs
@@ -4,7 +4,7 @@ trait Foo {
 
 impl Foo for u32 {
     const fn f() -> u32 {
-        // { dg-error "functions in traits cannot be declared const" "" { target *-*-* } .-1 }
+        // { dg-error "functions in traits cannot be declared .const." "" { target *-*-* } .-1 }
         22
     }
 }
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 23/25] gccrs: Parse trait functions as `AST::Function`.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (20 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 22/25] gccrs: Fix inconsistent formatting arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 24/25] gccrs: Remove obsolete classes and functions arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 25/25] gccrs: Fix macro parsing for trait items arthur.cohen
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

To use AST::Function for trait functions, we can parse trait functions
using available parse_function().

gcc/rust/ChangeLog:

	* parse/rust-parse-impl.h (Parser::parse_trait_item):
	Use parse_function() to parse trait functions.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/parse/rust-parse-impl.h | 127 +------------------------------
 1 file changed, 2 insertions(+), 125 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index a7de948006b..ed264371db7 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -5108,132 +5108,9 @@ Parser<ManagedTokenSource>::parse_trait_item ()
     case ASYNC:
     case UNSAFE:
     case EXTERN_KW:
-      case FN_KW: {
-	/* function and method can't be disambiguated by lookahead alone
-	 * (without a lot of work and waste), so either make a
-	 * "parse_trait_function_or_method" or parse here mostly and pass in
-	 * most parameters (or if short enough, parse whole thing here). */
-	// parse function and method here
-
-	// parse function or method qualifiers
-	AST::FunctionQualifiers qualifiers = parse_function_qualifiers ();
-
-	skip_token (FN_KW);
-
-	// parse function or method name
-	const_TokenPtr ident_tok = expect_token (IDENTIFIER);
-	if (ident_tok == nullptr)
-	  return nullptr;
-
-	Identifier ident{ident_tok};
-
-	// parse generic params
-	std::vector<std::unique_ptr<AST::GenericParam>> generic_params
-	  = parse_generic_params_in_angles ();
-
-	if (!skip_token (LEFT_PAREN))
-	  {
-	    // skip after somewhere?
-	    return nullptr;
-	  }
-
-	/* now for function vs method disambiguation - method has opening
-	 * "self" param */
-	auto initial_param = parse_self_param ();
-	if (!initial_param.has_value () && initial_param.error () != NOT_SELF)
-	  return nullptr;
-	/* FIXME: ensure that self param doesn't accidently consume tokens for
-	 * a function */
-	bool is_method = false;
-	if (initial_param.has_value ())
-	  {
-	    if ((*initial_param)->is_self ())
-	      is_method = true;
-
-	    /* skip comma so function and method regular params can be parsed
-	     * in same way */
-	    if (lexer.peek_token ()->get_id () == COMMA)
-	      lexer.skip_token ();
-	  }
-
-	// parse trait function params
-	std::vector<std::unique_ptr<AST::Param>> function_params
-	  = parse_function_params (
-	    [] (TokenId id) { return id == RIGHT_PAREN; });
-
-	if (!skip_token (RIGHT_PAREN))
-	  {
-	    // skip after somewhere?
-	    return nullptr;
-	  }
-
-	if (initial_param.has_value ())
-	  function_params.insert (function_params.begin (),
-				  std::move (*initial_param));
-
-	// parse return type (optional)
-	std::unique_ptr<AST::Type> return_type = parse_function_return_type ();
-
-	// parse where clause (optional)
-	AST::WhereClause where_clause = parse_where_clause ();
-
-	// parse semicolon or function definition (in block)
-	const_TokenPtr t = lexer.peek_token ();
-	std::unique_ptr<AST::BlockExpr> definition = nullptr;
-	switch (t->get_id ())
-	  {
-	  case SEMICOLON:
-	    lexer.skip_token ();
-	    // definition is already nullptr, so don't need to change it
-	    break;
-	  case LEFT_CURLY:
-	    definition = parse_block_expr ();
-	    /* FIXME: are these outer attributes meant to be passed into the
-	     * block? */
-	    break;
-	  default:
-	    add_error (
-	      Error (t->get_locus (),
-		     "expected %<;%> or definiton at the end of trait %s "
-		     "definition - found %qs instead",
-		     is_method ? "method" : "function",
-		     t->get_token_description ()));
-
-	    // skip?
-	    return nullptr;
-	  }
+    case FN_KW:
+      return parse_function (std::move (vis), std::move (outer_attrs));
 
-	// do actual if instead of ternary for return value optimisation
-	if (is_method)
-	  {
-	    AST::TraitMethodDecl method_decl (std::move (ident),
-					      std::move (qualifiers),
-					      std::move (generic_params),
-					      std::move (function_params),
-					      std::move (return_type),
-					      std::move (where_clause));
-
-	    // TODO: does this (method_decl) need move?
-	    return std::unique_ptr<AST::TraitItemMethod> (
-	      new AST::TraitItemMethod (std::move (method_decl),
-					std::move (definition),
-					std::move (outer_attrs),
-					tok->get_locus ()));
-	  }
-	else
-	  {
-	    AST::TraitFunctionDecl function_decl (std::move (ident),
-						  std::move (qualifiers),
-						  std::move (generic_params),
-						  std::move (function_params),
-						  std::move (return_type),
-						  std::move (where_clause));
-
-	    return std::unique_ptr<AST::TraitItemFunc> (new AST::TraitItemFunc (
-	      std::move (function_decl), std::move (definition),
-	      std::move (outer_attrs), tok->get_locus ()));
-	  }
-      }
       default: {
 	// TODO: try and parse macro invocation semi - if fails, maybe error.
 	std::unique_ptr<AST::TraitItem> macro_invoc
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 24/25] gccrs: Remove obsolete classes and functions.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (21 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 23/25] gccrs: Parse trait functions as `AST::Function` arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  2024-02-07 11:44 ` [COMMITTED 25/25] gccrs: Fix macro parsing for trait items arthur.cohen
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

Trait functions now use AST::Function class, so classes
AST::TraitItemFunc, AST::TraitItemMethod, AST::TraitFunctionDecl,
AST::TraitMethodDecl and their related functions can be removed.

gcc/rust/ChangeLog:

	* ast/rust-ast-collector.cc (TokenCollector::visit):
	Remove obsolete classes and functions.
	* ast/rust-ast-collector.h:
	Likewise.
	* ast/rust-ast-full-decls.h (class TraitFunctionDecl):
	Likewise.
	(class TraitItemFunc):
	Likewise.
	(class TraitMethodDecl):
	Likewise.
	(class TraitItemMethod):
	Likewise.
	* ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):
	Likewise.
	* ast/rust-ast-visitor.h:
	Likewise.
	* ast/rust-ast.cc (TraitItemFunc::TraitItemFunc):
	Likewise.
	(TraitItemFunc::operator=):
	Likewise.
	(TraitItemFunc::as_string):
	Likewise.
	(TraitFunctionDecl::as_string):
	Likewise.
	(TraitItemMethod::TraitItemMethod):
	Likewise.
	(TraitItemMethod::operator=):
	Likewise.
	(TraitItemMethod::as_string):
	Likewise.
	(TraitMethodDecl::as_string):
	Likewise.
	(TraitItemFunc::accept_vis):
	Likewise.
	(TraitItemMethod::accept_vis):
	Likewise.
	* ast/rust-item.h (class TraitFunctionDecl):
	Likewise.
	(class TraitItemFunc):
	Likewise.
	(class TraitMethodDecl):
	Likewise.
	(class TraitItemMethod):
	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::maybe_strip_trait_function_decl):
	Likewise.
	(CfgStrip::maybe_strip_trait_method_decl):
	Likewise.
	(CfgStrip::visit):
	Likewise.
	* expand/rust-cfg-strip.h:
	Likewise.
	* expand/rust-derive.h:
	Likewise.
	* expand/rust-expand-visitor.cc (ExpandVisitor::expand_trait_function_decl):
	Likewise.
	(ExpandVisitor::expand_trait_method_decl):
	Likewise.
	(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.
	* hir/rust-ast-lower-implitem.cc (ASTLowerTraitItem::visit):
	Likewise.
	* hir/rust-ast-lower-implitem.h:
	Likewise.
	* resolve/rust-ast-resolve-base.cc (ResolverBase::visit):
	Likewise.
	* resolve/rust-ast-resolve-base.h:
	Likewise.
	* resolve/rust-ast-resolve-implitem.h (visit):
	Likewise.
	* resolve/rust-ast-resolve-item.cc (ResolveTraitItems::visit):
	Likewise.
	* resolve/rust-ast-resolve-item.h:
	Likewise.
	* resolve/rust-default-resolver.cc (DefaultResolver::visit):
	Likewise.
	* resolve/rust-default-resolver.h:
	Likewise.
	* resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::visit):
	Likewise.
	* resolve/rust-toplevel-name-resolver-2.0.h:
	Likewise.
	* util/rust-attributes.cc (AttributeChecker::visit):
	Likewise.
	* util/rust-attributes.h:
	Likewise.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/ast/rust-ast-collector.cc            |  34 --
 gcc/rust/ast/rust-ast-collector.h             |   2 -
 gcc/rust/ast/rust-ast-full-decls.h            |   4 -
 gcc/rust/ast/rust-ast-visitor.cc              |  45 --
 gcc/rust/ast/rust-ast-visitor.h               |   6 -
 gcc/rust/ast/rust-ast.cc                      | 209 ---------
 gcc/rust/ast/rust-item.h                      | 406 ------------------
 gcc/rust/checks/errors/rust-ast-validation.cc |  17 -
 gcc/rust/checks/errors/rust-ast-validation.h  |   1 -
 gcc/rust/checks/errors/rust-feature-gate.h    |   2 -
 gcc/rust/expand/rust-cfg-strip.cc             | 105 -----
 gcc/rust/expand/rust-cfg-strip.h              |   4 -
 gcc/rust/expand/rust-derive.h                 |   2 -
 gcc/rust/expand/rust-expand-visitor.cc        |  54 ---
 gcc/rust/expand/rust-expand-visitor.h         |   4 -
 gcc/rust/hir/rust-ast-lower-base.cc           |   6 -
 gcc/rust/hir/rust-ast-lower-base.h            |   2 -
 gcc/rust/hir/rust-ast-lower-implitem.cc       | 159 -------
 gcc/rust/hir/rust-ast-lower-implitem.h        |   2 -
 gcc/rust/resolve/rust-ast-resolve-base.cc     |   8 -
 gcc/rust/resolve/rust-ast-resolve-base.h      |   2 -
 gcc/rust/resolve/rust-ast-resolve-implitem.h  |  40 --
 gcc/rust/resolve/rust-ast-resolve-item.cc     | 155 -------
 gcc/rust/resolve/rust-ast-resolve-item.h      |   2 -
 gcc/rust/resolve/rust-default-resolver.cc     |   8 -
 gcc/rust/resolve/rust-default-resolver.h      |   2 -
 .../rust-toplevel-name-resolver-2.0.cc        |  10 -
 .../resolve/rust-toplevel-name-resolver-2.0.h |   1 -
 gcc/rust/util/rust-attributes.cc              |   8 -
 gcc/rust/util/rust-attributes.h               |   2 -
 30 files changed, 1302 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index d5a98f1ccc7..fb0e6f9be1d 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1948,23 +1948,6 @@ TokenCollector::visit_function_common (std::unique_ptr<Type> &return_type,
     }
 }
 
-void
-TokenCollector::visit (TraitItemFunc &item)
-{
-  auto func = item.get_trait_function_decl ();
-  auto id = func.get_identifier ().as_string ();
-
-  push (Rust::Token::make (FN_KW, item.get_locus ()));
-  push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
-  push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
-
-  visit_items_joined_by_separator (func.get_function_params ());
-
-  push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
-
-  visit_function_common (func.get_return_type (), item.get_definition ());
-}
-
 void
 TokenCollector::visit (SelfParam &param)
 {
@@ -1987,23 +1970,6 @@ TokenCollector::visit (SelfParam &param)
     }
 }
 
-void
-TokenCollector::visit (TraitItemMethod &item)
-{
-  auto method = item.get_trait_method_decl ();
-  auto id = method.get_identifier ().as_string ();
-
-  push (Rust::Token::make (FN_KW, item.get_locus ()));
-  push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
-  push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
-
-  visit_items_joined_by_separator (method.get_function_params (), COMMA);
-
-  push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
-
-  visit_function_common (method.get_return_type (), item.get_definition ());
-}
-
 void
 TokenCollector::visit (TraitItemConst &item)
 {
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index 55c13d103d0..246411fa15f 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -325,9 +325,7 @@ public:
   void visit (Union &union_item);
   void visit (ConstantItem &const_item);
   void visit (StaticItem &static_item);
-  void visit (TraitItemFunc &item);
   void visit (SelfParam &param);
-  void visit (TraitItemMethod &item);
   void visit (TraitItemConst &item);
   void visit (TraitItemType &item);
   void visit (Trait &trait);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 0f95149a214..c96bbfb07d9 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -193,10 +193,6 @@ class Enum;
 class Union;
 class ConstantItem;
 class StaticItem;
-class TraitFunctionDecl;
-class TraitItemFunc;
-class TraitMethodDecl;
-class TraitItemMethod;
 class TraitItemConst;
 class TraitItemType;
 class Trait;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 586570377aa..cb7ba846c39 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -911,51 +911,6 @@ DefaultASTVisitor::visit (AST::StaticItem &static_item)
   visit (static_item.get_expr ());
 }
 
-void
-DefaultASTVisitor::visit (AST::TraitFunctionDecl &decl)
-{
-  visit (decl.get_qualifiers ());
-  for (auto &generic : decl.get_generic_params ())
-    visit (generic);
-  visit (decl.get_where_clause ());
-  for (auto &param : decl.get_function_params ())
-    visit (param);
-  if (decl.has_return_type ())
-    visit (decl.get_return_type ());
-}
-
-void
-DefaultASTVisitor::visit (AST::TraitItemFunc &item)
-{
-  visit_outer_attrs (item);
-  visit (item.get_trait_function_decl ());
-  if (item.has_definition ())
-    visit (item.get_definition ());
-}
-
-void
-DefaultASTVisitor::visit (AST::TraitMethodDecl &decl)
-{
-  visit (decl.get_qualifiers ());
-  for (auto &generic : decl.get_generic_params ())
-    visit (generic);
-  visit (decl.get_where_clause ());
-  visit (decl.get_self_param ());
-  for (auto &param : decl.get_function_params ())
-    visit (param);
-  if (decl.has_return_type ())
-    visit (decl.get_return_type ());
-}
-
-void
-DefaultASTVisitor::visit (AST::TraitItemMethod &item)
-{
-  visit_outer_attrs (item);
-  visit (item.get_trait_method_decl ());
-  if (item.has_definition ())
-    visit (item.get_definition ());
-}
-
 void
 DefaultASTVisitor::visit (AST::TraitItemConst &item)
 {
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 43cd750f5f7..6c9715eb077 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -156,8 +156,6 @@ public:
   virtual void visit (Union &union_item) = 0;
   virtual void visit (ConstantItem &const_item) = 0;
   virtual void visit (StaticItem &static_item) = 0;
-  virtual void visit (TraitItemFunc &item) = 0;
-  virtual void visit (TraitItemMethod &item) = 0;
   virtual void visit (TraitItemConst &item) = 0;
   virtual void visit (TraitItemType &item) = 0;
   virtual void visit (Trait &trait) = 0;
@@ -330,8 +328,6 @@ protected:
   virtual void visit (AST::Union &union_item) override;
   virtual void visit (AST::ConstantItem &const_item) override;
   virtual void visit (AST::StaticItem &static_item) override;
-  virtual void visit (AST::TraitItemFunc &item) override;
-  virtual void visit (AST::TraitItemMethod &item) override;
   virtual void visit (AST::TraitItemConst &item) override;
   virtual void visit (AST::TraitItemType &item) override;
   virtual void visit (AST::Trait &trait) override;
@@ -420,8 +416,6 @@ protected:
   virtual void visit (AST::WhereClause &where);
   virtual void visit (AST::StructField &field);
   virtual void visit (AST::TupleField &field);
-  virtual void visit (AST::TraitFunctionDecl &decl);
-  virtual void visit (AST::TraitMethodDecl &decl);
   virtual void visit (AST::NamedFunctionParam &param);
   virtual void visit (AST::MacroRule &rule);
   virtual void visit (AST::MacroInvocData &data);
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 360a9ceb6db..90fe9269404 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -3049,203 +3049,6 @@ NamedFunctionParam::as_string () const
   return str;
 }
 
-TraitItemFunc::TraitItemFunc (TraitItemFunc const &other)
-  : TraitItem (other.locus), outer_attrs (other.outer_attrs), decl (other.decl)
-{
-  node_id = other.node_id;
-
-  // guard to prevent null dereference
-  if (other.block_expr != nullptr)
-    block_expr = other.block_expr->clone_block_expr ();
-}
-
-TraitItemFunc &
-TraitItemFunc::operator= (TraitItemFunc const &other)
-{
-  TraitItem::operator= (other);
-  outer_attrs = other.outer_attrs;
-  decl = other.decl;
-  locus = other.locus;
-  node_id = other.node_id;
-
-  // guard to prevent null dereference
-  if (other.block_expr != nullptr)
-    block_expr = other.block_expr->clone_block_expr ();
-  else
-    block_expr = nullptr;
-
-  return *this;
-}
-std::string
-TraitItemFunc::as_string () const
-{
-  std::string str = append_attributes (outer_attrs, OUTER);
-
-  str += "\n" + decl.as_string ();
-
-  str += "\n Definition (block expr): ";
-  if (has_definition ())
-    str += block_expr->as_string ();
-  else
-    str += "none";
-
-  return str;
-}
-
-std::string
-TraitFunctionDecl::as_string () const
-{
-  std::string str
-    = qualifiers.as_string () + "fn " + function_name.as_string ();
-
-  // generic params
-  str += "\n Generic params: ";
-  if (generic_params.empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &param : generic_params)
-	{
-	  // DEBUG: null pointer check
-	  if (param == nullptr)
-	    {
-	      rust_debug (
-		"something really terrible has gone wrong - null pointer "
-		"generic param in trait function decl.");
-	      return "NULL_POINTER_MARK";
-	    }
-
-	  str += "\n  " + param->as_string ();
-	}
-    }
-
-  str += "\n Function params: ";
-  if (has_params ())
-    {
-      for (const auto &param : function_params)
-	str += "\n  " + param->as_string ();
-    }
-  else
-    {
-      str += "none";
-    }
-
-  str += "\n Return type: ";
-  if (has_return_type ())
-    str += return_type->as_string ();
-  else
-    str += "none (void)";
-
-  str += "\n Where clause: ";
-  if (has_where_clause ())
-    str += where_clause.as_string ();
-  else
-    str += "none";
-
-  return str;
-}
-
-TraitItemMethod::TraitItemMethod (TraitItemMethod const &other)
-  : TraitItem (other.locus), outer_attrs (other.outer_attrs), decl (other.decl)
-{
-  node_id = other.node_id;
-
-  // guard to prevent null dereference
-  if (other.block_expr != nullptr)
-    block_expr = other.block_expr->clone_block_expr ();
-}
-
-TraitItemMethod &
-TraitItemMethod::operator= (TraitItemMethod const &other)
-{
-  TraitItem::operator= (other);
-  outer_attrs = other.outer_attrs;
-  decl = other.decl;
-  locus = other.locus;
-  node_id = other.node_id;
-
-  // guard to prevent null dereference
-  if (other.block_expr != nullptr)
-    block_expr = other.block_expr->clone_block_expr ();
-  else
-    block_expr = nullptr;
-
-  return *this;
-}
-
-std::string
-TraitItemMethod::as_string () const
-{
-  std::string str = append_attributes (outer_attrs, OUTER);
-
-  str += "\n" + decl.as_string ();
-
-  str += "\n Definition (block expr): ";
-  if (has_definition ())
-    str += block_expr->as_string ();
-  else
-    str += "none";
-
-  return str;
-}
-
-std::string
-TraitMethodDecl::as_string () const
-{
-  std::string str
-    = qualifiers.as_string () + "fn " + function_name.as_string ();
-
-  // generic params
-  str += "\n Generic params: ";
-  if (generic_params.empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &param : generic_params)
-	{
-	  // DEBUG: null pointer check
-	  if (param == nullptr)
-	    {
-	      rust_debug (
-		"something really terrible has gone wrong - null pointer "
-		"generic param in trait function decl.");
-	      return "NULL_POINTER_MARK";
-	    }
-
-	  str += "\n  " + param->as_string ();
-	}
-    }
-
-  str += "\n Function params: ";
-  if (has_params ())
-    {
-      for (const auto &param : function_params)
-	str += "\n  " + param->as_string ();
-    }
-  else
-    {
-      str += "none";
-    }
-
-  str += "\n Return type: ";
-  if (has_return_type ())
-    str += return_type->as_string ();
-  else
-    str += "none (void)";
-
-  str += "\n Where clause: ";
-  if (has_where_clause ())
-    str += where_clause.as_string ();
-  else
-    str += "none";
-
-  return str;
-}
-
 std::string
 TraitItemConst::as_string () const
 {
@@ -5017,18 +4820,6 @@ StaticItem::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
-void
-TraitItemFunc::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-TraitItemMethod::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 TraitItemConst::accept_vis (ASTVisitor &vis)
 {
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 1defecc4452..0911719b716 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -2531,412 +2531,6 @@ protected:
   }
 };
 
-// Function declaration in traits
-class TraitFunctionDecl
-{
-  // TODO: delete and replace with Function decl item? no as no body in this.
-  FunctionQualifiers qualifiers;
-  Identifier function_name;
-
-  // bool has_generics;
-  // Generics generic_params;
-  std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
-
-  // bool has_params;
-  // FunctionParams function_params;
-  std::vector<std::unique_ptr<Param>> function_params; // inlined
-
-  // bool has_return_type;
-  std::unique_ptr<Type> return_type;
-
-  // bool has_where_clause;
-  WhereClause where_clause;
-
-  // should this store location info?
-
-public:
-  // Returns whether function decl has generic parameters.
-  bool has_generics () const { return !generic_params.empty (); }
-
-  // Returns whether function decl has regular parameters.
-  bool has_params () const { return !function_params.empty (); }
-
-  // Returns whether function has return type (otherwise is void).
-  bool has_return_type () const { return return_type != nullptr; }
-
-  // Returns whether function has a where clause.
-  bool has_where_clause () const { return !where_clause.is_empty (); }
-
-  Identifier get_identifier () const { return function_name; }
-
-  // Mega-constructor
-  TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
-		     std::vector<std::unique_ptr<GenericParam>> generic_params,
-		     std::vector<std::unique_ptr<Param>> function_params,
-		     std::unique_ptr<Type> return_type,
-		     WhereClause where_clause)
-    : 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))
-  {}
-
-  // Copy constructor with clone
-  TraitFunctionDecl (TraitFunctionDecl const &other)
-    : qualifiers (other.qualifiers), function_name (other.function_name),
-      where_clause (other.where_clause)
-  {
-    // guard to prevent nullptr dereference
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    function_params.reserve (other.function_params.size ());
-    for (const auto &e : other.function_params)
-      function_params.push_back (e->clone_param ());
-  }
-
-  ~TraitFunctionDecl () = default;
-
-  // Overloaded assignment operator with clone
-  TraitFunctionDecl &operator= (TraitFunctionDecl const &other)
-  {
-    function_name = other.function_name;
-    qualifiers = other.qualifiers;
-    where_clause = other.where_clause;
-
-    // guard to prevent nullptr dereference
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-    else
-      return_type = nullptr;
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    function_params.reserve (other.function_params.size ());
-    for (const auto &e : other.function_params)
-      function_params.push_back (e->clone_param ());
-
-    return *this;
-  }
-
-  // move constructors
-  TraitFunctionDecl (TraitFunctionDecl &&other) = default;
-  TraitFunctionDecl &operator= (TraitFunctionDecl &&other) = default;
-
-  std::string as_string () const;
-
-  // Invalid if function name is empty, so base stripping on that.
-  void mark_for_strip () { function_name = {""}; }
-  bool is_marked_for_strip () const { return function_name.empty (); }
-
-  // TODO: this mutable getter seems really dodgy. Think up better way.
-  std::vector<std::unique_ptr<Param>> &get_function_params ()
-  {
-    return function_params;
-  }
-  const std::vector<std::unique_ptr<Param>> &get_function_params () const
-  {
-    return function_params;
-  }
-
-  std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
-  {
-    return generic_params;
-  }
-  const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
-  {
-    return generic_params;
-  }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  WhereClause &get_where_clause () { return where_clause; }
-
-  FunctionQualifiers get_qualifiers () const { return qualifiers; }
-  FunctionQualifiers &get_qualifiers () { return qualifiers; }
-};
-
-// Actual trait item function declaration within traits
-class TraitItemFunc : public TraitItem
-{
-  std::vector<Attribute> outer_attrs;
-  TraitFunctionDecl decl;
-  std::unique_ptr<BlockExpr> block_expr;
-
-public:
-  // Returns whether function has a definition or is just a declaration.
-  bool has_definition () const { return block_expr != nullptr; }
-
-  TraitItemFunc (TraitFunctionDecl decl, std::unique_ptr<BlockExpr> block_expr,
-		 std::vector<Attribute> outer_attrs, location_t locus)
-    : TraitItem (locus), outer_attrs (std::move (outer_attrs)),
-      decl (std::move (decl)), block_expr (std::move (block_expr))
-  {}
-
-  // Copy constructor with clone
-  TraitItemFunc (TraitItemFunc const &other);
-
-  // Overloaded assignment operator to clone
-
-  TraitItemFunc &operator= (TraitItemFunc const &other);
-
-  // move constructors
-  TraitItemFunc (TraitItemFunc &&other) = default;
-  TraitItemFunc &operator= (TraitItemFunc &&other) = default;
-
-  std::string as_string () const override;
-
-  void accept_vis (ASTVisitor &vis) override;
-
-  // Invalid if trait decl is empty, so base stripping on that.
-  void mark_for_strip () override { decl.mark_for_strip (); }
-  bool is_marked_for_strip () const override
-  {
-    return decl.is_marked_for_strip ();
-  }
-
-  // TODO: this mutable getter seems really dodgy. Think up better way.
-  std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
-  const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<BlockExpr> &get_definition () { return block_expr; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  TraitFunctionDecl &get_trait_function_decl ()
-  {
-    // TODO: maybe only allow access if not marked for strip?
-    return decl;
-  }
-
-protected:
-  // Clone function implementation as (not pure) virtual method
-  TraitItemFunc *clone_associated_item_impl () const override
-  {
-    return new TraitItemFunc (*this);
-  }
-};
-
-// Method declaration within traits
-class TraitMethodDecl
-{
-  // TODO: delete and replace with Function decl item? no as no body.
-  FunctionQualifiers qualifiers;
-  Identifier function_name;
-
-  // bool has_generics;
-  // Generics generic_params;
-  std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
-
-  // bool has_params;
-  // FunctionParams function_params;
-  std::vector<std::unique_ptr<Param>> function_params; // inlined
-
-  // bool has_return_type;
-  std::unique_ptr<Type> return_type;
-
-  // bool has_where_clause;
-  WhereClause where_clause;
-
-  // should this store location info?
-
-public:
-  // Returns whether method decl has generic parameters.
-  bool has_generics () const { return !generic_params.empty (); }
-
-  // Returns whether method decl has regular parameters.
-  bool has_params () const { return !function_params.empty (); }
-
-  // Returns whether method has return type (otherwise is void).
-  bool has_return_type () const { return return_type != nullptr; }
-
-  // Returns whether method has a where clause.
-  bool has_where_clause () const { return !where_clause.is_empty (); }
-
-  Identifier get_identifier () const { return function_name; }
-
-  // Mega-constructor
-  TraitMethodDecl (Identifier function_name, FunctionQualifiers qualifiers,
-		   std::vector<std::unique_ptr<GenericParam>> generic_params,
-		   std::vector<std::unique_ptr<Param>> function_params,
-		   std::unique_ptr<Type> return_type, WhereClause where_clause)
-    : 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))
-  {}
-
-  // Copy constructor with clone
-  TraitMethodDecl (TraitMethodDecl const &other)
-    : qualifiers (other.qualifiers), function_name (other.function_name),
-      where_clause (other.where_clause)
-  {
-    // guard to prevent nullptr dereference
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    function_params.reserve (other.function_params.size ());
-    for (const auto &e : other.function_params)
-      function_params.push_back (e->clone_param ());
-  }
-
-  ~TraitMethodDecl () = default;
-
-  // Overloaded assignment operator with clone
-  TraitMethodDecl &operator= (TraitMethodDecl const &other)
-  {
-    function_name = other.function_name;
-    qualifiers = other.qualifiers;
-    where_clause = other.where_clause;
-
-    // guard to prevent nullptr dereference
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-    else
-      return_type = nullptr;
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    function_params.reserve (other.function_params.size ());
-    for (const auto &e : other.function_params)
-      function_params.push_back (e->clone_param ());
-
-    return *this;
-  }
-
-  // move constructors
-  TraitMethodDecl (TraitMethodDecl &&other) = default;
-  TraitMethodDecl &operator= (TraitMethodDecl &&other) = default;
-
-  std::string as_string () const;
-
-  // Invalid if method name is empty, so base stripping on that.
-  void mark_for_strip () { function_name = {""}; }
-  bool is_marked_for_strip () const { return function_name.empty (); }
-
-  // TODO: this mutable getter seems really dodgy. Think up better way.
-  std::vector<std::unique_ptr<Param>> &get_function_params ()
-  {
-    return function_params;
-  }
-  const std::vector<std::unique_ptr<Param>> &get_function_params () const
-  {
-    return function_params;
-  }
-
-  std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
-  {
-    return generic_params;
-  }
-  const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
-  {
-    return generic_params;
-  }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<Type> &get_return_type () { return return_type; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  WhereClause &get_where_clause () { return where_clause; }
-
-  bool has_self () const
-  {
-    return !function_params.empty () && function_params[0]->is_self ();
-  }
-
-  std::unique_ptr<Param> &get_self_param ()
-  {
-    rust_assert (has_self ());
-    return function_params[0];
-  }
-  const std::unique_ptr<Param> &get_self_param () const
-  {
-    rust_assert (has_self ());
-    return function_params[0];
-  }
-
-  FunctionQualifiers get_qualifiers () const { return qualifiers; }
-
-  FunctionQualifiers &get_qualifiers () { return qualifiers; }
-};
-
-// Actual trait item method declaration within traits
-class TraitItemMethod : public TraitItem
-{
-  std::vector<Attribute> outer_attrs;
-  TraitMethodDecl decl;
-  std::unique_ptr<BlockExpr> block_expr;
-
-public:
-  // Returns whether method has a definition or is just a declaration.
-  bool has_definition () const { return block_expr != nullptr; }
-
-  TraitItemMethod (TraitMethodDecl decl, std::unique_ptr<BlockExpr> block_expr,
-		   std::vector<Attribute> outer_attrs, location_t locus)
-    : TraitItem (locus), outer_attrs (std::move (outer_attrs)),
-      decl (std::move (decl)), block_expr (std::move (block_expr))
-  {}
-
-  // Copy constructor with clone
-  TraitItemMethod (TraitItemMethod const &other);
-  // Overloaded assignment operator to clone
-  TraitItemMethod &operator= (TraitItemMethod const &other);
-
-  // move constructors
-  TraitItemMethod (TraitItemMethod &&other) = default;
-  TraitItemMethod &operator= (TraitItemMethod &&other) = default;
-
-  std::string as_string () const override;
-
-  void accept_vis (ASTVisitor &vis) override;
-
-  // Invalid if trait decl is empty, so base stripping on that.
-  void mark_for_strip () override { decl.mark_for_strip (); }
-  bool is_marked_for_strip () const override
-  {
-    return decl.is_marked_for_strip ();
-  }
-
-  // TODO: this mutable getter seems really dodgy. Think up better way.
-  std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
-  const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  TraitMethodDecl &get_trait_method_decl ()
-  {
-    // TODO: maybe only allow access if not marked for strip?
-    return decl;
-  }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<BlockExpr> &get_definition () { return block_expr; }
-
-protected:
-  // Clone function implementation as (not pure) virtual method
-  TraitItemMethod *clone_associated_item_impl () const override
-  {
-    return new TraitItemMethod (*this);
-  }
-};
-
 // Constant item within traits
 class TraitItemConst : public TraitItem
 {
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc
index d1c8273a0b3..d57b7cb70fe 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -140,23 +140,6 @@ ASTValidation::visit (AST::Function &function)
   AST::ContextualASTVisitor::visit (function);
 }
 
-void
-ASTValidation::visit (AST::TraitFunctionDecl &decl)
-{
-  const auto &qualifiers = decl.get_qualifiers ();
-
-  if (context.back () == Context::TRAIT)
-    {
-      // may change soon
-      if (qualifiers.is_async ())
-	rust_error_at (decl.get_identifier ().get_locus (), ErrorCode::E0706,
-		       "functions in traits cannot be declared %<async%>");
-      if (qualifiers.is_const ())
-	rust_error_at (decl.get_identifier ().get_locus (), ErrorCode::E0379,
-		       "functions in traits cannot be declared %<const%>");
-    }
-}
-
 void
 ASTValidation::visit (AST::Trait &trait)
 {
diff --git a/gcc/rust/checks/errors/rust-ast-validation.h b/gcc/rust/checks/errors/rust-ast-validation.h
index 963357f86cd..01d923ceff3 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.h
+++ b/gcc/rust/checks/errors/rust-ast-validation.h
@@ -42,7 +42,6 @@ public:
   virtual void visit (AST::Union &item);
   virtual void visit (AST::Function &function);
   virtual void visit (AST::Trait &trait);
-  virtual void visit (AST::TraitFunctionDecl &decl);
 };
 
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h b/gcc/rust/checks/errors/rust-feature-gate.h
index 8d1a26a1361..ef7449aa581 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -125,8 +125,6 @@ public:
   void visit (AST::Union &union_item) override {}
   void visit (AST::ConstantItem &const_item) override {}
   void visit (AST::StaticItem &static_item) override {}
-  void visit (AST::TraitItemFunc &item) override {}
-  void visit (AST::TraitItemMethod &item) override {}
   void visit (AST::TraitItemConst &item) override {}
   void visit (AST::TraitItemType &item) override {}
   void visit (AST::Trait &trait) override {}
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 22f3127f587..2b51a890247 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -375,56 +375,6 @@ CfgStrip::maybe_strip_where_clause (AST::WhereClause &where_clause)
     item->accept_vis (*this);
 }
 
-void
-CfgStrip::maybe_strip_trait_function_decl (AST::TraitFunctionDecl &decl)
-{
-  // just expand sub-stuff - can't actually strip generic params themselves
-  for (auto &param : decl.get_generic_params ())
-    param->accept_vis (*this);
-
-  /* strip function parameters if required - this is specifically
-   * allowed by spec */
-  maybe_strip_function_params (decl.get_function_params ());
-
-  if (decl.has_return_type ())
-    {
-      auto &return_type = decl.get_return_type ();
-      return_type->accept_vis (*this);
-
-      if (return_type->is_marked_for_strip ())
-	rust_error_at (return_type->get_locus (),
-		       "cannot strip type in this position");
-    }
-
-  if (decl.has_where_clause ())
-    maybe_strip_where_clause (decl.get_where_clause ());
-}
-
-void
-CfgStrip::maybe_strip_trait_method_decl (AST::TraitMethodDecl &decl)
-{
-  // just expand sub-stuff - can't actually strip generic params themselves
-  for (auto &param : decl.get_generic_params ())
-    param->accept_vis (*this);
-
-  /* strip function parameters if required - this is specifically
-   * allowed by spec */
-  maybe_strip_function_params (decl.get_function_params ());
-
-  if (decl.has_return_type ())
-    {
-      auto &return_type = decl.get_return_type ();
-      return_type->accept_vis (*this);
-
-      if (return_type->is_marked_for_strip ())
-	rust_error_at (return_type->get_locus (),
-		       "cannot strip type in this position");
-    }
-
-  if (decl.has_where_clause ())
-    maybe_strip_where_clause (decl.get_where_clause ());
-}
-
 void
 CfgStrip::visit (AST::IdentifierExpr &ident_expr)
 {
@@ -2080,61 +2030,6 @@ CfgStrip::visit (AST::StaticItem &static_item)
 		   "cannot strip expression in this position - outer "
 		   "attributes not allowed");
 }
-void
-CfgStrip::visit (AST::TraitItemFunc &item)
-{
-  // initial test based on outer attrs
-  expand_cfg_attrs (item.get_outer_attrs ());
-  if (fails_cfg_with_expand (item.get_outer_attrs ()))
-    {
-      item.mark_for_strip ();
-      return;
-    }
-
-  maybe_strip_trait_function_decl (item.get_trait_function_decl ());
-
-  AST::DefaultASTVisitor::visit (item);
-
-  if (item.has_definition ())
-    {
-      /* strip any internal sub-expressions - expression itself isn't
-       * allowed to have external attributes in this position so can't be
-       * stripped. */
-      auto &block = item.get_definition ();
-      if (block->is_marked_for_strip ())
-	rust_error_at (block->get_locus (),
-		       "cannot strip block expression in this "
-		       "position - outer attributes not allowed");
-    }
-}
-
-void
-CfgStrip::visit (AST::TraitItemMethod &item)
-{
-  // initial test based on outer attrs
-  expand_cfg_attrs (item.get_outer_attrs ());
-  if (fails_cfg_with_expand (item.get_outer_attrs ()))
-    {
-      item.mark_for_strip ();
-      return;
-    }
-
-  maybe_strip_trait_method_decl (item.get_trait_method_decl ());
-
-  AST::DefaultASTVisitor::visit (item);
-
-  if (item.has_definition ())
-    {
-      /* strip any internal sub-expressions - expression itself isn't
-       * allowed to have external attributes in this position so can't be
-       * stripped. */
-      auto &block = item.get_definition ();
-      if (block->is_marked_for_strip ())
-	rust_error_at (block->get_locus (),
-		       "cannot strip block expression in this "
-		       "position - outer attributes not allowed");
-    }
-}
 
 void
 CfgStrip::visit (AST::TraitItemConst &item)
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 6b968b31d05..a3931823ab1 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -42,8 +42,6 @@ public:
   void maybe_strip_closure_params (std::vector<AST::ClosureParam> &params);
   void maybe_strip_self_param (AST::SelfParam &self_param);
   void maybe_strip_where_clause (AST::WhereClause &where_clause);
-  void maybe_strip_trait_function_decl (AST::TraitFunctionDecl &decl);
-  void maybe_strip_trait_method_decl (AST::TraitMethodDecl &decl);
 
   /**
    * maybe_strip a set of values, erasing them if they are marked for strip.
@@ -145,8 +143,6 @@ public:
   void visit (AST::Union &union_item) override;
   void visit (AST::ConstantItem &const_item) override;
   void visit (AST::StaticItem &static_item) override;
-  void visit (AST::TraitItemFunc &item) override;
-  void visit (AST::TraitItemMethod &item) override;
   void visit (AST::TraitItemConst &item) override;
   void visit (AST::TraitItemType &item) override;
   void visit (AST::Trait &trait) override;
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index d5c8b44442d..1531d81f57c 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -159,8 +159,6 @@ private:
   virtual void visit (EnumItemDiscriminant &item) override final{};
   virtual void visit (ConstantItem &const_item) override final{};
   virtual void visit (StaticItem &static_item) override final{};
-  virtual void visit (TraitItemFunc &item) override final{};
-  virtual void visit (TraitItemMethod &item) override final{};
   virtual void visit (TraitItemConst &item) override final{};
   virtual void visit (TraitItemType &item) override final{};
   virtual void visit (Trait &trait) override final{};
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index bc0149ca99d..e42715b865f 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -437,42 +437,6 @@ ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
     visit (item);
 }
 
-void
-ExpandVisitor::expand_trait_function_decl (AST::TraitFunctionDecl &decl)
-{
-  // just expand sub-stuff - can't actually strip generic params themselves
-  for (auto &param : decl.get_generic_params ())
-    visit (param);
-
-  /* strip function parameters if required - this is specifically
-   * allowed by spec */
-  expand_function_params (decl.get_function_params ());
-
-  if (decl.has_return_type ())
-    maybe_expand_type (decl.get_return_type ());
-
-  if (decl.has_where_clause ())
-    expand_where_clause (decl.get_where_clause ());
-}
-
-void
-ExpandVisitor::expand_trait_method_decl (AST::TraitMethodDecl &decl)
-{
-  for (auto &param : decl.get_generic_params ())
-    visit (param);
-
-  /* strip function parameters if required - this is specifically
-   * allowed by spec */
-  expand_function_params (decl.get_function_params ());
-
-  if (decl.has_return_type ())
-
-    maybe_expand_type (decl.get_return_type ());
-
-  if (decl.has_where_clause ())
-    expand_where_clause (decl.get_where_clause ());
-}
-
 void
 ExpandVisitor::visit (AST::Crate &crate)
 {
@@ -862,24 +826,6 @@ ExpandVisitor::visit (AST::StaticItem &static_item)
   maybe_expand_expr (static_item.get_expr ());
 }
 
-void
-ExpandVisitor::visit (AST::TraitItemFunc &item)
-{
-  expand_trait_function_decl (item.get_trait_function_decl ());
-
-  if (item.has_definition ())
-    visit (item.get_definition ());
-}
-
-void
-ExpandVisitor::visit (AST::TraitItemMethod &item)
-{
-  expand_trait_method_decl (item.get_trait_method_decl ());
-
-  if (item.has_definition ())
-    visit (item.get_definition ());
-}
-
 void
 ExpandVisitor::visit (AST::TraitItemConst &const_item)
 {
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index bae9b0f8fa5..8f61db659c3 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -86,8 +86,6 @@ public:
   // FIXME: Add documentation
   void expand_closure_params (std::vector<AST::ClosureParam> &params);
   void expand_where_clause (AST::WhereClause &where_clause);
-  void expand_trait_function_decl (AST::TraitFunctionDecl &decl);
-  void expand_trait_method_decl (AST::TraitMethodDecl &decl);
 
   /**
    * Expand a set of values, erasing them if they are marked for strip, and
@@ -248,8 +246,6 @@ public:
   void visit (AST::Union &union_item) override;
   void visit (AST::ConstantItem &const_item) override;
   void visit (AST::StaticItem &static_item) override;
-  void visit (AST::TraitItemFunc &item) override;
-  void visit (AST::TraitItemMethod &item) override;
   void visit (AST::TraitItemConst &item) override;
   void visit (AST::Trait &trait) override;
   void visit (AST::InherentImpl &impl) override;
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 19f20885209..3ff0f52e0c6 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -321,12 +321,6 @@ void
 ASTLoweringBase::visit (AST::StaticItem &)
 {}
 void
-ASTLoweringBase::visit (AST::TraitItemFunc &)
-{}
-void
-ASTLoweringBase::visit (AST::TraitItemMethod &)
-{}
-void
 ASTLoweringBase::visit (AST::TraitItemConst &)
 {}
 void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index 8da11750d18..d7b94ac8a70 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -177,8 +177,6 @@ public:
   virtual void visit (AST::Union &union_item);
   virtual void visit (AST::ConstantItem &const_item);
   virtual void visit (AST::StaticItem &static_item);
-  virtual void visit (AST::TraitItemFunc &item);
-  virtual void visit (AST::TraitItemMethod &item);
   virtual void visit (AST::TraitItemConst &item);
   virtual void visit (AST::TraitItemType &item);
   virtual void visit (AST::Trait &trait);
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc
index 77230e7a8bf..399c3fb8179 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.cc
+++ b/gcc/rust/hir/rust-ast-lower-implitem.cc
@@ -313,165 +313,6 @@ ASTLowerTraitItem::visit (AST::Function &func)
     }
 }
 
-void
-ASTLowerTraitItem::visit (AST::TraitItemFunc &func)
-{
-  AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();
-  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-  HIR::WhereClause where_clause (std::move (where_clause_items));
-  HIR::FunctionQualifiers qualifiers
-    = lower_qualifiers (func.get_trait_function_decl ().get_qualifiers ());
-
-  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-  if (ref.has_generics ())
-    {
-      generic_params = lower_generic_params (ref.get_generic_params ());
-    }
-
-  std::unique_ptr<HIR::Type> return_type
-    = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
-	ASTLoweringType::translate (ref.get_return_type ().get ()))
-			     : nullptr;
-
-  std::vector<HIR::FunctionParam> function_params;
-  for (auto &p : ref.get_function_params ())
-    {
-      if (p->is_variadic () || p->is_self ())
-	continue;
-
-      auto param = static_cast<AST::FunctionParam *> (p.get ());
-
-      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-	ASTLoweringPattern::translate (param->get_pattern ().get ()));
-      auto translated_type = std::unique_ptr<HIR::Type> (
-	ASTLoweringType::translate (param->get_type ().get ()));
-
-      auto crate_num = mappings->get_current_crate ();
-      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
-				     mappings->get_next_hir_id (crate_num),
-				     UNKNOWN_LOCAL_DEFID);
-
-      auto hir_param
-	= HIR::FunctionParam (mapping, std::move (translated_pattern),
-			      std::move (translated_type), param->get_locus ());
-      function_params.push_back (std::move (hir_param));
-    }
-
-  HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
-			       std::move (generic_params),
-			       HIR::SelfParam::error (),
-			       std::move (function_params),
-			       std::move (return_type),
-			       std::move (where_clause));
-  bool terminated = false;
-  std::unique_ptr<HIR::BlockExpr> block_expr
-    = func.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
-	ASTLoweringBlock::translate (func.get_definition ().get (),
-				     &terminated))
-			     : nullptr;
-
-  auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, func.get_node_id (),
-				 mappings->get_next_hir_id (crate_num),
-				 mappings->get_next_localdef_id (crate_num));
-
-  HIR::TraitItemFunc *trait_item
-    = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr),
-			      func.get_outer_attrs (), func.get_locus ());
-  translated = trait_item;
-
-  // add the mappings for the function params at the end
-  for (auto &param : trait_item->get_decl ().get_function_params ())
-    {
-      mappings->insert_hir_param (&param);
-      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-    }
-}
-
-void
-ASTLowerTraitItem::visit (AST::TraitItemMethod &method)
-{
-  AST::TraitMethodDecl &ref = method.get_trait_method_decl ();
-
-  std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-  HIR::WhereClause where_clause (std::move (where_clause_items));
-  HIR::FunctionQualifiers qualifiers
-    = lower_qualifiers (method.get_trait_method_decl ().get_qualifiers ());
-
-  std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-  if (ref.has_generics ())
-    {
-      generic_params = lower_generic_params (ref.get_generic_params ());
-    }
-
-  std::unique_ptr<HIR::Type> return_type
-    = ref.has_return_type () ? std::unique_ptr<HIR::Type> (
-	ASTLoweringType::translate (ref.get_return_type ().get ()))
-			     : nullptr;
-
-  HIR::SelfParam self_param = lower_self (ref.get_self_param ());
-
-  std::vector<HIR::FunctionParam> function_params;
-  for (auto &p : ref.get_function_params ())
-    {
-      if (p->is_variadic () || p->is_self ())
-	continue;
-
-      auto param = static_cast<AST::FunctionParam *> (p.get ());
-
-      auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-	ASTLoweringPattern::translate (param->get_pattern ().get ()));
-      auto translated_type = std::unique_ptr<HIR::Type> (
-	ASTLoweringType::translate (param->get_type ().get ()));
-
-      auto crate_num = mappings->get_current_crate ();
-      Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
-				     mappings->get_next_hir_id (crate_num),
-				     UNKNOWN_LOCAL_DEFID);
-
-      auto hir_param
-	= HIR::FunctionParam (mapping, std::move (translated_pattern),
-			      std::move (translated_type), param->get_locus ());
-      function_params.push_back (hir_param);
-    }
-
-  HIR::TraitFunctionDecl decl (ref.get_identifier (), std::move (qualifiers),
-			       std::move (generic_params),
-			       std::move (self_param),
-			       std::move (function_params),
-			       std::move (return_type),
-			       std::move (where_clause));
-
-  bool terminated = false;
-  std::unique_ptr<HIR::BlockExpr> block_expr
-    = method.has_definition () ? std::unique_ptr<HIR::BlockExpr> (
-	ASTLoweringBlock::translate (method.get_definition ().get (),
-				     &terminated))
-			       : nullptr;
-
-  auto crate_num = mappings->get_current_crate ();
-  Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
-				 mappings->get_next_hir_id (crate_num),
-				 mappings->get_next_localdef_id (crate_num));
-
-  HIR::TraitItemFunc *trait_item
-    = new HIR::TraitItemFunc (mapping, std::move (decl), std::move (block_expr),
-			      method.get_outer_attrs (), method.get_locus ());
-  translated = trait_item;
-
-  // insert mappings for self
-  mappings->insert_hir_self_param (&self_param);
-  mappings->insert_location (self_param.get_mappings ().get_hirid (),
-			     self_param.get_locus ());
-
-  // add the mappings for the function params at the end
-  for (auto &param : trait_item->get_decl ().get_function_params ())
-    {
-      mappings->insert_hir_param (&param);
-      mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-    }
-}
-
 void
 ASTLowerTraitItem::visit (AST::TraitItemConst &constant)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index b9d12cc4a56..bbde9f6878c 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -49,8 +49,6 @@ class ASTLowerTraitItem : public ASTLoweringBase
 public:
   static HIR::TraitItem *translate (AST::AssociatedItem *item);
   void visit (AST::Function &func) override;
-  void visit (AST::TraitItemFunc &func) override;
-  void visit (AST::TraitItemMethod &method) override;
   void visit (AST::TraitItemConst &constant) override;
   void visit (AST::TraitItemType &type) override;
 
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 1283d77d22b..c88bd58860a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -402,14 +402,6 @@ void
 ResolverBase::visit (AST::StaticItem &)
 {}
 
-void
-ResolverBase::visit (AST::TraitItemFunc &)
-{}
-
-void
-ResolverBase::visit (AST::TraitItemMethod &)
-{}
-
 void
 ResolverBase::visit (AST::TraitItemConst &)
 {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 78830498771..9bc64331f5a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -126,8 +126,6 @@ public:
   void visit (AST::Union &);
   void visit (AST::ConstantItem &);
   void visit (AST::StaticItem &);
-  void visit (AST::TraitItemFunc &);
-  void visit (AST::TraitItemMethod &);
   void visit (AST::TraitItemConst &);
   void visit (AST::TraitItemType &);
   void visit (AST::Trait &);
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index d9c9bcb28c9..fabc25817f5 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -130,46 +130,6 @@ public:
     mappings->insert_canonical_path (function.get_node_id (), cpath);
   }
 
-  void visit (AST::TraitItemFunc &function) override
-  {
-    auto decl = CanonicalPath::new_seg (
-      function.get_node_id (),
-      function.get_trait_function_decl ().get_identifier ().as_string ());
-    auto path = prefix.append (decl);
-    auto cpath = canonical_prefix.append (decl);
-
-    resolver->get_name_scope ().insert (
-      path, function.get_node_id (), function.get_locus (), false,
-      Rib::ItemType::Function,
-      [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
-	rich_location r (line_table, function.get_locus ());
-	r.add_range (locus);
-	rust_error_at (r, "redefined multiple times");
-      });
-
-    mappings->insert_canonical_path (function.get_node_id (), cpath);
-  }
-
-  void visit (AST::TraitItemMethod &method) override
-  {
-    auto decl = CanonicalPath::new_seg (
-      method.get_node_id (),
-      method.get_trait_method_decl ().get_identifier ().as_string ());
-    auto path = prefix.append (decl);
-    auto cpath = canonical_prefix.append (decl);
-
-    resolver->get_name_scope ().insert (
-      path, method.get_node_id (), method.get_locus (), false,
-      Rib::ItemType::Function,
-      [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
-	rich_location r (line_table, method.get_locus ());
-	r.add_range (locus);
-	rust_error_at (r, "redefined multiple times");
-      });
-
-    mappings->insert_canonical_path (method.get_node_id (), cpath);
-  }
-
   void visit (AST::TraitItemConst &constant) override
   {
     auto decl
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 6037fe59f5b..e69b945407c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -146,161 +146,6 @@ ResolveTraitItems::visit (AST::TraitItemType &type)
     ResolveTypeBound::go (bound.get ());
 }
 
-void
-ResolveTraitItems::visit (AST::TraitItemFunc &func)
-{
-  auto decl = CanonicalPath::new_seg (
-    func.get_node_id (),
-    func.get_trait_function_decl ().get_identifier ().as_string ());
-  auto path = prefix.append (decl);
-  auto cpath = canonical_prefix.append (decl);
-  mappings->insert_canonical_path (func.get_node_id (), cpath);
-
-  NodeId scope_node_id = func.get_node_id ();
-  resolver->get_name_scope ().push (scope_node_id);
-  resolver->get_type_scope ().push (scope_node_id);
-  resolver->get_label_scope ().push (scope_node_id);
-  resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
-  resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
-
-  AST::TraitFunctionDecl &function = func.get_trait_function_decl ();
-  if (function.has_generics ())
-    for (auto &generic : function.get_generic_params ())
-      ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
-
-  if (function.has_return_type ())
-    ResolveType::go (function.get_return_type ().get ());
-
-  std::vector<PatternBinding> bindings
-    = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
-  // we make a new scope so the names of parameters are resolved and shadowed
-  // correctly
-  for (auto &p : function.get_function_params ())
-    {
-      if (p->is_variadic ())
-	{
-	  auto param = static_cast<AST::VariadicParam *> (p.get ());
-	  PatternDeclaration::go (param->get_pattern ().get (),
-				  Rib::ItemType::Param, bindings);
-	}
-      else if (p->is_self ())
-	{
-	  auto param = static_cast<AST::SelfParam *> (p.get ());
-	  ResolveType::go (param->get_type ().get ());
-	}
-      else
-	{
-	  auto param = static_cast<AST::FunctionParam *> (p.get ());
-	  ResolveType::go (param->get_type ().get ());
-	  PatternDeclaration::go (param->get_pattern ().get (),
-				  Rib::ItemType::Param, bindings);
-	}
-    }
-
-  if (function.has_where_clause ())
-    ResolveWhereClause::Resolve (function.get_where_clause ());
-
-  // trait items have an optional body
-  if (func.has_definition ())
-    ResolveExpr::go (func.get_definition ().get (), path, cpath);
-
-  resolver->get_name_scope ().pop ();
-  resolver->get_type_scope ().pop ();
-  resolver->get_label_scope ().pop ();
-}
-
-void
-ResolveTraitItems::visit (AST::TraitItemMethod &func)
-{
-  auto decl = CanonicalPath::new_seg (
-    func.get_node_id (),
-    func.get_trait_method_decl ().get_identifier ().as_string ());
-  auto path = prefix.append (decl);
-  auto cpath = canonical_prefix.append (decl);
-  mappings->insert_canonical_path (func.get_node_id (), cpath);
-
-  NodeId scope_node_id = func.get_node_id ();
-  resolver->get_name_scope ().push (scope_node_id);
-  resolver->get_type_scope ().push (scope_node_id);
-  resolver->get_label_scope ().push (scope_node_id);
-  resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
-  resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
-  resolver->push_new_label_rib (resolver->get_type_scope ().peek ());
-
-  AST::TraitMethodDecl &function = func.get_trait_method_decl ();
-  if (function.has_generics ())
-    for (auto &generic : function.get_generic_params ())
-      ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
-
-  if (function.has_return_type ())
-    ResolveType::go (function.get_return_type ().get ());
-
-  // self turns into (self: Self) as a function param
-  std::vector<PatternBinding> bindings
-    = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
-  // we make a new scope so the names of parameters are resolved and shadowed
-  // correctly
-  for (auto &p : function.get_function_params ())
-    {
-      if (p->is_variadic ())
-	{
-	  auto param = static_cast<AST::VariadicParam *> (p.get ());
-	  PatternDeclaration::go (param->get_pattern ().get (),
-				  Rib::ItemType::Param, bindings);
-	}
-      else if (p->is_self ())
-	{
-	  auto param = static_cast<AST::SelfParam *> (p.get ());
-	  // FIXME: which location should be used for Rust::Identifier `self`?
-	  AST::IdentifierPattern self_pattern (
-	    param->get_node_id (), {"self"}, param->get_locus (),
-	    param->get_has_ref (), param->get_is_mut (),
-	    std::unique_ptr<AST::Pattern> (nullptr));
-
-	  PatternDeclaration::go (&self_pattern, Rib::ItemType::Param);
-
-	  if (param->has_type ())
-	    {
-	      // This shouldn't happen the parser should already error for this
-	      rust_assert (!param->get_has_ref ());
-	      ResolveType::go (param->get_type ().get ());
-	    }
-	  else
-	    {
-	      // here we implicitly make self have a type path of Self
-	      std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
-	      segments.push_back (std::unique_ptr<AST::TypePathSegment> (
-		new AST::TypePathSegment ("Self", false, param->get_locus ())));
-
-	      AST::TypePath self_type_path (std::move (segments),
-					    param->get_locus ());
-	      ResolveType::go (&self_type_path);
-	    }
-	}
-      else
-	{
-	  auto param = static_cast<AST::FunctionParam *> (p.get ());
-	  ResolveType::go (param->get_type ().get ());
-	  PatternDeclaration::go (param->get_pattern ().get (),
-				  Rib::ItemType::Param, bindings);
-	}
-    }
-
-  if (function.has_where_clause ())
-    ResolveWhereClause::Resolve (function.get_where_clause ());
-
-  // trait items have an optional body
-  if (func.has_definition ())
-    ResolveExpr::go (func.get_definition ().get (), path, cpath);
-
-  resolver->get_name_scope ().pop ();
-  resolver->get_type_scope ().pop ();
-  resolver->get_label_scope ().pop ();
-}
-
 void
 ResolveTraitItems::visit (AST::TraitItemConst &constant)
 {
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 33a78e21957..0c7b7527c44 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -37,8 +37,6 @@ public:
 
   void visit (AST::Function &type) override;
   void visit (AST::TraitItemType &type) override;
-  void visit (AST::TraitItemFunc &func) override;
-  void visit (AST::TraitItemMethod &func) override;
   void visit (AST::TraitItemConst &constant) override;
 
 private:
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index ab4d5e8b70d..b1163535657 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -402,14 +402,6 @@ DefaultResolver::visit (AST::StaticItem &item)
   ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
 }
 
-void
-DefaultResolver::visit (AST::TraitItemFunc &)
-{}
-
-void
-DefaultResolver::visit (AST::TraitItemMethod &)
-{}
-
 void
 DefaultResolver::visit (AST::TraitItemConst &)
 {}
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 20dbff8e110..d508ff3ac79 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -114,8 +114,6 @@ public:
   void visit (AST::EnumItemDiscriminant &);
   void visit (AST::ConstantItem &);
   void visit (AST::StaticItem &);
-  void visit (AST::TraitItemFunc &);
-  void visit (AST::TraitItemMethod &);
   void visit (AST::TraitItemConst &);
   void visit (AST::TraitItemType &);
   void visit (AST::ExternalTypeItem &);
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 46113a8a46b..af7766d7b96 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -228,16 +228,6 @@ TopLevel::visit (AST::StaticItem &static_item)
   ctx.scoped (Rib::Kind::Item, static_item.get_node_id (), sub_vis);
 }
 
-void
-TopLevel::visit (AST::TraitItemFunc &item)
-{
-  auto def_vis
-    = [this, &item] () { item.get_definition ()->accept_vis (*this); };
-
-  if (item.has_definition ())
-    ctx.scoped (Rib::Kind::Function, item.get_node_id (), def_vis);
-}
-
 void
 TopLevel::visit (AST::StructStruct &struct_item)
 {
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 996899b0848..f1943ee1398 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -65,7 +65,6 @@ private:
   void visit (AST::Function &function) override;
   void visit (AST::BlockExpr &expr) override;
   void visit (AST::StaticItem &static_item) override;
-  void visit (AST::TraitItemFunc &item) override;
   void visit (AST::StructStruct &struct_item) override;
   void visit (AST::TupleStruct &tuple_struct) override;
   void visit (AST::EnumItem &variant) override;
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 3c296b565f5..715e9a0b361 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -730,14 +730,6 @@ AttributeChecker::visit (AST::StaticItem &item)
   check_proc_macro_non_function (item.get_outer_attrs ());
 }
 
-void
-AttributeChecker::visit (AST::TraitItemFunc &)
-{}
-
-void
-AttributeChecker::visit (AST::TraitItemMethod &)
-{}
-
 void
 AttributeChecker::visit (AST::TraitItemConst &)
 {}
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index eecc4c0050b..d78ab0b3319 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -192,8 +192,6 @@ private:
   void visit (AST::Union &union_item) override;
   void visit (AST::ConstantItem &const_item) override;
   void visit (AST::StaticItem &static_item) override;
-  void visit (AST::TraitItemFunc &item) override;
-  void visit (AST::TraitItemMethod &item) override;
   void visit (AST::TraitItemConst &item) override;
   void visit (AST::TraitItemType &item) override;
   void visit (AST::Trait &trait) override;
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [COMMITTED 25/25] gccrs: Fix macro parsing for trait items.
  2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
                   ` (22 preceding siblings ...)
  2024-02-07 11:44 ` [COMMITTED 24/25] gccrs: Remove obsolete classes and functions arthur.cohen
@ 2024-02-07 11:44 ` arthur.cohen
  23 siblings, 0 replies; 30+ messages in thread
From: arthur.cohen @ 2024-02-07 11:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-rust, Kushal Pal

From: Kushal Pal <kushalpal109@gmail.com>

gcc/rust/ChangeLog:

	* parse/rust-parse-impl.h (Parser::parse_trait_item):
	Handle macros in trait items similar to how its handled for trait
	implementation items.

Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
---
 gcc/rust/parse/rust-parse-impl.h | 37 ++++++++++++++++----------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ed264371db7..ac1754542d4 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -5094,6 +5094,18 @@ Parser<ManagedTokenSource>::parse_trait_item ()
   const_TokenPtr tok = lexer.peek_token ();
   switch (tok->get_id ())
     {
+    case SUPER:
+    case SELF:
+    case CRATE:
+    case DOLLAR_SIGN:
+      // these seem to be SimplePath tokens, so this is a macro invocation
+      // semi
+      return parse_macro_invocation_semi (std::move (outer_attrs));
+    case IDENTIFIER:
+      if (lexer.peek_token ()->get_str () == Values::WeakKeywords::DEFAULT)
+	return parse_function (std::move (vis), std::move (outer_attrs));
+      else
+	return parse_macro_invocation_semi (std::move (outer_attrs));
     case TYPE:
       return parse_trait_type (std::move (outer_attrs), vis);
     case CONST:
@@ -5110,25 +5122,14 @@ Parser<ManagedTokenSource>::parse_trait_item ()
     case EXTERN_KW:
     case FN_KW:
       return parse_function (std::move (vis), std::move (outer_attrs));
-
-      default: {
-	// TODO: try and parse macro invocation semi - if fails, maybe error.
-	std::unique_ptr<AST::TraitItem> macro_invoc
-	  = parse_macro_invocation_semi (outer_attrs);
-
-	if (macro_invoc == nullptr)
-	  {
-	    // TODO: error?
-	    return nullptr;
-	  }
-	else
-	  {
-	    return macro_invoc;
-	  }
-	/* FIXME: macro invocations can only start with certain tokens. be
-	 * more picky with these? */
-      }
+    default:
+      break;
     }
+  add_error (Error (tok->get_locus (),
+		    "unrecognised token %qs for item in trait",
+		    tok->get_token_description ()));
+  // skip?
+  return nullptr;
 }
 
 // Parse a typedef trait item.
-- 
2.42.1


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [COMMITTED 07/25] gccrs: TyTy: Store region constraints
  2024-02-07 15:26   ` Bernhard Reutner-Fischer
@ 2024-02-07 14:46     ` Arthur Cohen
  0 siblings, 0 replies; 30+ messages in thread
From: Arthur Cohen @ 2024-02-07 14:46 UTC (permalink / raw)
  To: Bernhard Reutner-Fischer; +Cc: gcc-patches, gcc-rust, Jakub Dupak


[-- Attachment #1.1.1: Type: text/plain, Size: 997 bytes --]

On 2/7/24 16:26, Bernhard Reutner-Fischer wrote:
> On Wed,  7 Feb 2024 12:43:53 +0100
> arthur.cohen@embecosm.com wrote:
> 
>> diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> index 067465ec77a..4d178440775 100644
>> --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> @@ -97,6 +97,7 @@ private:
>>     HIR::ImplBlock *parent;
>>     TyTy::BaseType *self;
>>     std::vector<TyTy::SubstitutionParamMapping> substitutions;
>> +  TyTy::RegionConstraints region_costraints;
>>   };
> 
> /region_costraint/s/cos/cons/;# or delete since it seems unused ATM?
> 
> thanks

Thanks!

We're merging this in our development branch at the moment and it will 
be upstreamed soon. I'd rather keep the field for now as one of our 
contributor is working on this and splitting commits as much as possible 
to make reviewing easier.

Kindly,

Arthur

[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3195 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [COMMITTED 07/25] gccrs: TyTy: Store region constraints
  2024-02-07 11:43 ` [COMMITTED 07/25] gccrs: TyTy: Store region constraints arthur.cohen
@ 2024-02-07 15:26   ` Bernhard Reutner-Fischer
  2024-02-07 14:46     ` Arthur Cohen
  0 siblings, 1 reply; 30+ messages in thread
From: Bernhard Reutner-Fischer @ 2024-02-07 15:26 UTC (permalink / raw)
  To: arthur.cohen; +Cc: rep.dot.nop, gcc-patches, gcc-rust, Jakub Dupak

On Wed,  7 Feb 2024 12:43:53 +0100
arthur.cohen@embecosm.com wrote:

> diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> index 067465ec77a..4d178440775 100644
> --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> @@ -97,6 +97,7 @@ private:
>    HIR::ImplBlock *parent;
>    TyTy::BaseType *self;
>    std::vector<TyTy::SubstitutionParamMapping> substitutions;
> +  TyTy::RegionConstraints region_costraints;
>  };

/region_costraint/s/cos/cons/;# or delete since it seems unused ATM?

thanks

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg
  2024-02-07 11:43 ` [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg arthur.cohen
@ 2024-02-09 10:03   ` Jakub Jelinek
  2024-02-15  9:10     ` [PATCH] gccrs: Avoid *.bak suffixed tests - use dg-skip-if instead Jakub Jelinek
  0 siblings, 1 reply; 30+ messages in thread
From: Jakub Jelinek @ 2024-02-09 10:03 UTC (permalink / raw)
  To: arthur.cohen; +Cc: gcc-patches, gcc-rust, Philip Herron

On Wed, Feb 07, 2024 at 12:43:59PM +0100, arthur.cohen@embecosm.com wrote:
> From: Philip Herron <herron.philip@googlemail.com>
> 
> This patch introduces one regression because generics are getting better
> understood over time. The code here used to apply generics with the same
> symbol from previous segments which was a bit of a hack with out limited
> inference variable support. The regression looks like it will be related
> to another issue which needs to default integer inference variables much
> more aggresivly to default integer.
> 
> Fixes #2723
> 
> gcc/rust/ChangeLog:
> 
> 	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): remove hack
> 
> gcc/testsuite/ChangeLog:
> 
> 	* rust/compile/issue-1773.rs: Moved to...
> 	* rust/compile/issue-1773.rs.bak: ...here.

Please don't use such suffixes in the testsuite.
Either delete the testcase, or xfail it somehow until the bug is fixed.

	Jakub


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] gccrs: Avoid *.bak suffixed tests - use dg-skip-if instead
  2024-02-09 10:03   ` Jakub Jelinek
@ 2024-02-15  9:10     ` Jakub Jelinek
  2024-02-15 13:12       ` Arthur Cohen
  0 siblings, 1 reply; 30+ messages in thread
From: Jakub Jelinek @ 2024-02-15  9:10 UTC (permalink / raw)
  To: Arthur Cohen, Philip Herron; +Cc: gcc-patches, gcc-rust

On Fri, Feb 09, 2024 at 11:03:38AM +0100, Jakub Jelinek wrote:
> On Wed, Feb 07, 2024 at 12:43:59PM +0100, arthur.cohen@embecosm.com wrote:
> > From: Philip Herron <herron.philip@googlemail.com>
> > 
> > This patch introduces one regression because generics are getting better
> > understood over time. The code here used to apply generics with the same
> > symbol from previous segments which was a bit of a hack with out limited
> > inference variable support. The regression looks like it will be related
> > to another issue which needs to default integer inference variables much
> > more aggresivly to default integer.
> > 
> > Fixes #2723
> > 
> > gcc/rust/ChangeLog:
> > 
> > 	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): remove hack
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > 	* rust/compile/issue-1773.rs: Moved to...
> > 	* rust/compile/issue-1773.rs.bak: ...here.
> 
> Please don't use such suffixes in the testsuite.
> Either delete the testcase, or xfail it somehow until the bug is fixed.

To be precise, I have scripts to look for backup files in the tree (*~,
*.bak, *.orig, *.rej etc.) and this stands in the way several times a day.

Here is a fix for that in patch form, tested on x86_64-linux with
make check-rust RUNTESTFLAGS='compile.exp=issue-1773.rs'
Ok for trunk?

2024-02-15  Jakub Jelinek  <jakub@redhat.com>

	* rust/compile/issue-1773.rs.bak: Rename to ...
	* rust/compile/issue-1773.rs: ... this.  Add dg-skip-if directive.

diff --git a/gcc/testsuite/rust/compile/issue-1773.rs.bak b/gcc/testsuite/rust/compile/issue-1773.rs
similarity index 89%
rename from gcc/testsuite/rust/compile/issue-1773.rs.bak
rename to gcc/testsuite/rust/compile/issue-1773.rs
index a4542aea00b..468497a4792 100644
--- a/gcc/testsuite/rust/compile/issue-1773.rs.bak
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -1,4 +1,5 @@
 #[lang = "sized"]
+// { dg-skip-if "" { *-*-* } }
 pub trait Sized {}
 
 trait Foo<T> {

	Jakub


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] gccrs: Avoid *.bak suffixed tests - use dg-skip-if instead
  2024-02-15  9:10     ` [PATCH] gccrs: Avoid *.bak suffixed tests - use dg-skip-if instead Jakub Jelinek
@ 2024-02-15 13:12       ` Arthur Cohen
  0 siblings, 0 replies; 30+ messages in thread
From: Arthur Cohen @ 2024-02-15 13:12 UTC (permalink / raw)
  To: Jakub Jelinek, Philip Herron; +Cc: gcc-patches, gcc-rust

Hi Jakub,

On 2/15/24 10:10, Jakub Jelinek wrote:
> On Fri, Feb 09, 2024 at 11:03:38AM +0100, Jakub Jelinek wrote:
>> On Wed, Feb 07, 2024 at 12:43:59PM +0100, arthur.cohen@embecosm.com wrote:
>>> From: Philip Herron <herron.philip@googlemail.com>
>>>
>>> This patch introduces one regression because generics are getting better
>>> understood over time. The code here used to apply generics with the same
>>> symbol from previous segments which was a bit of a hack with out limited
>>> inference variable support. The regression looks like it will be related
>>> to another issue which needs to default integer inference variables much
>>> more aggresivly to default integer.
>>>
>>> Fixes #2723
>>>
>>> gcc/rust/ChangeLog:
>>>
>>> 	* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): remove hack
>>>
>>> gcc/testsuite/ChangeLog:
>>>
>>> 	* rust/compile/issue-1773.rs: Moved to...
>>> 	* rust/compile/issue-1773.rs.bak: ...here.
>>
>> Please don't use such suffixes in the testsuite.
>> Either delete the testcase, or xfail it somehow until the bug is fixed.
> 
> To be precise, I have scripts to look for backup files in the tree (*~,
> *.bak, *.orig, *.rej etc.) and this stands in the way several times a day.
> 
> Here is a fix for that in patch form, tested on x86_64-linux with
> make check-rust RUNTESTFLAGS='compile.exp=issue-1773.rs'
> Ok for trunk? >
> 2024-02-15  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* rust/compile/issue-1773.rs.bak: Rename to ...
> 	* rust/compile/issue-1773.rs: ... this.  Add dg-skip-if directive.
> 
> diff --git a/gcc/testsuite/rust/compile/issue-1773.rs.bak b/gcc/testsuite/rust/compile/issue-1773.rs
> similarity index 89%
> rename from gcc/testsuite/rust/compile/issue-1773.rs.bak
> rename to gcc/testsuite/rust/compile/issue-1773.rs
> index a4542aea00b..468497a4792 100644
> --- a/gcc/testsuite/rust/compile/issue-1773.rs.bak
> +++ b/gcc/testsuite/rust/compile/issue-1773.rs
> @@ -1,4 +1,5 @@
>   #[lang = "sized"]
> +// { dg-skip-if "" { *-*-* } }
>   pub trait Sized {}
>   
>   trait Foo<T> {
> 
> 	Jakub
> 


Looks good to me, thanks for taking the time! OK for trunk.

Best,

Arthur

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2024-02-15 12:12 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-07 11:43 [COMMITTED 01/25] gccrs: Parse normal functions with `self` parameter correctly arthur.cohen
2024-02-07 11:43 ` [COMMITTED 02/25] gccrs: Implement quick-check for Unicode arthur.cohen
2024-02-07 11:43 ` [COMMITTED 03/25] gccrs: Typecheck: lifetime interning and resolution tool arthur.cohen
2024-02-07 11:43 ` [COMMITTED 04/25] gccrs: TyTy: Region (lifetime) representation arthur.cohen
2024-02-07 11:43 ` [COMMITTED 05/25] gccrs: HIR: Add mising getter arthur.cohen
2024-02-07 11:43 ` [COMMITTED 06/25] gccrs: Typecheck: add regions (lifetimes) to TyTy arthur.cohen
2024-02-07 11:43 ` [COMMITTED 07/25] gccrs: TyTy: Store region constraints arthur.cohen
2024-02-07 15:26   ` Bernhard Reutner-Fischer
2024-02-07 14:46     ` Arthur Cohen
2024-02-07 11:43 ` [COMMITTED 08/25] gccrs: TyTy: Store reference to type before any substitutions arthur.cohen
2024-02-07 11:43 ` [COMMITTED 09/25] gccrs: Set the default ABI to C for extern blocks and extern functions arthur.cohen
2024-02-07 11:43 ` [COMMITTED 10/25] gccrs: add testcase to prove issue has already been fixed arthur.cohen
2024-02-07 11:43 ` [COMMITTED 11/25] gccrs: add test cases to prove type inference is working arthur.cohen
2024-02-07 11:43 ` [COMMITTED 12/25] gccrs: Fix ICE accessing empty vector without check arthur.cohen
2024-02-07 11:43 ` [COMMITTED 13/25] gccrs: remove old generics hack to reuse generic symbols from previous seg arthur.cohen
2024-02-09 10:03   ` Jakub Jelinek
2024-02-15  9:10     ` [PATCH] gccrs: Avoid *.bak suffixed tests - use dg-skip-if instead Jakub Jelinek
2024-02-15 13:12       ` Arthur Cohen
2024-02-07 11:44 ` [COMMITTED 14/25] gccrs: remove similar hack in type paths as we had in path expressions arthur.cohen
2024-02-07 11:44 ` [COMMITTED 15/25] gccrs: refactor inference variable computation into a seperate method arthur.cohen
2024-02-07 11:44 ` [COMMITTED 16/25] gccrs: Move the Implementation of implitem lowering into its own file arthur.cohen
2024-02-07 11:44 ` [COMMITTED 17/25] gccrs: Add testcase to show issue is already fixed arthur.cohen
2024-02-07 11:44 ` [COMMITTED 18/25] gccrs: fix bug in pattern check for tuples arthur.cohen
2024-02-07 11:44 ` [COMMITTED 19/25] gccrs: Use AssociatedItem in place of TraitItem arthur.cohen
2024-02-07 11:44 ` [COMMITTED 20/25] gccrs: Add checks for Trait functions arthur.cohen
2024-02-07 11:44 ` [COMMITTED 21/25] gccrs: Add missing visitors for AST::Function arthur.cohen
2024-02-07 11:44 ` [COMMITTED 22/25] gccrs: Fix inconsistent formatting arthur.cohen
2024-02-07 11:44 ` [COMMITTED 23/25] gccrs: Parse trait functions as `AST::Function` arthur.cohen
2024-02-07 11:44 ` [COMMITTED 24/25] gccrs: Remove obsolete classes and functions arthur.cohen
2024-02-07 11:44 ` [COMMITTED 25/25] gccrs: Fix macro parsing for trait items arthur.cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).