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

Hide = _ as associated constant value inside impl blocks #134321

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

dtolnay
Copy link
Member

@dtolnay dtolnay commented Dec 14, 2024

Closes #134320.

Before:

 

After:

 

r? @fmease

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Dec 14, 2024
@dtolnay
Copy link
Member Author

dtolnay commented Dec 14, 2024

@fmease — I saw that you self-assigned #134320. If you think of a different implementation approach that would be a better fix, I would be happy to close this PR and we can go with yours.

Copy link
Member

@fmease fmease left a 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 ^^')).

@@ -554,7 +554,7 @@ impl Item {
matches!(self.kind, AssocConstItem(..) | StrippedItem(box AssocConstItem(..)))
}
pub(crate) fn is_ty_associated_const(&self) -> bool {
Copy link
Member

@fmease fmease Dec 14, 2024

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, good call. Done.

Copy link
Member

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.

Copy link
Member Author

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:

  • Constant needs to contain Option<ConstantKind>, which has a big blast radius because non-associated constants and paths (dyn Foo<K = 0>) use this same Constant type in a context where not having a value doesn't make sense.

  • or we need TraitAssocConstItem to store not Constant but some other ConstantWithOptionalValue type — which ends up being not less duplication than splitting ProvidedAssocConstItem vs RequiredAssocConstItem.

There is a more promising approach, which I gave up on but is still potentially salvageable. Notice this parent argument:

fn render_assoc_item(
w: &mut Buffer,
item: &clean::Item,
link: AssocItemLink<'_>,
parent: ItemType,

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.

render_assoc_item(
w,
m,
AssocItemLink::Anchor(Some(&id)),
ItemType::Impl,
cx,
RenderMode::Normal,
);

Copy link
Member

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
Copy link
Member

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

/// 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>),
Copy link
Member

@fmease fmease Dec 15, 2024

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?

Copy link
Member Author

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.

@dtolnay dtolnay removed the A-rustdoc-json Area: Rustdoc JSON backend label Dec 15, 2024
Copy link
Member

@fmease fmease left a 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*".

Copy link
Member

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!

@rustbot rustbot added the A-rustdoc-json Area: Rustdoc JSON backend label Dec 19, 2024
@dtolnay dtolnay removed the A-rustdoc-json Area: Rustdoc JSON backend label Dec 19, 2024
@dtolnay
Copy link
Member Author

dtolnay commented Dec 19, 2024

I squashed all commits renaming functions (is_ty_associated_const, is_ty_associated_type) into the same commit that renamed the corresponding type, and I eliminated the DefaultAssocConstItem naming from commit history.

@bors r=fmease

@bors
Copy link
Contributor

bors commented Dec 19, 2024

📌 Commit 7ee31eb has been approved by fmease

It is now in the queue for this repository.

@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 Dec 19, 2024
jhpratt added a commit to jhpratt/rust that referenced this pull request Dec 20, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 20, 2024
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
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-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rustdoc shows = _ needlessly in non-trait associated constants
4 participants