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

tag/niche terminology cleanup #72497

Merged
merged 3 commits into from
Jun 19, 2020
Merged

tag/niche terminology cleanup #72497

merged 3 commits into from
Jun 19, 2020

Conversation

RalfJung
Copy link
Member

The term "discriminant" was used in two ways throughout the compiler:

  • every enum variant has a corresponding discriminant, that can be given explicitly with Variant = N.
  • that discriminant is then encoded in memory to store which variant is active -- but this encoded form of the discriminant was also often called "discriminant", even though it is conceptually quite different (e.g., it can be smaller in size, or even use niche-filling).

After discussion with @eddyb, this renames the second term to "tag". The way the tag is encoded can be either TagEncoding::Direct (formerly DiscriminantKind::Tag) or TagEncoding::Niche (formerly DiscrimianntKind::Niche).

This finally resolves some long-standing confusion I had about the handling of variant indices and discriminants, which surfaced in #72419.

(There is also a DiscriminantKind type in libcore, it remains unaffected. I think this corresponds to the discriminant, not the tag, so that seems all right.)

r? @eddyb

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 23, 2020
@RalfJung
Copy link
Member Author

Cc @rust-lang/compiler

@eddyb
Copy link
Member

eddyb commented May 23, 2020

Previous relevant issue: #49938.

I think the problem here arose from trying to unify the "tagged" and "niche-filling" representations.

When we needed a word to refer to "tag or niche" we ended up with "discr(iminant)" again in some places (despite referring to the encoding of the discriminant, and not the discriminant itself), but we should've called both of them "tag" and be done with it.

@RalfJung RalfJung force-pushed the tag-term branch 2 times, most recently from 10d7af2 to 2fa9161 Compare May 23, 2020 12:02
Comment on lines +1642 to +1643
RegularTag { tag_field: Field, tag_type_metadata: &'ll DIType },
OptimizedTag,
Copy link
Member Author

Choose a reason for hiding this comment

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

Does this correspond to Direct and Niche encodings? If yes, would it make sense to align terminology here?

Copy link
Member

Choose a reason for hiding this comment

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

I suspected it might mean something like univariant but I think you're right. Also, instead of NoTag, maybe we could use Option around EnumTagInfo.

Copy link
Member Author

@RalfJung RalfJung Jun 5, 2020

Choose a reason for hiding this comment

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

If we are not sure, maybe I'll just leave this as-is for now and hope someone else documents it eventually.^^

Copy link
Contributor

Choose a reason for hiding this comment

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

OptimizedTag only refers to Niche encodings. Direct encodings can be RegularTag or NoTag depending on whether enum fallback is happening or not. Univariant enums or structs are always NoTag.

I do like the idea of using Option<EnumTagInfo> and eliminating the NoTag variant.

Copy link
Contributor

Choose a reason for hiding this comment

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

r=oli-obk,eddyb with this addressed or a fixme left with instructions on what should be done

Copy link
Member Author

Choose a reason for hiding this comment

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

Direct encodings can be RegularTag or NoTag depending on whether enum fallback is happening or not. Univariant enums or structs are always NoTag.

What is "enum fallback"? If it's "no tag needed because there is just one variant", AFAIK those do not have a TagEncoding at all, they are Variant::Single.

Copy link
Member Author

Choose a reason for hiding this comment

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

@oli-obk I added a FIXME, could you check if that comment makes any sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

What is "enum fallback"?

It's a windows thing, because windows debuginfo isn't caught up yet

@RalfJung RalfJung added I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 25, 2020
@bors
Copy link
Contributor

bors commented May 30, 2020

☔ The latest upstream changes (presumably #72768) made this pull request unmergeable. Please resolve the merge conflicts.

@nikomatsakis
Copy link
Contributor

I think this terminology is fine but we should document it in the rustc-dev-guide

@RalfJung
Copy link
Member Author

RalfJung commented Jun 2, 2020

Where in the guide would this fit best?

@nikomatsakis
Copy link
Contributor

@RalfJung maybe folks from @rust-lang/wg-rustc-dev-guide have thoughts, but the glossary might work :)

@nikomatsakis
Copy link
Contributor

I feel like we should (ultimately) have a Layout section of the guide that talks about the layout code and how it works, that'd be ideal.

@mark-i-m
Copy link
Member

mark-i-m commented Jun 4, 2020

A layout section would be awesome, but if that's not feasible, it would be great to update/add the relevant definitions to the glossary.

@RalfJung
Copy link
Member Author

RalfJung commented Jun 5, 2020

If this is accepted, I am happy to write a paragraph or two about it somewhere, if I am told where. :) The glossary makes sense. But writing an entire chapter on "layout" is a bit too much.

@mark-i-m
Copy link
Member

mark-i-m commented Jun 5, 2020

Would it make sense to add a section to one of the "codegen" chapters?

@RalfJung
Copy link
Member Author

So, what is this blocked on? As far as I am concerned, I am waiting for this to be accepted before I put in the work of writing docs.

@nikomatsakis
Copy link
Contributor

My impression was that we were happy with this terminology choice. So the PR just needs review.

@spastorino
Copy link
Member

spastorino commented Jun 10, 2020

Unnominating this as it was already discussed in our last T-compiler meeting.

@RalfJung
Copy link
Member Author

