]> 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)
committerPhilip Herron <philip.herron@embecosm.com>
Mon, 2 Dec 2024 17:30:59 +0000 (17:30 +0000)
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 e39c2a993257a5d5d77ae424166ba170833b6823..a4d0d062acccef43095675f16e5b46a29e75d3c1 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 bf175d748a0b44f099d3e8126deee8399b304eb1..3c50535552f542491ce385a5314ab9450978e45f 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 dfc8055a353b155a0af68ac773eb9f050ca9036c..6a3c3b0e1c02651ef5ebae7c7a76cc244e1684b0 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 8537d818791e63270fa282f83bd5db3a291ca44c..60159b63fd5bd7f17069259be7b2a803a7a80cba 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;
+}