Skip to content

Commit db3d8fb

Browse files
committed
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 #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>
1 parent fa93e28 commit db3d8fb

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

gcc/rust/backend/rust-compile-base.cc

+12-3
Original file line numberDiff line numberDiff line change
@@ -777,13 +777,18 @@ HIRCompileBase::compile_function (
777777

778778
tree
779779
HIRCompileBase::compile_constant_item (
780-
TyTy::BaseType *resolved_type, const Resolver::CanonicalPath &canonical_path,
781-
HIR::Expr &const_value_expr, location_t locus)
780+
HirId coercion_id, TyTy::BaseType *resolved_type,
781+
TyTy::BaseType *expected_type, const Resolver::CanonicalPath &canonical_path,
782+
HIR::Expr &const_value_expr, location_t locus, location_t expr_locus)
782783
{
783784
const std::string &ident = canonical_path.get ();
784785

785786
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
786787
tree const_type = build_qualified_type (type, TYPE_QUAL_CONST);
788+
789+
tree actual_type = TyTyResolveCompile::compile (ctx, expected_type);
790+
tree actual_const_type = build_qualified_type (actual_type, TYPE_QUAL_CONST);
791+
787792
bool is_block_expr
788793
= const_value_expr.get_expression_type () == HIR::Expr::ExprType::Block;
789794

@@ -851,7 +856,11 @@ HIRCompileBase::compile_constant_item (
851856
tree call = build_call_array_loc (locus, const_type, fndecl, 0, NULL);
852857
tree folded_expr = fold_expr (call);
853858

854-
return named_constant_expression (const_type, ident, folded_expr, locus);
859+
// coercion site
860+
tree coerced = coercion_site (coercion_id, folded_expr, resolved_type,
861+
expected_type, locus, expr_locus);
862+
863+
return named_constant_expression (actual_const_type, ident, coerced, locus);
855864
}
856865

857866
tree

gcc/rust/backend/rust-compile-base.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ class HIRCompileBase
9090
void compile_function_body (tree fndecl, HIR::BlockExpr &function_body,
9191
TyTy::BaseType *fn_return_ty);
9292

93-
tree compile_constant_item (TyTy::BaseType *resolved_type,
93+
tree compile_constant_item (HirId coercion_id, TyTy::BaseType *resolved_type,
94+
TyTy::BaseType *expected_type,
9495
const Resolver::CanonicalPath &canonical_path,
95-
HIR::Expr &const_value_expr, location_t locus);
96+
HIR::Expr &const_value_expr, location_t locus,
97+
location_t expr_locus);
9698

9799
tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param,
98100
std::vector<HIR::FunctionParam> &function_params,

gcc/rust/backend/rust-compile-implitem.cc

+9-2
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,16 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
4545
rust_assert (canonical_path);
4646

4747
HIR::Expr &const_value_expr = constant.get_expr ();
48+
TyTy::BaseType *expr_type = nullptr;
49+
bool ok = ctx->get_tyctx ()->lookup_type (
50+
const_value_expr.get_mappings ().get_hirid (), &expr_type);
51+
rust_assert (ok);
52+
4853
tree const_expr
49-
= compile_constant_item (resolved_type, *canonical_path, const_value_expr,
50-
constant.get_locus ());
54+
= compile_constant_item (constant.get_mappings ().get_hirid (), expr_type,
55+
resolved_type, *canonical_path, const_value_expr,
56+
constant.get_locus (),
57+
const_value_expr.get_locus ());
5158
ctx->push_const (const_expr);
5259
ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
5360

gcc/rust/backend/rust-compile-item.cc

+21-8
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,16 @@ CompileItem::visit (HIR::StaticItem &var)
3535
return;
3636
}
3737

38+
HIR::Expr &const_value_expr = var.get_expr ();
39+
3840
TyTy::BaseType *resolved_type = nullptr;
41+
TyTy::BaseType *expr_type = nullptr;
3942
bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (),
4043
&resolved_type);
4144
rust_assert (ok);
45+
ok = ctx->get_tyctx ()->lookup_type (
46+
const_value_expr.get_mappings ().get_hirid (), &expr_type);
47+
rust_assert (ok);
4248

4349
tree type = TyTyResolveCompile::compile (ctx, resolved_type);
4450

@@ -60,10 +66,11 @@ CompileItem::visit (HIR::StaticItem &var)
6066

6167
rust_assert (canonical_path.has_value ());
6268

63-
HIR::Expr &const_value_expr = var.get_expr ();
6469
ctx->push_const_context ();
65-
tree value = compile_constant_item (resolved_type, *canonical_path,
66-
const_value_expr, var.get_locus ());
70+
tree value
71+
= compile_constant_item (var.get_mappings ().get_hirid (), expr_type,
72+
resolved_type, *canonical_path, const_value_expr,
73+
var.get_locus (), const_value_expr.get_locus ());
6774
ctx->pop_const_context ();
6875

6976
std::string name = canonical_path->get ();
@@ -89,16 +96,21 @@ CompileItem::visit (HIR::StaticItem &var)
8996
void
9097
CompileItem::visit (HIR::ConstantItem &constant)
9198
{
99+
HIR::Expr &const_value_expr = constant.get_expr ();
92100
auto &mappings = constant.get_mappings ();
93101

94102
if (ctx->lookup_const_decl (mappings.get_hirid (), &reference))
95103
return;
96104

97105
// resolve the type
98-
TyTy::BaseType *resolved_type = nullptr;
106+
TyTy::BaseType *constant_type = nullptr;
107+
TyTy::BaseType *expr_type = nullptr;
99108

100109
bool ok
101-
= ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &resolved_type);
110+
= ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &constant_type);
111+
rust_assert (ok);
112+
ok = ctx->get_tyctx ()->lookup_type (
113+
const_value_expr.get_mappings ().get_hirid (), &expr_type);
102114
rust_assert (ok);
103115

104116
// canonical path
@@ -120,11 +132,12 @@ CompileItem::visit (HIR::ConstantItem &constant)
120132
.value ();
121133
}
122134

123-
HIR::Expr &const_value_expr = constant.get_expr ();
124135
ctx->push_const_context ();
125136
tree const_expr
126-
= compile_constant_item (resolved_type, canonical_path, const_value_expr,
127-
constant.get_locus ());
137+
= compile_constant_item (mappings.get_hirid (), expr_type, constant_type,
138+
canonical_path, const_value_expr,
139+
constant.get_locus (),
140+
const_value_expr.get_locus ());
128141
ctx->pop_const_context ();
129142

130143
ctx->push_const (const_expr);
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
const slice: &[i32] = &[1, 2, 3];
3+
let _slice2: &[i32] = slice;
4+
}

0 commit comments

Comments
 (0)