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

Tracking issue for feature(repr128); enums with 128-bit discriminants #56071

Open
Centril opened this issue Nov 19, 2018 · 15 comments
Open

Tracking issue for feature(repr128); enums with 128-bit discriminants #56071

Centril opened this issue Nov 19, 2018 · 15 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC I-lang-nominated Nominated for discussion during a lang team meeting. S-tracking-unimplemented Status: The feature has not been implemented. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Centril
Copy link
Contributor

Centril commented Nov 19, 2018

This issue tracks repr128, i.e. "enums with 128-bit discriminant" as per rust-lang/rfcs#1504.
Originally this was tracked in #35118.


Nothing has changed re repr128… It is still the case that at least LLVM’s debuginfo API blocks us from implementing it at all. There’s very little incentive to work on it, though, and I’m not planning to do anything in that direction until a very convincing use-case for 128-bit enum discriminants comes up.

- @nagisa

@Centril Centril added B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. T-lang Relevant to the language team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC labels Nov 19, 2018
@Centril Centril removed the B-unstable Blocker: Implemented in the nightly compiler and unstable. label Nov 19, 2018
@clarfonthey
Copy link
Contributor

I actually double checked the RFC text and I didn't see mentions of repr(u128) anywhere. Is it still a feature that's desired?

@nagisa
Copy link
Member

nagisa commented Nov 20, 2018

It’s a generic feature tied to integers in the language. It is not mentioned in the RFC because it would’ve implemented along with the integers themselves lest the roadblocks didn’t show up.

JohnTitor added a commit to JohnTitor/rust that referenced this issue Oct 12, 2020
… r=jonas-schievink

Mark `repr128` as `incomplete_features`

As mentioned in rust-lang#56071 and noticed in rust-lang#77457, `repr(u128)` and `repr(i128)` do not work properly due to lack of LLVM support. We should thus warn users trying to use the feature that they may encounter ICEs when using it.

Closes rust-lang#77457.
JohnTitor added a commit to JohnTitor/rust that referenced this issue Oct 12, 2020
… r=jonas-schievink

Mark `repr128` as `incomplete_features`

As mentioned in rust-lang#56071 and noticed in rust-lang#77457, `repr(u128)` and `repr(i128)` do not work properly due to lack of LLVM support. We should thus warn users trying to use the feature that they may encounter ICEs when using it.

Closes rust-lang#77457.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Oct 22, 2020
… r=jonas-schievink

Mark `repr128` as `incomplete_features`

As mentioned in rust-lang#56071 and noticed in rust-lang#77457, `repr(u128)` and `repr(i128)` do not work properly due to lack of LLVM support. We should thus warn users trying to use the feature that they may encounter ICEs when using it.

Closes rust-lang#77457.
JohnTitor added a commit to JohnTitor/rust that referenced this issue Oct 23, 2020
… r=jonas-schievink

Mark `repr128` as `incomplete_features`

As mentioned in rust-lang#56071 and noticed in rust-lang#77457, `repr(u128)` and `repr(i128)` do not work properly due to lack of LLVM support. We should thus warn users trying to use the feature that they may encounter ICEs when using it.

Closes rust-lang#77457.
@marmeladema
Copy link
Contributor

Is there any progress on this?

My use-case is that I often use #[repr(uXXX)] on enums with the enumflags2 crate in order to be able to manage set of values packed in an integer. That is very handy to avoid using a BTreeSet (heap allocation etc) but as soon as you have more then 64 different values (and less than 128 obviously), you would want to use #[repr(u128)] in stable but that's not currently possible.

I don't know if that's enough of a convincing use-case but that would be really handy to have this working in stable.

Is there any path forward that I could help with? Is LLVM debuginfo API still a blocker?

@varkor
Copy link
Member

varkor commented Dec 14, 2020

I believe there hasn't been any progress on this since the original comment.

@dan-da
Copy link

dan-da commented Sep 1, 2021

I have a use-case also, using an enum to represent fixed amount denominations for a cryptocurrency in development. u128 is necessary/desirable to have enough divisibility.

presently I am working around by defining the variants as a list (without integer values) and then using giant match statements to convert to/from. works, but is ugly.

@clarfonthey
Copy link
Contributor

I mean, u64 allows up to 10^19, so I'm not sure what kinds of quantities you need to include. If we translate that into metric prefixes, that'd be all the way to exa (10^18).

@dan-da
Copy link

dan-da commented Sep 1, 2021

yes, well in fact we may use u64 in the end, but there has been discussion/debate around using u128 for greater divisibility, so our prototype code can build either way via a type alias. Unfortunately trying to use repr(u128) fails to compile, hence the workaround.

There are other ways we could represent this. We don't have to use an enum at all. It is simply the data structure that seems most suited to the task, so I was (a bit) surprised to find that u128 doesn't work the same as other integer types. Symmetry is beautiful, and this lacks symmetry.

@scottmcm scottmcm added the S-tracking-unimplemented Status: The feature has not been implemented. label Jun 1, 2022
@joshtriplett joshtriplett added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Jun 8, 2022
bors added a commit to rust-lang-ci/rust that referenced this issue Nov 21, 2022
…r=nagisa

Pass 128-bit C-style enum enumerator values to LLVM

Pass the full 128 bits of C-style enum enumerators through to LLVM. This means that debuginfo for C-style repr128 enums is now emitted correctly for DWARF platforms (as compared to not being correctly emitted on any platform).

Tracking issue: rust-lang#56071
Aaron1011 pushed a commit to Aaron1011/rust that referenced this issue Jan 6, 2023
…r=nagisa

Pass 128-bit C-style enum enumerator values to LLVM

Pass the full 128 bits of C-style enum enumerators through to LLVM. This means that debuginfo for C-style repr128 enums is now emitted correctly for DWARF platforms (as compared to not being correctly emitted on any platform).

Tracking issue: rust-lang#56071
github-actions bot pushed a commit to rust-lang/glacier that referenced this issue Jun 18, 2023
=== stdout ===
=== stderr ===
warning: the feature `repr128` is incomplete and may not be safe to use and/or cause compiler crashes
 --> <anon>:3:12
  |
3 | #![feature(repr128, arbitrary_enum_discriminant)]
  |            ^^^^^^^
  |
  = note: see issue #56071 <rust-lang/rust#56071> for more information
  = note: `#[warn(incomplete_features)]` on by default

warning: the feature `arbitrary_enum_discriminant` has been stable since 1.66.0 and no longer requires an attribute to enable
 --> <anon>:3:21
  |
3 | #![feature(repr128, arbitrary_enum_discriminant)]
  |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(stable_features)]` on by default

warning: 2 warnings emitted

==============
@VladimirMakaev
Copy link
Contributor

There seems to be an issue with #[repr(i128)] I discovered this when working on https://reviews.llvm.org/D149213
With the example program from the diff variables direct_tag_128_a and direct_tag_128_b give incorrect values in LLDB (with my change as you couldn't debug enums before).

Also something is wrong when those enums are defined as globals. Their values are completely off in both no_std and std compilations. I'm not 100% sure it's not LLDB issues or the change I did in LLDB but what I observed when debugging this is that this structure represents a variant

0x00000ab8:       DW_TAG_structure_type
                    DW_AT_name	("A")
                    DW_AT_byte_size	(0x18)
                    DW_AT_alignment	(8)

0x00000abf:         DW_TAG_member
                      DW_AT_name	("__0")
                      DW_AT_type	(0x00000b8f "u32")
                      DW_AT_alignment	(4)
                      DW_AT_data_member_location	(0x10)

__0 field having offset 16, but in reality in memory it was located at offset 8. So it's either the bug in debug info or in compiler.

@beetrees
Copy link
Contributor

__0 field having offset 16, but in reality in memory it was located at offset 8. So it's either the bug in debug info or in compiler.

@VladimirMakaev Is this still an issue? I've checked the example from the diff locally on Rust nightly and everything seems to agree that __0 it at offset 16 (straight after the 16-byte i128 discriminant).

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 21, 2024
… r=<try>

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 21, 2024
… r=<try>

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 21, 2024
… r=<try>

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2024
… r=<try>

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Aug 14, 2024
… r=michaelwoerister

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Aug 15, 2024
… r=michaelwoerister

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
bors added a commit to rust-lang-ci/rust that referenced this issue Aug 15, 2024
… r=michaelwoerister

Use the `enum2$` Natvis visualiser for repr128 C-style enums

Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly.

Tracking issue: rust-lang#56071

try-job: x86_64-msvc
@clarfonthey
Copy link
Contributor

As I find myself wanting to use this, I'm curious what the specific limitations of the current implementation are. Since the feature exists in the compiler, it would be nice to properly document what exactly doesn't work and what's blocked on LLVM's side, so that folks know what the main blockers to this feature are.

@beetrees
Copy link
Contributor

beetrees commented Dec 12, 2024

AFAIK, the only issue remaining is that, in DWARF debuginfo for enums with fields (aka not C-style), LLVM truncates the discriminants to 64-bit integers (or triggers an LLVM assertion if they are enabled and the discriminant doesn't fit in a 64-bit integer). I couldn't find an upstream LLVM issue tracking this, so I've opened one at llvm/llvm-project#119655. Apart from that debuginfo issue I think this is ready to be stabilised.

@bjoernager
Copy link
Contributor

Would it be possible to temporarily disable debug info for DWARF in this case, stabilise the feature, and then re-enable debug info at a later time if/when the LLVM issue has been resolved? If I understand correctly that this is entirely due to debug info.

@beetrees
Copy link
Contributor

It would definitely be possible to just omit discriminant values on the rustc side if they don't fit in 64 bits until the LLVM bug is fixed - even if rustc emitted the 128-bit discriminant value correctly, neither gdb nor lldb currently support enums with 128-bit discriminants. gdb doesn't support 128-bit discriminants at all (this can already be encountered on stable with types like Option<NonZero<u128>>), whereas lldb only supports discriminant values that fit in 32 bits (which can be encountered on stable using #[repr(u64)]).

AFAIK, it's up to the lang team whether it would be acceptable to stabilise the feature without full debuginfo emission support or not.

@clarfonthey
Copy link
Contributor

clarfonthey commented Dec 24, 2024

If you can already encounter this bug on stable with Option<NonZero<u128>> I would say that's a pretty good argument in favour of stabilising this as-is, then determining a proper fix after the fact. But we'll have to see what the lang team thinks. Perhaps this should be nominated for that discussion?

@beetrees
Copy link
Contributor

beetrees commented Dec 28, 2024

@rustbot label +I-lang-nominated

feature(repr128) allows the use of #[repr(u128)] and #[repr(i128)] on enums, and is the only part of 128-bit integers support that hasn't been stabilised.

The only known issue is with DWARF debuginfo generation for non-C-like enums, as the LLVM DWARF debuginfo backend currently truncates variant discriminant values to 64 bits (LLVM issue llvm/llvm-project#119655, this causes an LLVM assertion if LLVM assertions are enabled and the value doesn't fit in 64 bits). As a tempoarary workaround, rustc could just not emit the discriminant value in the debuginfo if the discriminant doesn't fit in 64 bits: this wouldn't provide any worse user experience as neither gdb or lldb support 128-bit enum discriminants at the moment anyway (this can be encountered when debugging stable types like Option<NonZero<u128>>). The question for the lang team is: would it be acceptable to stabilise repr128 with the suggested tempoarary workaround, or is fixing llvm/llvm-project#119655 a prerequisite for stabilisation?

@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Dec 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC I-lang-nominated Nominated for discussion during a lang team meeting. S-tracking-unimplemented Status: The feature has not been implemented. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests