if (elems.has_struct_pattern_fields ())
{
visit_items_joined_by_separator (elems.get_struct_pattern_fields ());
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
push (Rust::Token::make (COMMA, UNDEF_LOCATION));
visit_items_as_lines (elems.get_etc_outer_attrs ());
str += "\n " + field->as_string ();
}
- str += "\n Etc: ";
- if (has_struct_pattern_etc)
+ str += "\n Has rest: ";
+ if (has_rest_pattern)
str += "true";
else
str += "false";
// bool has_struct_pattern_fields;
std::vector<std::unique_ptr<StructPatternField>> fields;
- bool has_struct_pattern_etc;
+ bool has_rest_pattern;
std::vector<Attribute> struct_pattern_etc_attrs;
// StructPatternEtc etc;
* no etc). */
bool is_empty () const
{
- return !has_struct_pattern_fields () && !has_struct_pattern_etc;
+ return !has_struct_pattern_fields () && !has_rest_pattern;
}
- bool has_etc () const { return has_struct_pattern_etc; }
+ bool has_rest () const { return has_rest_pattern; }
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields,
std::vector<Attribute> etc_attrs)
- : fields (std::move (fields)), has_struct_pattern_etc (true),
+ : fields (std::move (fields)), has_rest_pattern (true),
struct_pattern_etc_attrs (std::move (etc_attrs))
{}
// Constructor for StructPatternElements with no StructPatternEtc
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields)
- : fields (std::move (fields)), has_struct_pattern_etc (false),
+ : fields (std::move (fields)), has_rest_pattern (false),
struct_pattern_etc_attrs ()
{}
// Copy constructor with vector clone
StructPatternElements (StructPatternElements const &other)
- : has_struct_pattern_etc (other.has_struct_pattern_etc),
+ : has_rest_pattern (other.has_rest_pattern),
struct_pattern_etc_attrs (other.struct_pattern_etc_attrs)
{
fields.reserve (other.fields.size ());
StructPatternElements &operator= (StructPatternElements const &other)
{
struct_pattern_etc_attrs = other.struct_pattern_etc_attrs;
- has_struct_pattern_etc = other.has_struct_pattern_etc;
+ has_rest_pattern = other.has_rest_pattern;
fields.clear ();
fields.reserve (other.fields.size ());
void strip_etc ()
{
- has_struct_pattern_etc = false;
+ has_rest_pattern = false;
struct_pattern_etc_attrs.clear ();
struct_pattern_etc_attrs.shrink_to_fit ();
}
maybe_strip_pointer_allow_strip (elems.get_struct_pattern_fields ());
// assuming you can strip the ".." part
- if (elems.has_etc ())
+ if (elems.has_rest ())
{
expand_cfg_attrs (elems.get_etc_outer_attrs ());
if (fails_cfg_with_expand (elems.get_etc_outer_attrs ()))
= ASTLowerPathInExpression::translate (pattern.get_path ());
auto &raw_elems = pattern.get_struct_pattern_elems ();
- rust_assert (!raw_elems.has_etc ());
std::vector<std::unique_ptr<HIR::StructPatternField>> fields;
for (auto &field : raw_elems.get_struct_pattern_fields ())
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::StructPatternElements elems (std::move (fields));
+ HIR::StructPatternElements elems (
+ std::move (fields), pattern.get_struct_pattern_elems ().has_rest ());
translated = new HIR::StructPattern (mapping, *path, std::move (elems));
}
class StructPatternElements
{
std::vector<std::unique_ptr<StructPatternField>> fields;
+ bool has_rest_pattern;
public:
// Returns whether there are any struct pattern fields
* no etc). */
bool is_empty () const { return !has_struct_pattern_fields (); }
+ bool has_rest () const { return has_rest_pattern; }
+
// Constructor for StructPatternElements with both (potentially)
StructPatternElements (
std::vector<std::unique_ptr<StructPatternField>> fields)
- : fields (std::move (fields))
+ : fields (std::move (fields)), has_rest_pattern (false)
+ {}
+
+ StructPatternElements (
+ std::vector<std::unique_ptr<StructPatternField>> fields,
+ bool has_rest_pattern)
+ : fields (std::move (fields)), has_rest_pattern (has_rest_pattern)
{}
// Copy constructor with vector clone
{
fields.reserve (other.fields.size ());
for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_pattern_field ());
+ fields.emplace_back (e->clone_struct_pattern_field ());
+ has_rest_pattern = other.has_rest_pattern;
}
// Overloaded assignment operator with vector clone
fields.clear ();
fields.reserve (other.fields.size ());
for (const auto &e : other.fields)
- fields.push_back (e->clone_struct_pattern_field ());
-
+ fields.emplace_back (e->clone_struct_pattern_field ());
+ has_rest_pattern = other.has_rest_pattern;
return *this;
}
std::vector<std::unique_ptr<AST::StructPatternField>> fields;
AST::AttrVec etc_attrs;
- bool has_etc = false;
+ bool has_rest = false;
// try parsing struct pattern fields
const_TokenPtr t = lexer.peek_token ();
{
lexer.skip_token ();
etc_attrs = std::move (outer_attrs);
- has_etc = true;
+ has_rest = true;
break;
}
t = lexer.peek_token ();
}
- if (has_etc)
+ if (has_rest)
return AST::StructPatternElements (std::move (fields),
std::move (etc_attrs));
else
// Expects enum struct or struct struct.
// error[E0027]: pattern does not mention fields `x`, `y`
// error[E0026]: variant `Foo::D` does not have a field named `b`
- if (named_fields.size () != variant->num_fields ())
+ if (!pattern.get_struct_pattern_elems ().has_rest ()
+ && named_fields.size () != variant->num_fields ())
{
std::map<std::string, bool> missing_names;
--- /dev/null
+// { dg-options "-w" }
+struct S();
+
+fn main() {
+ let s = S{};
+ match s {
+ S{..} => {}
+ }
+}
--- /dev/null
+// { dg-options "-w" }
+struct S {
+ x: i32,
+ y: i32,
+}
+
+fn main() {
+ let s = S{x: 1, y: 2};
+ match s {
+ S{x: 1, ..} => {}
+ }
+}