diff --git a/src/protocol/parser/pass_definitions_types.rs b/src/protocol/parser/pass_definitions_types.rs index d2a2eab8d58350b4b5a675e48ad2c868df0b7579..2f1a74fe8a86218c622676f0ca9805a9b43041b6 100644 --- a/src/protocol/parser/pass_definitions_types.rs +++ b/src/protocol/parser/pass_definitions_types.rs @@ -97,17 +97,18 @@ impl ParserTypeParser { self.first_pos = tuple_start_pos; // last pos will be set later, this is a tuple let tuple_entry_index = self.entries.len() as u32; + let tuple_depth = self.cur_depth(); self.push_depth(DepthKind::Tuple, tuple_entry_index, tuple_start_pos); self.entries.push(Entry{ element: ParserTypeElement{ element_span: InputSpan::from_positions(tuple_start_pos, tuple_start_pos), variant: ParserTypeVariant::Tuple(0), }, - depth: self.cur_depth(), + depth: tuple_depth, }); iter.consume(); - ParseState::PolyArgStart + ParseState::TupleStart }, _ => return Err(ParseError::new_error_str_at_pos(source, iter.last_valid_pos(), "expected a type")), }; @@ -231,7 +232,6 @@ impl ParserTypeParser { if encountered_embedded == 0 { // Every polymorphic argument should be inferred if !allow_inference { - println!("DEBUG: Ended up with {:?}", self.entries); return Err(ParseError::new_error_str_at_span( source, cur_element.element.element_span, "type inference is not allowed here" @@ -267,7 +267,11 @@ impl ParserTypeParser { debug_assert!(!self.entries.is_empty()); for entry in self.entries.drain(..) { - elements.push(entry.element) + if ParserTypeVariant::Tuple(1) == entry.element.variant { + // We strip these ones + } else { + elements.push(entry.element); + } } return Ok(ParserType{ diff --git a/src/protocol/parser/type_table.rs b/src/protocol/parser/type_table.rs index 20d1e4a11d9f1469b3f22071e059ad80b62b2b58..18947e699fc1be5cc114d4c1294b17214879dac1 100644 --- a/src/protocol/parser/type_table.rs +++ b/src/protocol/parser/type_table.rs @@ -1496,6 +1496,7 @@ impl TypeTable { PTV::Array => Some(CTP::Array), PTV::Input => Some(CTP::Input), PTV::Output => Some(CTP::Output), + PTV::Tuple(num) => Some(CTP::Tuple(*num)), PTV::Definition(definition_id, num) => Some(CTP::Instance(*definition_id, *num)), _ => None } diff --git a/src/protocol/tests/parser_validation.rs b/src/protocol/tests/parser_validation.rs index 863a9b294fd694e58c142ac58e70bc296ebfbd55..1294724006b3c63165ccee5466b58d3b7f037468 100644 --- a/src/protocol/tests/parser_validation.rs +++ b/src/protocol/tests/parser_validation.rs @@ -352,6 +352,71 @@ fn test_incorrect_union_instance() { }); } +#[test] +fn test_correct_tuple_members() { + // Tuples with zero members + Tester::new_single_source_expect_ok( + "single zero-tuple", + "struct Foo{ () bar }" + ).for_struct("Foo", |s| { s + .for_field("bar", |f| { f.assert_parser_type("()"); }) + .assert_size_alignment("Foo", 0, 1); + }); + + Tester::new_single_source_expect_ok( + "triple zero-tuple", + "struct Foo{ () bar, () baz, () qux }" + ).for_struct("Foo", |s| { s + .assert_size_alignment("Foo", 0, 1); + }); + + // Tuples with one member (which are elided, because due to ambiguity + // between a one-tuple literal and a parenthesized expression, we're not + // going to be able to construct one-tuples). + Tester::new_single_source_expect_ok( + "single elided one-tuple", + "struct Foo{ (u32) bar }" + ).for_struct("Foo", |s| { s + .for_field("bar", |f| { f.assert_parser_type("u32"); }) + .assert_size_alignment("Foo", 4, 4); + }); + + Tester::new_single_source_expect_ok( + "triple elided one-tuple", + "struct Foo{ (u8) bar, (u16) baz, (u32) qux }" + ).for_struct("Foo", |s| { s + .assert_size_alignment("Foo", 8, 4); + }); + + // Tuples with three members + Tester::new_single_source_expect_ok( + "single three-tuple", + "struct Foo{ (u8, u16, u32) bar }" + ).for_struct("Foo", |s| { s + .for_field("bar", |f| { f.assert_parser_type("(u8,u16,u32)"); }) + .assert_size_alignment("Foo", 8, 4); + }); + + Tester::new_single_source_expect_ok( + "double three-tuple", + "struct Foo{ (u8,u16,u32,) bar, (s8,s16,s32,) baz }" + ).for_struct("Foo", |s| { s + .for_field("bar", |f| { f.assert_parser_type("(u8,u16,u32)"); }) + .for_field("baz", |f| { f.assert_parser_type("(s8,s16,s32)"); }) + .assert_size_alignment("Foo", 16, 4); + }); +} + +#[test] +fn test_correct_tuple_polymorph_args() { + todo!("write"); +} + +#[test] +fn test_incorrect_tuple_polymorph_args() { + todo!("write"); +} + #[test] fn test_polymorph_array_types() { Tester::new_single_source_expect_ok(