-
Notifications
You must be signed in to change notification settings - Fork 14k
Hide = _ as associated constant value inside impl blocks
#134321
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
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.
I have some minor comments, otherwise looks ok (rustdoc's const handling is sadly pretty scuffed atm as you prolly know (and I made some parts worse I know ^^')).
src/librustdoc/clean/types.rs
Outdated
| pub(crate) fn is_associated_const(&self) -> bool { | ||
| matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..))) | ||
| } | ||
| pub(crate) fn is_ty_associated_const(&self) -> bool { |
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.
We should rename is_ty_associated_const to is_required_assoc_const and update the names the assoc ty and fn equivents, too. However, it's fine to do that in a follow-up PR, too (not necessarily authored by you).
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.
Yes, good call. Done.
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.
Hmm, having 3 variants for assoc consts is a bit excessive, I wish it was just TraitAssocConst & ImplAssocConst at the maximum but that probably calls for a larger refactoring.
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.
Yeah I gave this some thought before going with the current approach. From what I figured out (I haven't worked in this code before):
Before this PR, AssocConstItem and TyAssocConstItem are separate variants because they must store different contents. The variant's data is either Constant (which is Generics + ConstantKind + Type) or just Generics + Type.
In order to merge ProvidedAssocConstItem and RequiredAssocConstItem into a single TraitAssocConstItem variant, either:
-
Constantneeds to containOption<ConstantKind>, which has a big blast radius because non-associated constants and paths (dyn Foo<K = 0>) use this sameConstanttype in a context where not having a value doesn't make sense. -
or we need
TraitAssocConstItemto store notConstantbut some otherConstantWithOptionalValuetype — which ends up being not less duplication than splittingProvidedAssocConstItemvsRequiredAssocConstItem.
There is a more promising approach, which I gave up on but is still potentially salvageable. Notice this parent argument:
rust/src/librustdoc/html/render/mod.rs
Lines 1068 to 1072 in 0aeaa5e
| fn render_assoc_item( | |
| w: &mut Buffer, | |
| item: &clean::Item, | |
| link: AssocItemLink<'_>, | |
| parent: ItemType, |
rust/src/librustdoc/html/render/mod.rs
Lines 1094 to 1103 in 0aeaa5e
| clean::AssocConstItem(ci) => assoc_const( | |
| w, | |
| item, | |
| &ci.generics, | |
| &ci.type_, | |
| Some(&ci.kind), | |
| link, | |
| if parent == ItemType::Trait { 4 } else { 0 }, | |
| cx, | |
| ), |
When printing, associated constants are supposed to know whether they are inside of a ItemType::Trait as opposed to a ItemType::Impl. This would be perfect for deciding whether = _ needs to be shown (only when parent is trait, never when parent is impl).
But this doesn't work because parent ends up being misused under the assumption that it's only relevant for indentation (?). See this call site, which is inside a function called item_trait and is responsible for printing a trait and its contents. And yet it is passing ItemType::Impl as the value of parent, which does not make sense.
rust/src/librustdoc/html/render/print_item.rs
Lines 820 to 827 in 0aeaa5e
| render_assoc_item( | |
| w, | |
| m, | |
| AssocItemLink::Anchor(Some(&id)), | |
| ItemType::Impl, | |
| cx, | |
| RenderMode::Normal, | |
| ); |
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.
Oof, that's super odd. Thanks for the thorough investigation, I have to look into cleaning this up at some point!
| let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx)); | ||
| if match value { | ||
| AssocConstValue::TraitDefault(_) => true, // always show | ||
| AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show |
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.
unfortunate string comparison but it's alright for the time being
src/librustdoc/clean/types.rs
Outdated
| /// An associated constant in a trait impl or a provided one in a trait declaration. | ||
| AssocConstItem(Box<Constant>), | ||
| /// An associated constant in a trait declaration with provided default value. | ||
| DefaultAssocConstItem(Box<Constant>), |
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.
DefaultAssocConstItem sounds like default const ITEM: Ty = EXPR; (specialization) to me. Can you relate? Maybe ProvidedAssocConstItem or DefaultedAssocConstItem instead?
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.
None of the terminology is fantastic, but I'm okay with either of your suggestions; they are both improvements on what is in the PR. "Provided" is probably the least confusable. Initially it sounds like it could possibly refer to "the constant value that a trait impl provided as the value for a trait's associated constant" (provided by impl vs provided by trait) but it doesn't seem possible to remain confused about this for long given the existence of ImplAssocConstItem which clearly refers to something in an impl.
I was also thinking along the lines of OptionalAssocConstItem to contrast with RequiredAssocConstItem or even synonyms like "discretionary" but none of that is established terminology in Rust in this context.
fmease
left a 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.
Sorry for the delay! Thanks r=me after squashing some of the micro renaming commits and if it's not too annoying also git-fixing up the "split assocconstitem" commit with commit "rename default* to provided*".
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.
Oof, that's super odd. Thanks for the thorough investigation, I have to look into cleaning this up at some point!
aadc477 to
7ee31eb
Compare
|
I squashed all commits renaming functions ( @bors r=fmease |
Rollup of 6 pull requests Successful merges: - rust-lang#126118 (docs: Mention `spare_capacity_mut()` in `Vec::set_len`) - rust-lang#132830 (Rename `elem_offset` to `element_offset`) - rust-lang#133103 (Pass FnAbi to find_mir_or_eval_fn) - rust-lang#134321 (Hide `= _` as associated constant value inside impl blocks) - rust-lang#134518 (fix typos in the example code in the doc comments of `Ipv4Addr::from_bits()`, `Ipv6Addr::from_bits()` & `Ipv6Addr::to_bits()`) - rust-lang#134521 (Arbitrary self types v2: roll loop.) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#134321 - dtolnay:docassocconst, r=fmease Hide `= _` as associated constant value inside impl blocks Closes rust-lang#134320. ### Before: <img src="https://github.com/user-attachments/assets/19d28811-45d2-4563-9726-f40c6af411c6" width="300"> <img src="https://github.com/user-attachments/assets/1ecf8764-97ce-47f0-87fa-3b174d2fc578" width="300"> ### After: <img src="https://github.com/user-attachments/assets/6408c4ca-b1c4-42e4-884b-248833a4865f" width="300"> <img src="https://github.com/user-attachments/assets/df2f6981-16f6-409f-8abb-73c0a4a71d6b" width="300"> r? `@fmease`
Closes #134320.
Before:
After:
r? @fmease