I opened a dev-guide PR: rust-lang/rustc-dev-guide#747

@oli-obk
Copy link
Contributor

oli-obk commented Jun 15, 2020

r? @oli-obk

@rust-highfive rust-highfive assigned oli-obk and unassigned eddyb Jun 15, 2020
assert_eq!(tag_layout.size, tag_val.layout.size);
assert_eq!(tag_layout.abi.is_signed(), tag_val.layout.abi.is_signed());
let tag_val = tag_val.to_scalar()?;
trace!("tag value: {:?}", tag_val);

// Figure out which discriminant and variant this corresponds to.
Ok(match *tag_kind {
DiscriminantKind::Tag => {
Ok(match *tag_encoding {
Copy link
Contributor

Choose a reason for hiding this comment

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

I really wish we could deduplicate this with the codegen_ssa logic. Maybe we need a codegen_miri in addition to codegen_llvm. That backend could then interpret the values immediately instead of generating code. Not sure if that can be pulled off..

Anyway, off topic for this PR

@oli-obk
Copy link
Contributor

oli-obk commented Jun 16, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Jun 16, 2020

📌 Commit 10c8d2a has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 16, 2020
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 16, 2020
tag/niche terminology cleanup

The term "discriminant" was used in two ways throughout the compiler:
* every enum variant has a corresponding discriminant, that can be given explicitly with `Variant = N`.
* that discriminant is then encoded in memory to store which variant is active -- but this encoded form of the discriminant was also often called "discriminant", even though it is conceptually quite different (e.g., it can be smaller in size, or even use niche-filling).

After discussion with @eddyb, this renames the second term to "tag". The way the tag is encoded can be either `TagEncoding::Direct` (formerly `DiscriminantKind::Tag`) or `TagEncoding::Niche` (formerly `DiscrimianntKind::Niche`).

This finally resolves some long-standing confusion I had about the handling of variant indices and discriminants, which surfaced in rust-lang#72419.

(There is also a `DiscriminantKind` type in libcore, it remains unaffected. I think this corresponds to the discriminant, not the tag, so that seems all right.)

r? @eddyb
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 16, 2020
tag/niche terminology cleanup

The term "discriminant" was used in two ways throughout the compiler:
* every enum variant has a corresponding discriminant, that can be given explicitly with `Variant = N`.
* that discriminant is then encoded in memory to store which variant is active -- but this encoded form of the discriminant was also often called "discriminant", even though it is conceptually quite different (e.g., it can be smaller in size, or even use niche-filling).

After discussion with @eddyb, this renames the second term to "tag". The way the tag is encoded can be either `TagEncoding::Direct` (formerly `DiscriminantKind::Tag`) or `TagEncoding::Niche` (formerly `DiscrimianntKind::Niche`).

This finally resolves some long-standing confusion I had about the handling of variant indices and discriminants, which surfaced in rust-lang#72419.

(There is also a `DiscriminantKind` type in libcore, it remains unaffected. I think this corresponds to the discriminant, not the tag, so that seems all right.)

r? @eddyb
Manishearth added a commit to Manishearth/rust that referenced this pull request Jun 18, 2020
tag/niche terminology cleanup

The term "discriminant" was used in two ways throughout the compiler:
* every enum variant has a corresponding discriminant, that can be given explicitly with `Variant = N`.
* that discriminant is then encoded in memory to store which variant is active -- but this encoded form of the discriminant was also often called "discriminant", even though it is conceptually quite different (e.g., it can be smaller in size, or even use niche-filling).

After discussion with @eddyb, this renames the second term to "tag". The way the tag is encoded can be either `TagEncoding::Direct` (formerly `DiscriminantKind::Tag`) or `TagEncoding::Niche` (formerly `DiscrimianntKind::Niche`).

This finally resolves some long-standing confusion I had about the handling of variant indices and discriminants, which surfaced in rust-lang#72419.

(There is also a `DiscriminantKind` type in libcore, it remains unaffected. I think this corresponds to the discriminant, not the tag, so that seems all right.)

r? @eddyb
bors added a commit to rust-lang-ci/rust that referenced this pull request Jun 19, 2020
Rollup of 13 pull requests

Successful merges:

 - rust-lang#70740 (Enabling static-pie for musl)
 - rust-lang#72331 (Report error when casting an C-like enum implementing Drop)
 - rust-lang#72486 (Fix asinh of negative values)
 - rust-lang#72497 (tag/niche terminology cleanup)
 - rust-lang#72999 (Create self-contained directory and move there some of external binaries/libs)
 - rust-lang#73130 (Remove const prop for indirects)
 - rust-lang#73142 (Ensure std benchmarks get tested.)
 - rust-lang#73305 (Disallow loading crates with non-ascii identifier name.)
 - rust-lang#73346 (Add rust specific features to print target features)
 - rust-lang#73362 (Test that bounds checks are elided when slice len is checked up-front)
 - rust-lang#73459 (Reduce pointer casts in Box::into_boxed_slice)
 - rust-lang#73464 (Document format correction)
 - rust-lang#73479 (Minor tweaks to liballoc)

Failed merges:

r? @ghost
@bors bors merged commit 5e7eec2 into rust-lang:master Jun 19, 2020
@RalfJung RalfJung deleted the tag-term branch June 20, 2020 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants