Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[toolchain] Parsing support for struct literals, following #653. #699

Merged
merged 9 commits into from
Aug 28, 2021
Merged

[toolchain] Parsing support for struct literals, following #653. #699

merged 9 commits into from
Aug 28, 2021

Conversation

zygoloid
Copy link
Contributor

@zygoloid zygoloid commented Aug 3, 2021

This supports both struct type literals, {x: i32, y: i32}, and struct
value literals, {.x = 3, .y = 4}. The degenerate case of {} is
treated as a struct value literal, with the expectation that an empty
struct value has the same type/value duality as an empty tuple value.

This supports both struct type literals, `{x: i32, y: i32}`, and struct
value literals, `{.x = 3, .y = 4}`. The degenerate case of `{}` is
treated as a struct value literal, with the expectation that an empty
struct value has the same type/value duality as an empty tuple value.
@zygoloid zygoloid requested a review from a team as a code owner August 3, 2021 19:55
@google-cla google-cla bot added the cla: yes PR meets CLA requirements according to bot. label Aug 3, 2021
@@ -970,6 +970,82 @@ TEST_F(ParseTreeTest, Tuples) {
MatchFileEnd()}));
}

TEST_F(ParseTreeTest, Structs) {
TokenizedBuffer tokens = GetTokenizedBuffer(R"(
var x: {a: i32, b: i32} = {.a = 1, .b = 2};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This proposes something outside of #653, and is nesting patterns into positional fields? Or does this have some other meaning?

Generally not sure what we're doing with struct patterns yet... Do the names a and b have to match here? We never really answered some of these questions in the whole struct pattern discussion.

Copy link
Contributor Author

@zygoloid zygoloid Aug 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The {a: i32, b: i32} here is a type, not a struct pattern, following the syntax in the decision on #653. Though I've now noticed that the syntax decision in #561 and the syntax described in #653 aren't the same and #561 uses {.a: i32, .b: i32} instead. I've raised the question of whether to include the . on #syntax and in #561.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule has been changed in #653 to require . here; patch updated to match.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(not sure this update got pushed)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops :) Look again now?

TokenizedBuffer tokens = GetTokenizedBuffer(R"(
var x: {a: i32, b: i32} = {.a = 1, .b = 2};
var y: {} = {};
var z: {c: i32 = 0} = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This in particular seems like it should be {.c: i32 = 0}?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per #561, support for default values in types removed.

Copy link
Contributor

@chandlerc chandlerc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looking for some extra tests, the functionality looks good. Feel free to submit with tests.

Comment on lines +61 to +62
bool can_be_type;
bool can_be_value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about is_type_valid and is_value_valid?

I'm ambivalent. The is_ prefix is more obviously a bool to me, but it reads a touch worse and is a bit longer.

Don't change unless you like it, fine to bias towards what you have.

Comment on lines +144 to +150
static constexpr const char* Message = "Expected `,` or `{0}`.";

TokenKind close;

auto Format() -> std::string {
return llvm::formatv(Message, close.GetFixedSpelling()).str();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diagnostic change seems untested? (Maybe this would be covered by the requested diagnostic tests above actually.)

Comment on lines 1015 to 1037
llvm::StringLiteral testcases[] = {
"var x: {i32} = {};",
"var x: {a} = {};",
"var x: {a:} = {};",
"var x: {a=} = {};",
"var x: {.} = {};",
"var x: {.a} = {};",
"var x: {.a:} = {};",
"var x: {.a=} = {};",
"var x: {.a: i32, .b = 0} = {};",
"var x: {.a = 0, b: i32} = {};",
"var x: {,} = {};",
"var x: {.a: i32,} = {};",
"var x: {.a = 0,} = {};",
};

for (llvm::StringLiteral testcase : testcases) {
TokenizedBuffer tokens = GetTokenizedBuffer(testcase);
ErrorTrackingDiagnosticConsumer error_tracker(consumer);
ParseTree tree = ParseTree::Parse(tokens, error_tracker);
EXPECT_TRUE(tree.HasErrors());
EXPECT_TRUE(error_tracker.SeenError());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I'm happy to have a loop covering patterns like this, I think at least the ones that we expect to diagnose differently should be tested with tests against the diagnostics themselves?

@zygoloid zygoloid merged commit 3803fb6 into carbon-language:trunk Aug 28, 2021
@zygoloid zygoloid deleted the toolchain branch March 11, 2022 01:02
chandlerc pushed a commit that referenced this pull request Jun 28, 2022
… (#699)

This supports both struct type literals, `{.x: i32, .y: i32}`, and struct
value literals, `{.x = 3, .y = 4}`. The degenerate case of `{}` is
treated as a struct value literal, with the expectation that an empty
struct value has the same type/value duality as an empty tuple value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes PR meets CLA requirements according to bot.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants