@@ -9,7 +9,7 @@ use crate::visit::DocVisitor;
99
1010use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1111use rustc_hir:: def_id:: DefId ;
12- use rustc_middle:: ty:: DefIdTree ;
12+ use rustc_middle:: ty:: { self , DefIdTree } ;
1313use rustc_span:: symbol:: sym;
1414
1515pub ( crate ) const COLLECT_TRAIT_IMPLS : Pass = Pass {
@@ -81,8 +81,35 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
8181 // Do not calculate blanket impl list for docs that are not going to be rendered.
8282 // While the `impl` blocks themselves are only in `libcore`, the module with `doc`
8383 // attached is directly included in `libstd` as well.
84+ let tcx = cx. tcx ;
8485 if did. is_local ( ) {
85- for def_id in prim. impls ( cx. tcx ) {
86+ for def_id in prim. impls ( tcx) . filter ( |def_id| {
87+ // Avoid including impl blocks with filled-in generics.
88+ // https://github.com/rust-lang/rust/issues/94937
89+ //
90+ // FIXME(notriddle): https://github.com/rust-lang/rust/issues/97129
91+ //
92+ // This tactic of using inherent impl blocks for getting
93+ // auto traits and blanket impls is a hack. What we really
94+ // want is to check if `[T]` impls `Send`, which has
95+ // nothing to do with the inherent impl.
96+ //
97+ // Rustdoc currently uses these `impl` block as a source of
98+ // the `Ty`, as well as the `ParamEnv`, `SubstsRef`, and
99+ // `Generics`. To avoid relying on the `impl` block, these
100+ // things would need to be created from wholecloth, in a
101+ // form that is valid for use in type inference.
102+ let ty = tcx. type_of ( def_id) ;
103+ match ty. kind ( ) {
104+ ty:: Slice ( ty)
105+ | ty:: Ref ( _, ty, _)
106+ | ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) => {
107+ matches ! ( ty. kind( ) , ty:: Param ( ..) )
108+ }
109+ ty:: Tuple ( tys) => tys. iter ( ) . all ( |ty| matches ! ( ty. kind( ) , ty:: Param ( ..) ) ) ,
110+ _ => true ,
111+ }
112+ } ) {
86113 let impls = get_auto_trait_and_blanket_impls ( cx, def_id) ;
87114 new_items_external. extend ( impls. filter ( |i| cx. inlined . insert ( i. item_id ) ) ) ;
88115 }
0 commit comments