https://gcc.gnu.org/g:db3d8fb22c8d10a3687742a85de85242a96ac1ba

commit db3d8fb22c8d10a3687742a85de85242a96ac1ba
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Mon Dec 2 16:17:54 2024 +0000

    gccrs: constant evaluation like these are coercion sites
    
    The code here was wrongly assuming the decl type from the folding of the
    expression would be the type of the constant decl. This is not the case for
    unsized coercions for slices, where the expression here is a reference to
    an array then we require the coercion to fix the result up to the expected
    type.
    
    Fixes Rust-GCC#1525
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-base.cc: apply coercion site to result
            * backend/rust-compile-base.h: update prototype
            * backend/rust-compile-implitem.cc (CompileTraitItem::visit): send 
in coercion info
            * backend/rust-compile-item.cc (CompileItem::visit): likewise
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-1525.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/backend/rust-compile-base.cc     | 15 ++++++++++++---
 gcc/rust/backend/rust-compile-base.h      |  6 ++++--
 gcc/rust/backend/rust-compile-implitem.cc | 11 +++++++++--
 gcc/rust/backend/rust-compile-item.cc     | 29 +++++++++++++++++++++--------
 gcc/testsuite/rust/compile/issue-1525.rs  |  4 ++++
 5 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc 
b/gcc/rust/backend/rust-compile-base.cc
index e39c2a993257..a4d0d062accc 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -777,13 +777,18 @@ HIRCompileBase::compile_function (
 
 tree
 HIRCompileBase::compile_constant_item (
-  TyTy::BaseType *resolved_type, const Resolver::CanonicalPath &canonical_path,
-  HIR::Expr &const_value_expr, location_t locus)
+  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)
 {
   const std::string &ident = canonical_path.get ();
 
   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
   tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+  tree actual_type = TyTyResolveCompile::compile (ctx, expected_type);
+  tree actual_const_type = build_qualified_type (actual_type, TYPE_QUAL_CONST);
+
   bool is_block_expr
     = const_value_expr.get_expression_type () == HIR::Expr::ExprType::Block;
 
@@ -851,7 +856,11 @@ HIRCompileBase::compile_constant_item (
   tree call = build_call_array_loc (locus, const_type, fndecl, 0, NULL);
   tree folded_expr = fold_expr (call);
 
-  return named_constant_expression (const_type, ident, folded_expr, locus);
+  // coercion site
+  tree coerced = coercion_site (coercion_id, folded_expr, resolved_type,
+                               expected_type, locus, expr_locus);
+
+  return named_constant_expression (actual_const_type, ident, coerced, locus);
 }
 
 tree
diff --git a/gcc/rust/backend/rust-compile-base.h 
b/gcc/rust/backend/rust-compile-base.h
index bf175d748a0b..3c50535552f5 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -90,9 +90,11 @@ protected:
   void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
                              TyTy::BaseType *fn_return_ty);
 
-  tree compile_constant_item (TyTy::BaseType *resolved_type,
+  tree compile_constant_item (HirId coercion_id, TyTy::BaseType *resolved_type,
+                             TyTy::BaseType *expected_type,
                              const Resolver::CanonicalPath &canonical_path,
-                             HIR::Expr &const_value_expr, location_t locus);
+                             HIR::Expr &const_value_expr, location_t locus,
+                             location_t expr_locus);
 
   tree compile_function (const std::string &fn_name, HIR::SelfParam 
&self_param,
                         std::vector<HIR::FunctionParam> &function_params,
diff --git a/gcc/rust/backend/rust-compile-implitem.cc 
b/gcc/rust/backend/rust-compile-implitem.cc
index dfc8055a353b..6a3c3b0e1c02 100644
--- a/gcc/rust/backend/rust-compile-implitem.cc
+++ b/gcc/rust/backend/rust-compile-implitem.cc
@@ -45,9 +45,16 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
   rust_assert (canonical_path);
 
   HIR::Expr &const_value_expr = constant.get_expr ();
+  TyTy::BaseType *expr_type = nullptr;
+  bool ok = ctx->get_tyctx ()->lookup_type (
+    const_value_expr.get_mappings ().get_hirid (), &expr_type);
+  rust_assert (ok);
+
   tree const_expr
-    = compile_constant_item (resolved_type, *canonical_path, const_value_expr,
-                            constant.get_locus ());
+    = compile_constant_item (constant.get_mappings ().get_hirid (), expr_type,
+                            resolved_type, *canonical_path, const_value_expr,
+                            constant.get_locus (),
+                            const_value_expr.get_locus ());
   ctx->push_const (const_expr);
   ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
 
diff --git a/gcc/rust/backend/rust-compile-item.cc 
b/gcc/rust/backend/rust-compile-item.cc
index 8537d818791e..60159b63fd5b 100644
--- a/gcc/rust/backend/rust-compile-item.cc
+++ b/gcc/rust/backend/rust-compile-item.cc
@@ -35,10 +35,16 @@ CompileItem::visit (HIR::StaticItem &var)
       return;
     }
 
