Skip to content

rustdoc's resugaring of projection predicates to type bindings is flawed when supertraits are involved #113015

Open

Description

First discovered thanks to bevyengine/bevy#8898: There, the Output type of the cross-crate opaque impl FnMut(…) -> bool gets dropped by rustdoc resulting in impl FnMut(…). This specific bug is caused by rustdoc's opaque bound cleaner not realizing that it can & should utilize the Output assoc ty defined on FnMut's supertrait FnOnce. During further investigations I've discovered more bugs in this area.

In rustdoc there are two three major and distinct places where we resugar bounds. Both All three are flawed but each one exhibits different bugs.

  • (1) clean_middle_opaque_bounds for bounds of opaques (existential impl-Trait)
    • we only check for TraitRef equality while we should also check the super predicates (incl. their substs tho!)
      • (once we do, ensure that we don't intro name clashes into the list of type bindings (this can be triggered by relatively simple user code involving supertraits))
  • (2) clean_ty_generics for bounds in where-clauses and APIT (universal impl-Trait)
    • we do check super predicates but we only ever check DefIds (of traits) and never the relevant substs which is super incorrect leading rustdoc to move some projection predicates to unrelated trait bounds
    • the process mutates state by yanking those predicates rendering it order dependent (consider permutations of super and subtraits each one with own type bindings)
  • (3) param_env_to_generics in auto_trait.rs for where-clauses of synthetic impls
    • update: replaced by simplify::{where_clauses,sized_bounds} in #123340
    • doesn't use simplify::merge_bounds at all unlike the other two places
    • doesn't merge two partially resugared bounds like Tr<A = …> and Tr<B = …>
    • doesn't render bound vars / higher-ranked parameters at all
    • (I haven't thoroughly checked yet how supertraits are handled but it seems like Fn-family traits are special-cased)

Probably there are some more but less important bugs to be found (e.g. related to bound vars I can imagine).

I'm already deep in the weeds working on a correct & most general fix for this.
Opening this issue to keep the description of the future PR more slender.
@rustbot claim

@rustbot label C-bug T-rustdoc A-cross-crate-reexports

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-cross-crate-reexportsArea: Documentation that has been re-exported from a different crateC-bugCategory: This is a bug.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions