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

Stop name mangling at an imported package name #4294

Merged
merged 6 commits into from
Sep 18, 2024

Conversation

dwblaikie
Copy link
Contributor

To ensure the outer package name is not mangled into imported names.

With this change I can successfully link/run a two-file example:

package Mod;
fn HelloWorld() {
  Core.Print(42);
}
import Mod;
fn Run() -> i32 {
  Mod.HelloWorld();
  return 0;
}
$ carbon compile mod.carbon main.carbon
$ carbon link mod.o main.o --output=a.out
$ ./a.out
42

\o/

Copy link
Contributor

@jonmeow jonmeow left a comment

Choose a reason for hiding this comment

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

LG. :)

@jonmeow jonmeow added this pull request to the merge queue Sep 10, 2024
@jonmeow jonmeow removed this pull request from the merge queue due to a manual request Sep 10, 2024
@@ -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) {
Copy link
Contributor

@jonmeow jonmeow Sep 10, 2024

Choose a reason for hiding this comment

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

Suggested change
if (!name_scope.is_closed_import) {
if (!name_scope.is_closed_import || name_scope.parent_scope_id != NameScopeId::Package) {

Per #toolchain comment

Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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?)

Copy link
Contributor

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)

github-merge-queue bot pushed a commit that referenced this pull request Sep 17, 2024
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.
hamphet pushed a commit to hamphet/carbon-lang that referenced this pull request Sep 18, 2024
Spin off from
carbon-language#4294 (comment)

---------

Co-authored-by: Richard Smith <[email protected]>
Co-authored-by: Carbon Infra Bot <[email protected]>
toolchain/sem_ir/name_scope.h Outdated Show resolved Hide resolved
@@ -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) {
Copy link
Contributor

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]>
Copy link
Contributor

@jonmeow jonmeow left a comment

Choose a reason for hiding this comment

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

Looks good.

toolchain/sem_ir/name_scope.h Outdated Show resolved Hide resolved
@dwblaikie dwblaikie added this pull request to the merge queue Sep 18, 2024
Merged via the queue into carbon-language:trunk with commit 4631767 Sep 18, 2024
8 checks passed
@dwblaikie dwblaikie deleted the mangle_imported_name branch September 18, 2024 23:28
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.

4 participants