@@ -12,9 +12,9 @@ lean on its data collection and refinement but provide a different front-end.
12
12
# Motivation
13
13
[ motivation ] : #motivation
14
14
15
- The current HTML output of ` rustdoc ` is often lauded as a key selling point of Rust. Using this
16
- ubiquitous tool, you can easily find nearly anything you need to know about a crate. However,
17
- despite its versatility, the use of this specific output has its drawbacks:
15
+ The current HTML output of ` rustdoc ` is often lauded as a key selling point of Rust. It's a ubiquitous
16
+ tool, that you can use to easily find nearly anything you need to know about a crate. However,
17
+ despite its versatility, its output format has some drawbacks:
18
18
19
19
- Viewing this output requires a web browser, with (for some features of the output) a JavaScript
20
20
interpreter.
@@ -33,7 +33,7 @@ indicating that it would be a nice feature to have.
33
33
In [ the draft RFC from 2018] [ previous-rfc ] there was some discussion of utilizing ` save-analysis ` to
34
34
provide this information, but with [ RLS being replaced by rust-analyzer] [ RA-RLS ] it's possible that
35
35
the feature will be eventually removed from the compiler. In addition ` save-analysis ` output is just
36
- as if not more unstable than the current HTML output of ` rustdoc ` , so a separate feature is preferable.
36
+ as unstable as the current HTML output of ` rustdoc ` , so a separate format is preferable.
37
37
38
38
[ remove-json ] : https://github.com/rust-lang/rust/pull/32773
39
39
[ 2018-discussion ] : https://internals.rust-lang.org/t/design-discussion-json-output-for-rustdoc/8271/6
@@ -71,20 +71,86 @@ pub fn some_fn() {}
71
71
pub struct SomeStruct ;
72
72
```
73
73
74
- After running the above command, you should get a ` lib.json ` file like the following (indented for
75
- clarity):
74
+ After running the above command, you should get a ` lib.json ` file like the following:
76
75
77
76
``` json
78
77
{
79
- TODO
78
+ "id" : [0 , 0 ],
79
+ "name" : " doctest" ,
80
+ "source" : {
81
+ "filename" : " src/lib.rs" ,
82
+ "begin" : [1 , 0 ],
83
+ "end" : [12 , 22 ]
84
+ },
85
+ "visibility" : " Public" ,
86
+ "docs" : " Here are some crate-level docs!" ,
87
+ "inner" : {
88
+ "ModuleItem" : {
89
+ "is_crate" : true ,
90
+ "items" : [
91
+ {
92
+ "id" : [0 , 4 ],
93
+ "name" : " SomeStruct" ,
94
+ "source" : {
95
+ "filename" : " src/lib.rs" ,
96
+ "begin" : [12 , 0 ],
97
+ "end" : [12 , 22 ]
98
+ },
99
+ "visibility" : " Public" ,
100
+ "docs" : " Here are some docs for `SomeStruct`!" ,
101
+ "inner" : {
102
+ "StructItem" : {
103
+ "struct_type" : " Unit" ,
104
+ "generics" : {
105
+ "params" : [],
106
+ "where_predicates" : []
107
+ },
108
+ "fields_stripped" : false ,
109
+ "fields" : []
110
+ }
111
+ }
112
+ },
113
+ {
114
+ "id" : [0 , 3 ],
115
+ "name" : " some_fn" ,
116
+ "source" : {
117
+ "filename" : " src/lib.rs" ,
118
+ "begin" : [8 , 0 ],
119
+ "end" : [8 , 19 ]
120
+ },
121
+ "visibility" : " Public" ,
122
+ "docs" : " Here are some docs for `some_fn`!" ,
123
+ "inner" : {
124
+ "FunctionItem" : {
125
+ "decl" : {
126
+ "inputs" : [],
127
+ "output" : null ,
128
+ "c_variadic" : false
129
+ },
130
+ "generics" : {
131
+ "params" : [],
132
+ "where_predicates" : []
133
+ },
134
+ "header" : {
135
+ "is_unsafe" : false ,
136
+ "is_const" : false ,
137
+ "is_async" : false ,
138
+ "abi" : " \" Rust\" "
139
+ }
140
+ }
141
+ }
142
+ }
143
+ ]
144
+ }
145
+ }
80
146
}
81
147
```
82
148
83
149
# Reference-level explanation
84
150
[ reference-level-explanation ] : #reference-level-explanation
85
151
86
152
(* Upon successful implementation/stabilization, this documentation should live in The Rustdoc
87
- Book.* )
153
+ Book and/or an external crate's Rustdoc .* )
88
154
89
155
When you request JSON output from ` rustdoc ` , you're getting a version of the Rust abstract syntax
90
156
tree (AST), so you could see anything that you could export from a valid Rust crate. The following
@@ -97,9 +163,9 @@ trait and vice versa. The structure of those mappings is as follows:
97
163
98
164
TODO
99
165
100
- (* This documentation is deliberately left incomplete; filling it out will happen during the design process. * )
101
-
102
- ( * Complete documentation information is deferred to final design and implementation work. * )
166
+ (* Given that the JSON output will be implemented as a set of Rust types with serde serialization,
167
+ the most useful docs for them would be the 40 or so types themselves. It may be helpful to provide
168
+ some sort of [ schema ] ( http://json-schema.org/ ) for use with other languages * )
103
169
104
170
# Drawbacks
105
171
[ drawbacks ] : #drawbacks
@@ -121,12 +187,8 @@ TODO
121
187
remains deprecated and unused.
122
188
- ** Alternate data format (XML, Bincode, CapnProto, etc).** JSON was selected for its ubiquity in
123
189
available parsers, but selecting a different data format may provide benefits for file size,
124
- compressibility, speed of conversion, etc. If the implementation leans on serde then this may be a
125
- non-issue as it would be trivial to switch serialization formats.
126
- - ** Alternate data structure.** Massage the data so that it echoes something closer to user
127
- perception, rather than the internal ` clean ` AST that they're currently modeled after. Such a
128
- refinement can be provided in a future RFC, as a potential alternate data format to output, if
129
- necessary.
190
+ compressibility, speed of conversion, etc. Since the implementation will lean on serde then this
191
+ may be a non-issue as it would be trivial to switch serialization formats.
130
192
131
193
# Prior art
132
194
[ prior-art ] : #prior-art
@@ -163,34 +225,40 @@ representation separate from the human-readable outputs:
163
225
- What is the stabilization story? As langauge features are added, this representation will need to
164
226
be extended to accommodate it. As this will change the structure of the data, what does that mean
165
227
for its consumers?
166
- - How will intra-doc links be handled? Supporting ` struct.SomeStruct.html ` style links is pretty
167
- infeasible since it would tie alternative front-ends to ` rustdoc ` 's file/folder format. With the
168
- nightly intra-rustdoc link syntax it's debatable whether we should resolve those to HTML links or
169
- leave that up to whatever consumes the JSON.
170
- - How do we represent types, and allow people to properly collect type information from places like
171
- struct fields, function signatures, etc? ` rustdoc ` 's own ` clean::Type ` enum is large and recursive
172
- and represents a lot of primitives, in addition to ultimately deferring the lookup to a DefId.
173
- - The ` id ` field is basically a copy of DefId from inside the compiler; is there a better way to
174
- represent it? How necessary is it to have?
175
- - Where should we store impls?
176
- - In ` rustdoc ` , trait impls are pooled in the crate root (or placed in the module they're declared
177
- in), but before rendering, the information is copied into two maps: one mapping traits to their
178
- implementors, and one mapping types to all their impls (inherent or trait).
179
- - The HIR copies all trait impls into a map connecting traits to their implementors, though
180
- they're also available in the location they're defined if you iterate over the HIR.
181
- - However, while trait impls are unburdened by scope rules for visibility, * inherent* impls are.
182
- Currently, if ` --document-private-items ` is passed, the methods defined in an impl are all
183
- pooled into a struct, and any ` pub(restricted) ` scopes link to their respective modules.
184
- However, private methods are just shown as private, without any information connecting them to
185
- where they're allowed.
186
- - This leads to wanting to pool impls on their type (and copying them in to their trait for trait
187
- impls), and leaving the visibility fix for a later PR.
188
-
228
+ - How will users be able to manipulate the data? Is it a good idea to host a crate outside the
229
+ compiler that contains the struct definitions for all the types that get serialized so that
230
+ people could easily hack on the data without the compiler?
231
+ - How will intra-doc links be handled?
232
+ - Supporting ` struct.SomeStruct.html ` style links seems infeasible since it would tie alternative
233
+ front-ends to ` rustdoc ` 's file/folder format.
234
+ - With the nightly [ intra-rustdoc link syntax] ( https://github.com/rust-lang/rust/pull/47046 ) it's
235
+ debatable whether we should resolve those to HTML links or leave that up to whatever consumes
236
+ the JSON. Leaving them unresolved seems preferable but it would mean that consumers have to do
237
+ markdown parsing to replace them with actual links.
238
+ - In the case of items from external crates should the behavior be different?
239
+ - If there's an ` html_root_url ` attribute/argument should the behavior be different?
240
+ - Should we store ` Span ` s in the output even though we're not exporting the source itself like the
241
+ HTML output does? If so is there a simple way to sanitize relative links to the files to avoid
242
+ inconsistent output based on where ` rustdoc ` is invoked from?
243
+
244
+ ## Output structure
245
+
246
+ - Should the items be output as one large tree or a flattened map of id's to items? The latter
247
+ seems like it would have better ergonomics because finding any item is easy as opposed to the
248
+ tree structure where you'd have to traverse the nested submodules to get to a particular item.
249
+ It would however introduce another level of indirection when you actually do want to traverse
250
+ the children of a module because for every item/submodule you'd need to go look it up in the map.
251
+ - Besides the set of language items in the crate, what other information should we output? The
252
+ mappings of type id's to lists of trait impl id's seems useful as well as the reverse
253
+ mapping. Are there other mappings/info from the ` Cache ` or elsewhere in the compiler that would
254
+ be helpful to users (` paths ` , ` extern_locations ` , ` primitive_locations ` , etc.)?
255
+ - There are some items such as attributes that defer to compiler internal symbols in their ` Clean `
256
+ representations. Is it OK to simply stringify these and leave their handling up to the user?
257
+ - Should we specially handle ` Deref ` trait impls to make it easier for a struct to find the methods
258
+ they can access from their deref target?
189
259
190
260
# Future possibilities
191
261
[ future-possibilities ] : #future-possibilities
192
262
193
- - Since refactoring has to be done to support both the HTML and JSON backends to ` rustdoc ` , future
194
- work to add other output formats such as pure markdown should be relatively simple after this.
195
- - Once the JSON output is added, a Rust library for parsing it back into useful structs that lives
196
- outside the compiler would be helpful to allow people to easily use this representation.
263
+ - Since refactoring has been done to support multiple backends to ` rustdoc ` , future work to add
264
+ other output formats will be more manageable.
0 commit comments