Skip to content

Commit 704dab6

Browse files
committed
ast: Use AnonConst for array type sizes
gcc/rust/ChangeLog: * ast/rust-expr.h: Add handling for deferred consts. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. * ast/rust-ast.cc (AnonConst::as_string): Likewise. (ArrayType::as_string): Likewise. * ast/rust-type.h (class ArrayType): Use AnonConst for sizes. * parse/rust-parse-impl.h (Parser::parse_anon_const): New function. (Parser::parse_slice_or_array_type): Call it. * parse/rust-parse.h: Declare it.
1 parent 9fee471 commit 704dab6

File tree

6 files changed

+96
-28
lines changed

6 files changed

+96
-28
lines changed

gcc/rust/ast/rust-ast-visitor.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ DefaultASTVisitor::visit (AST::ConstBlock &expr)
464464
void
465465
DefaultASTVisitor::visit (AST::AnonConst &expr)
466466
{
467-
visit (expr.get_inner_expr ());
467+
if (!expr.is_deferred ())
468+
visit (expr.get_inner_expr ());
468469
}
469470

470471
void

gcc/rust/ast/rust-ast.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,14 @@ BlockExpr::as_string () const
12811281
std::string
12821282
AnonConst::as_string () const
12831283
{
1284-
return "AnonConst: " + expr->as_string ();
1284+
std::string str = "AnonConst: ";
1285+
1286+
if (kind == AnonConst::Kind::DeferredInference)
1287+
str += "_";
1288+
else
1289+
str += expr.value ()->as_string ();
1290+
1291+
return str;
12851292
}
12861293

12871294
std::string
@@ -2768,7 +2775,7 @@ std::string
27682775
ArrayType::as_string () const
27692776
{
27702777
// TODO: rewrite to work with non-linearisable types and exprs
2771-
return "[" + elem_type->as_string () + "; " + size->as_string () + "]";
2778+
return "[" + elem_type->as_string () + "; " + size.as_string () + "]";
27722779
}
27732780

27742781
std::string

gcc/rust/ast/rust-expr.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef RUST_AST_EXPR_H
22
#define RUST_AST_EXPR_H
33

4+
#include "optional.h"
45
#include "rust-ast.h"
56
#include "rust-common.h"
67
#include "rust-path.h"
@@ -2759,24 +2760,42 @@ class BlockExpr : public ExprWithBlock
27592760
class AnonConst : public ExprWithBlock
27602761
{
27612762
public:
2763+
enum class Kind
2764+
{
2765+
Explicit,
2766+
DeferredInference,
2767+
};
2768+
27622769
AnonConst (std::unique_ptr<Expr> &&expr, location_t locus = UNKNOWN_LOCATION)
2763-
: ExprWithBlock (), locus (locus), expr (std::move (expr))
2770+
: ExprWithBlock (), locus (locus), kind (Kind::Explicit),
2771+
expr (std::move (expr))
27642772
{
2765-
rust_assert (this->expr);
2773+
rust_assert (this->expr.value ());
27662774
}
27672775

2776+
AnonConst (location_t locus = UNKNOWN_LOCATION)
2777+
: ExprWithBlock (), locus (locus), kind (Kind::DeferredInference),
2778+
expr (tl::nullopt)
2779+
{}
2780+
27682781
AnonConst (const AnonConst &other)
27692782
{
27702783
node_id = other.node_id;
27712784
locus = other.locus;
2772-
expr = other.expr->clone_expr ();
2785+
kind = other.kind;
2786+
2787+
if (other.expr)
2788+
expr = other.expr.value ()->clone_expr ();
27732789
}
27742790

27752791
AnonConst operator= (const AnonConst &other)
27762792
{
27772793
node_id = other.node_id;
27782794
locus = other.locus;
2779-
expr = other.expr->clone_expr ();
2795+
kind = other.kind;
2796+
2797+
if (other.expr)
2798+
expr = other.expr.value ()->clone_expr ();
27802799

27812800
return *this;
27822801
}
@@ -2786,7 +2805,13 @@ class AnonConst : public ExprWithBlock
27862805
Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstExpr; }
27872806

