Generate documentation for auto-trait impls

A new section is added to both both struct and trait doc pages.

On struct/enum pages, a new 'Auto Trait Implementations' section displays any
synthetic implementations for auto traits. Currently, this is only done
for Send and Sync.

On trait pages, a new 'Auto Implementors' section displays all types
which automatically implement the trait. Effectively, this is a list of
all public types in the standard library.

Synthesized impls for a particular auto trait ('synthetic impls') take
into account generic bounds. For example, a type 'struct Foo<T>(T)' will
have 'impl<T> Send for Foo<T> where T: Send' generated for it.

Manual implementations of auto traits are also taken into account. If we have
the following types:

'struct Foo<T>(T)'
'struct Wrapper<T>(Foo<T>)'
'unsafe impl<T> Send for Wrapper<T>' // pretend that Wrapper<T> makes
this sound somehow

Then Wrapper will have the following impl generated:
'impl<T> Send for Wrapper<T>'
reflecting the fact that 'T: Send' need not hold for 'Wrapper<T>: Send'
to hold

Lifetimes, HRTBS, and projections (e.g. '<T as Iterator>::Item') are
taken into account by synthetic impls

However, if a type can *never* implement a particular auto trait
(e.g. 'struct MyStruct<T>(*const T)'), then a negative impl will be
generated (in this case, 'impl<T> !Send for MyStruct<T>')

All of this means that a user should be able to copy-paste a synthetic
impl into their code, without any observable changes in behavior
(assuming the rest of the program remains unchanged).
This commit is contained in:
Aaron Hill
2017-11-22 16:16:55 -05:00
parent 27a046e933
commit 6728f21d85
29 changed files with 2486 additions and 154 deletions

View File

@@ -1563,14 +1563,29 @@
window.initSidebarItems = initSidebarItems;
window.register_implementors = function(imp) {
var list = document.getElementById('implementors-list');
var implementors = document.getElementById('implementors-list');
var synthetic_implementors = document.getElementById('synthetic-implementors-list');
var libs = Object.getOwnPropertyNames(imp);
for (var i = 0; i < libs.length; ++i) {
if (libs[i] === currentCrate) { continue; }
var structs = imp[libs[i]];
for (var j = 0; j < structs.length; ++j) {
var struct = structs[j];
var list = struct.synthetic ? synthetic_implementors : implementors;
var bail = false;
for (var k = 0; k < struct.types.length; k++) {
if (window.inlined_types.has(struct.types[k])) {
bail = true;
break;
}
}
if (bail) {
continue;
}
var code = document.createElement('code');
code.innerHTML = structs[j];
code.innerHTML = struct.text;
var x = code.getElementsByTagName('a');
for (var k = 0; k < x.length; k++) {