This is something that needs to be implemented by each derive macro individually. A derive macro does not have to create a single impl of the same name. It can create whatever code it wants - multiple impl blocks, new types, standalone functions, maybe even nothing at all (not useful, but possible). The only rules are that the derive macro cannot touch the type declaration itself - except for removing the attributes associated with it, which is done by the builtin attribute macro #[derive] rather by the individual derive macros.
This means there is nothing the language can do to add documentation on the impl block - the derive macro will have to do it. Which it can do today, via attributes:
/// Some documentation for the type itself
#[derive(Default)]
#[default(doc = "Some documentation for the Default impl")]
struct MyCollection(Vec<i32>);
There is one thing the language can do to help though. Just like it allows declaring associated attributes for the macro, it can allow declaring attributes for the doc comment:
/// Some documentation for the type itself
///
/// # #[default]
///
/// Some documentation for the Default impl
#[derive(Default)]
struct MyCollection(Vec<i32>);
The derive macro could strip any section of the doc comment tagged with an attribute associated with any of the derives. It'd still be up to the derive macros to parse the doc comment and emit their own doc comments on whatever they create.
I think it would be better to avoid adding more layers of text processing, and I see a way to do it: you can already use doc comment syntax as part of the contents of an attribute; the following is syntactically valid:
#[derive(Foo)]
#[foo_doc(
/// Hello world
)]
struct Bar {}
Derive macros could add support for documentation specified using helper attributes of this form without any changes to the language. (If this becomes a common pattern, rustfmt support for it would be useful, though; currently it is unformatted.)