Skip to content

Commit da50d8c

Browse files
committed
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.
1 parent 704dab6 commit da50d8c

File tree

6 files changed

+67
-15
lines changed

6 files changed

+67
-15
lines changed

gcc/rust/hir/rust-ast-lower-expr.cc

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,24 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr)
130130
void
131131
ASTLoweringExpr::visit (AST::AnonConst &expr)
132132
{
133-
auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
134-
135133
auto &mappings = Analysis::Mappings::get ();
136134
auto crate_num = mappings.get_current_crate ();
137135
auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
138136
mappings.get_next_hir_id (crate_num),
139137
UNKNOWN_LOCAL_DEFID);
140138

141-
translated = new HIR::AnonConst (std::move (mapping),
142-
std::unique_ptr<Expr> (inner_expr),
143-
expr.get_locus ());
139+
if (expr.is_deferred ())
140+
{
141+
translated = new HIR::AnonConst (std::move (mapping), expr.get_locus ());
142+
}
143+
else
144+
{
145+
auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
146+
147+
translated = new HIR::AnonConst (std::move (mapping),
148+
std::unique_ptr<Expr> (inner_expr),
149+
expr.get_locus ());
150+
}
144151
}
145152

146153
void

gcc/rust/hir/tree/rust-hir-expr.cc

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "rust-hir-expr.h"
2020
#include "rust-hir-map.h"
21+
#include "optional.h"
2122
#include "rust-operators.h"
2223
#include "rust-hir-stmt.h"
2324

@@ -794,22 +795,33 @@ BlockExpr::operator= (BlockExpr const &other)
794795
AnonConst::AnonConst (Analysis::NodeMapping mappings,
795796
std::unique_ptr<Expr> &&expr, location_t locus)
796797
: ExprWithBlock (std::move (mappings), {}), locus (locus),
797-
expr (std::move (expr))
798+
kind (Kind::Explicit), expr (std::move (expr))
798799
{
799-
rust_assert (this->expr);
800+
rust_assert (this->expr.value ());
800801
}
801802

802-
AnonConst::AnonConst (const AnonConst &other)
803-
: ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr ())
803+
AnonConst::AnonConst (Analysis::NodeMapping mappings, location_t locus)
804+
: ExprWithBlock (std::move (mappings), {}), locus (locus),
805+
kind (Kind::DeferredInference), expr (tl::nullopt)
804806
{}
805807

808+
AnonConst::AnonConst (const AnonConst &other)
809+
: ExprWithBlock (other), locus (other.locus), kind (other.kind)
810+
{
811+
if (other.expr)
812+
expr = other.expr.value ()->clone_expr ();
813+
}
814+
806815
AnonConst
807816
AnonConst::operator= (const AnonConst &other)
808817
{
809818
ExprWithBlock::operator= (other);
810819

811820
locus = other.locus;
812-
expr = other.expr->clone_expr ();
821+
kind = other.kind;
822+
823+
if (other.expr)
824+
expr = other.expr.value ()->clone_expr ();
813825

814826
return *this;
815827
}

gcc/rust/hir/tree/rust-hir-expr.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,8 +1806,16 @@ class BlockExpr : public ExprWithBlock, public WithInnerAttrs
18061806
class AnonConst : public ExprWithBlock
18071807
{
18081808
public:
1809+
enum class Kind
1810+
{
1811+
Explicit,
1812+
DeferredInference
1813+
};
1814+
18091815
AnonConst (Analysis::NodeMapping mappings, std::unique_ptr<Expr> &&expr,
18101816
location_t locus = UNKNOWN_LOCATION);
1817+
AnonConst (Analysis::NodeMapping mappings,
1818+
location_t locus = UNKNOWN_LOCATION);
18111819
AnonConst (const AnonConst &other);
18121820
AnonConst operator= (const AnonConst &other);
18131821

@@ -1822,12 +1830,25 @@ class AnonConst : public ExprWithBlock
18221830
}
18231831

18241832
location_t get_locus () const override { return locus; }
1825-
Expr &get_inner_expr () { return *expr; }
1826-
const Expr &get_inner_expr () const { return *expr; }
1833+
1834+
Expr &get_inner_expr ()
1835+
{
1836+
rust_assert (kind == Kind::Explicit);
1837+
return *expr.value ();
1838+
}
1839+
1840+
const Expr &get_inner_expr () const
1841+
{
1842+
rust_assert (kind == Kind::Explicit);
1843+
return *expr.value ();
1844+
}
1845+
1846+
bool is_deferred () const { return kind == Kind::DeferredInference; }
18271847

18281848
private:
18291849
location_t locus;
1830-
std::unique_ptr<Expr> expr;
1850+
Kind kind;
1851+
tl::optional<std::unique_ptr<Expr>> expr;
18311852

18321853
AnonConst *clone_expr_with_block_impl () const override
18331854
{

gcc/rust/hir/tree/rust-hir-visitor.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ DefaultHIRVisitor::walk (BlockExpr &expr)
370370
void
371371
DefaultHIRVisitor::walk (AnonConst &expr)
372372
{
373-
expr.get_inner_expr ().accept_vis (*this);
373+
if (!expr.is_deferred ())
374+
expr.get_inner_expr ().accept_vis (*this);
374375
}
375376

376377
void
@@ -1176,4 +1177,4 @@ DefaultHIRVisitor::walk (BareFunctionType &type)
11761177
}
11771178

11781179
} // namespace HIR
1179-
} // namespace Rust
1180+
} // namespace Rust

gcc/rust/typecheck/rust-hir-type-check-expr.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,10 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
664664
void
665665
TypeCheckExpr::visit (HIR::AnonConst &expr)
666666
{
667+
// FIXME: How do we typecheck a deferred inference const?
668+
669+
rust_assert (!expr.is_deferred ());
670+
667671
infered = TypeCheckExpr::Resolve (expr.get_inner_expr ());
668672
}
669673

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// { dg-additional-options "-frust-compile-until=typecheck" }
2+
3+
// #![feature(generic_arg_infer)]
4+
5+
fn main() {
6+
let a: [u32; _] = [15u32];
7+
}

0 commit comments

Comments
 (0)