From: Philip Herron <[email protected]>

When we have an invalid capacity expression we can't try to then also
const fold it as GCC will assert on invalid conversions.

Fixes Rust-GCC#4168

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): check 
for invalid capacity

gcc/testsuite/ChangeLog:

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

Signed-off-by: Philip Herron <[email protected]>
---
 .../typecheck/rust-hir-type-check-type.cc     | 37 +++++++++++++------
 gcc/testsuite/rust/compile/issue-4168.rs      |  7 ++++
 2 files changed, 32 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4168.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc 
b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index dfefae8bef3..833ad92db59 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -720,19 +720,32 @@ TypeCheckType::visit (HIR::ArrayType &type)
   else
     {
       HirId size_id = type.get_size_expr ().get_mappings ().get_hirid ();
-      unify_site (size_id, TyTy::TyWithLocation (expected_ty),
-                 TyTy::TyWithLocation (capacity_type,
-                                       type.get_size_expr ().get_locus ()),
-                 type.get_size_expr ().get_locus ());
+      TyTy::BaseType *result
+       = unify_site (size_id, TyTy::TyWithLocation (expected_ty),
+                     TyTy::TyWithLocation (capacity_type,
+                                           type.get_size_expr ().get_locus ()),
+                     type.get_size_expr ().get_locus ());
 
-      auto ctx = Compile::Context::get ();
-      tree capacity_expr = Compile::HIRCompileBase::query_compile_const_expr (
-       ctx, capacity_type, type.get_size_expr ());
-
-      const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value, "",
-                                       expected_ty, capacity_expr, {},
-                                       type.get_size_expr ().get_locus (),
-                                       size_id, size_id);
+      if (result->is<TyTy::ErrorType> ())
+       {
+         const_type
+           = new TyTy::ConstType (TyTy::ConstType::ConstKind::Error, "",
+                                  expected_ty, error_mark_node, {},
+                                  type.get_size_expr ().get_locus (), size_id,
+                                  size_id);
+       }
+      else
+       {
+         auto ctx = Compile::Context::get ();
+         tree capacity_expr
+           = Compile::HIRCompileBase::query_compile_const_expr (
+             ctx, capacity_type, type.get_size_expr ());
+
+         const_type = new TyTy::ConstType (TyTy::ConstType::ConstKind::Value,
+                                           "", expected_ty, capacity_expr, {},
+                                           type.get_size_expr ().get_locus (),
+                                           size_id, size_id);
+       }
     }
 
   translated
diff --git a/gcc/testsuite/rust/compile/issue-4168.rs 
b/gcc/testsuite/rust/compile/issue-4168.rs
new file mode 100644
index 00000000000..abb1190ebc3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4168.rs
@@ -0,0 +1,7 @@
+const fn add(x: usize, y: usize) -> i32 {
+    add + y
+    // { dg-error "cannot apply operator .+. to types fn .x usize,y usize,. -> 
i32 and usize" "" { target *-*-* } .-1 }
+}
+const ARR: [i32; add(1, 2)] = [5, 6, 1];
+// { dg-error "mismatched types, expected .usize. but got .i32. .E0308." "" { 
target *-*-* } .-1 }
+// { dg-error "mismatched types" "" { target *-*-* } .-2 }
-- 
2.50.1

Reply via email to