27882807
location_t get_locus () const override { return locus; }
2789-
Expr &get_inner_expr () { return *expr; }
2808+
2809+
Expr &get_inner_expr ()
2810+
{
2811+
rust_assert (expr.has_value ());
2812+
return *expr.value ();
2813+
}
2814+
27902815
NodeId get_node_id () const override { return node_id; }
27912816

27922817
/* FIXME: AnonConst are always "internal" and should not have outer attributes
@@ -2807,9 +2832,12 @@ class AnonConst : public ExprWithBlock
28072832

28082833
void accept_vis (ASTVisitor &vis) override;
28092834

2835+
bool is_deferred () const { return kind == Kind::DeferredInference; }
2836+
28102837
private:
28112838
location_t locus;
2812-
std::unique_ptr<Expr> expr;
2839+
Kind kind;
2840+
tl::optional<std::unique_ptr<Expr>> expr;
28132841

28142842
AnonConst *clone_expr_with_block_impl () const override
28152843
{

gcc/rust/ast/rust-type.h

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "optional.h"
2323
#include "rust-ast.h"
24+
#include "rust-expr.h"
2425
#include "rust-path.h"
2526

2627
namespace Rust {
@@ -678,27 +679,26 @@ class ReferenceType : public TypeNoBounds
678679
class ArrayType : public TypeNoBounds
679680
{
680681
std::unique_ptr<Type> elem_type;
681-
std::unique_ptr<Expr> size;
682+
AnonConst size;
682683
location_t locus;
683684

684685
public:
685686
// Constructor requires pointers for polymorphism
686-
ArrayType (std::unique_ptr<Type> type, std::unique_ptr<Expr> array_size,
687-
location_t locus)
687+
ArrayType (std::unique_ptr<Type> type, AnonConst array_size, location_t locus)
688688
: elem_type (std::move (type)), size (std::move (array_size)), locus (locus)
689689
{}
690690

691691
// Copy constructor requires deep copies of both unique pointers
692692
ArrayType (ArrayType const &other)
693-
: elem_type (other.elem_type->clone_type ()),
694-
size (other.size->clone_expr ()), locus (other.locus)
693+
: elem_type (other.elem_type->clone_type ()), size (other.size),
694+
locus (other.locus)
695695
{}
696696

697697
// Overload assignment operator to deep copy pointers
698698
ArrayType &operator= (ArrayType const &other)
699699
{
700700
elem_type = other.elem_type->clone_type ();
701-
size = other.size->clone_expr ();
701+
size = other.size;
702702
locus = other.locus;
703703
return *this;
704704
}
@@ -721,17 +721,15 @@ class ArrayType : public TypeNoBounds
721721
}
722722

723723
// TODO: would a "vis_expr" be better?
724-
Expr &get_size_expr ()
724+
AnonConst &get_size_expr ()
725725
{
726-
rust_assert (size != nullptr);
727-
return *size;
726+
// rust_assert (size != nullptr);
727+
728+
return size;
728729
}
729730

730731
std::unique_ptr<Type> &get_element_type () { return elem_type; }
731732

732-
// Additional getter for direct access to the size expr unique_ptr
733-
std::unique_ptr<Expr> &get_size_ptr () { return size; }
734-
735733
protected:
736734
/* Use covariance to implement clone function as returning this object rather
737735
* than base */
@@ -741,10 +739,9 @@ class ArrayType : public TypeNoBounds
741739
}
742740
ArrayType *reconstruct_impl () const override
743741
{
744-
return new ArrayType (
745-
elem_type->reconstruct (),
746-
size->clone_expr () /* FIXME: This should be `reconstruct_expr()` */,
747-
locus);
742+
return new ArrayType (elem_type->reconstruct (),
743+
size /* FIXME: This should be `reconstruct_expr()` */,
744+
locus);
748745
}
749746
};
750747

