Skip to content

Commit 1f210e3

Browse files
Merge branch 'master' into fix-no-input-segfault-v2
2 parents 0e2e175 + 0db7472 commit 1f210e3

File tree

5 files changed

+69
-11
lines changed

5 files changed

+69
-11
lines changed

gcc/rust/typecheck/rust-hir-type-check-base.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
412412
bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
413413
if (is_repr && !attr.has_attr_input ())
414414
{
415-
rust_error_at (attr.get_locus (), "malformed %qs attribute", "repr");
415+
rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
416416
continue;
417417
}
418418

@@ -421,7 +421,11 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
421421
const AST::AttrInput &input = attr.get_attr_input ();
422422
bool is_token_tree = input.get_attr_input_type ()
423423
== AST::AttrInput::AttrInputType::TOKEN_TREE;
424-
rust_assert (is_token_tree);
424+
if (!is_token_tree)
425+
{
426+
rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
427+
continue;
428+
}
425429
const auto &option = static_cast<const AST::DelimTokenTree &> (input);
426430
AST::AttrInputMetaItemContainer *meta_items
427431
= option.parse_to_meta_item ();

gcc/rust/typecheck/rust-hir-type-check-pattern.cc

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,32 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
162162

163163
infered = pattern_ty;
164164
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
165-
rust_assert (adt->number_of_variants () > 0);
166165

167-
TyTy::VariantDef *variant = adt->get_variants ().at (0);
166+
TyTy::VariantDef *variant = nullptr;
168167
if (adt->is_enum ())
169168
{
170169
HirId variant_id = UNKNOWN_HIRID;
171170
bool ok = context->lookup_variant_definition (
172171
pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
173-
rust_assert (ok);
172+
if (!ok)
173+
{
174+
rust_error_at (
175+
pattern.get_locus (), ErrorCode::E0532,
176+
"expected tuple struct or tuple variant, found enum %qs",
177+
pattern_ty->get_name ().c_str ());
178+
return;
179+
}
174180

175181
ok = adt->lookup_variant_by_id (variant_id, &variant);
176182
rust_assert (ok);
177183
}
184+
else
185+
{
186+
rust_assert (adt->number_of_variants () > 0);
187+
variant = adt->get_variants ().at (0);
188+
}
189+
190+
rust_assert (variant != nullptr);
178191

179192
// error[E0532]: expected tuple struct or tuple variant, found struct
180193
// variant `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
@@ -644,14 +657,14 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
644657
{
645658
emit_pattern_size_error (pattern, par.get_fields ().size (),
646659
min_size_required);
647-
// TODO attempt to continue to do typechecking even after wrong
648-
// size
649-
break;
660+
// continue and attempt to resolve individual items in the pattern
650661
}
651662

652663
// Resolve lower patterns
653664
std::vector<TyTy::TyVar> pattern_elems;
654-
for (size_t i = 0; i < lower.size (); i++)
665+
size_t nlower_items_to_resolve
666+
= std::min (lower.size (), par.get_fields ().size ());
667+
for (size_t i = 0; i < nlower_items_to_resolve; i++)
655668
{
656669
auto &p = lower[i];
657670
TyTy::BaseType *par_type = par.get_field (i);
@@ -660,16 +673,23 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
660673
pattern_elems.emplace_back (elem->get_ref ());
661674
}
662675

676+
if (lower.size () > par.get_fields ().size ())
677+
break;
678+
663679
// Pad pattern_elems until needing to resolve upper patterns
664-
size_t rest_end = par.get_fields ().size () - upper.size ();
680+
size_t rest_end
681+
= std::max (par.get_fields ().size () - upper.size (), lower.size ());
665682
for (size_t i = lower.size (); i < rest_end; i++)
666683
{
667684
TyTy::BaseType *par_type = par.get_field (i);
668685
pattern_elems.emplace_back (par_type->get_ref ());
669686
}
670687

688+
size_t nupper_items_to_resolve
689+
= std::min (upper.size (),
690+
par.get_fields ().size () - pattern_elems.size ());
671691
// Resolve upper patterns
672-
for (size_t i = 0; i < upper.size (); i++)
692+
for (size_t i = 0; i < nupper_items_to_resolve; i++)
673693
{
674694
auto &p = upper[i];
675695
TyTy::BaseType *par_type = par.get_field (rest_end + i);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[repr = ""] // { dg-error "malformed .repr. attribute" }
2+
struct ThreeInts {
3+
first: i16,
4+
second: i8,
5+
third: i32
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
enum Empty {}
2+
enum NonEmpty {
3+
Foo(i32),
4+
}
5+
6+
fn f(e: Empty) {
7+
match e {
8+
Empty(0) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'Empty'" }
9+
}
10+
11+
match e {
12+
Empty(Empty(..)) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'Empty'" }
13+
}
14+
}
15+
16+
fn g(e: NonEmpty) {
17+
match e {
18+
NonEmpty(0) => {} // { dg-error "expected tuple struct or tuple variant, found enum 'NonEmpty'" }
19+
}
20+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
match (1, 2.2, "not 3") {
3+
// { dg-error "expected a tuple with 3 elements, found one with 5 elements" "" { target *-*-* } .+1 }
4+
(a, b, .., c, d, e) => {
5+
let _ = b + c; // { dg-error "cannot apply operator .+. to types <float> and & str" }
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)