From: Arthur Cohen Date: Tue, 8 Jul 2025 12:34:04 +0000 (+0200) Subject: gccrs: hir: Handle deferred const inference variables X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=03cdb5236c50f43a16f916159a03a785aa14b024;p=thirdparty%2Fgcc.git gccrs: hir: Handle deferred const inference variables gcc/rust/ChangeLog: * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Handle defered consts. * hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise. (AnonConst::operator=): Likewise. * hir/tree/rust-hir-expr.h: Likewise. * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. gcc/testsuite/ChangeLog: * rust/compile/deferred_const_inference.rs: New test. --- diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index 3f3d6007e46..96820fd8c18 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -130,17 +130,24 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr) void ASTLoweringExpr::visit (AST::AnonConst &expr) { - auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ()); - auto &mappings = Analysis::Mappings::get (); auto crate_num = mappings.get_current_crate (); auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (), mappings.get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID); - translated = new HIR::AnonConst (std::move (mapping), - std::unique_ptr (inner_expr), - expr.get_locus ()); + if (expr.is_deferred ()) + { + translated = new HIR::AnonConst (std::move (mapping), expr.get_locus ()); + } + else + { + auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ()); + + translated = new HIR::AnonConst (std::move (mapping), + std::unique_ptr (inner_expr), + expr.get_locus ()); + } } void diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc index 038bfc77f94..8544ed6708b 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -18,6 +18,7 @@ #include "rust-hir-expr.h" #include "rust-hir-map.h" +#include "optional.h" #include "rust-operators.h" #include "rust-hir-stmt.h" @@ -794,22 +795,33 @@ BlockExpr::operator= (BlockExpr const &other) AnonConst::AnonConst (Analysis::NodeMapping mappings, std::unique_ptr &&expr, location_t locus) : ExprWithBlock (std::move (mappings), {}), locus (locus), - expr (std::move (expr)) + kind (Kind::Explicit), expr (std::move (expr)) { - rust_assert (this->expr); + rust_assert (this->expr.value ()); } -AnonConst::AnonConst (const AnonConst &other) - : ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr ()) +AnonConst::AnonConst (Analysis::NodeMapping mappings, location_t locus) + : ExprWithBlock (std::move (mappings), {}), locus (locus), + kind (Kind::DeferredInference), expr (tl::nullopt) {} +AnonConst::AnonConst (const AnonConst &other) + : ExprWithBlock (other), locus (other.locus), kind (other.kind) +{ + if (other.expr) + expr = other.expr.value ()->clone_expr (); +} + AnonConst AnonConst::operator= (const AnonConst &other) { ExprWithBlock::operator= (other); locus = other.locus; - expr = other.expr->clone_expr (); + kind = other.kind; + + if (other.expr) + expr = other.expr.value ()->clone_expr (); return *this; } diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 028455b9870..8e14a7b2912 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -1806,8 +1806,16 @@ protected: class AnonConst : public ExprWithBlock { public: + enum class Kind + { + Explicit, + DeferredInference + }; + AnonConst (Analysis::NodeMapping mappings, std::unique_ptr &&expr, location_t locus = UNKNOWN_LOCATION); + AnonConst (Analysis::NodeMapping mappings, + location_t locus = UNKNOWN_LOCATION); AnonConst (const AnonConst &other); AnonConst operator= (const AnonConst &other); @@ -1822,12 +1830,25 @@ public: } location_t get_locus () const override { return locus; } - Expr &get_inner_expr () { return *expr; } - const Expr &get_inner_expr () const { return *expr; } + + Expr &get_inner_expr () + { + rust_assert (kind == Kind::Explicit); + return *expr.value (); + } + + const Expr &get_inner_expr () const + { + rust_assert (kind == Kind::Explicit); + return *expr.value (); + } + + bool is_deferred () const { return kind == Kind::DeferredInference; } private: location_t locus; - std::unique_ptr expr; + Kind kind; + tl::optional> expr; AnonConst *clone_expr_with_block_impl () const override { diff --git a/gcc/rust/hir/tree/rust-hir-visitor.cc b/gcc/rust/hir/tree/rust-hir-visitor.cc index 447606ebc8c..ece47eba851 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.cc +++ b/gcc/rust/hir/tree/rust-hir-visitor.cc @@ -370,7 +370,8 @@ DefaultHIRVisitor::walk (BlockExpr &expr) void DefaultHIRVisitor::walk (AnonConst &expr) { - expr.get_inner_expr ().accept_vis (*this); + if (!expr.is_deferred ()) + expr.get_inner_expr ().accept_vis (*this); } void @@ -1176,4 +1177,4 @@ DefaultHIRVisitor::walk (BareFunctionType &type) } } // namespace HIR -} // namespace Rust \ No newline at end of file +} // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 5db0e5690c9..9f8d31109b1 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -664,6 +664,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr) void TypeCheckExpr::visit (HIR::AnonConst &expr) { + // FIXME: How do we typecheck a deferred inference const? + + rust_assert (!expr.is_deferred ()); + infered = TypeCheckExpr::Resolve (expr.get_inner_expr ()); } diff --git a/gcc/testsuite/rust/compile/deferred_const_inference.rs b/gcc/testsuite/rust/compile/deferred_const_inference.rs new file mode 100644 index 00000000000..25a3b17096a --- /dev/null +++ b/gcc/testsuite/rust/compile/deferred_const_inference.rs @@ -0,0 +1,7 @@ +// { dg-additional-options "-frust-compile-until=typecheck" } + +// #![feature(generic_arg_infer)] + +fn main() { + let a: [u32; _] = [15u32]; +}