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

Add missing impls field to typedef #89272

Closed
wants to merge 2 commits into from
Closed

Conversation

Urgau
Copy link
Member

@Urgau Urgau commented Sep 26, 2021

This pull-request add a impls field to the Typedef definition of rustdoc-json-types and populates it in the same way it's done for struct, enum and union.

@rustbot label +T-rustdoc +A-rustdoc-json

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Sep 26, 2021
@rust-highfive
Copy link
Collaborator

rustdoc-json-types is a public (although nightly-only) API. Consider changing src/librustdoc/json/conversions.rs instead; otherwise, make sure you update format_version.

cc @CraftSpider,@aDotInTheVoid

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @ollie27 (or someone else) soon.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 26, 2021
@bors
Copy link
Contributor

bors commented Sep 29, 2021

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

@aDotInTheVoid
Copy link
Member

aDotInTheVoid commented Oct 1, 2021

I dont think this is needed.

With the following code:

#![no_core]
#![feature(no_core)]

pub struct A;

pub trait T{}

impl T for A{}

pub type B = A;

The JSON is (unnessesary bits removed)

{
  "index": {
    "0:0": {
      "inner": {
        "is_crate": true,
        "items": [
          "0:1",
          "0:3",
          "0:5"
        ]
      },
      "kind": "module"
    },
    "0:1": {
      // Struct A
      "inner": {
        "impls": [
          "0:4"
        ],
        "struct_type": "unit"
      },
      "kind": "struct",
      "name": "A"
    },
    "0:3": {
      // Trait T
      "inner": {
        "implementors": [
          "0:4"
        ]
      },
      "kind": "trait",
      "name": "T"
    },
    "0:4": {
      // impl T for A
      "inner": {
        "for": {
          "inner": {
            "args": {
              "angle_bracketed": {
                "args": [],
                "bindings": []
              }
            },
            "id": "0:1",
            "name": "A",
            "param_names": []
          },
          "kind": "resolved_path"
        },
        "trait": {
          "inner": {
            "id": "0:3",
            "name": "T"
          },
          "kind": "resolved_path"
        }
      },
      "kind": "impl"
    },
    "0:5": {
      "id": "0:5",
      "inner": {
        // type B = A
        "type": {
          "inner": {
            "id": "0:1",
            "name": "A"
          },
          "kind": "resolved_path"
        }
      },
      "kind": "typedef",
      "name": "B"
    }
  },
  "root": "0:0"
}

If you want the typedefs on the typedef (0:5), you can find the underlying type (0:1) and then read its impls (0:4)

the reason this is done for struct, enum and union is they can have traits implemented on them, whereas a trait implemented on a typedef just implements it on the underling type. (we currently dont document this correctly, see #89452)

@Urgau
Copy link
Member Author

Urgau commented Oct 2, 2021

Yeah, you're right if the goal is to get the full list of impls for A one could just watch on A; but my goal with this PR is to get the list of impls that directly and only use B.

Consider this example:

#![no_core]
#![feature(no_core)]

pub struct A;
pub type B = A;

pub trait T1{}
pub trait T2{}

impl T1 for A{}
impl T2 for B{}
JSON output
{
    "root": "0:0",
    "crate_version": null,
    "includes_private": false,
    "index": {
        "0:6": {
            "id": "0:6",
            "crate_id": 0,
            "name": "B",
            "span": {
                "filename": "lib.rs",
                "begin": [
                    11,
                    0
                ],
                "end": [
                    11,
                    15
                ]
            },
            "visibility": "public",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "typedef",
            "inner": {
                "type": {
                    "kind": "resolved_path",
                    "inner": {
                        "name": "A",
                        "id": "0:1",
                        "args": {
                            "angle_bracketed": {
                                "args": [],
                                "bindings": []
                            }
                        },
                        "param_names": []
                    }
                },
                "generics": {
                    "params": [],
                    "where_predicates": []
                }
            }
        },
        "0:7": {
            "id": "0:7",
            "crate_id": 0,
            "name": null,
            "span": {
                "filename": "lib.rs",
                "begin": [
                    13,
                    0
                ],
                "end": [
                    13,
                    15
                ]
            },
            "visibility": "crate",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "impl",
            "inner": {
                "is_unsafe": false,
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "provided_trait_methods": [],
                "trait": {
                    "kind": "resolved_path",
                    "inner": {
                        "name": "T2",
                        "id": "0:4",
                        "args": {
                            "angle_bracketed": {
                                "args": [],
                                "bindings": []
                            }
                        },
                        "param_names": []
                    }
                },
                "for": {
                    "kind": "resolved_path",
                    "inner": {
                        "name": "B",
                        "id": "0:6",
                        "args": {
                            "angle_bracketed": {
                                "args": [],
                                "bindings": []
                            }
                        },
                        "param_names": []
                    }
                },
                "items": [],
                "negative": false,
                "synthetic": false,
                "blanket_impl": null
            }
        },
        "0:4": {
            "id": "0:4",
            "crate_id": 0,
            "name": "T2",
            "span": {
                "filename": "lib.rs",
                "begin": [
                    7,
                    0
                ],
                "end": [
                    7,
                    14
                ]
            },
            "visibility": "public",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "trait",
            "inner": {
                "is_auto": false,
                "is_unsafe": false,
                "items": [],
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "bounds": [],
                "implementors": [
                    "0:7"
                ]
            }
        },
        "0:0": {
            "id": "0:0",
            "crate_id": 0,
            "name": "lib",
            "span": {
                "filename": "lib.rs",
                "begin": [
                    1,
                    0
                ],
                "end": [
                    13,
                    15
                ]
            },
            "visibility": "public",
            "docs": null,
            "links": {},
            "attrs": [
                "#![no_core]",
                "#![feature(no_core)]"
            ],
            "deprecation": null,
            "kind": "module",
            "inner": {
                "is_crate": true,
                "items": [
                    "0:1",
                    "0:3",
                    "0:4",
                    "0:6"
                ]
            }
        },
        "0:3": {
            "id": "0:3",
            "crate_id": 0,
            "name": "T1",
            "span": {
                "filename": "lib.rs",
                "begin": [
                    6,
                    0
                ],
                "end": [
                    6,
                    14
                ]
            },
            "visibility": "public",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "trait",
            "inner": {
                "is_auto": false,
                "is_unsafe": false,
                "items": [],
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "bounds": [],
                "implementors": [
                    "0:5"
                ]
            }
        },
        "0:5": {
            "id": "0:5",
            "crate_id": 0,
            "name": null,
            "span": {
                "filename": "lib.rs",
                "begin": [
                    9,
                    0
                ],
                "end": [
                    9,
                    15
                ]
            },
            "visibility": "crate",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "impl",
            "inner": {
                "is_unsafe": false,
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "provided_trait_methods": [],
                "trait": {
                    "kind": "resolved_path",
                    "inner": {
                        "name": "T1",
                        "id": "0:3",
                        "args": {
                            "angle_bracketed": {
                                "args": [],
                                "bindings": []
                            }
                        },
                        "param_names": []
                    }
                },
                "for": {
                    "kind": "resolved_path",
                    "inner": {
                        "name": "A",
                        "id": "0:1",
                        "args": {
                            "angle_bracketed": {
                                "args": [],
                                "bindings": []
                            }
                        },
                        "param_names": []
                    }
                },
                "items": [],
                "negative": false,
                "synthetic": false,
                "blanket_impl": null
            }
        },
        "0:1": {
            "id": "0:1",
            "crate_id": 0,
            "name": "A",
            "span": {
                "filename": "lib.rs",
                "begin": [
                    4,
                    0
                ],
                "end": [
                    4,
                    13
                ]
            },
            "visibility": "public",
            "docs": null,
            "links": {},
            "attrs": [],
            "deprecation": null,
            "kind": "struct",
            "inner": {
                "struct_type": "unit",
                "generics": {
                    "params": [],
                    "where_predicates": []
                },
                "fields_stripped": false,
                "fields": [],
                "impls": [
                    "0:5"
                ]
            }
        }
    },
    "paths": {
        "0:0": {
            "crate_id": 0,
            "path": [
                "lib"
            ],
            "kind": "module"
        },
        "0:1": {
            "crate_id": 0,
            "path": [
                "lib",
                "A"
            ],
            "kind": "struct"
        },
        "0:3": {
            "crate_id": 0,
            "path": [
                "lib",
                "T1"
            ],
            "kind": "trait"
        },
        "0:4": {
            "crate_id": 0,
            "path": [
                "lib",
                "T2"
            ],
            "kind": "trait"
        },
        "0:6": {
            "crate_id": 0,
            "path": [
                "lib",
                "B"
            ],
            "kind": "typedef"
        }
    },
    "external_crates": {},
    "format_version": 7
}

There are two traits T1 and T2 who are implemented for the struct A, directly and indirectly (via type B).
If everything worked correctly (#89452 😀) struct A would have T1 and T2 as impls but there would be no direct way from type B what is implemented from it.

While writing this I remark that this is not true, searching from B in A.impls for every impl item where for = B could do the job, but I'm not sure that would work in every case and this would be a lot more complex than juts iterating over B.impls.

@aDotInTheVoid
Copy link
Member

but my goal with this PR is to get the list of impls that directly and only use B.

but there would be no direct way from type B what is implemented from it.

Do you mean you want to be able to tell the difference between impl T for A and impl T for B (where type B = A)?

@Urgau
Copy link
Member Author

Urgau commented Oct 3, 2021

but my goal with this PR is to get the list of impls that directly and only use B.

but there would be no direct way from type B what is implemented from it.

Do you mean you want to be able to tell the difference between impl T for A and impl T for B (where type B = A)?

Yes, absolutely.

@jyn514
Copy link
Member

jyn514 commented Oct 3, 2021

I don't think this is a good idea. Any impl that works for the alias B will also work for A.

@bors
Copy link
Contributor

bors commented Oct 9, 2021

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

@jyn514
Copy link
Member

jyn514 commented Oct 9, 2021

I'm going to close this since you can already access almost all this information.

@jyn514 jyn514 closed this Oct 9, 2021
@Urgau Urgau deleted the typedef-impls branch May 5, 2023 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants