Skip to content

Commit

Permalink
gccrs: [E0164] Neither tuple struct nor tuple variant used as a pattern
Browse files Browse the repository at this point in the history
Checking if pattern has items, before returing solves ICE.
Added error code and rich location.
Also, fixes Rust-GCC#2430

gcc/rust/ChangeLog:

	* ast/rust-pattern.h: No need of assertion, we are handling it.
	* resolve/rust-early-name-resolver.cc (EarlyNameResolver::visit):
	Added check which emits error instead of using assertion.
	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit):
	Added rich location and error code.

gcc/testsuite/ChangeLog:

	* rust/compile/match5.rs:
	Updated comment for dejagnu.
	* rust/compile/pattern-struct.rs: New test for ICE.

Signed-off-by: Muhammad Mahad <[email protected]>
  • Loading branch information
MahadMuhammad authored and CohenArthur committed Jan 16, 2024
1 parent fb3f64a commit d2ec386
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 9 deletions.
7 changes: 1 addition & 6 deletions gcc/rust/ast/rust-pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -1176,12 +1176,7 @@ class TupleStructPattern : public Pattern

void accept_vis (ASTVisitor &vis) override;

// TODO: seems kinda dodgy. Think of better way.
std::unique_ptr<TupleStructItems> &get_items ()
{
rust_assert (has_items ());
return items;
}
std::unique_ptr<TupleStructItems> &get_items () { return items; }

PathInExpression &get_path () { return path; }
const PathInExpression &get_path () const { return path; }
Expand Down
10 changes: 10 additions & 0 deletions gcc/rust/resolve/rust-early-name-resolver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,16 @@ EarlyNameResolver::visit (AST::TupleStructItemsRange &tuple_items)
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
6 changes: 4 additions & 2 deletions gcc/rust/typecheck/rust-hir-type-check-pattern.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
}

// error[E0532]: expected tuple struct or tuple variant, found struct variant
// `Foo::D`
// `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
if (variant->get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
{
std::string variant_type
= TyTy::VariantDef::variant_type_string (variant->get_variant_type ());

rich_location rich_locus (line_table, pattern.get_locus ());
rich_locus.add_fixit_replace ("not a tuple struct or tuple variant");
rust_error_at (
pattern.get_locus (),
rich_locus, ErrorCode::E0164,
"expected tuple struct or tuple variant, found %s variant %<%s::%s%>",
variant_type.c_str (), adt->get_name ().c_str (),
variant->get_identifier ().c_str ());
Expand Down
2 changes: 1 addition & 1 deletion gcc/testsuite/rust/compile/match5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ fn inspect(f: Foo) {
Foo::A => {}
Foo::B => {}
Foo::C(a) => {}
Foo::D(x, y) => {} // { dg-error "expected tuple struct or tuple variant, found struct variant 'Foo::D'" }
Foo::D(x, y) => {} // { dg-error "expected tuple struct or tuple variant, found struct variant .Foo::D." }
}
}
18 changes: 18 additions & 0 deletions gcc/testsuite/rust/compile/pattern-struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fn main() {
enum A {
B,
C,
}

impl A {
fn new() {}
}

fn bar(foo: A) {
match foo {
A::new() => (),
// { dg-error "expected tuple struct or tuple variant, found associated function" "" { target *-*-* } .-1 }
_ => {}
}
}
}

0 comments on commit d2ec386

Please sign in to comment.