]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: constant evaluation like these are coercion sites
authorPhilip Herron <herron.philip@googlemail.com>
Mon, 2 Dec 2024 16:17:54 +0000 (16:17 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Fri, 21 Mar 2025 11:33:08 +0000 (12:33 +0100)
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.philip@googlemail.com>
gcc/rust/backend/rust-compile-base.cc
gcc/rust/backend/rust-compile-base.h
gcc/rust/backend/rust-compile-implitem.cc
gcc/rust/backend/rust-compile-item.cc
gcc/testsuite/rust/compile/issue-1525.rs [new file with mode: 0644]

index fb4aace955598fdb9a9e5f9cdb83ce55a4d07847..bcc7fc4fcbf442d8f5ebc8a291d266815b7b8bac 100644 (file)
@@ -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
index 5fb1d83f2eebbd836381b5bd4d9e88ca8eb06481..9328a7f74830a678c754686a1b272cfe1a326a92 100644 (file)
@@ -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,
index 129e97879fa4096d13665f536964604857d3d499..71b3e8d3002d49516ede549dc19ef04b2d0e6f6d 100644 (file)
@@ -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);
 
index dd37e3997d697ce7b69585c3c1d6f648b73b36d5..52cd59f94e4f4e3b4730605143bd8db09b351d8c 100644 (file)
@@ -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 (file)
index 0000000..b2247cd
--- /dev/null
@@ -0,0 +1,4 @@
+fn main() {
+    const slice: &[i32] = &[1, 2, 3];
+    let _slice2: &[i32] = slice;
+}