https://gcc.gnu.org/g:9a53a1d1abe2e97207a7bf9ed4db735c4bafb771
commit r15-8555-g9a53a1d1abe2e97207a7bf9ed4db735c4bafb771 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 fb4aace95559..bcc7fc4fcbf4 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 5fb1d83f2eeb..9328a7f74830 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 129e97879fa4..71b3e8d3002d 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 dd37e3997d69..52cd59f94e4f 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; +}