+  HIR::Expr &const_value_expr = var.get_expr ();
+
   TyTy::BaseType *resolved_type = nullptr;
+  TyTy::BaseType *expr_type = nullptr;
   bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
                                            &resolved_type);
   rust_assert (ok);
+  ok = ctx->get_tyctx ()->lookup_type (
+    const_value_expr.get_mappings ().get_hirid (), &expr_type);
+  rust_assert (ok);
 
   tree type = TyTyResolveCompile::compile (ctx, resolved_type);
 
@@ -60,10 +66,11 @@ CompileItem::visit (HIR::StaticItem &var)
 
   rust_assert (canonical_path.has_value ());
 
-  HIR::Expr &const_value_expr = var.get_expr ();
   ctx->push_const_context ();
-  tree value = compile_constant_item (resolved_type, *canonical_path,
-                                     const_value_expr, var.get_locus ());
+  tree value
+    = compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
+                            resolved_type, *canonical_path, const_value_expr,
+                            var.get_locus (), const_value_expr.get_locus ());
   ctx->pop_const_context ();
 
   std::string name = canonical_path->get ();
@@ -89,16 +96,21 @@ CompileItem::visit (HIR::StaticItem &var)
 void
 CompileItem::visit (HIR::ConstantItem &constant)
 {
+  HIR::Expr &const_value_expr = constant.get_expr ();
   auto &mappings = constant.get_mappings ();
 
   if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
     return;
 
   // resolve the type
-  TyTy::BaseType *resolved_type = nullptr;
+  TyTy::BaseType *constant_type = nullptr;
+  TyTy::BaseType *expr_type = nullptr;
 
   bool ok
-    = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &resolved_type);
+    = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
+  rust_assert (ok);
+  ok = ctx->get_tyctx ()->lookup_type (
+    const_value_expr.get_mappings ().get_hirid (), &expr_type);
   rust_assert (ok);
 
   // canonical path
@@ -120,11 +132,12 @@ CompileItem::visit (HIR::ConstantItem &constant)
                         .value ();
     }
 
-  HIR::Expr &const_value_expr = constant.get_expr ();
   ctx->push_const_context ();
   tree const_expr
-    = compile_constant_item (resolved_type, canonical_path, const_value_expr,
-                            constant.get_locus ());
+    = compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
+                            canonical_path, const_value_expr,
+                            constant.get_locus (),
+                            const_value_expr.get_locus ());
   ctx->pop_const_context ();
 
   ctx->push_const (const_expr);
diff --git a/gcc/testsuite/rust/compile/issue-1525.rs 
b/gcc/testsuite/rust/compile/issue-1525.rs
new file mode 100644
index 000000000000..b2247cd9e7d2
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1525.rs
@@ -0,0 +1,4 @@
+fn main() {
+    const slice: &[i32] = &[1, 2, 3];
+    let _slice2: &[i32] = slice;
+}

Reply via email to