[COMMITTED 01/35] gccrs: Fix function name to printf

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

Function could not be found and triggered an error message.

gcc/testsuite/ChangeLog:

* rust/compile/feature_rust_attri0.rs: Add extern
function declaration and change name to printf.
* rust/compile/nr2/exclude: Remove now passing test from exclusion
list.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/feature_rust_attri0.rs | 6 +-
 gcc/testsuite/rust/compile/nr2/exclude| 1 -
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/rust/compile/feature_rust_attri0.rs 
b/gcc/testsuite/rust/compile/feature_rust_attri0.rs
index 9c11f561b5b..1937acf3fe5 100644
--- a/gcc/testsuite/rust/compile/feature_rust_attri0.rs
+++ b/gcc/testsuite/rust/compile/feature_rust_attri0.rs
@@ -1,3 +1,7 @@
+extern "C" {
+fn printf(s: *const i8, ...);
+}
+
 #[rustc_builtin_macro] //{ dg-error "internal implementation detail. " "" { 
target *-*-* }  }
 macro_rules! line {
 () => {{}};
@@ -5,7 +9,7 @@ macro_rules! line {
 
 fn main() -> i32 {
 let a = line!();
-print(a);
+printf("%d\0" as *const str as *const i8, a);
 
 0
 }
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index fed7bde6307..1582d5a2d96 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -1,7 +1,6 @@
 canonical_paths1.rs
 cfg1.rs
 const_generics_3.rs
-feature_rust_attri0.rs
 generics9.rs
 issue-1901.rs
 issue-1981.rs
-- 
2.49.0



[COMMITTED 05/35] gccrs: parser: Parse let-else statements

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

gcc/rust/ChangeLog:

* parse/rust-parse-impl.h (Parser::parse_let_stmt): Add new parsing in 
case of `else` token.
---
 gcc/rust/parse/rust-parse-impl.h | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index dd6086896f8..71d72504cfc 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -6163,6 +6163,10 @@ Parser::parse_let_stmt (AST::AttrVec 
outer_attrs,
}
 }
 
+  tl::optional> else_expr = tl::nullopt;
+  if (maybe_skip_token (ELSE))
+else_expr = parse_block_expr ();
+
   if (restrictions.consume_semi)
 {
   // `stmt` macro variables are parsed without a semicolon, but should be
@@ -6177,7 +6181,7 @@ Parser::parse_let_stmt (AST::AttrVec 
outer_attrs,
 
   return std::unique_ptr (
 new AST::LetStmt (std::move (pattern), std::move (expr), std::move (type),
- std::move (outer_attrs), locus));
+ std::move (else_expr), std::move (outer_attrs), locus));
 }
 
 // Parses a type path.
-- 
2.49.0



[COMMITTED 06/35] gccrs: dump: Handle let-else properly

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

gcc/rust/ChangeLog:

* ast/rust-ast-collector.cc (TokenCollector::visit): Add handling for 
diverging else
expression.
---
 gcc/rust/ast/rust-ast-collector.cc | 8 
 1 file changed, 8 insertions(+)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 073fa728dcf..3297407e6e8 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -22,6 +22,7 @@
 #include "rust-expr.h"
 #include "rust-item.h"
 #include "rust-keyword-values.h"
+#include "rust-location.h"
 #include "rust-path.h"
 #include "rust-system.h"
 #include "rust-token.h"
@@ -2587,6 +2588,13 @@ TokenCollector::visit (LetStmt &stmt)
   push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
   visit (stmt.get_init_expr ());
 }
+
+  if (stmt.has_else_expr ())
+{
+  push (Rust::Token::make (ELSE, UNDEF_LOCATION));
+  visit (stmt.get_else_expr ());
+}
+
   push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
 }
 
-- 
2.49.0



[COMMITTED 03/35] gccrs: Remove now passing test from exclusion list

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

Those tests were malformed and failed with the new name resolution
because of it.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove test from exclusion list.

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

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 1582d5a2d96..45e90a4df93 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -2,8 +2,6 @@ canonical_paths1.rs
 cfg1.rs
 const_generics_3.rs
 generics9.rs
-issue-1901.rs
-issue-1981.rs
 issue-2043.rs
 issue-2330.rs
 issue-2812.rs
@@ -21,7 +19,6 @@ privacy8.rs
 pub_restricted_1.rs
 pub_restricted_2.rs
 pub_restricted_3.rs
-sizeof-stray-infer-var-bug.rs
 undeclared_label.rs
 use_1.rs
 while_break_expr.rs
@@ -37,9 +34,7 @@ issue-3403.rs
 derive-eq-invalid.rs
 derive-hash1.rs
 torture/alt_patterns1.rs
-torture/builtin_abort.rs
 torture/loop4.rs
 torture/loop8.rs
 torture/name_resolve1.rs
-torture/uninit-intrinsic-1.rs
 # please don't delete the trailing newline
-- 
2.49.0



[COMMITTED 04/35] gccrs: ast: Add optional diverging else to AST::LetStmt

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

gcc/rust/ChangeLog:

* ast/rust-stmt.h (class LetStmt): Add optional expression for 
diverging else.
* ast/rust-ast-builder.cc (Builder::let): Use new API.
---
 gcc/rust/ast/rust-ast-builder.cc |  3 ++-
 gcc/rust/ast/rust-stmt.h | 29 -
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 86290e199c6..cdc6eec254b 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -17,6 +17,7 @@
 // .
 
 #include "rust-ast-builder.h"
+#include "optional.h"
 #include "rust-ast-builder-type.h"
 #include "rust-ast.h"
 #include "rust-common.h"
@@ -352,7 +353,7 @@ Builder::let (std::unique_ptr &&pattern, 
std::unique_ptr &&type,
 {
   return std::unique_ptr (new LetStmt (std::move (pattern),
 std::move (init), std::move (type),
-{}, loc));
+tl::nullopt, {}, loc));
 }
 
 std::unique_ptr
diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h
index 6cbecaffd03..f843a79b3f9 100644
--- a/gcc/rust/ast/rust-stmt.h
+++ b/gcc/rust/ast/rust-stmt.h
@@ -19,6 +19,7 @@
 #ifndef RUST_AST_STATEMENT_H
 #define RUST_AST_STATEMENT_H
 
+#include "optional.h"
 #include "rust-ast.h"
 #include "rust-path.h"
 #include "rust-expr.h"
@@ -72,6 +73,8 @@ class LetStmt : public Stmt
   // bool has_init_expr;
   std::unique_ptr init_expr;
 
+  tl::optional> else_expr;
+
   location_t locus;
 
 public:
@@ -85,15 +88,18 @@ public:
 
   // Returns whether let statement has an initialisation expression.
   bool has_init_expr () const { return init_expr != nullptr; }
+  bool has_else_expr () const { return else_expr.has_value (); }
 
   std::string as_string () const override;
 
   LetStmt (std::unique_ptr variables_pattern,
   std::unique_ptr init_expr, std::unique_ptr type,
+  tl::optional> else_expr,
   std::vector outer_attrs, location_t locus)
 : outer_attrs (std::move (outer_attrs)),
   variables_pattern (std::move (variables_pattern)),
-  type (std::move (type)), init_expr (std::move (init_expr)), locus (locus)
+  type (std::move (type)), init_expr (std::move (init_expr)),
+  else_expr (std::move (else_expr)), locus (locus)
   {}
 
   // Copy constructor with clone
