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

Aliased imports of enum variants does not work #6123

Open
jjcnn opened this issue Jun 13, 2024 · 2 comments
Open

Aliased imports of enum variants does not work #6123

jjcnn opened this issue Jun 13, 2024 · 2 comments
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen

Comments

@jjcnn
Copy link
Contributor

jjcnn commented Jun 13, 2024

The following program causes a problem:

// a.sw
library;

pub enum Enum {
    X: u64,
}

// main.sw
use a::Enum::X as Y;  // Renames X to Y within main.sw

fn main() {
  let _ = Y(42); // Create a value out of Enum::X, but using the aliased name
}

This causes an error in the Y(42) expression saying that Y is not bound.

It is not clear to me what ought to happen. I see two options:

  • The above program should be legal, and the expression Y(42) should create the value a::Enum::X(42).
  • Aliasing an enum variant is illegal, and an error should be reported on the line use ... as Y.

Since neither of these options correspond to the current behavior I consider the current behavior to be a bug.

@jjcnn jjcnn added bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Jun 13, 2024
@Dr-Maxwell
Copy link

The Issue:

You're trying to alias an enum variant (X) with a new name (Y) within your main.sw file.
However, the compiler throws an error saying Y is not bound, indicating it doesn't recognize the alias.
Expected Behavior (Option 1):

Ideally, the program should be legal. Using Y(42) should create a value of type a::Enum::X(42).
Current Behavior (Bug):

Aliasing enum variants seems to be unsupported in this context.
My own take :

Don't Alias Variants:

The simplest solution is to remove the alias line entirely. Instead of:

use a::Enum::X as Y;
Use the original variant directly:

let _ = a::Enum::X(42);
Check Language Support:

It's possible that the language you're using (.sw suggests a custom language) doesn't support aliasing enum variants. Refer to the language documentation to confirm if this feature is available.
Report the Bug:

If aliasing enum variants should be supported, consider reporting this as a bug to the language developers. They can investigate and potentially fix the issue in future versions.

JoshuaBatty added a commit that referenced this issue Jul 15, 2024
## Description

Fixes #3113 . Closes #2767 as Won't Fix, since one must use `pub use` to
reexport items.

This PR Introduce reexports through the use of `pub use`. The
implementation now keeps track of the visibility of a `use` statement,
and that visibility is in turn taken into account when items are
imported from the module where the `use` statement resides.

This feature allows `std::prelude` and `core::prelude` to be handled
correctly, instead of the special-case handling that we have been using
so far. The method `star_import_with_reexports` has therefore been
merged with `star_import`, and the `prelude.sw` files have accordingly
been changed to use `pub use` instead of `use`.

Note that `sway-lib-std/lib.sw` has a spurious import of `core::*`,
which has no effect, so I have removed that import.

This change also allows us to remove a hacky solution in
`lexical_scope.rs`. The hack was introduced because the special-case
handling of preludes meant that the preludes would contain multiple
copies of the same `std` and `core` items. Now that we no longer need to
treat the preludes specially, we can remove the hack.

I have gone a little overboard in adding tests, partly because I wanted
to make sure I hadn't missed some corner cases, but also because our
tests of the import logic has poor code coverage. I have found the
following issues that I don't think belongs in this PR, but which need
to be handled at some point:

- Path resolution is broken. The tests
`should_pass/language/reexport/simple_path_access` and
`should_fail/language/reexport/simple_path_access` are supposed to test
that you can access reexported using a path into the reexporting module,
i.e., without importing them using a `use` statement. Both tests are
disabled because path resolution is broken. I plan to fix that as part
of #5498 . A simlar problem exists in the test
`should_pass/language/reexport/reexport_paths` where an item is imported
via `std::prelude`.
- There is an issue with the import and reexport of enum variants, which
is illustrated in
`should_pass/language/reexport/reexport_paths_external_lib`. In short,
`pub use ext_3_lib::Items3_Variants::U` elevates the name `U` to the
top-level namespace in a module, and this makes `U` inaccessible as a
variant of `Items3_Variants`. I'm not sure how this is supposed to work,
but since it's related to all imports whether they are reexported or not
I have left it as a separate issue #6233 .
- Aliasing of enum variants (`use lib::Enum::X as MyX`) doesn't work
properly. In some cases `MyX` is available in the way you would expect,
and in other cases it is not, and sometimes it is available but not
recognized as being a variant of `lib::Enum`. The test
`should_pass/language/reexport/aliases` has a number of tests of these
types of things. #6123 tracks the issue.
- Aliased traits are not handled correctly by the dead code analysis.
The test `should_pass/language/reexport/aliases` generates warnings
about unimplemented traits that are actually implemented, but since they
are aliased in imports the DCA doesn't catch them. #6234 tracks the
issue.