gcc/rust/parse/rust-parse-impl.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
/* DO NOT INCLUDE ANYWHERE - this is automatically included with rust-parse.h
2323
* This is also the reason why there are no include guards. */
2424

25+
#include "expected.h"
26+
#include "rust-ast.h"
2527
#include "rust-common.h"
2628
#include "rust-expr.h"
2729
#include "rust-item.h"
2830
#include "rust-common.h"
31+
#include "rust-parse.h"
2932
#include "rust-token.h"
3033
#define INCLUDE_ALGORITHM
3134
#include "rust-diagnostics.h"
@@ -7272,6 +7275,27 @@ Parser<ManagedTokenSource>::parse_block_expr (
72727275
std::move (label), locus, end_locus));
72737276
}
72747277

7278+
/* Parse an anonymous const expression. This can be a regular const expression
7279+
* or an underscore for deferred const inference */
7280+
template <typename ManagedTokenSource>
7281+
tl::expected<AST::AnonConst, AnonConstError>
7282+
Parser<ManagedTokenSource>::parse_anon_const ()
7283+
{
7284+
auto current = lexer.peek_token ();
7285+
auto locus = current->get_locus ();
7286+
7287+
// Special case deferred inference constants
7288+
if (maybe_skip_token (UNDERSCORE))
7289+
return AST::AnonConst (locus);
7290+
7291+
auto expr = parse_expr ();
7292+
7293+
if (!expr)
7294+
return tl::make_unexpected (AnonConstError::InvalidSizeExpr);
7295+
7296+
return AST::AnonConst (std::move (expr), locus);
7297+
}
7298+
72757299
/* Parse a "const block", a block preceded by the `const` keyword whose
72767300
* statements can be const evaluated and used in constant contexts */
72777301
template <typename ManagedTokenSource>
@@ -9848,8 +9872,9 @@ Parser<ManagedTokenSource>::parse_slice_or_array_type ()
98489872
lexer.skip_token ();
98499873

98509874
// parse required array size expression
9851-
std::unique_ptr<AST::Expr> size = parse_expr ();
9852-
if (size == nullptr)
9875+
auto size = parse_anon_const ();
9876+
9877+
if (!size)
98539878
{
98549879
Error error (lexer.peek_token ()->get_locus (),
98559880
"failed to parse size expression in array type");
@@ -9864,7 +9889,8 @@ Parser<ManagedTokenSource>::parse_slice_or_array_type ()
98649889
}
98659890

98669891
return std::unique_ptr<AST::ArrayType> (
9867-
new AST::ArrayType (std::move (inner_type), std::move (size), locus));
9892+
new AST::ArrayType (std::move (inner_type), std::move (*size),
9893+
locus));
98689894
}
98699895
default:
98709896
// error

gcc/rust/parse/rust-parse.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,18 @@ class ParseLifetimeParamError
3434
class ParseLifetimeError
3535
{
3636
};
37+
38+
enum class AnonConstError
39+
{
40+
InvalidSizeExpr,
41+
};
42+
3743
enum class ParseLoopLabelError
3844
{
3945
NOT_LOOP_LABEL,
4046
MISSING_COLON,
4147
};
48+
4249
enum class ParseSelfError
4350
{
4451
SELF_PTR,
@@ -166,6 +173,8 @@ template <typename ManagedTokenSource> class Parser
166173
tl::optional<AST::LoopLabel> = tl::nullopt,
167174
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
168175

176+
tl::expected<AST::AnonConst, AnonConstError> parse_anon_const ();
177+
169178
std::unique_ptr<AST::ConstBlock>
170179
parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
171180
location_t loc = UNKNOWN_LOCATION);

0 commit comments

Comments
 (0)