@@ -107,6 +113,9 @@ public:
 // guard to prevent null dereference (always required)
 if (other.init_expr != nullptr)
   init_expr = other.init_expr->clone_expr ();
+if (other.else_expr.has_value ())
+  else_expr = other.else_expr.value ()->clone_expr ();
+
 if (other.type != nullptr)
   type = other.type->clone_type ();
   }
@@ -128,6 +137,12 @@ public:
   init_expr = other.init_expr->clone_expr ();
 else
   init_expr = nullptr;
+
+if (other.else_expr != nullptr)
+  else_expr = other.else_expr.value ()->clone_expr ();
+else
+  else_expr = tl::nullopt;
+
 if (other.type != nullptr)
   type = other.type->clone_type ();
 else
@@ -162,12 +177,24 @@ public:
 return *init_expr;
   }
 
+  Expr &get_else_expr ()
+  {
+rust_assert (has_else_expr ());
+return *else_expr.value ();
+  }
+
   std::unique_ptr &get_init_expr_ptr ()
   {
 rust_assert (has_init_expr ());
 return init_expr;
   }
 
+  std::unique_ptr &get_else_expr_ptr ()
+  {
+rust_assert (has_else_expr ());
+return else_expr.value ();
+  }
+
   Pattern &get_pattern ()
   {
 rust_assert (variables_pattern != nullptr);
-- 
2.49.0



[COMMITTED 02/35] gccrs: Fix testcase module path

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

Those tests are coming from libcore and module inlining was wrong, in
libcore there was a use declaration to import those modules which was
missing here.

gcc/testsuite/ChangeLog:

* rust/compile/issue-2330.rs: Use complete path from crate root.
* rust/compile/issue-1901.rs: Likewise.
* rust/compile/issue-1981.rs: Likewise.
* rust/compile/iterators1.rs: Likewise.
* rust/compile/sizeof-stray-infer-var-bug.rs: Likewise.
* rust/compile/for-loop1.rs: Likewise.
* rust/compile/for-loop2.rs: Likewise.
* rust/compile/torture/builtin_abort.rs: Likewise.
* rust/compile/torture/uninit-intrinsic-1.rs: Likewise.

Signed-off-by: Pierre-Emmanuel Patry 
---
 gcc/testsuite/rust/compile/for-loop1.rs   | 60 -
 gcc/testsuite/rust/compile/for-loop2.rs   | 66 ++-
 gcc/testsuite/rust/compile/issue-1901.rs  |  4 +-
 gcc/testsuite/rust/compile/issue-1981.rs  | 40 +--
 gcc/testsuite/rust/compile/issue-2330.rs  | 38 +--
 gcc/testsuite/rust/compile/iterators1.rs  | 58 
 .../compile/sizeof-stray-infer-var-bug.rs |  2 +-
 .../rust/compile/torture/builtin_abort.rs |  4 +-
 .../compile/torture/uninit-intrinsic-1.rs |  4 +-
 9 files changed, 139 insertions(+), 137 deletions(-)

diff --git a/gcc/testsuite/rust/compile/for-loop1.rs 
b/gcc/testsuite/rust/compile/for-loop1.rs
index 1023ecde1c3..21e0399161b 100644
--- a/gcc/testsuite/rust/compile/for-loop1.rs
+++ b/gcc/testsuite/rust/compile/for-loop1.rs
@@ -102,30 +102,30 @@ mod ptr {
 #[lang = "const_ptr"]
 impl *const T {
 pub unsafe fn offset(self, count: isize) -> *const T {
-intrinsics::offset(self, count)
+crate::intrinsics::offset(self, count)
 }
 }
 
 #[lang = "mut_ptr"]
 impl *mut T {
 pub unsafe fn offset(self, count: isize) -> *mut T {
-intrinsics::offset(self, count) as *mut T
+crate::intrinsics::offset(self, count) as *mut T
 }
 }
 
 pub unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) {
 let x = x as *mut u8;
 let y = y as *mut u8;
-let len = mem::size_of::() * count;
+let len = crate::mem::size_of::() * count;
 swap_nonoverlapping_bytes(x, y, len)
 }
 
 pub unsafe fn swap_nonoverlapping_one(x: *mut T, y: *mut T) {
 // For types smaller than the block optimization below,
 // just swap directly to avoid pessimizing codegen.
-if mem::size_of::() < 32 {
+if crate::mem::size_of::() < 32 {
 let z = read(x);
-intrinsics::copy_nonoverlapping(y, x, 1);
+crate::intrinsics::copy_nonoverlapping(y, x, 1);
 write(y, z);
 } else {
 swap_nonoverlapping(x, y, 1);
@@ -133,12 +133,12 @@ mod ptr {
 }
 
 pub unsafe fn write(dst: *mut T, src: T) {
-intrinsics::move_val_init(&mut *dst, src)
+crate::intrinsics::move_val_init(&mut *dst, src)
 }
 
 pub unsafe fn read(src: *const T) -> T {
-let mut tmp: T = mem::uninitialized();
-intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
+let mut tmp: T = crate::mem::uninitialized();
+crate::intrinsics::copy_nonoverlapping(src, &mut tmp, 1);
 tmp
 }
 
@@ -146,7 +146,7 @@ mod ptr {
 struct Block(u64, u64, u64, u64);
 struct UnalignedBlock(u64, u64, u64, u64);
 
-let block_size = mem::size_of::();
+let block_size = crate::mem::size_of::();
 
 // Loop through x & y, copying them `Block` at a time
 // The optimizer should unroll the loop fully for most types
@@ -155,31 +155,31 @@ mod ptr {
 while i + block_size <= len {
 // Create some uninitialized memory as scratch space
 // Declaring `t` here avoids aligning the stack when this loop is 
unused
-let mut t: Block = mem::uninitialized();
+let mut t: Block = crate::mem::uninitialized();
 let t = &mut t as *mut _ as *mut u8;
 let x = x.offset(i as isize);
 let y = y.offset(i as isize);
 
 // Swap a block of bytes of x & y, using t as a temporary buffer
 // This should be optimized into efficient SIMD operations where 
available
-intrinsics::copy_nonoverlapping(x, t, block_size);
-intrinsics::copy_nonoverlapping(y, x, block_size);
-intrinsics::copy_nonoverlapping(t, y, block_size);
+crate::intrinsics::copy_nonoverlapping(x, t, block_size);
+crate::intrinsics::copy_nonoverlapping(y, x, block_size);
+crate::intrinsics::copy_nonoverlapping(t, y, block_size);
 i += block_size;
 }
 
 if i < len {
 // Swap any remaining bytes
-let mut t: UnalignedBlock = mem::uninitialized();
+let mut t: Un

[COMMITTED 14/35] gccrs: fix unconstrained infer vars on generic associated type

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

The trick here is that when Bar::test is resolved it resolves to the
trait method:

  fn , T> (placeholder) -> placeholder

Which is fine so we need to setup the associated types for Bar which
means looking up the associated impl block then setting up the projection
of A = T so it becomes:

  fn , T> (placeholder: projection:T)
-> placeholder: projection:T

But previously it was auto injecting inference variables so it became:

  fn , T> (placeholder: projection:?T)
-> placeholder: projection:?T

The issue is that the binding of the generics was still T so this caused
inference variables to be injected again but unlinked. A possible tweak
would be that we are substituting again with new infer vars to actually
just unify them enplace so they are all part of the chain. This still
might be needed but lets hold off for now.

So basically when we are Path probing we dont allow GAT's to generate new
inference vars because they wont be bound to this current segment which
just causes confusion.

Fixes Rust-GCC#3242

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-reference.h: add default infer arg
* typecheck/rust-hir-trait-resolve.cc: dont add new infer vars
* typecheck/rust-hir-type-check-path.cc 
(TypeCheckExpr::resolve_segments): dont infer

gcc/testsuite/ChangeLog:

* rust/compile/issue-3242.rs: no longer skip the test

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-trait-reference.h  | 7 +++
 gcc/rust/typecheck/rust-hir-trait-resolve.cc   | 8 
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 4 ++--
 gcc/testsuite/rust/compile/issue-3242.rs   | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h 
b/gcc/rust/typecheck/rust-hir-trait-reference.h
index 6a570ed0fdb..8b1ac7daf7f 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -254,10 +254,9 @@ public:
 
   void setup_raw_associated_types ();
 
-  TyTy::BaseType *
-  setup_associated_types (const TyTy::BaseType *self,
- const TyTy::TypeBoundPredicate &bound,
- TyTy::SubstitutionArgumentMappings *args = nullptr);
+  TyTy::BaseType *setup_associated_types (
+const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
+TyTy::SubstitutionArgumentMappings *args = nullptr, bool infer = true);
 
   void reset_associated_types ();
 
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index c07425d48b7..e4a61bdb062 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -485,7 +485,7 @@ AssociatedImplTrait::setup_raw_associated_types ()
 TyTy::BaseType *
 AssociatedImplTrait::setup_associated_types (
   const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
-  TyTy::SubstitutionArgumentMappings *args)
+  TyTy::SubstitutionArgumentMappings *args, bool infer)
 {
   // compute the constrained impl block generic arguments based on self and the
   // higher ranked trait bound
@@ -545,7 +545,7 @@ AssociatedImplTrait::setup_associated_types (
   std::vector subst_args;
   for (auto &p : substitutions)
 {
-  if (p.needs_substitution ())
+  if (p.needs_substitution () && infer)
{
  TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
  subst_args.push_back (
@@ -619,7 +619,7 @@ AssociatedImplTrait::setup_associated_types (
= unify_site_and (a->get_ref (), TyTy::TyWithLocation (a),
  TyTy::TyWithLocation (b), impl_predicate.get_locus (),
  true /*emit-errors*/, true /*commit-if-ok*/,
- false /*infer*/, true /*cleanup-on-fail*/);
+ true /*infer*/, true /*cleanup-on-fail*/);
   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
 }
 
@@ -632,7 +632,7 @@ AssociatedImplTrait::setup_associated_types (
TyTy::TyWithLocation (impl_self_infer),
impl_predicate.get_locus (),
true /*emit-errors*/, true /*commit-if-ok*/,
-   false /*infer*/, true /*cleanup-on-fail*/);
+   true /*infer*/, true /*cleanup-on-fail*/);
   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
   TyTy::BaseType *self_result = result;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 33570ffa1c7..1fe39aaeb64 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -535,8 +535,8 @@ TypeCheckExpr::resolve_segments (NodeId 
root_resolved_node_id,
= impl_block_ty->lookup_predicate (trait_ref.get_defid ());
  if (!predicate.is_error ())

[COMMITTED 15/35] gccrs: Fix core library test with proper canonical path

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

Import from core library was wrong, it misses several crate directives
since we're no longer dealing with multiple files.

gcc/testsuite/ChangeLog:

* rust/compile/issue-2905-2.rs: Import from core library into a single
file misses the crate directives.

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

diff --git a/gcc/testsuite/rust/compile/issue-2905-2.rs 
b/gcc/testsuite/rust/compile/issue-2905-2.rs
index 83c54ed92e5..1c9516df946 100644
--- a/gcc/testsuite/rust/compile/issue-2905-2.rs
+++ b/gcc/testsuite/rust/compile/issue-2905-2.rs
@@ -17,10 +17,10 @@ pub mod core {
 }
 
 pub mod slice {
-use core::marker::PhantomData;
-use core::option::Option;
+use crate::core::marker::PhantomData;
+use crate::core::option::Option;
 
-impl core::iter::IntoIterator for &[T] {
+impl crate::core::iter::IntoIterator for &[T] {
 type Item = &T;
 type IntoIter = Weird;
 
@@ -108,7 +108,7 @@ pub mod core {
 }
 
 pub mod iter {
-use option::Option;
+use crate::core::option::Option;
 
 pub trait IntoIterator {
 type Item;
-- 
2.49.0



[COMMITTED 17/35] gccrs: Add check for super traits being implemented by Self

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

We need to recursively check the super traits of the predicate the Self
type is trying to implement. Otherwise its cannot implement it.

Fixes Rust-GCC#3553

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-item.cc 
(TypeCheckItem::resolve_impl_block_substitutions):
Track the polarity
* typecheck/rust-tyty-bounds.cc 
(TypeBoundPredicate::validate_type_implements_this):
new validator
* typecheck/rust-tyty.h: new prototypes

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-item.cc | 13 +++-
 gcc/rust/typecheck/rust-tyty-bounds.cc| 59 +++
 gcc/rust/typecheck/rust-tyty.h|  8 +++
 gcc/testsuite/rust/compile/issue-3553.rs  | 18 ++
 4 files changed, 95 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3553.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc 
b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index a003848cce0..97749214351 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -725,11 +725,11 @@ TypeCheckItem::resolve_impl_block_substitutions 
(HIR::ImplBlock &impl_block,
 
   // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
   // for example
-  specified_bound = get_predicate_from_bound (ref, impl_block.get_type ());
+  specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
+ impl_block.get_polarity ());
 }
 
   TyTy::BaseType *self = TypeCheckType::Resolve (impl_block.get_type ());
-
   if (self->is ())
 {
   // we cannot check for unconstrained type arguments when the Self type is
@@ -771,7 +771,14 @@ TypeCheckItem::validate_trait_impl_block (
 
   // we don't error out here see: gcc/testsuite/rust/compile/traits2.rs
   // for example
-  specified_bound = get_predicate_from_bound (ref, impl_block.get_type ());
+  specified_bound = get_predicate_from_bound (ref, impl_block.get_type (),
+ impl_block.get_polarity ());
+
+  // need to check that if this specified bound has super traits does this
+  // Self
+  // implement them?
+  specified_bound.validate_type_implements_super_traits (
+   *self, impl_block.get_type (), impl_block.get_trait_ref ());
 }
 
   bool is_trait_impl_block = !trait_reference->is_error ();
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 65f24c0aa2a..e028a0af80b 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -828,6 +828,65 @@ TypeBoundPredicate::is_equal (const TypeBoundPredicate 
&other) const
   return true;
 }
 
+bool
+TypeBoundPredicate::validate_type_implements_super_traits (
+  TyTy::BaseType &self, HIR::Type &impl_type, HIR::Type &trait) const
+{
+  if (get_polarity () != BoundPolarity::RegularBound)
+return true;
+
+  auto &ptref = *get ();
+  for (auto &super : super_traits)
+{
+  if (super.get_polarity () != BoundPolarity::RegularBound)
+   continue;
+
+  if (!super.validate_type_implements_this (self, impl_type, trait))
+   {
+ auto &sptref = *super.get ();
+
+ // emit error
+ std::string fixit1
+   = "required by this bound in: " + ptref.get_name ();
+ std::string fixit2 = "the trait " + sptref.get_name ()
+  + " is not implemented for "
+  + impl_type.as_string ();
+
+ rich_location r (line_table, trait.get_locus ());
+ r.add_fixit_insert_after (super.get_locus (), fixit1.c_str ());
+ r.add_fixit_insert_after (trait.get_locus (), fixit2.c_str ());
+ rust_error_at (r, ErrorCode::E0277,
+"the trait bound %<%s: %s%> is not satisfied",
+impl_type.as_string ().c_str (),
+sptref.get_name ().c_str ());
+
+ return false;
+   }
+
+  if (!super.validate_type_implements_super_traits (self, impl_type, 
trait))
+   return false;
+}
+
+  return true;
+}
+
+bool
+TypeBoundPredicate::validate_type_implements_this (TyTy::BaseType &self,
+  HIR::Type &impl_type,
+  HIR::Type &trait) const
+{
+  const auto &ptref = *get ();
+  auto probed_bounds = Resolver::TypeBoundsProbe::Probe (&self);
+  for (auto &elem : probed_bounds)
+{
+  auto &tref = *(elem.first);
+  if (ptref.is_equal (tref))
+   return true;
+}
+
+  return false;
+}
+
 // trait item reference
 
 const Resolver::TraitItemReference *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 0bfd29d98bb..e814f07f445 100644
--- 

[COMMITTED 07/35] gccrs: name-resolution: Handle let-else properly

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

gcc/rust/ChangeLog:

* resolve/rust-ast-resolve-stmt.h: Add handling for diverging else.
* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise.
---
 gcc/rust/resolve/rust-ast-resolve-stmt.h| 7 ---
 gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 3 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h 
b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index d3ff14f755e..6c99d6a6f6c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -73,9 +73,10 @@ public:
   void visit (AST::LetStmt &stmt) override
   {
 if (stmt.has_init_expr ())
-  {
-   ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix);
-  }
+  ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix);
+
+if (stmt.has_else_expr ())
+  ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix);
 
 PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var);
 if (stmt.has_type ())
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index cf7b7dcd03f..95df7272c75 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -140,6 +140,9 @@ Late::visit (AST::LetStmt &let)
 visit (let.get_init_expr ());
   visit (let.get_pattern ());
 
+  if (let.has_else_expr ())
+visit (let.get_init_expr ());
+
   // how do we deal with the fact that `let a = blipbloup` should look for a
   // label and cannot go through function ribs, but `let a = blipbloup()` can?
 
-- 
2.49.0



[COMMITTED 35/35] gccrs: Fix SEGV when type path resolver fails outright

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

When we resolve paths we resolve to Types first we walk each segment to
the last module which has no type but then in the event that the child
of a module is not found we have a null root_tyty which needs to be caught
and turned into an ErrorType node.

Fixes Rust-GCC#3613

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-type.cc 
(TypeCheckType::resolve_root_path):
catch nullptr root_tyty

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-type.cc |  7 +++
 gcc/testsuite/rust/compile/issue-3613.rs   | 18 ++
 2 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3613.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index e56fa397e2a..54f50ec41f1 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -360,6 +360,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, 
size_t *offset,
 seg->as_string ().c_str ());
  return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
}
+ else if (root_tyty == nullptr)
+   {
+ rust_error_at (seg->get_locus (),
+"unknown reference for resolved name: %qs",
+seg->as_string ().c_str ());
+ return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+   }
  return root_tyty;
}
 
diff --git a/gcc/testsuite/rust/compile/issue-3613.rs 
b/gcc/testsuite/rust/compile/issue-3613.rs
new file mode 100644
index 000..f2e10921f67
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3613.rs
@@ -0,0 +1,18 @@
+mod m1 {
+pub enum Baz4 {
+foo1,
+foo2,
+}
+}
+
+fn bar(x: m1::foo) {
+// { dg-error "unknown reference for resolved name: .foo." "" { target 
*-*-* } .-1 }
+match x {
+m1::foo::foo1 => {}
+// { dg-error "failed to type resolve root segment" "" { target *-*-* 
} .-1 }
+m1::NodePosition::foo2 => {}
+// { dg-error "failed to type resolve root segment" "" { target *-*-* 
} .-1 }
+}
+}
+
+pub fn main() {}
-- 
2.49.0



[COMMITTED 20/35] gccrs: Fix ICE when doing method resolution on trait predicates

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

We need to ensure we are adding methods to the possible candidates.

Fixes Rust-GCC#3554

gcc/rust/ChangeLog:

* typecheck/rust-hir-dot-operator.cc:

gcc/testsuite/ChangeLog:

* rust/compile/issue-3554-1.rs: New test.
* rust/compile/issue-3554-2.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-dot-operator.cc |  7 +--
 gcc/testsuite/rust/compile/issue-3554-1.rs  |  8 
 gcc/testsuite/rust/compile/issue-3554-2.rs  | 18 ++
 3 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3554-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3554-2.rs

diff --git a/gcc/rust/typecheck/rust-hir-dot-operator.cc 
b/gcc/rust/typecheck/rust-hir-dot-operator.cc
index 38bd5b75fb7..c1165e9e5b1 100644
--- a/gcc/rust/typecheck/rust-hir-dot-operator.cc
+++ b/gcc/rust/typecheck/rust-hir-dot-operator.cc
@@ -472,8 +472,11 @@ MethodResolver::get_predicate_items (
   if (ty->get_kind () == TyTy::TypeKind::FNDEF)
{
  TyTy::FnType *fnty = static_cast (ty);
- predicate_candidate candidate{lookup, fnty};
- predicate_items.push_back (candidate);
+ if (fnty->is_method ())
+   {
+ predicate_candidate candidate{lookup, fnty};
+ predicate_items.push_back (candidate);
+   }
}
 }
 
diff --git a/gcc/testsuite/rust/compile/issue-3554-1.rs 
b/gcc/testsuite/rust/compile/issue-3554-1.rs
new file mode 100644
index 000..a66be35d363
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3554-1.rs
@@ -0,0 +1,8 @@
+trait Tr {
+fn foo();
+
+fn bar(&self) {
+self.foo()
+// { dg-error "no method named .foo. found in the current scope 
.E0599." "" { target *-*-* } .-1 }
+}
+}
diff --git a/gcc/testsuite/rust/compile/issue-3554-2.rs 
b/gcc/testsuite/rust/compile/issue-3554-2.rs
new file mode 100644
index 000..e455a8b2cec
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3554-2.rs
@@ -0,0 +1,18 @@
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "fn_once"]
+pub trait FnOnce {
+#[lang = "fn_once_output"]
+type Output;
+
+extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+trait Tr {
+fn foo();
+
+fn bar(&self) {
+(|| self.foo())()
+// { dg-error "no method named .foo. found in the current scope 
.E0599." "" { target *-*-* } .-1 }
+}
+}
-- 
2.49.0



[COMMITTED 33/35] gccrs: fix ice when setting up regions

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

num regions is based on the used arguments of regions which can be
less than the substutions requirements. So lets check for that and allow
anon regions to be created for them.

Fixes Rust-GCC#3605

gcc/rust/ChangeLog:

* typecheck/rust-tyty-subst.h: check for min range

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-tyty-subst.h | 2 +-
 gcc/testsuite/rust/compile/issue-3605.rs | 5 +
 2 files changed, 6 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3605.rs

diff --git a/gcc/rust/typecheck/rust-tyty-subst.h 
b/gcc/rust/typecheck/rust-tyty-subst.h
index b8e928d60f0..3f0b912fa7b 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -125,7 +125,7 @@ public:
 std::vector subst)
   {
 RegionParamList list (num_regions);
-for (size_t i = 0; i < subst.size (); i++)
+for (size_t i = 0; i < MIN (num_regions, subst.size ()); i++)
   list.regions.at (i) = subst.at (i);
 for (size_t i = subst.size (); i < num_regions; i++)
   {
diff --git a/gcc/testsuite/rust/compile/issue-3605.rs 
b/gcc/testsuite/rust/compile/issue-3605.rs
new file mode 100644
index 000..05e6e48e66e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3605.rs
@@ -0,0 +1,5 @@
+enum Foo<'a> {}
+
+enum Bar<'a> {
+in_band_def_explicit_impl(Foo<'a>),
+}
-- 
2.49.0



[COMMITTED 23/35] gccrs: Update exclusion list

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

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove now passing tests from exclusion
list.

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

diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index 9273bd1489e..75a0ae0ea0e 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -2,12 +2,8 @@ canonical_paths1.rs
 cfg1.rs
 generics9.rs
 issue-2043.rs
-issue-2330.rs
 issue-2812.rs
-issue-850.rs
-issue-855.rs
 issue-3315-2.rs
-iterators1.rs
 lookup_err1.rs
 macros/mbe/macro43.rs
 macros/mbe/macro6.rs
@@ -27,8 +23,6 @@ derive_clone_enum3.rs
 derive-debug1.rs
 derive-default1.rs
 issue-3402-1.rs
-for-loop1.rs
-for-loop2.rs
 issue-3403.rs
 derive-eq-invalid.rs
 derive-hash1.rs
-- 
2.49.0



[COMMITTED 22/35] gccrs: Resolve module final self segment in use decls

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

Lowercase self suffix with path was not resolved properly, this should
point to the module right before.

gcc/rust/ChangeLog:

* resolve/rust-forever-stack.hxx: Add a new specialized function
to retrieve the last "real" segment depending on the namespace.
* resolve/rust-forever-stack.h: Add new function prototype.
* resolve/rust-early-name-resolver-2.0.cc 
(Early::finalize_rebind_import):
Set declared name according to the selected segment, if there is a self
suffix in the use declaration then select the previous segment.

Signed-off-by: Pierre-Emmanuel Patry 
---
 .../resolve/rust-early-name-resolver-2.0.cc   | 17 ---
 gcc/rust/resolve/rust-forever-stack.h |  4 +++
 gcc/rust/resolve/rust-forever-stack.hxx   | 29 ---
 3 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 492a665f43e..afaca1f71f0 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -417,10 +417,19 @@ Early::finalize_rebind_import (const Early::ImportPair 
&mapping)
   declared_name = rebind.get_identifier ().as_string ();
   locus = rebind.get_identifier ().get_locus ();
   break;
-case AST::UseTreeRebind::NewBindType::NONE:
-  declared_name = path.get_final_segment ().as_string ();
-  locus = path.get_final_segment ().get_locus ();
-  break;
+  case AST::UseTreeRebind::NewBindType::NONE: {
+   const auto &segments = path.get_segments ();
+   // We don't want to insert `self` with `use module::self`
+   if (path.get_final_segment ().is_lower_self_seg ())
+ {
+   rust_assert (segments.size () > 1);
+   declared_name = segments[segments.size () - 2].as_string ();
+ }
+   else
+ declared_name = path.get_final_segment ().as_string ();
+   locus = path.get_final_segment ().get_locus ();
+   break;
+  }
 case AST::UseTreeRebind::NewBindType::WILDCARD:
   rust_unreachable ();
   break;
diff --git a/gcc/rust/resolve/rust-forever-stack.h 
b/gcc/rust/resolve/rust-forever-stack.h
index 2a4c7348728..d86212073b8 100644
--- a/gcc/rust/resolve/rust-forever-stack.h
+++ b/gcc/rust/resolve/rust-forever-stack.h
@@ -795,6 +795,10 @@ private:
 SegIterator iterator,
 std::function insert_segment_resolution);
 
+  tl::optional resolve_final_segment (Node &final_node,
+  std::string &seg_name,
+  bool is_lower_self);
+
   /* Helper functions for forward resolution (to_canonical_path, to_rib...) */
   struct DfsResult
   {
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx 
b/gcc/rust/resolve/rust-forever-stack.hxx
index a6e0b30a57b..fbe537d3b41 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -594,6 +594,26 @@ ForeverStack::resolve_segments (
   return *current_node;
 }
 
+template <>
+inline tl::optional
+ForeverStack::resolve_final_segment (Node &final_node,
+  std::string &seg_name,
+  bool is_lower_self)
+{
+  if (is_lower_self)
+return Rib::Definition::NonShadowable (final_node.id);
+  else
+return final_node.rib.get (seg_name);
+}
+
+template 
+tl::optional
+ForeverStack::resolve_final_segment (Node &final_node, std::string 
&seg_name,
+   bool is_lower_self)
+{
+  return final_node.rib.get (seg_name);
+}
+
 template 
 template 
 tl::optional
@@ -643,12 +663,13 @@ ForeverStack::resolve_path (
   if (final_node.rib.kind == Rib::Kind::TraitOrImpl)
return tl::nullopt;
 
-  std::string seg_name
-   = unwrap_type_segment (segments.back ()).as_string ();
+  auto &seg = unwrap_type_segment (segments.back ());
+  std::string seg_name = seg.as_string ();
 
   // assuming this can't be a lang item segment
-  tl::optional res = final_node.rib.get (seg_name);
-
+  tl::optional res
+   = resolve_final_segment (final_node, seg_name,
+seg.is_lower_self_seg ());
   // Ok we didn't find it in the rib, Lets try the prelude...
   if (!res)
res = get_prelude (seg_name);
-- 
2.49.0



[COMMITTED 34/35] gccrs: fix crash in parse repr options and missing delete call

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

Fixes Rust-GCC#3606

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::parse_repr_options):
check for null and empty and add missing delete call

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 .../typecheck/rust-hir-type-check-base.cc | 20 +--
 gcc/testsuite/rust/compile/issue-3606.rs  |  6 ++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3606.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 7fc6467e8ae..34a726cc665 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -321,8 +321,22 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  AST::AttrInputMetaItemContainer *meta_items
= option.parse_to_meta_item ();
 
- const std::string inline_option
-   = meta_items->get_items ().at (0)->as_string ();
+ if (meta_items == nullptr)
+   {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute",
+"repr");
+ continue;
+   }
+
+ auto &items = meta_items->get_items ();
+ if (items.size () == 0)
+   {
+ // nothing to do with this its empty
+ delete meta_items;
+ continue;
+   }
+
+ const std::string inline_option = items.at (0)->as_string ();
 
  // TODO: it would probably be better to make the MetaItems more aware
  // of constructs with nesting like #[repr(packed(2))] rather than
@@ -359,6 +373,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
  else if (is_align)
repr.align = value;
 
+ delete meta_items;
+
  // Multiple repr options must be specified with e.g. #[repr(C,
  // packed(2))].
  break;
diff --git a/gcc/testsuite/rust/compile/issue-3606.rs 
b/gcc/testsuite/rust/compile/issue-3606.rs
new file mode 100644
index 000..73b0bd6743b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3606.rs
@@ -0,0 +1,6 @@
+// { dg-options "-w" }
+#[repr()]
+pub struct Coord {
+x: u32,
+y: u32,
+}
-- 
2.49.0



[COMMITTED 30/35] gccrs: Fix ICE in array ref constexpr

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

Since 898d55ad7e2 was fixed to remove the VIEW_CONVERT_EXPR from
array expressions we can now turn on the array element access
const expr.

Fixes Rust-GCC#3563

gcc/rust/ChangeLog:

* backend/rust-constexpr.cc (eval_store_expression): turn this back on

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-constexpr.cc   |  6 ++
 gcc/testsuite/rust/compile/issue-3563.rs | 17 +
 2 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3563.rs

diff --git a/gcc/rust/backend/rust-constexpr.cc 
b/gcc/rust/backend/rust-constexpr.cc
index 2f2bbbd921d..dc2d6b1066b 100644
--- a/gcc/rust/backend/rust-constexpr.cc
+++ b/gcc/rust/backend/rust-constexpr.cc
@@ -2697,10 +2697,8 @@ eval_store_expression (const constexpr_ctx *ctx, tree t, 
bool lval,
  }
if (TREE_CODE (probe) == ARRAY_REF)
  {
-   // TODO
-   rust_unreachable ();
-   // elt = eval_and_check_array_index (ctx, probe, false,
-   //non_constant_p, overflow_p);
+   elt = eval_and_check_array_index (ctx, probe, false,
+ non_constant_p, overflow_p);
if (*non_constant_p)
  return t;
  }
diff --git a/gcc/testsuite/rust/compile/issue-3563.rs 
b/gcc/testsuite/rust/compile/issue-3563.rs
new file mode 100644
index 000..46e762464b8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3563.rs
@@ -0,0 +1,17 @@
+pub struct AA {
+pub data: [u8; 10],
+}
+
+impl AA {
+pub const fn new() -> Self {
+let mut res: AA = AA { data: [0; 10] };
+res.data[0] = 5;
+res
+}
+}
+
+static mut BB: AA = AA::new();
+
+fn main() {
+let _ptr = unsafe { &mut BB };
+}
-- 
2.49.0



[COMMITTED 18/35] gccrs: Fix ICE when compiling block expressions in array capacity

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

We need to reuse the existing compile_constant_item helper which handles
the case if this is a simple expression, fn-call or a block expression.
The patch extracts out this helper as a static method so this can be used
in more places.

Fixes Rust-GCC#3566

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc (HIRCompileBase::address_expression): 
new helper constexpr
* backend/rust-compile-base.h: prototype
* backend/rust-compile-type.cc (TyTyResolveCompile::visit): call 
constexpr helper

gcc/testsuite/ChangeLog:

* rust/compile/issue-3566-1.rs: New test.
* rust/compile/issue-3566-2.rs: New test.

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-base.cc  | 12 
 gcc/rust/backend/rust-compile-base.h   |  6 ++
 gcc/rust/backend/rust-compile-type.cc  | 12 +++-
 gcc/testsuite/rust/compile/issue-3566-1.rs |  8 
 gcc/testsuite/rust/compile/issue-3566-2.rs | 22 ++
 5 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3566-1.rs
 create mode 100644 gcc/testsuite/rust/compile/issue-3566-2.rs

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index bcc7fc4fcbf..b47711364e5 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -560,6 +560,18 @@ HIRCompileBase::address_expression (tree expr, location_t 
location)
   return build_fold_addr_expr_loc (location, expr);
 }
 
+tree
+HIRCompileBase::compile_constant_expr (
+  Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
+  TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path,
+  HIR::Expr &const_value_expr, location_t locus, location_t expr_locus)
+{
+  HIRCompileBase c (ctx);
+  return c.compile_constant_item (coercion_id, resolved_type, expected_type,
+ canonical_path, const_value_expr, locus,
+ expr_locus);
+}
+
 tree
 HIRCompileBase::indirect_expression (tree expr, location_t locus)
 {
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 9328a7f7483..109c8530321 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -31,6 +31,12 @@ public:
 
   static tree address_expression (tree expr, location_t locus);
 
+  static tree compile_constant_expr (
+Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type,
+TyTy::BaseType *expected_type,
+const Resolver::CanonicalPath &canonical_path, HIR::Expr &const_value_expr,
+location_t locus, location_t expr_locus);
+
 protected:
   HIRCompileBase (Context *ctx) : ctx (ctx) {}
 
diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index d8af1d1af6b..73548011cd0 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -456,7 +456,17 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
 = TyTyResolveCompile::compile (ctx, type.get_element_type ());
 
   ctx->push_const_context ();
-  tree capacity_expr = CompileExpr::Compile (type.get_capacity_expr (), ctx);
+
+  HIR::Expr &hir_capacity_expr = type.get_capacity_expr ();
+  TyTy::BaseType *capacity_expr_ty = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_type (
+hir_capacity_expr.get_mappings ().get_hirid (), &capacity_expr_ty);
+  rust_assert (ok);
+  tree capacity_expr = HIRCompileBase::compile_constant_expr (
+ctx, hir_capacity_expr.get_mappings ().get_hirid (), capacity_expr_ty,
+capacity_expr_ty, Resolver::CanonicalPath::create_empty (),
+hir_capacity_expr, type.get_locus (), hir_capacity_expr.get_locus ());
+
   ctx->pop_const_context ();
 
   tree folded_capacity_expr = fold_expr (capacity_expr);
diff --git a/gcc/testsuite/rust/compile/issue-3566-1.rs 
b/gcc/testsuite/rust/compile/issue-3566-1.rs
new file mode 100644
index 000..b7e5be0ab57
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3566-1.rs
@@ -0,0 +1,8 @@
+mod a {
+pub mod b {
+
+pub fn f(x: [u8; { 100 }]) -> [u8; { 100 }] {
+x
+}
+}
+}
diff --git a/gcc/testsuite/rust/compile/issue-3566-2.rs 
b/gcc/testsuite/rust/compile/issue-3566-2.rs
new file mode 100644
index 000..3f3ea73789a
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3566-2.rs
@@ -0,0 +1,22 @@
+// run-pass
+
+#![allow(H8)]
+#![allow(dead_code)]
+
+
+// pretty-expanded FIXME #23616
+
+mod a {
+pub mod b {
+pub type t = isize;
+
+pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8;  { let z = 18; 100 }] {
+//~^ WARN unused variable: `s`
+//~| WARN unused variable: `z`
+x
+}
+}
+}
+
+pub fn main() {//~ ERROR cannot move out
+}
-- 
2.49.0



[COMMITTED 31/35] gccrs: FIX ICE when working with HIR::BareFunctionType

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

Fixes Rust-GCC#3615

gcc/rust/ChangeLog:

* hir/rust-hir-dump.cc (Dump::visit): check has type
* hir/tree/rust-hir-type.cc (BareFunctionType::BareFunctionType): 
likewise

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/hir/rust-hir-dump.cc| 4 +++-
 gcc/rust/hir/tree/rust-hir-type.cc   | 3 ++-
 gcc/testsuite/rust/compile/issue-3615.rs | 7 +++
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-3615.rs

diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 0a9d617a919..89fcc3dd1f9 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -2440,7 +2440,9 @@ Dump::visit (BareFunctionType &e)
   end_field ("params");
 }
 
