diff --git a/dora-frontend/src/typeck/stmt.rs b/dora-frontend/src/typeck/stmt.rs index 4680b7a9c..a648890e4 100644 --- a/dora-frontend/src/typeck/stmt.rs +++ b/dora-frontend/src/typeck/stmt.rs @@ -322,12 +322,16 @@ fn check_pattern_enum( ck.sa.report(ck.file_id, pattern.span(), msg); } - let expected_types = variant - .fields - .iter() - .map(|f| specialize_type(ck.sa, f.parsed_type.ty(), &value_type_params)) - .collect::>(); - check_subpatterns(ck, ctxt, pattern, &expected_types); + if variant.field_name_style.is_named() { + check_subpatterns_named(ck, ctxt, pattern, variant, &value_type_params); + } else { + let expected_types = variant + .fields + .iter() + .map(|f| specialize_type(ck.sa, f.parsed_type.ty(), &value_type_params)) + .collect::>(); + check_subpatterns(ck, ctxt, pattern, &expected_types); + } } else { if !ty.is_error() { let ty = ty.name(ck.sa); @@ -397,13 +401,16 @@ fn check_pattern_class( IdentType::Class(cls_id, value_type_params.clone()), ); - let expected_types = cls - .fields - .iter() - .map(|f| specialize_type(ck.sa, f.ty(), &value_type_params)) - .collect::>(); - - check_subpatterns(ck, ctxt, pattern, &expected_types); + if cls.field_name_style.is_named() { + check_subpatterns_named(ck, ctxt, pattern, cls, &value_type_params); + } else { + let expected_types = cls + .fields + .iter() + .map(|f| specialize_type(ck.sa, f.ty(), &value_type_params)) + .collect::>(); + check_subpatterns(ck, ctxt, pattern, &expected_types); + } } else { if !ty.is_error() { let ty = ty.name(ck.sa); @@ -442,15 +449,15 @@ fn check_pattern_struct( IdentType::Struct(struct_id, value_type_params.clone()), ); - let expected_types = struct_ - .fields - .iter() - .map(|f| specialize_type(ck.sa, f.ty(), &value_type_params)) - .collect::>(); - if struct_.field_name_style.is_named() { - check_subpatterns_named(ck, ctxt, pattern, struct_); + check_subpatterns_named(ck, ctxt, pattern, struct_, &value_type_params); } else { + let expected_types = struct_ + .fields + .iter() + .map(|f| specialize_type(ck.sa, f.ty(), &value_type_params)) + .collect::>(); + check_subpatterns(ck, ctxt, pattern, &expected_types); } } else { @@ -469,6 +476,7 @@ fn check_subpatterns_named<'a>( ctxt: &mut Context, pattern: &ast::PatternAlt, element: &dyn ElementWithFields, + element_type_params: &SourceTypeArray, ) { let params = match pattern { ast::PatternAlt::ClassOrStructOrEnum(ref p) => p.params.as_ref(), @@ -514,7 +522,8 @@ fn check_subpatterns_named<'a>( if let Some(idx) = used_names.remove(&name) { let field_pattern = ¶ms[idx]; ck.analysis.map_field_ids.insert(field_pattern.id, field.id); - check_pattern_inner(ck, ctxt, &field_pattern.pattern, field.ty); + let ty = specialize_type(ck.sa, field.ty, element_type_params); + check_pattern_inner(ck, ctxt, &field_pattern.pattern, ty); } else if !rest_seen { let name = ck.sa.interner.str(name).to_string(); let msg = ErrorMessage::MissingNamedArgument(name); diff --git a/tests/language/pattern-rest3.dora b/tests/language/pattern-rest3.dora index 980fe4442..49efdf0c8 100644 --- a/tests/language/pattern-rest3.dora +++ b/tests/language/pattern-rest3.dora @@ -1,13 +1,13 @@ -class Foo { a: Int64, b: Int64, c: Int64 } +class Foo(Int64, Int64, Int64) fn main() { - assert(fst(Foo(a=1, b=3, c=7)) == 1); - assert(mid(Foo(a=1, b=3, c=7)) == 3); - assert(lst(Foo(a=1, b=3, c=7)) == 7); + assert(fst(Foo(1, 3, 7)) == 1); + assert(mid(Foo(1, 3, 7)) == 3); + assert(lst(Foo(1, 3, 7)) == 7); - assert(fst(Foo(a=7, b=4, c=1)) == 7); - assert(mid(Foo(a=7, b=4, c=1)) == 4); - assert(lst(Foo(a=7, b=4, c=1)) == 1); + assert(fst(Foo(7, 4, 1)) == 7); + assert(mid(Foo(7, 4, 1)) == 4); + assert(lst(Foo(7, 4, 1)) == 1); } fn fst(x: Foo): Int64 {