Checking if pattern has items, before returing solves ICE.
Added error code and rich location.
Also, fixes https://github.com/Rust-GCC/gccrs/issues/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 <mahadtxt@gmail.com>
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; }
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);
}
}
// 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 ());
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." }
}
}
--- /dev/null
+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 }
+ _ => {}
+ }
+ }
+}