-  visit_field ("return_type", e.get_return_type ());
+  if (e.has_return_type ())
+visit_field ("return_type", e.get_return_type ());
+
   put_field ("is_variadic", std::to_string (e.get_is_variadic ()));
   end ("BareFunctionType");
 }
diff --git a/gcc/rust/hir/tree/rust-hir-type.cc 
b/gcc/rust/hir/tree/rust-hir-type.cc
index 689d86b7372..6a6c319fc98 100644
--- a/gcc/rust/hir/tree/rust-hir-type.cc
+++ b/gcc/rust/hir/tree/rust-hir-type.cc
@@ -268,7 +268,8 @@ BareFunctionType::BareFunctionType (BareFunctionType const 
&other)
 for_lifetimes (other.for_lifetimes),
 function_qualifiers (other.function_qualifiers), params (other.params),
 is_variadic (other.is_variadic),
-return_type (other.return_type->clone_type ())
+return_type (other.has_return_type () ? other.return_type->clone_type ()
+ : nullptr)
 {}
 
 BareFunctionType &
diff --git a/gcc/testsuite/rust/compile/issue-3615.rs 
b/gcc/testsuite/rust/compile/issue-3615.rs
new file mode 100644
index 000..e5c50725ea2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3615.rs
@@ -0,0 +1,7 @@
+pub trait Trait {
+pub fn nrvo(init: fn()) -> [u8; 4096] {
+let mut buf = [0; 4096];
+
+buf
+}
+}
-- 
2.49.0



