X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustdoc%2Fpasses%2Fcollect_trait_impls.rs;h=0dc1c9d9663130ea46095484d6c4eaeb792b5b62;hb=f5ac93b94b611bd9193b81c7eae85a3afe835549;hp=d245c3750ec08d64e153f08e16bdadbf5aed33fa;hpb=91e5a47aae1407e8ae9f4ae94812b1cd94394405;p=rust.git diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index d245c3750ec..0dc1c9d9663 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::DefId; -use rustc_middle::ty::DefIdTree; +use rustc_middle::ty::{self, DefIdTree}; use rustc_span::symbol::sym; crate const COLLECT_TRAIT_IMPLS: Pass = Pass { @@ -53,9 +53,7 @@ while let Some(did) = parent { attr_buf.extend( cx.tcx - .get_attrs(did) - .iter() - .filter(|attr| attr.has_name(sym::doc)) + .get_attrs(did, sym::doc) .filter(|attr| { if let Some([attr]) = attr.meta_item_list().as_deref() { attr.has_name(sym::cfg) @@ -83,8 +81,33 @@ // Do not calculate blanket impl list for docs that are not going to be rendered. // While the `impl` blocks themselves are only in `libcore`, the module with `doc` // attached is directly included in `libstd` as well. + let tcx = cx.tcx; if did.is_local() { - for def_id in prim.impls(cx.tcx) { + for def_id in prim.impls(tcx).filter(|def_id| { + // Avoid including impl blocks with filled-in generics. + // https://github.com/rust-lang/rust/issues/94937 + // + // FIXME(notriddle): https://github.com/rust-lang/rust/issues/97129 + // + // This tactic of using inherent impl blocks for getting + // auto traits and blanket impls is a hack. What we really + // want is to check if `[T]` impls `Send`, which has + // nothing to do with the inherent impl. + // + // Rustdoc currently uses these `impl` block as a source of + // the `Ty`, as well as the `ParamEnv`, `SubstsRef`, and + // `Generics`. To avoid relying on the `impl` block, these + // things would need to be created from wholecloth, in a + // form that is valid for use in type inference. + let ty = tcx.type_of(def_id); + match ty.kind() { + ty::Slice(ty) => matches!(ty.kind(), ty::Param(..)), + ty::Ref(_region, ty, _mutbl) => matches!(ty.kind(), ty::Param(..)), + ty::RawPtr(ty::TypeAndMut { ty, .. }) => matches!(ty.kind(), ty::Param(..)), + ty::Tuple(tys) => tys.iter().all(|ty| matches!(ty.kind(), ty::Param(..))), + _ => true, + } + }) { let impls = get_auto_trait_and_blanket_impls(cx, def_id); new_items_external.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); }