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

Swift: collection/tuple content for dictionary flow #13947

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

rdmarsh2
Copy link
Contributor

This PR models dictionary content as being TupleContent nested within CollectionContent, and adds a new DictionarySubscriptNode to represent the intermediate step, where only the TupleContent has been stored, or only the CollectionContent has been read. This means models for the generic Collection protocol will work for dictionaries without modification.

@rdmarsh2 rdmarsh2 requested a review from a team as a code owner August 10, 2023 20:57
@github-actions github-actions bot added the Swift label Aug 10, 2023
@hvitved
Copy link
Contributor

hvitved commented Aug 11, 2023

This PR models dictionary content as being TupleContent nested within CollectionContent

FTR, this is also how it's done in C# 👍 (though instead of TupleContent it's a FieldContent representing a KeyValuePair)

@rdmarsh2
Copy link
Contributor Author

That's good to know. Swift has had first-class tuples from the start, so they just alias (Key, Value) as the element type.

Comment on lines 761 to 771
subscript.getArgument(0).getExpr() = node1.asExpr() and
node2.(DictionarySubscriptNode).getExpr() = subscript and
c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1))
or
assign.getSource() = node1.asExpr() and
node2.(DictionarySubscriptNode).getExpr() = subscript and
c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1))
or
node1.(DictionarySubscriptNode) = node1 and
node2.asExpr() = subscript and
c.isSingleton(any(Content::CollectionContent cc))
Copy link
Contributor

Choose a reason for hiding this comment

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

So now we do:

source -> TupleContent -> CollectionContent

in two steps (which makes sense), and I gather that the last of these three cases is the CollectionContent step. But why do we need two cases to cover the first step? I would have thought that only the middle cases was needed, and the first case would happen through reverse reads?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think there are two steps to assemble the tuple because one is for the key and one is for the value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The first case is the step from the key in dict[key] = value - I typoed and it should be tc.getIndex() = 0 there.

Comment on lines 761 to 771
subscript.getArgument(0).getExpr() = node1.asExpr() and
node2.(DictionarySubscriptNode).getExpr() = subscript and
c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1))
or
assign.getSource() = node1.asExpr() and
node2.(DictionarySubscriptNode).getExpr() = subscript and
c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = 1))
or
node1.(DictionarySubscriptNode) = node1 and
node2.asExpr() = subscript and
c.isSingleton(any(Content::CollectionContent cc))
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there are two steps to assemble the tuple because one is for the key and one is for the value.

Comment on lines 878 to 881
(
c.isSingleton(any(Content::FieldContent fc)) or
c.isSingleton(any(Content::TupleContent tc))
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this restriction? Do we not want to clear CollectionContent and ArrayContent?

Copy link
Contributor

Choose a reason for hiding this comment

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

... or EnumContent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't want to clear CollectionContent and ArrayContent at a post-update node because they may have been only partially overwritten - consider the case here. It shouldn't clear the content from line 779.

I think we do want to clear EnumContent, though. Good catch.

Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

My concerns have been addressed, how about you @MathiasVP

@MathiasVP
Copy link
Contributor

My concerns have been addressed, how about you @MathiasVP

I think so, yes. I'd still like to see a DCA run on this PR, though 🙏. In addition, it would be nice if we could have a testcase that demonstrated the impact of 3ee3eab (although this can be done in a future PR if you prefer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants