Skip to content

Commit 85bd4ce

Browse files
bors[bot]yizhepku
andauthored
Merge #288
288: Fix crash with zero length array r=philberty a=YizhePKU This PR fixes the crash that results from zero-length arrays, such as `let arr = []`(issue #260). `ArrayExpr` now uses `ArrayElemsValues` to represent an empty array like that, instead of `nullptr`. However, currently such code still doesn't compile. Four tests were added, two of which report an error: ```Rust // compilable/array_empty_list.rs fn main() { let arr = []; } // rust1: error: unable to determine type: please give this a type: 24 ``` ```Rust // compilable/array_zero_length_fold.rs fn main() { let arr = ["Hello"; 123 - 123]; } // array_zero_length_fold.rs:2:25: fatal error: failed to fold capacity constant ``` I think these are best treated as separate bugs. We can merge first and fix later, or we can delay this PR. Either is OK. Co-authored-by: Yizhe <[email protected]> Co-authored-by: YizhePKU <[email protected]> Co-authored-by: YizhePKU <[email protected]>
2 parents 4937562 + 90d5337 commit 85bd4ce

File tree

11 files changed

+166
-131
lines changed

11 files changed

+166
-131
lines changed

gcc/rust/ast/rust-ast-full-test.cc

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,10 +2165,7 @@ ArrayExpr::as_string () const
21652165
str += append_attributes (inner_attrs, INNER);
21662166

21672167
str += "\n Array elems: ";
2168-
if (!has_array_elems ())
2169-
str += "none";
2170-
else
2171-
str += internal_elements->as_string ();
2168+
str += internal_elements->as_string ();
21722169

21732170
return str;
21742171
}

gcc/rust/ast/rust-expr.h

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,26 +1099,25 @@ class ArrayExpr : public ExprWithoutBlock
10991099
outer_attrs = std::move (new_attrs);
11001100
}
11011101

1102-
// Returns whether array expr has array elems or if it is just empty.
1103-
bool has_array_elems () const { return internal_elements != nullptr; }
1104-
11051102
// Constructor requires ArrayElems pointer
11061103
ArrayExpr (std::unique_ptr<ArrayElems> array_elems,
11071104
std::vector<Attribute> inner_attribs,
11081105
std::vector<Attribute> outer_attribs, Location locus)
11091106
: outer_attrs (std::move (outer_attribs)),
11101107
inner_attrs (std::move (inner_attribs)),
11111108
internal_elements (std::move (array_elems)), locus (locus)
1112-
{}
1109+
{
1110+
rust_assert (internal_elements != nullptr);
1111+
}
11131112

11141113
// Copy constructor requires cloning ArrayElems for polymorphism to hold
11151114
ArrayExpr (ArrayExpr const &other)
11161115
: ExprWithoutBlock (other), outer_attrs (other.outer_attrs),
11171116
inner_attrs (other.inner_attrs), locus (other.locus),
11181117
marked_for_strip (other.marked_for_strip)
11191118
{
1120-
if (other.has_array_elems ())
1121-
internal_elements = other.internal_elements->clone_array_elems ();
1119+
internal_elements = other.internal_elements->clone_array_elems ();
1120+
rust_assert (internal_elements != nullptr);
11221121
}
11231122

11241123
// Overload assignment operator to clone internal_elements
@@ -1130,11 +1129,9 @@ class ArrayExpr : public ExprWithoutBlock
11301129
marked_for_strip = other.marked_for_strip;
11311130
outer_attrs = other.outer_attrs;
11321131

1133-
if (other.has_array_elems ())
1134-
internal_elements = other.internal_elements->clone_array_elems ();
1135-
else
1136-
internal_elements = nullptr;
1132+
internal_elements = other.internal_elements->clone_array_elems ();
11371133

1134+
rust_assert (internal_elements != nullptr);
11381135
return *this;
11391136
}
11401137

gcc/rust/expand/rust-macro-expand.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -727,8 +727,7 @@ class AttrVisitor : public AST::ASTVisitor
727727

728728
/* assuming you can't strip away the ArrayElems type, but can strip
729729
* internal expressions and whatever */
730-
if (expr.has_array_elems ())
731-
expr.get_array_elems ()->accept_vis (*this);
730+
expr.get_array_elems ()->accept_vis (*this);
732731
}
733732
void visit (AST::ArrayIndexExpr &expr) override
734733
{
@@ -3264,8 +3263,8 @@ MacroExpander::expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc)
32643263
// how would errors be signalled? null fragment? something else?
32653264
// what about error vs just not having stuff in rules definition yet?
32663265

3267-
/* replace macro invocation with ast frag. actually, don't have any context here. maybe attach ast
3268-
* frag to macro invocation, and then have a method above get it? Or just return the ast frag from
3266+
/* replace macro invocation with ast frag. actually, don't have any context here. maybe attach ast
3267+
* frag to macro invocation, and then have a method above get it? Or just return the ast frag from
32693268
* this method. */
32703269
}
32713270
#endif

0 commit comments

Comments
 (0)