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

[Serialization] Track whether a cross-reference came from Clang #17333

Conversation

jrose-apple
Copy link
Contributor

Cross-references are identified by their containing module, with the assumption that two modules will never have the same name. However, an overlay has the same name as its underlying Clang module, which means that there can be two declarations with the same name, the same type, and the same module name. This is the underlying cause of the 'UIEdgeInsetsZero' problem (#17122), but it also affects the CloudKit overlay.

By tracking a bit that just says "this came from Clang", we're able to resolve otherwise ambiguous cross-references.

(Why didn't we do it this way all along? Because if a declaration moves from Clang to Swift or vice versa, that would break the cross-reference. But that's only interesting if the swiftmodule format is meant to be persistent across changing dependencies, and it looks like we're moving away from that anyway. It's also a little weird for SerializedModuleLoader to have special cases for Clang, but this isn't the first.)

Note that I'm not reverting the UIEdgeInsetsZero workaround here; the end state will have that coming just from UIKit as originally described in #17122.

rdar://problem/40839486

Cross-references are identified by their containing module, with the
assumption that two modules will never have the same name. However, an
overlay has the same name as its underlying Clang module, which means
that there can be two declarations with the same name, the same type,
and the same module name. This is the underlying cause of the
'UIEdgeInsetsZero' problem, but it also affects the CloudKit overlay.

By tracking a bit that just says "this came from Clang", we're able
to resolve otherwise ambiguous cross-references.

(Why didn't we do it this way all along? Because if a declaration
moves from Clang to Swift or vice versa, that would break the
cross-reference. But that's only interesting if the swiftmodule format
is meant to be persistent across changing dependencies, and it looks
like we're moving away from that anyway. It's also a little weird for
SerializedModuleLoader to have special cases for Clang, but this isn't
the first.)

Note that I'm not reverting the UIEdgeInsetsZero workaround here; the
end state will have that coming just from UIKit as originally
described.

rdar://problem/40839486
@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

@rjmccall
Copy link
Member

rjmccall commented Jun 19, 2018

A more general way of thinking about this is that our cross-references exist at a lower level than the source language and that therefore there are just separate namespaces of modules that we need to build cross-references to. I think that makes it more obvious that this is a reasonable design and that, if we started importing e.g. Rust modules, we would just have to generalize this bit to a tri-state or beyond.

Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

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

Approach and implementation look fine; the NS_ERROR_ENUM thing is much less likely to happen in practice.

@@ -1226,6 +1227,8 @@ static void filterValues(Type expectedTy, ModuleDecl *expectedModule,
return true;
if (value->isStatic() != isStatic)
return true;
if (value->hasClangNode() != importedFromClang)
Copy link
Member

Choose a reason for hiding this comment

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

IIRC, hasClangNode() won't be true for NS_ERROR_ENUM struct types, so you likely have the same issue with cross-references to those.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I was going to punt on that. I suppose this could all be a getModuleScopeContext check instead.

@jrose-apple jrose-apple merged commit 6b89415 into apple:master Jun 20, 2018
@jrose-apple jrose-apple deleted the reference-types-but-not-those-reference-types branch June 20, 2018 21:51
jrose-apple added a commit to jrose-apple/swift that referenced this pull request Jun 20, 2018
…e#17333)

Cross-references are identified by their containing module, with the
assumption that two modules will never have the same name. However, an
overlay has the same name as its underlying Clang module, which means
that there can be two declarations with the same name, the same type,
and the same module name. This is the underlying cause of the
'UIEdgeInsetsZero' problem, but it also affects the CloudKit overlay.

By tracking a bit that just says "this came from Clang", we're able
to resolve otherwise ambiguous cross-references.

(Why didn't we do it this way all along? Because if a declaration
moves from Clang to Swift or vice versa, that would break the
cross-reference. But that's only interesting if the swiftmodule format
is meant to be persistent across changing dependencies, and it looks
like we're moving away from that anyway. It's also a little weird for
SerializedModuleLoader to have special cases for Clang, but this isn't
the first.)

Note that I'm not reverting the UIEdgeInsetsZero workaround here; the
end state will have that coming just from UIKit as originally
described.

rdar://problem/40839486
(cherry picked from commit 6b89415)
jrose-apple added a commit to jrose-apple/swift that referenced this pull request Jun 20, 2018
…e#17333)

Cross-references are identified by their containing module, with the
assumption that two modules will never have the same name. However, an
overlay has the same name as its underlying Clang module, which means
that there can be two declarations with the same name, the same type,
and the same module name. This is the underlying cause of the
'UIEdgeInsetsZero' problem, but it also affects the CloudKit overlay.

By tracking a bit that just says "this came from Clang", we're able
to resolve otherwise ambiguous cross-references.

(Why didn't we do it this way all along? Because if a declaration
moves from Clang to Swift or vice versa, that would break the
cross-reference. But that's only interesting if the swiftmodule format
is meant to be persistent across changing dependencies, and it looks
like we're moving away from that anyway. It's also a little weird for
SerializedModuleLoader to have special cases for Clang, but this isn't
the first.)

Note that I'm not reverting the UIEdgeInsetsZero workaround here; the
end state will have that coming just from UIKit as originally
described.

rdar://problem/40839486
(cherry picked from commit 6b89415)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants