-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AccessScope] Treat PackageUnit as enclosing scope of ModuleDecl #64230
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
Conversation
@swift-ci smoke test |
include/swift/AST/Module.h
Outdated
create(Identifier name, ModuleDecl &src, ASTContext &ctx) { | ||
return new (ctx) PackageUnit(name, src); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is…pretty weird. Wouldn’t we prefer to have one instance of PackageUnit
shared by all of the ModuleDecl
s in the same package? That way you could ==
the DeclContext pointers to see if they match, just like other DeclContexts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this way easier to look up the module from a package unit in DeclContext::getModuleScopeContext
and DeclContext::getParentModule
; otherwise will have to compare ModuleDecl pointers in an array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That kind of just moves the question. Why do getParentModule()
and getModuleScopeContext()
return the module when you call them on the package? That seems, if anything, backwards from what you’d want. (And yes, I know you’re trying to avoid making the package a parent of the module, but making it a child instead seems pretty strange.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing code assumes ModuleDecl is the top level context as long as there's non-null DeclContext (otherwise public
) and performs isa
/cast
without checking if it's null, which is everywhere. With a package context now introduced, those existing functions are still called on the target DeclContext that may or may not be package, and will crash on isa
/cast
if the returned context is not module. Either we'll have to add assert or null check before casting or add package specific handling before each; by returning the module mapped to a package as in this PR, the changes required are minimal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also added doc comments in AccessScope, DeclContext, PackageUnit, ModuleDecl with more info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually tried other PackageUnit-ModuleDecl mappings first but there were issues with each as follows.
- Set
PackageUnit
asModuleDecl
's parent context (most clean, straightforward hierarchy)- Can only pass
PackageUnit
toModuleDecl
's ctor directly for the main module; for loaded modules, aPackageUnit
needs to be created and set as a newDeclContext
. setDeclContext
does not seem to actually override theContext
field inDeclContext
once set (not sure why), thus looking up the new context returns garbage.- Still need a way to look up
ModuleDecl
fromPackageUnit
for the existing module getters inDeclContext
to avoid crashes as mentioned in the previous comment.
- Can only pass
- Create a PackageUnit-ModuleDecl map in
ASTContext
(reasonable, no circular reference b/t the two classes)- Adding the entry to the map when PackageUnit is created from either class results in calling
DeclContext::getASTContext()
which callsDeclContext::getParentModule()
, which then callsDeclContext::getASTContext()
, resulting in a cycle.
- Adding the entry to the map when PackageUnit is created from either class results in calling
Thus, resorted to having PackageUnit
as a property in ModuleDecl
and have a weak reference back to ModuleDecl
from PackageUnit
. Lmk if if the way it references is not actually a weak reference though.
@swift-ci smoke test |
95dae6e
to
6726d07
Compare
@swift-ci smoke test |
* Weakly reference ModuleDecl from PackageUnit * Add PackageUnit decl context getter and use it for a package AccessScope * Return module decl referenced by PackageUnit in getModuleScopeContext and getParentModule * Handle package acl in access scope checkers * Remove AccessLimitKind * Fix tests Resolves rdar://104987295, rdar://105187216, rdar://104723918
@swift-ci smoke test |
@@ -1679,6 +1679,7 @@ ERROR(access_control_open_bad_decl,none, | |||
WARNING(access_control_non_objc_open_member,none, | |||
"non-'@objc' %0 in extensions cannot be overridden; use 'public' instead", | |||
(DescriptiveDeclKind)) | |||
ERROR(access_control_requires_package_name, none, "decl has a package access level but no -package-name was passed", ()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a forgotten long line.
package
access levelDeclContext::getModuleScopeContext
andDeclContext::getParentModule
to avoid breaking existing codeResolves rdar://104987295, rdar://105187216, rdar://104723918