Skip to content

Commit

Permalink
Ensure TupleStructPattern and TuplePattern have items
Browse files Browse the repository at this point in the history
Note that instances of both classes which have been
moved from will have (items == nullptr).

gcc/rust/ChangeLog:

	* ast/rust-pattern.h
	(class TupleStructPattern): Assert that items != nullptr.
	(class TuplePattern): Likewise.
	(TupleStructPattern::has_items): Remove.
	(TuplePattern::has_tuple_pattern_items): Likewise.
	* parse/rust-parse-impl.h
	(Parser::parse_ident_leading_pattern):
	Prevent construction of TupleStructPattern with
	(items == nullptr).
	(Parser::parse_pattern_no_alt): Likewise.
	* ast/rust-ast-collector.cc
	(TokenCollector::visit): Remove usage of
	TupleStructPattern::has_items.
	* ast/rust-ast-visitor.cc
	(DefaultASTVisitor::visit): Likewise.
	* resolve/rust-early-name-resolver.cc
	(EarlyNameResolver::visit): Likewise.

gcc/testsuite/ChangeLog:

	* rust/compile/pattern-struct.rs: Fix test.

Signed-off-by: Owen Avery <[email protected]>
  • Loading branch information
powerboat9 authored and CohenArthur committed Mar 4, 2024
1 parent ede65c2 commit dae69e8
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 54 deletions.
3 changes: 1 addition & 2 deletions gcc/rust/ast/rust-ast-collector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2503,8 +2503,7 @@ TokenCollector::visit (TupleStructPattern &pattern)
{
visit (pattern.get_path ());
push (Rust::Token::make (LEFT_PAREN, pattern.get_locus ()));
if (pattern.has_items ())
visit (pattern.get_items ());
visit (pattern.get_items ());
push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
}

Expand Down
3 changes: 1 addition & 2 deletions gcc/rust/ast/rust-ast-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1225,8 +1225,7 @@ void
DefaultASTVisitor::visit (AST::TupleStructPattern &pattern)
{
visit (pattern.get_path ());
if (pattern.has_items ())
visit (pattern.get_items ());
visit (pattern.get_items ());
}

void
Expand Down
46 changes: 23 additions & 23 deletions gcc/rust/ast/rust-pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -1123,22 +1123,22 @@ class TupleStructPattern : public Pattern
public:
std::string as_string () const override;

// Returns whether the pattern has tuple struct items.
bool has_items () const { return items != nullptr; }

TupleStructPattern (PathInExpression tuple_struct_path,
std::unique_ptr<TupleStructItems> items)
: path (std::move (tuple_struct_path)), items (std::move (items)),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
{
rust_assert (this->items != nullptr);
}

// Copy constructor required to clone
TupleStructPattern (TupleStructPattern const &other) : path (other.path)
{
// guard to protect from null dereference
rust_assert (other.items != nullptr);

node_id = other.node_id;
if (other.items != nullptr)
items = other.items->clone_tuple_struct_items ();
items = other.items->clone_tuple_struct_items ();
}

// Operator overload assignment operator to clone
Expand All @@ -1148,10 +1148,9 @@ class TupleStructPattern : public Pattern
node_id = other.node_id;

// guard to protect from null dereference
if (other.items != nullptr)
items = other.items->clone_tuple_struct_items ();
else
items = nullptr;
rust_assert (other.items != nullptr);

items = other.items->clone_tuple_struct_items ();

return *this;
}
Expand All @@ -1164,7 +1163,11 @@ class TupleStructPattern : public Pattern

void accept_vis (ASTVisitor &vis) override;

std::unique_ptr<TupleStructItems> &get_items () { return items; }
std::unique_ptr<TupleStructItems> &get_items ()
{
rust_assert (items != nullptr);
return items;
}

PathInExpression &get_path () { return path; }
const PathInExpression &get_path () const { return path; }
Expand Down Expand Up @@ -1358,29 +1361,28 @@ class TuplePatternItemsRanged : public TuplePatternItems
// AST node representing a tuple pattern
class TuplePattern : public Pattern
{
// bool has_tuple_pattern_items;
std::unique_ptr<TuplePatternItems> items;
location_t locus;
NodeId node_id;

public:
std::string as_string () const override;

// Returns true if the tuple pattern has items
bool has_tuple_pattern_items () const { return items != nullptr; }

TuplePattern (std::unique_ptr<TuplePatternItems> items, location_t locus)
: items (std::move (items)), locus (locus),
node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
{
rust_assert (this->items != nullptr);
}

// Copy constructor requires clone
TuplePattern (TuplePattern const &other) : locus (other.locus)
{
// guard to prevent null dereference
rust_assert (other.items != nullptr);

node_id = other.node_id;
if (other.items != nullptr)
items = other.items->clone_tuple_pattern_items ();
items = other.items->clone_tuple_pattern_items ();
}

// Overload assignment operator to clone
Expand All @@ -1390,11 +1392,9 @@ class TuplePattern : public Pattern
node_id = other.node_id;

// guard to prevent null dereference
if (other.items != nullptr)
items = other.items->clone_tuple_pattern_items ();
else
items = nullptr;
rust_assert (other.items != nullptr);

items = other.items->clone_tuple_pattern_items ();
return *this;
}

Expand All @@ -1405,7 +1405,7 @@ class TuplePattern : public Pattern
// TODO: seems kinda dodgy. Think of better way.
std::unique_ptr<TuplePatternItems> &get_items ()
{
rust_assert (has_tuple_pattern_items ());
rust_assert (items != nullptr);
return items;
}

Expand Down
16 changes: 0 additions & 16 deletions gcc/rust/parse/rust-parse-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10631,14 +10631,6 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt ()
// tuple struct
lexer.skip_token ();

// check if empty tuple
if (lexer.peek_token ()->get_id () == RIGHT_PAREN)
{
lexer.skip_token ();
return std::unique_ptr<AST::TupleStructPattern> (
new AST::TupleStructPattern (std::move (path), nullptr));
}

// parse items
std::unique_ptr<AST::TupleStructItems> items
= parse_tuple_struct_items ();
Expand Down Expand Up @@ -11094,14 +11086,6 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern ()
// DEBUG
rust_debug ("parsing tuple struct pattern");

// check if empty tuple
if (lexer.peek_token ()->get_id () == RIGHT_PAREN)
{
lexer.skip_token ();
return std::unique_ptr<AST::TupleStructPattern> (
new AST::TupleStructPattern (std::move (path), nullptr));
}

// parse items
std::unique_ptr<AST::TupleStructItems> items
= parse_tuple_struct_items ();
Expand Down
10 changes: 0 additions & 10 deletions gcc/rust/resolve/rust-early-name-resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -558,16 +558,6 @@ EarlyNameResolver::visit (AST::StructPattern &)
void
EarlyNameResolver::visit (AST::TupleStructPattern &pattern)
{
if (!pattern.has_items ())
{
rich_location rich_locus (line_table, pattern.get_locus ());
rich_locus.add_fixit_replace (
"function calls are not allowed in patterns");
rust_error_at (
rich_locus, ErrorCode::E0164,
"expected tuple struct or tuple variant, found associated function");
return;
}
pattern.get_items ()->accept_vis (*this);
}

Expand Down
2 changes: 1 addition & 1 deletion gcc/testsuite/rust/compile/pattern-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() {
fn bar(foo: A) {
match foo {
A::new() => (),
// { dg-error "expected tuple struct or tuple variant, found associated function" "" { target *-*-* } .-1 }
// { dg-error "expected tuple struct or tuple variant, found function" "" { target *-*-* } .-1 }
_ => {}
}
}
Expand Down

0 comments on commit dae69e8

Please sign in to comment.