[COMMITTED 21/35] gccrs: Give the builtin unit struct an actual locus

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

This has been a pet peeve of mine for a while because the gimple never
emitted the struct () name properly it was always empty which for record
types they always require a real locus or they dont get a proper name.

gcc/rust/ChangeLog:

* backend/rust-compile-base.cc (HIRCompileBase::unit_expression): pass 
ctx
* backend/rust-compile-base.h: cant be static
* backend/rust-compile-intrinsic.cc (try_handler_inner): pass ctx
* backend/rust-compile-type.cc
(TyTyResolveCompile::get_unit_type): update to grab the first locus
(TyTyResolveCompile::visit): pass ctx
* backend/rust-compile-type.h: likewise

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-base.cc  |  2 +-
 gcc/rust/backend/rust-compile-base.h   |  2 +-
 gcc/rust/backend/rust-compile-intrinsic.cc |  2 +-
 gcc/rust/backend/rust-compile-type.cc  | 17 +
 gcc/rust/backend/rust-compile-type.h   |  2 +-
 5 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index b47711364e5..fdbca7f1558 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -1023,7 +1023,7 @@ HIRCompileBase::resolve_method_address (TyTy::FnType 
*fntype,
 tree
 HIRCompileBase::unit_expression (location_t locus)
 {
-  tree unit_type = TyTyResolveCompile::get_unit_type ();
+  tree unit_type = TyTyResolveCompile::get_unit_type (ctx);
   return Backend::constructor_expression (unit_type, false, {}, -1, locus);
 }
 
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index 109c8530321..4b4f8b09256 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -110,7 +110,7 @@ protected:
 const Resolver::CanonicalPath &canonical_path,
 TyTy::FnType *fntype);
 
