-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Stop name mangling at an imported package name #4294
Stop name mangling at an imported package name #4294
Conversation
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.
LG. :)
toolchain/lower/mangler.cpp
Outdated
@@ -89,8 +89,10 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, | |||
CARBON_FATAL() << "Attempting to mangle unsupported SemIR."; | |||
break; | |||
} | |||
names_to_render.push_back( | |||
{.name_scope_id = name_scope.parent_scope_id, .prefix = '.'}); | |||
if (!name_scope.is_closed_import) { |
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.
if (!name_scope.is_closed_import) { | |
if (!name_scope.is_closed_import || name_scope.parent_scope_id != NameScopeId::Package) { |
Per #toolchain comment
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.
Can we add a name_scope.is_package()
for this? I think this is a little subtle to be writing out by hand here.
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.
#toolchain comment in question: https://discord.com/channels/655572317891461132/655578254970716160/1283200462782464030
[4:00 PM]zygoloid: Does is_closed_import also return true for namespaces in imported packages?
[4:01 PM]JonMeow: Mayyybe yes
[4:01 PM]JonMeow: I guess maybe it's actually something like is_closed_import && parent_scope_id == NameScopeId::Package
Ah, I think I see - thanks for the details.
Hmm, I thought what you were discussing would mean that calling a function in a namespace in an imported package. But when I tried that the is_closed_import
(without the Package test added) it seemed to work, mangled as _CHelloWorld.NameSpace.Mod
on both call and definition.
What's the case you had in mind where the code as-is (without the Package test) would misbehave?
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 case. Even if we aren't setting is_closed_import
it's possible we should be.
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.
If you want to avoid testing the package, I'll suggest also fixing is_closed_import
to be set correctly on imported namespaces for other packages.
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.
Here, the
Nested
namespace isn't redeclared, but is actually used from the other package. In this case,is_closed
would lead to a diagnostic;
Yeah, with the patch applied:
b.carbon:2:1: ERROR: Duplicate name being declared in the same scope.
namespace Other;
^~~~~~~~~~~~~~~~
b.carbon:1:1: Name is previously declared here.
import Other;
^~~~~~
b.carbon:3:10: ERROR: Imported packages cannot be used for declarations.
fn Other.Nested.F();
^~~~~~
b.carbon:1:1: In import.
import Other;
^~~~~~
a.carbon:2:1: Package imported here.
namespace Nested;
^~~~~~~~~~~~~~~~~
as-is, I expect this won't diagnose again.
Can confirm, yeah - it diagnoses the Other duplicate, but no error for using Nested
.
In particular, once the name conflict is resolved, then it will diagnose. My thought here is that renaming Other (either one) shouldn't lead to a new diagnostic.
I've got mixed feelings there - the tradeoff compared to the example I provided where it produces an extra diagnostic that isn't needed. Neither's a great situation, to be sure.
I like your test case though, so I'll add that and send out a PR. #4312
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.
Now that #4312 is merged, can we progress this PR?
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.
@josh11b FYI this PR still needs to be updated. The comment is unchanged.
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.
Added test coverage for this problem, added the helper function (but I could only figure out how to make IsImportedPackage
- I wasn't sure how to get the NameScopeId
from the NameScope
so I could check if it was == NameScopeId::Package
- happy to change that to something more general (could be a free function that takes a NameScopeId
and NameScopeStore
and test against Package, then does the lookup (which would be a bit redundant since we've already done the lookup in the mangler) and other checks) folks might suggest?)
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.
Note, discussed offline, I think IsImportedPackage is fine as a helper (versus IsPackage)
Spin off from #4294 (comment) --------- Co-authored-by: Richard Smith <[email protected]> Co-authored-by: Carbon Infra Bot <[email protected]>
To ensure the outer package name is not mangled into imported names. With this change I can successfully link/run a two-file example: ``` import Mod; fn Run() -> i32 { Mod.HelloWorld(); return 0; } ``` ``` package Mod; fn HelloWorld() { Core.Print(42); } ``` ``` $ carbon compile mod.carbon main.carbon $ carbon link mod.o main.o --output=a.out $ ./a.out 42 ``` \o/
If the call is to a function in a namespace in a foreign package, it mismangles by stopping at the foreign namespace, missing the foreign package name.
b7dec12
to
3600196
Compare
Spin off from carbon-language#4294 (comment) --------- Co-authored-by: Richard Smith <[email protected]> Co-authored-by: Carbon Infra Bot <[email protected]>
toolchain/lower/mangler.cpp
Outdated
@@ -89,8 +89,10 @@ auto Mangler::MangleInverseQualifiedNameScope(llvm::raw_ostream& os, | |||
CARBON_FATAL() << "Attempting to mangle unsupported SemIR."; | |||
break; | |||
} | |||
names_to_render.push_back( | |||
{.name_scope_id = name_scope.parent_scope_id, .prefix = '.'}); | |||
if (!name_scope.is_closed_import) { |
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.
Note, discussed offline, I think IsImportedPackage is fine as a helper (versus IsPackage)
Co-authored-by: Jon Ross-Perkins <[email protected]>
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.
Looks good.
Co-authored-by: Jon Ross-Perkins <[email protected]>
ffe2afd
to
8073c78
Compare
To ensure the outer package name is not mangled into imported names.
With this change I can successfully link/run a two-file example:
\o/