Re. documentation: The whole import system is completely undocumented in
the Sway book, and I plan to write up a draft how it works when I'm done
fixing (the majority of) the many issue we have there. At the very least
I'd like to postpone the documentation efforts until path resolution
works correctly, since that is key to how the import system works.


## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Co-authored-by: João Matos <joao@tritao.eu>
@jjcnn
Copy link
Contributor Author

jjcnn commented Jul 15, 2024

The test should_pass/language/reexport/aliases has a number of disabled cases that tests enum variant aliasing.

esdrubal pushed a commit that referenced this issue Aug 13, 2024
## Description

Fixes #3113 . Closes #2767 as Won't Fix, since one must use `pub use` to
reexport items.

This PR Introduce reexports through the use of `pub use`. The
implementation now keeps track of the visibility of a `use` statement,
and that visibility is in turn taken into account when items are
imported from the module where the `use` statement resides.

This feature allows `std::prelude` and `core::prelude` to be handled
correctly, instead of the special-case handling that we have been using
so far. The method `star_import_with_reexports` has therefore been
merged with `star_import`, and the `prelude.sw` files have accordingly
been changed to use `pub use` instead of `use`.

Note that `sway-lib-std/lib.sw` has a spurious import of `core::*`,
which has no effect, so I have removed that import.

This change also allows us to remove a hacky solution in
`lexical_scope.rs`. The hack was introduced because the special-case
handling of preludes meant that the preludes would contain multiple
copies of the same `std` and `core` items. Now that we no longer need to
treat the preludes specially, we can remove the hack.

I have gone a little overboard in adding tests, partly because I wanted
to make sure I hadn't missed some corner cases, but also because our
tests of the import logic has poor code coverage. I have found the
following issues that I don't think belongs in this PR, but which need
to be handled at some point:

- Path resolution is broken. The tests
`should_pass/language/reexport/simple_path_access` and
`should_fail/language/reexport/simple_path_access` are supposed to test
that you can access reexported using a path into the reexporting module,
i.e., without importing them using a `use` statement. Both tests are
disabled because path resolution is broken. I plan to fix that as part
of #5498 . A simlar problem exists in the test
`should_pass/language/reexport/reexport_paths` where an item is imported
via `std::prelude`.
- There is an issue with the import and reexport of enum variants, which
is illustrated in
`should_pass/language/reexport/reexport_paths_external_lib`. In short,
`pub use ext_3_lib::Items3_Variants::U` elevates the name `U` to the
top-level namespace in a module, and this makes `U` inaccessible as a
variant of `Items3_Variants`. I'm not sure how this is supposed to work,
but since it's related to all imports whether they are reexported or not
I have left it as a separate issue #6233 .
- Aliasing of enum variants (`use lib::Enum::X as MyX`) doesn't work
properly. In some cases `MyX` is available in the way you would expect,
and in other cases it is not, and sometimes it is available but not
recognized as being a variant of `lib::Enum`. The test
`should_pass/language/reexport/aliases` has a number of tests of these
types of things. #6123 tracks the issue.
- Aliased traits are not handled correctly by the dead code analysis.
The test `should_pass/language/reexport/aliases` generates warnings
about unimplemented traits that are actually implemented, but since they
are aliased in imports the DCA doesn't catch them. #6234 tracks the
issue.

Re. documentation: The whole import system is completely undocumented in
the Sway book, and I plan to write up a draft how it works when I'm done
fixing (the majority of) the many issue we have there. At the very least
I'd like to postpone the documentation efforts until path resolution
works correctly, since that is key to how the import system works.


## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: Joshua Batty <joshpbatty@gmail.com>
Co-authored-by: João Matos <joao@tritao.eu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen
Projects
None yet
Development

No branches or pull requests

2 participants