-  static tree unit_expression (location_t locus);
+  tree unit_expression (location_t locus);
 
   void setup_fndecl (tree fndecl, bool is_main_entry_point, bool is_generic_fn,
 HIR::Visibility &visibility,
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc 
b/gcc/rust/backend/rust-compile-intrinsic.cc
index fb0c66101fa..4888e23ed1e 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -1322,7 +1322,7 @@ try_handler_inner (Context *ctx, TyTy::FnType *fntype, 
bool is_new_api)
 
   if (is_new_api)
 {
-  auto ret_type = TyTyResolveCompile::get_unit_type ();
+  auto ret_type = TyTyResolveCompile::get_unit_type (ctx);
   auto ret_expr = Backend::constructor_expression (ret_type, false, {}, -1,
   UNDEF_LOCATION);
   normal_return_stmt
diff --git a/gcc/rust/backend/rust-compile-type.cc 
b/gcc/rust/backend/rust-compile-type.cc
index 73548011cd0..813e11c47cf 100644
--- a/gcc/rust/backend/rust-compile-type.cc
+++ b/gcc/rust/backend/rust-compile-type.cc
@@ -81,13 +81,22 @@ TyTyResolveCompile::get_implicit_enumeral_node_type 
(TyTy::BaseType *repr)
 }
 
 tree
-TyTyResolveCompile::get_unit_type ()
+TyTyResolveCompile::get_unit_type (Context *ctx)
 {
   static tree unit_type;
   if (unit_type == nullptr)
 {
+  auto cn = ctx->get_mappings ().get_current_crate ();
+  auto &c = ctx->get_mappings ().get_ast_crate (cn);
+  location_t locus = BUILTINS_LOCATION;
+  if (c.items.size () > 0)
+   {
+ auto &item = c.items[0];
+ locus = item->get_locus ();
+   }
+
   auto unit_type_node = Backend::struct_type ({});
-  unit_type = Backend::named_type ("()", unit_type_node, 
BUILTINS_LOCATION);
+  unit_type = Backend::named_type ("()", unit_type_node, locus);
 }
   return unit_type;
 }
@@ -421,7 +430,7 @@ TyTyResolveCompile::visit (const TyTy::TupleType &type)
 {
   if (type.num_fields () == 0)
 {
-  translated = get_unit_type ();
+  translated = get_unit_type (ctx);
   return;
 }
 
@@ -724,7 +733,7 @@ TyTyResolveCompile::visit (const TyTy::StrType &type)
 void
 TyTyResolveCompile::visit (const TyTy::NeverType &)
 {
-  translated = get_unit_type ();
+  translated = get_unit_type (ctx);
 }
 
 void
diff --git a/gcc/rust/backend/rust-compile-type.h 
b/gcc/rust/backend/rust-compile-type.h
index bc611cfbc73..7ebc4a63192 100644
--- a/gcc/rust/backend/rust-compile-type.h
+++ b/gcc/rust/backend/rust-compile-type.h
@@ -30,7 +30,7 @@ public:
   static tree compile (Context *ctx, const TyTy::BaseType *ty,
   bool trait_object_mode = false);
 
-  static tree get_unit_type ();
+  static tree get_unit_type (Context *ctx);
 
   void visit (const TyTy::InferType &) override;
   void visit (const TyTy::ADTType &) override;
-- 
2.49.0



[COMMITTED 10/35] rust: Lower minimum supported Rust version to 1.49

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

gcc/rust/ChangeLog:

* checks/errors/borrowck/ffi-polonius/Cargo.lock: Regenerate.
* checks/errors/borrowck/ffi-polonius/Cargo.toml: Update to use source 
patching instead of
vendoring, lower edition to 2018.
* checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml: Change 
edition to 2018.
* checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs: Remove 
uses of unstable
feature.
* checks/errors/borrowck/ffi-polonius/.cargo/config.toml: Removed.

libgrust/ChangeLog:

* libformat_parser/Makefile.am: Avoid using --config as it is 
unsupported by cargo 1.49.
* libformat_parser/Makefile.in: Regenerate.
* libformat_parser/generic_format_parser/src/lib.rs: Use extension 
trait for missing
features.
* libformat_parser/src/lib.rs: Likewise.
* libformat_parser/.cargo/config: Moved to...
* libformat_parser/.cargo/config.toml: ...here.
---
 .../errors/borrowck/ffi-polonius/Cargo.lock   |  10 --
 .../errors/borrowck/ffi-polonius/Cargo.toml   |  10 +-
 .../ffi-polonius/vendor/log/Cargo.toml|   2 +-
 .../ffi-polonius/vendor/log/src/lib.rs| 138 --
 libgrust/libformat_parser/.cargo/config   |   5 -
 .../libformat_parser}/.cargo/config.toml  |   0
 libgrust/libformat_parser/Makefile.am |  11 +-
 libgrust/libformat_parser/Makefile.in |  10 +-
 .../generic_format_parser/src/lib.rs  |  14 ++
 libgrust/libformat_parser/src/lib.rs  |  11 ++
 10 files changed, 41 insertions(+), 170 deletions(-)
 delete mode 100644 libgrust/libformat_parser/.cargo/config
 rename {gcc/rust/checks/errors/borrowck/ffi-polonius => 
libgrust/libformat_parser}/.cargo/config.toml (100%)

diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
index f7cbd414caf..1b223b65556 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.lock
@@ -1,12 +1,8 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
-
 [[package]]
 name = "datafrog"
 version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
 
 [[package]]
 name = "ffi-polonius"
@@ -18,14 +14,10 @@ dependencies = [
 [[package]]
 name = "log"
 version = "0.4.22"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
 [[package]]
 name = "polonius-engine"
 version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "c4e8e505342045d397d0b6674dcb82d6faf5cf40484d30eeb88fc82ef14e903f"
 dependencies = [
  "datafrog",
  "log",
@@ -35,5 +27,3 @@ dependencies = [
 [[package]]
 name = "rustc-hash"
 version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
index 71315c3b635..3bc8e3f873e 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/Cargo.toml
@@ -1,11 +1,17 @@
 [package]
 name = "ffi-polonius"
 version = "0.1.0"
-edition = "2021"
+edition = "2018"
 license = "GPL-3"
 
 [lib]
 crate-type = ["staticlib"]
 
 [dependencies]
-polonius-engine = "0.13.0"
\ No newline at end of file
+polonius-engine = "0.13.0"
+
+[patch.crates-io]
+log = { path = "vendor/log" }
+datafrog = { path = "vendor/datafrog" }
+polonius-engine = { path = "vendor/polonius-engine" }
+rustc-hash = { path = "vendor/rustc-hash" }
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
index 313a0051ae5..a199e317010 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/Cargo.toml
@@ -10,7 +10,7 @@
 # See Cargo.toml.orig for the original contents.
 
 [package]
-edition = "2021"
+edition = "2018"
 rust-version = "1.60.0"
 name = "log"
 version = "0.4.22"
diff --git a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs 
b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
index 6b43a9ae16d..603bbacb18c 100644
--- a/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
+++ b/gcc/rust/checks/errors/borrowck/ffi-polonius/vendor/log/src/lib.rs
@@ -397,20 +397,13 @@ mod serde;
 #[cfg(feature = "kv")]
 pub mod kv;
 
-#[cfg(target_has_atomic = "ptr")]
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-#[cfg(not(target_has_atomic = "ptr"))]
 use std::cell::Cell;
-#[cfg(not(target_has_atomic = "ptr"))]
 use s

[COMMITTED 32/35] gccrs: FIX ICE for malformed repr attribute

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

Fixes Rust-GCC#3614

gcc/rust/ChangeLog:

* typecheck/rust-hir-type-check-base.cc 
(TypeCheckBase::parse_repr_options): check for input

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/typecheck/rust-hir-type-check-base.cc | 6 ++
 gcc/testsuite/rust/compile/issue-3614.rs   | 3 +++
 2 files changed, 9 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3614.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc 
b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 8f2471d54d5..7fc6467e8ae 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -305,6 +305,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec 
&attrs, location_t locus)
   for (const auto &attr : attrs)
 {
   bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
+  if (is_repr && !attr.has_attr_input ())
+   {
+ rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr");
+ continue;
+   }
+
   if (is_repr)
{
  const AST::AttrInput &input = attr.get_attr_input ();
diff --git a/gcc/testsuite/rust/compile/issue-3614.rs 
b/gcc/testsuite/rust/compile/issue-3614.rs
new file mode 100644
index 000..350a7e43ba8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3614.rs
@@ -0,0 +1,3 @@
+#[repr] // { dg-error "malformed .repr. attribute" }
+
+struct _B {}
-- 
2.49.0



[COMMITTED 24/35] gccrs: Add new test to highlight namespace for self import

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

gcc/testsuite/ChangeLog:

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

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

diff --git a/gcc/testsuite/rust/compile/self_import_namespace.rs 
b/gcc/testsuite/rust/compile/self_import_namespace.rs
new file mode 100644
index 000..2d9b2ed8e0f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/self_import_namespace.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-frust-name-resolution-2.0" }
+
+mod bar {
+pub mod foo {}
+pub fn foo() {}
+}
+
+// This only imports the module `foo`. The function `foo` lives in
+// the value namespace and is not imported.
+use bar::foo::{self};
+
+fn main() {
+foo(); // { dg-error "expected value" }
+}
-- 
2.49.0



[Bug rust/117869] rust fails to build with cargo command error

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

--- Comment #3 from Sam James  ---
Since r15-9083-gd560f3f9594339, 1.49 should work again, but it needs
documenting still.

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

[COMMITTED 16/35] gccrs: Fix ICE when array elements are not a value

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

We need to check for error_mark_node when doing adjustments from coercion
sites otherwise we hit assetions as part of the coercion. That fixes the
ICE but the reason for the error_mark_node is because the array element
value.

Fixes Rust-GCC#3567

gcc/rust/ChangeLog:

* backend/rust-compile-expr.cc (CompileExpr::array_value_expr): add 
value chk for array expr

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron 
---
 gcc/rust/backend/rust-compile-expr.cc| 11 +++
 gcc/testsuite/rust/compile/issue-3567.rs |  4 
 2 files changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/rust/compile/issue-3567.rs

diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 21f4ca1ba18..e4ab9f010b8 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1902,6 +1902,14 @@ CompileExpr::array_value_expr (location_t expr_locus,
   for (auto &elem : elems.get_values ())
 {
   tree translated_expr = CompileExpr::Compile (*elem, ctx);
+  if (translated_expr == error_mark_node)
+   {
+ rich_location r (line_table, expr_locus);
+ r.add_fixit_replace (elem->get_locus (), "not a value");
+ rust_error_at (r, ErrorCode::E0423, "expected value");
+ return error_mark_node;
+   }
+
   constructor.push_back (translated_expr);
   indexes.push_back (i++);
 }
@@ -2003,6 +2011,9 @@ HIRCompileBase::resolve_adjustements (
   tree e = expression;
   for (auto &adjustment : adjustments)
 {
+  if (e == error_mark_node)
+   return error_mark_node;
+
   switch (adjustment.get_type ())
{
case Resolver::Adjustment::AdjustmentType::ERROR:
diff --git a/gcc/testsuite/rust/compile/issue-3567.rs 
b/gcc/testsuite/rust/compile/issue-3567.rs
new file mode 100644
index 000..021d9c27838
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3567.rs
@@ -0,0 +1,4 @@
+fn main() {
+let _: &[i8] = &[i8];
+// { dg-error "expected value .E0423." "" { target *-*-* } .-1 }
+}
-- 
2.49.0