From 54ea8eb232fd17ca903cfa29848f7ea70ad167ff Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 15 Jul 2018 23:37:40 +0200 Subject: [PATCH 01/17] Start of generic impl fix for rustdoc --- src/Cargo.lock | 56 ++++++------------------------ src/librustdoc/clean/auto_trait.rs | 27 ++++++++++++-- 2 files changed, 35 insertions(+), 48 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 09baaeadaee..6dc10d506e7 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -208,14 +208,13 @@ dependencies = [ "ignore 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -244,18 +243,6 @@ dependencies = [ "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cargo_metadata" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cargotest2" version = "0.1.0" @@ -642,14 +629,6 @@ dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "error-chain" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "error_index_generator" version = "0.0.0" @@ -1032,7 +1011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazycell" -version = "1.0.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1237,13 +1216,12 @@ name = "miri" version = "0.1.0" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1383,7 +1361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2364,18 +2342,6 @@ dependencies = [ "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rustfix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustfmt-nightly" version = "0.8.2" @@ -2497,8 +2463,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "socket2" @@ -3065,7 +3034,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" -"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" "checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699" @@ -3097,7 +3065,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" @@ -3136,7 +3103,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum languageserver-types 0.45.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91d91d1c23db74187096d191967cb49f49bb175ad6d855fa9229d16ef2c982" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" -"checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50" +"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9dcce5a1ecca1891ab06c1545a422fd4b35f65c19acec51ea638c66d5be0810d" "checksum libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c628b499e8d1a4f4bd09a95d6cb1f8aeb231b46a9d40959bbd0408f14dd63adf" @@ -3223,7 +3190,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" "checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396" -"checksum rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e2613df31a403754605dba168ded93d529a2b88c5a63b78cf2421bb5d62c936" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" @@ -3237,7 +3203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514" +"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" "checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703" "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 0cdab134815..f35d7b15f3e 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::traits::auto_trait as auto; -use rustc::ty::TypeFoldable; -use rustc::hir; +use rustc::{self, hir}; +use rustc::traits::{self, auto_trait as auto}; +use rustc::ty::{ToPredicate, TypeFoldable}; use std::fmt::Debug; use super::*; @@ -82,6 +82,27 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { + + if ::std::env::var("LOL").is_ok() { + let ty = self.cx.tcx.type_of(def_id); + if let ty::TyAdt(_adt, _) = ty.sty { + let subts = ty::subst::Substs::identity_for_item(self.cx.tcx.clone(), def_id); + self.cx.tcx.infer_ctxt().enter(|infcx| { + for impl_ in infcx.tcx.all_trait_implementations(LOCAL_CRATE).iter() { + let trait_ref = rustc::ty::TraitRef::new(*impl_, subts); + let pred = trait_ref.to_predicate(); + let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), + rustc::ty::ParamEnv::empty(), + pred); + println!("{} => {}", + infcx.tcx.item_name(*impl_).to_string(), + infcx.predicate_may_hold(&obligation)); + } + }); + } + } + //let res = self.cx.tcx.trait_impls_of(def_id); + //println!("=> {:?} {:?}", res.blanket_impls.len(), res.non_blanket_impls.len()); if self.cx .tcx .get_attrs(def_id) From 39849d5128609040087e9942978af3405e17f958 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 17 Jul 2018 01:14:52 +0200 Subject: [PATCH 02/17] First step to generic trait impls --- src/librustdoc/clean/auto_trait.rs | 132 ++++++++++++++++++++++++----- src/librustdoc/clean/mod.rs | 1 - src/librustdoc/html/render.rs | 1 + 3 files changed, 114 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f35d7b15f3e..e8fc8fec93c 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::{self, hir}; +use rustc::hir; use rustc::traits::{self, auto_trait as auto}; use rustc::ty::{ToPredicate, TypeFoldable}; +use rustc::ty::subst::Subst; +use rustc::infer::InferOk; use std::fmt::Debug; +use syntax_pos::DUMMY_SP; use super::*; @@ -82,22 +85,115 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { + let tcx = self.cx.tcx; + let generics = self.cx.tcx.generics_of(def_id); - if ::std::env::var("LOL").is_ok() { - let ty = self.cx.tcx.type_of(def_id); - if let ty::TyAdt(_adt, _) = ty.sty { - let subts = ty::subst::Substs::identity_for_item(self.cx.tcx.clone(), def_id); - self.cx.tcx.infer_ctxt().enter(|infcx| { - for impl_ in infcx.tcx.all_trait_implementations(LOCAL_CRATE).iter() { - let trait_ref = rustc::ty::TraitRef::new(*impl_, subts); - let pred = trait_ref.to_predicate(); - let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), - rustc::ty::ParamEnv::empty(), - pred); - println!("{} => {}", - infcx.tcx.item_name(*impl_).to_string(), - infcx.predicate_may_hold(&obligation)); - } + let ty = self.cx.tcx.type_of(def_id); + let mut traits = FxHashMap(); + if let ty::TyAdt(_adt, _) = ty.sty { + use std::rc::Rc; + + let name = Rc::new(name.clone()); + let param_env = self.cx.tcx.param_env(def_id); + for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() { + let name = name.clone(); + self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { + let name = name.clone(); + self.cx.tcx.infer_ctxt().enter(|infcx| { + let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); + let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); + let ty = ty.subst(infcx.tcx, substs); + let param_env = param_env.subst(infcx.tcx, substs); + + let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty); + if let Ok(InferOk { value: (), obligations }) = eq_result { + // FIXME(eddyb) ignoring `obligations` might cause false positives. + drop(obligations); + + let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( + cause.clone(), + param_env, + trait_ref.to_predicate(), + )); + if may_apply { + // FIXME: add crate's id before the name to avoid removing a + // trait which doesn't exist. + if traits.get(&trait_def_id).is_none() { + /*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx); + get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/ + /*if let Some(i) = self.get_auto_trait_impl_for( + def_id, + name.clone(), + generics.clone(), + def_ctor, + trait_def_id, + ) { + traits.insert(trait_name, i); + }*/ + + let path = get_path_for_type(infcx.tcx, def_id, def_ctor); + let mut segments = path.clone().segments.into_vec(); + let last = segments.pop().unwrap(); + + use std::ops::Deref; + let t_name: Option = name.deref().clone(); + let real_name = t_name.map(|name| Ident::from_str(&name)).unwrap_or(last.ident); + + segments.push(hir::PathSegment::new( + real_name, + self.generics_to_path_params(generics.clone()), + false, + )); + let new_path = hir::Path { + span: path.span, + def: path.def, + segments: HirVec::from_vec(segments), + }; + let ty = hir::Ty { + id: ast::DUMMY_NODE_ID, + node: hir::Ty_::TyPath(hir::QPath::Resolved(None, P(new_path))), + span: DUMMY_SP, + hir_id: hir::DUMMY_HIR_ID, + }; + traits.insert(trait_def_id, Item { + source: Span::empty(), + name: None, + attrs: Default::default(), + visibility: None, + def_id: self.next_def_id(def_id.krate), + stability: None, + deprecation: None, + inner: ImplItem(Impl { + unsafety: hir::Unsafety::Normal, + generics: Generics { + params: generics.params.clean(self.cx), + where_predicates: Vec::new(), + }, + provided_trait_methods: FxHashSet(), + trait_: Some(hir::TraitRef { + path, + ref_id: ast::DUMMY_NODE_ID, + }.clean(self.cx)), + + //Some(trait_ref.clean(self.cx)), + for_: ty.clean(self.cx), + items: Vec::new(), + polarity: None, + synthetic: true, + }) + }); + } + //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); + } + debug!("{:?} => {}", trait_ref, may_apply); + } + }); }); } } @@ -117,9 +213,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { return Vec::new(); } - let tcx = self.cx.tcx; - let generics = self.cx.tcx.generics_of(def_id); - debug!( "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}", def_id, generics @@ -143,6 +236,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) + .chain(traits.into_iter().map(|(_, v)| v)) .collect(); debug!( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 77521db835b..68842522223 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1551,7 +1551,6 @@ impl GenericBound { } fn get_trait_type(&self) -> Option { - if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self { return Some(trait_.clone()); } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ade33c8dd7d..606cf7a6125 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2082,6 +2082,7 @@ where F: Fn(&mut fmt::Formatter) -> fmt::Result { impl<'a> fmt::Display for Item<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { debug_assert!(!self.item.is_stripped()); + println!("=> {:?}", self.item.name); // Write the breadcrumb trail header for the top write!(fmt, "

")?; match self.item.inner { From ccdf4ae814a91ff56a760580b21e59982ebe4d31 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 17 Jul 2018 23:32:59 +0200 Subject: [PATCH 03/17] part 2 --- src/librustdoc/clean/auto_trait.rs | 95 ++++++++++++------------------ src/librustdoc/html/render.rs | 6 +- 2 files changed, 44 insertions(+), 57 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index e8fc8fec93c..d884e6e29fd 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -91,18 +91,13 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let ty = self.cx.tcx.type_of(def_id); let mut traits = FxHashMap(); if let ty::TyAdt(_adt, _) = ty.sty { - use std::rc::Rc; - - let name = Rc::new(name.clone()); let param_env = self.cx.tcx.param_env(def_id); for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() { - let name = name.clone(); self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { - let name = name.clone(); self.cx.tcx.infer_ctxt().enter(|infcx| { let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); - let ty = ty.subst(infcx.tcx, substs); + let ty2 = ty.subst(infcx.tcx, substs); let param_env = param_env.subst(infcx.tcx, substs); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); @@ -111,7 +106,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. let cause = traits::ObligationCause::dummy(); - let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty); + let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2); if let Ok(InferOk { value: (), obligations }) = eq_result { // FIXME(eddyb) ignoring `obligations` might cause false positives. drop(obligations); @@ -137,57 +132,40 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { traits.insert(trait_name, i); }*/ - let path = get_path_for_type(infcx.tcx, def_id, def_ctor); - let mut segments = path.clone().segments.into_vec(); - let last = segments.pop().unwrap(); + let mut impls = Vec::new(); + ::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls); + /*if ::std::env::var("LOL").is_ok() { + println!("=> {} ::> {}", + infcx.tcx.item_name(trait_def_id).to_string(), + impls.len()); + println!("{:?}", impls); + }*/ + for impl_ in &mut impls { + if let ImplItem(ref mut i) = impl_.inner { + i.synthetic = true; + i.for_ = ty.clean(&self.cx); + } + } + traits.insert(trait_def_id, impls); - use std::ops::Deref; - let t_name: Option = name.deref().clone(); - let real_name = t_name.map(|name| Ident::from_str(&name)).unwrap_or(last.ident); + /*use ::clean::{self, inline::*}; - segments.push(hir::PathSegment::new( - real_name, - self.generics_to_path_params(generics.clone()), - false, - )); - let new_path = hir::Path { - span: path.span, - def: path.def, - segments: HirVec::from_vec(segments), - }; - let ty = hir::Ty { - id: ast::DUMMY_NODE_ID, - node: hir::Ty_::TyPath(hir::QPath::Resolved(None, P(new_path))), - span: DUMMY_SP, - hir_id: hir::DUMMY_HIR_ID, - }; - traits.insert(trait_def_id, Item { - source: Span::empty(), - name: None, - attrs: Default::default(), - visibility: None, - def_id: self.next_def_id(def_id.krate), - stability: None, - deprecation: None, - inner: ImplItem(Impl { - unsafety: hir::Unsafety::Normal, - generics: Generics { - params: generics.params.clean(self.cx), - where_predicates: Vec::new(), - }, - provided_trait_methods: FxHashSet(), - trait_: Some(hir::TraitRef { - path, - ref_id: ast::DUMMY_NODE_ID, - }.clean(self.cx)), - - //Some(trait_ref.clean(self.cx)), - for_: ty.clean(self.cx), - items: Vec::new(), - polarity: None, - synthetic: true, - }) + let mut ret = Vec::with_capacity(2); + record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait); + ret.extend(build_impls(self.cx, trait_def_id, false)); + let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id)); + let cx = self.cx; + ret.push(clean::Item { + source: infcx.tcx.def_span(trait_def_id).clean(cx), + name: Some(infcx.tcx.item_name(trait_def_id).to_string()), + attrs: load_attrs(cx, trait_def_id), + inner, + visibility: Some(clean::Public), + stability: cx.tcx.lookup_stability(trait_def_id).clean(cx), + deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx), + def_id: trait_def_id, }); + traits.insert(trait_def_id, ret);*/ } //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); } @@ -236,13 +214,18 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) - .chain(traits.into_iter().map(|(_, v)| v)) + .chain(traits.into_iter().flat_map(|(_, v)| v.into_iter())) .collect(); debug!( "get_auto_traits: type {:?} auto_traits {:?}", def_id, auto_traits ); + if ::std::env::var("LOL").is_ok() { + for x in &auto_traits { + println!("\n=> {:?}", x); + } + } auto_traits } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 606cf7a6125..45cffe00cf8 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2082,7 +2082,6 @@ where F: Fn(&mut fmt::Formatter) -> fmt::Result { impl<'a> fmt::Display for Item<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { debug_assert!(!self.item.is_stripped()); - println!("=> {:?}", self.item.name); // Write the breadcrumb trail header for the top write!(fmt, "

")?; match self.item.inner { @@ -3586,6 +3585,11 @@ fn render_assoc_items(w: &mut fmt::Formatter, None => return Ok(()), }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { + if ::std::env::var("LOL").is_ok() { + if let Some(ref t) = i.inner_impl().trait_ { + println!("==> {:?}", t); + } + } i.inner_impl().trait_.is_none() }); if !non_trait.is_empty() { From 73cb82384a9e97f5afd79c056ff5dba2454e6184 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 18 Jul 2018 00:39:26 +0200 Subject: [PATCH 04/17] some improvements --- src/Cargo.lock | 56 ++++++++++++++++++++++++------ src/librustdoc/clean/auto_trait.rs | 11 ++++-- src/librustdoc/core.rs | 4 ++- src/librustdoc/html/render.rs | 15 ++++++-- 4 files changed, 68 insertions(+), 18 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 6dc10d506e7..09baaeadaee 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -208,13 +208,14 @@ dependencies = [ "ignore 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -243,6 +244,18 @@ dependencies = [ "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cargo_metadata" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -629,6 +642,14 @@ dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "error_index_generator" version = "0.0.0" @@ -1011,7 +1032,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazycell" -version = "0.6.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1216,12 +1237,13 @@ name = "miri" version = "0.1.0" dependencies = [ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1361,7 +1383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2342,6 +2364,18 @@ dependencies = [ "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustfix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustfmt-nightly" version = "0.8.2" @@ -2463,11 +2497,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "socket2" @@ -3034,6 +3065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum cargo_metadata 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1efca0b863ca03ed4c109fb1c55e0bc4bbeb221d3e103d86251046b06a526bd0" +"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" "checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699" @@ -3065,6 +3097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0e6e40ebb0e66918a37b38c7acab4e10d299e0463fe2af5d29b9cc86710cfd2a" "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" @@ -3103,7 +3136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum languageserver-types 0.45.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91d91d1c23db74187096d191967cb49f49bb175ad6d855fa9229d16ef2c982" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" -"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" +"checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9dcce5a1ecca1891ab06c1545a422fd4b35f65c19acec51ea638c66d5be0810d" "checksum libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c628b499e8d1a4f4bd09a95d6cb1f8aeb231b46a9d40959bbd0408f14dd63adf" @@ -3190,6 +3223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" "checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396" +"checksum rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e2613df31a403754605dba168ded93d529a2b88c5a63b78cf2421bb5d62c936" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" @@ -3203,7 +3237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" +"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514" "checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703" "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index d884e6e29fd..faa41c53d73 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -92,7 +92,11 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let mut traits = FxHashMap(); if let ty::TyAdt(_adt, _) = ty.sty { let param_env = self.cx.tcx.param_env(def_id); - for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() { + match _adt.adt_kind() { + AdtKind::Struct => println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string()), + _ => {} + } + for &trait_def_id in self.cx.all_traits.iter() { self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); @@ -120,6 +124,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // FIXME: add crate's id before the name to avoid removing a // trait which doesn't exist. if traits.get(&trait_def_id).is_none() { + println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); /*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx); get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/ /*if let Some(i) = self.get_auto_trait_impl_for( @@ -221,11 +226,11 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { "get_auto_traits: type {:?} auto_traits {:?}", def_id, auto_traits ); - if ::std::env::var("LOL").is_ok() { + /*if ::std::env::var("LOL").is_ok() { for x in &auto_traits { println!("\n=> {:?}", x); } - } + }*/ auto_traits } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 375a9c981a1..ac7dcc13061 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,7 +11,7 @@ use rustc_lint; use rustc_driver::{self, driver, target_features, abort_on_err}; use rustc::session::{self, config}; -use rustc::hir::def_id::{DefId, CrateNum}; +use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::hir::def::Def; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; @@ -84,6 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { /// Maps (type_id, trait_id) -> auto trait impl pub generated_synthetics: RefCell>, pub current_item_name: RefCell>, + pub all_traits: Lrc>, } impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { @@ -385,6 +386,7 @@ pub fn run_core(search_paths: SearchPaths, all_fake_def_ids: RefCell::new(FxHashSet()), generated_synthetics: RefCell::new(FxHashSet()), current_item_name: RefCell::new(None), + all_traits: tcx.all_traits(LOCAL_CRATE), }; debug!("crate: {:?}", tcx.hir.krate()); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 45cffe00cf8..5dc91882b5c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3585,11 +3585,11 @@ fn render_assoc_items(w: &mut fmt::Formatter, None => return Ok(()), }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { - if ::std::env::var("LOL").is_ok() { + /*if ::std::env::var("LOL").is_ok() { if let Some(ref t) = i.inner_impl().trait_ { println!("==> {:?}", t); } - } + }*/ i.inner_impl().trait_.is_none() }); if !non_trait.is_empty() { @@ -3632,7 +3632,16 @@ fn render_assoc_items(w: &mut fmt::Formatter, let (synthetic, concrete) = traits .iter() - .partition::, _>(|t| t.inner_impl().synthetic); + .partition::, _>(|t| t.inner_impl().synthetic); + + // ugly hacks to remove duplicates. + let synthetic = synthetic.into_iter() + .filter(|t| { + !concrete.iter() + .any(|tt| { + tt.inner_impl().trait_.def_id() == t.inner_impl().trait_.def_id() + }) + }).collect::>(); struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item); From e8cca55283ec61c5442b4a40e123d03d997c92ff Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 00:15:08 +0200 Subject: [PATCH 05/17] Working generic impl --- src/librustdoc/clean/auto_trait.rs | 281 +++++++++++++++++------------ src/librustdoc/clean/inline.rs | 6 + src/librustdoc/core.rs | 4 +- src/librustdoc/html/render.rs | 46 ++--- 4 files changed, 199 insertions(+), 138 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index faa41c53d73..9203398dcb3 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -85,103 +85,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { - let tcx = self.cx.tcx; - let generics = self.cx.tcx.generics_of(def_id); - - let ty = self.cx.tcx.type_of(def_id); - let mut traits = FxHashMap(); - if let ty::TyAdt(_adt, _) = ty.sty { - let param_env = self.cx.tcx.param_env(def_id); - match _adt.adt_kind() { - AdtKind::Struct => println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string()), - _ => {} - } - for &trait_def_id in self.cx.all_traits.iter() { - self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { - self.cx.tcx.infer_ctxt().enter(|infcx| { - let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); - let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); - let ty2 = ty.subst(infcx.tcx, substs); - let param_env = param_env.subst(infcx.tcx, substs); - - let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); - let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); - - // Require the type the impl is implemented on to match - // our type, and ignore the impl if there was a mismatch. - let cause = traits::ObligationCause::dummy(); - let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2); - if let Ok(InferOk { value: (), obligations }) = eq_result { - // FIXME(eddyb) ignoring `obligations` might cause false positives. - drop(obligations); - - let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( - cause.clone(), - param_env, - trait_ref.to_predicate(), - )); - if may_apply { - // FIXME: add crate's id before the name to avoid removing a - // trait which doesn't exist. - if traits.get(&trait_def_id).is_none() { - println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); - /*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx); - get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/ - /*if let Some(i) = self.get_auto_trait_impl_for( - def_id, - name.clone(), - generics.clone(), - def_ctor, - trait_def_id, - ) { - traits.insert(trait_name, i); - }*/ - - let mut impls = Vec::new(); - ::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls); - /*if ::std::env::var("LOL").is_ok() { - println!("=> {} ::> {}", - infcx.tcx.item_name(trait_def_id).to_string(), - impls.len()); - println!("{:?}", impls); - }*/ - for impl_ in &mut impls { - if let ImplItem(ref mut i) = impl_.inner { - i.synthetic = true; - i.for_ = ty.clean(&self.cx); - } - } - traits.insert(trait_def_id, impls); - - /*use ::clean::{self, inline::*}; - - let mut ret = Vec::with_capacity(2); - record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait); - ret.extend(build_impls(self.cx, trait_def_id, false)); - let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id)); - let cx = self.cx; - ret.push(clean::Item { - source: infcx.tcx.def_span(trait_def_id).clean(cx), - name: Some(infcx.tcx.item_name(trait_def_id).to_string()), - attrs: load_attrs(cx, trait_def_id), - inner, - visibility: Some(clean::Public), - stability: cx.tcx.lookup_stability(trait_def_id).clean(cx), - deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx), - def_id: trait_def_id, - }); - traits.insert(trait_def_id, ret);*/ - } - //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); - } - debug!("{:?} => {}", trait_ref, may_apply); - } - }); - }); - } - } - //let res = self.cx.tcx.trait_impls_of(def_id); - //println!("=> {:?} {:?}", res.blanket_impls.len(), res.non_blanket_impls.len()); if self.cx .tcx .get_attrs(def_id) @@ -196,22 +99,172 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { return Vec::new(); } + let tcx = self.cx.tcx; + let generics = self.cx.tcx.generics_of(def_id); + + let ty = self.cx.tcx.type_of(def_id); + let mut traits = FxHashMap(); + if self.cx.crate_name != Some("core".to_string()) { + if let ty::TyAdt(_adt, _) = ty.sty { + let param_env = self.cx.tcx.param_env(def_id); + /*let print = match _adt.adt_kind() { + AdtKind::Struct => { + //println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string()); + true + } + _ => false, + };*/ + for &trait_def_id in self.cx.all_traits.iter() { + if traits.get(&trait_def_id).is_some() { + continue + } + let t_name = self.cx.tcx.item_name(trait_def_id).to_string(); + self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { + self.cx.tcx.infer_ctxt().enter(|infcx| { + let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); + let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); + let ty2 = ty.subst(infcx.tcx, substs); + let param_env = param_env.subst(infcx.tcx, substs); + + let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2); + if let Ok(InferOk { value: (), obligations }) = eq_result { + // FIXME(eddyb) ignoring `obligations` might cause false positives. + drop(obligations); + + let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( + cause.clone(), + param_env, + trait_ref.to_predicate(), + )); + /*if print { + println!("==> {}", infcx.tcx.item_name(trait_def_id).to_string()); + }*/ + if may_apply { + if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { + println!("may_apply: {:?}", t_name); + } + // FIXME: add crate's id before the name to avoid removing a + // trait which doesn't exist. + if traits.get(&trait_def_id).is_none() { + if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { + println!("in!"); + } + /*if print { + println!("> {}", infcx.tcx.item_name(trait_def_id).to_string()); + }*/ + /*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx); + get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/ + /*if let Some(i) = self.get_auto_trait_impl_for( + def_id, + name.clone(), + generics.clone(), + def_ctor, + trait_def_id, + ) { + traits.insert(trait_name, i); + }*/ + + let mut impls = Vec::new(); + ::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls); + /*if ::std::env::var("LOL").is_ok() { + println!("=> {} ::> {}", + infcx.tcx.item_name(trait_def_id).to_string(), + impls.len()); + println!("{:?}", impls); + }*/ + for impl_ in &mut impls { + if let ImplItem(ref mut i) = impl_.inner { + i.synthetic = true; + i.for_ = ty.clean(&self.cx); + //i.visibility = None; + } + //impl_.visibility = None; + if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { + println!("**> {:?}", impl_); + } + } + //traits.insert(trait_def_id, impls); + let trait_ = hir::TraitRef { + path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), + ref_id: ast::DUMMY_NODE_ID, + }; + let provided_trait_methods = infcx.tcx.provided_trait_methods(impl_def_id) + .into_iter() + .map(|meth| meth.ident.to_string()) + .collect(); + println!("|||> {}", t_name); + traits.insert(trait_def_id, Item { + source: Span::empty(), + name: None, + attrs: Default::default(), + visibility: None, + def_id: self.next_def_id(impl_def_id.krate), + stability: None, + deprecation: None, + inner: ImplItem(Impl { + unsafety: hir::Unsafety::Normal, + generics: (infcx.tcx.generics_of(trait_def_id), &Default::default()).clean(self.cx), + provided_trait_methods, + trait_: Some(trait_.clean(self.cx)), + for_: ty.clean(self.cx), + items: infcx.tcx.associated_items(impl_def_id).collect::>().clean(self.cx), + polarity: None, + synthetic: true, + }), + }); + + /*use ::clean::{self, inline::*}; + + let mut ret = Vec::with_capacity(2); + record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait); + ret.extend(build_impls(self.cx, trait_def_id, false)); + let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id)); + let cx = self.cx; + ret.push(clean::Item { + source: infcx.tcx.def_span(trait_def_id).clean(cx), + name: Some(infcx.tcx.item_name(trait_def_id).to_string()), + attrs: load_attrs(cx, trait_def_id), + inner, + visibility: Some(clean::Public), + stability: cx.tcx.lookup_stability(trait_def_id).clean(cx), + deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx), + def_id: trait_def_id, + }); + traits.insert(trait_def_id, ret);*/ + } + //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); + } + debug!("{:?} => {}", trait_ref, may_apply); + } + }); + }); + } + } + } + //let res = self.cx.tcx.trait_impls_of(def_id); + //println!("=> {:?} {:?}", res.blanket_impls.len(), res.non_blanket_impls.len()); + debug!( "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}", def_id, generics ); - let auto_traits: Vec<_> = self.cx - .send_trait - .and_then(|send_trait| { - self.get_auto_trait_impl_for( - def_id, - name.clone(), - generics.clone(), - def_ctor, - send_trait, - ) - }) - .into_iter() + let auto_traits: Vec<_> = + self.cx.send_trait + .and_then(|send_trait| { + self.get_auto_trait_impl_for( + def_id, + name.clone(), + generics.clone(), + def_ctor, + send_trait, + ) + }).into_iter() .chain(self.get_auto_trait_impl_for( def_id, name.clone(), @@ -219,18 +272,16 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) - .chain(traits.into_iter().flat_map(|(_, v)| v.into_iter())) + .chain(traits.into_iter().map(|(_, v)| v))//.flat_map(|(_, v)| v.into_iter())) .collect(); debug!( "get_auto_traits: type {:?} auto_traits {:?}", def_id, auto_traits ); - /*if ::std::env::var("LOL").is_ok() { - for x in &auto_traits { - println!("\n=> {:?}", x); - } - }*/ + if self.cx.crate_name == Some("std".to_string()) { + println!("((((((> {} {:?}", auto_traits.len(), auto_traits); + } auto_traits } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 0117e4fde84..cb9cb7a3e0f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -276,6 +276,9 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec {} {:?}\n", auto_impls.len(), auto_impls); + } let new_impls: Vec = auto_impls.into_iter() .filter(|i| renderinfo.inlined.insert(i.def_id)).collect(); @@ -337,6 +340,9 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec {} {:?}\n", auto_impls.len(), auto_impls); + } let mut renderinfo = cx.renderinfo.borrow_mut(); let new_impls: Vec = auto_impls.into_iter() diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index ac7dcc13061..d893ec415e8 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -84,7 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { /// Maps (type_id, trait_id) -> auto trait impl pub generated_synthetics: RefCell>, pub current_item_name: RefCell>, - pub all_traits: Lrc>, + pub all_traits: Vec, } impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { @@ -386,7 +386,7 @@ pub fn run_core(search_paths: SearchPaths, all_fake_def_ids: RefCell::new(FxHashSet()), generated_synthetics: RefCell::new(FxHashSet()), current_item_name: RefCell::new(None), - all_traits: tcx.all_traits(LOCAL_CRATE), + all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(), }; debug!("crate: {:?}", tcx.hir.krate()); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 5dc91882b5c..408250a259b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3584,29 +3584,32 @@ fn render_assoc_items(w: &mut fmt::Formatter, Some(v) => v, None => return Ok(()), }; + //println!("=======> {:?}", containing_item.name); let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { - /*if ::std::env::var("LOL").is_ok() { - if let Some(ref t) = i.inner_impl().trait_ { - println!("==> {:?}", t); - } + /*if let Some(ref t) = i.inner_impl().trait_ { + println!("++++++> {:?}", t); + }*/ + /*if i.inner_impl().trait_.is_some() { + println!("++++++> {:?}", i.name); }*/ i.inner_impl().trait_.is_none() }); if !non_trait.is_empty() { let render_mode = match what { AssocItemRender::All => { - write!(w, " -

- Methods -

+ write!(w, "\ +

\ + Methods\ +

\ ")?; RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { - write!(w, " -

- Methods from {}<Target = {}> -

+ write!(w, "\ +

\ + Methods from {}<Target = {}>\ + \ +

\ ", trait_, type_)?; RenderMode::ForDeref { mut_: deref_mut_ } } @@ -3653,19 +3656,20 @@ fn render_assoc_items(w: &mut fmt::Formatter, let impls = format!("{}", RendererStruct(cx, concrete, containing_item)); if !impls.is_empty() { - write!(w, " -

- Trait Implementations -

+ write!(w, "\ +

\ + Trait Implementations\ +

\
{}
", impls)?; } if !synthetic.is_empty() { - write!(w, " -

- Auto Trait Implementations -

-
+ write!(w, "\ +

\ + Auto Trait Implementations\ + \ +

\ +
\ ")?; render_impls(cx, w, &synthetic, containing_item)?; write!(w, "
")?; From 2bc7c03af6166ceecb2d0037e30c558f6892c7d3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 12:15:32 +0200 Subject: [PATCH 06/17] Add filter over non generic impls --- src/librustdoc/clean/auto_trait.rs | 82 ++++++++++++++---------------- src/librustdoc/clean/inline.rs | 7 --- src/librustdoc/html/render.rs | 1 - 3 files changed, 37 insertions(+), 53 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9203398dcb3..9a6495694c5 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -16,6 +16,8 @@ use rustc::infer::InferOk; use std::fmt::Debug; use syntax_pos::DUMMY_SP; +use core::DocAccessLevels; + use super::*; pub struct AutoTraitFinder<'a, 'tcx: 'a, 'rcx: 'a> { @@ -115,13 +117,38 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { _ => false, };*/ for &trait_def_id in self.cx.all_traits.iter() { - if traits.get(&trait_def_id).is_some() { + if traits.get(&trait_def_id).is_some() || + !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) { continue } let t_name = self.cx.tcx.item_name(trait_def_id).to_string(); self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { + let generics = infcx.tcx.generics_of(impl_def_id); + + /*if generics.count() == 0 { + return; + }*/ let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); + /*if !trait_ref.substs.iter().any(|x| match x.unpack() { + ::rustc::ty::subst::UnpackedKind::Type(ref t) => { + match t.sty { + ::rustc::ty::TypeVariants::TyParam(_) => true, + _ => false, + } + } + _ => false, + }) { + return; + }*/ + + if !match infcx.tcx.type_of(impl_def_id).sty { + ::rustc::ty::TypeVariants::TyParam(_) => true, + _ => false, + } { + return; + } + let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); let ty2 = ty.subst(infcx.tcx, substs); let param_env = param_env.subst(infcx.tcx, substs); @@ -146,50 +173,18 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { println!("==> {}", infcx.tcx.item_name(trait_def_id).to_string()); }*/ if may_apply { - if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { - println!("may_apply: {:?}", t_name); - } // FIXME: add crate's id before the name to avoid removing a // trait which doesn't exist. if traits.get(&trait_def_id).is_none() { - if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { - println!("in!"); + if self.cx.crate_name == Some("std".to_string()) { + println!("visibility: ({} {}) [{} {:?}] [{} {:?}]", + self.cx.tcx.item_name(def_id).to_string(), t_name, + impl_def_id.krate, impl_def_id.index, + trait_def_id.krate, trait_def_id.index); + println!("{:?}", infcx.tcx.visibility(impl_def_id)); + println!("{:?}", infcx.tcx.visibility(trait_def_id)); } - /*if print { - println!("> {}", infcx.tcx.item_name(trait_def_id).to_string()); - }*/ - /*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx); - get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/ - /*if let Some(i) = self.get_auto_trait_impl_for( - def_id, - name.clone(), - generics.clone(), - def_ctor, - trait_def_id, - ) { - traits.insert(trait_name, i); - }*/ - let mut impls = Vec::new(); - ::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls); - /*if ::std::env::var("LOL").is_ok() { - println!("=> {} ::> {}", - infcx.tcx.item_name(trait_def_id).to_string(), - impls.len()); - println!("{:?}", impls); - }*/ - for impl_ in &mut impls { - if let ImplItem(ref mut i) = impl_.inner { - i.synthetic = true; - i.for_ = ty.clean(&self.cx); - //i.visibility = None; - } - //impl_.visibility = None; - if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" { - println!("**> {:?}", impl_); - } - } - //traits.insert(trait_def_id, impls); let trait_ = hir::TraitRef { path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), ref_id: ast::DUMMY_NODE_ID, @@ -198,7 +193,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { .into_iter() .map(|meth| meth.ident.to_string()) .collect(); - println!("|||> {}", t_name); traits.insert(trait_def_id, Item { source: Span::empty(), name: None, @@ -209,7 +203,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { deprecation: None, inner: ImplItem(Impl { unsafety: hir::Unsafety::Normal, - generics: (infcx.tcx.generics_of(trait_def_id), &Default::default()).clean(self.cx), + generics: (generics, + &tcx.predicates_of(impl_def_id)).clean(self.cx), provided_trait_methods, trait_: Some(trait_.clean(self.cx)), for_: ty.clean(self.cx), @@ -279,9 +274,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { "get_auto_traits: type {:?} auto_traits {:?}", def_id, auto_traits ); - if self.cx.crate_name == Some("std".to_string()) { - println!("((((((> {} {:?}", auto_traits.len(), auto_traits); - } auto_traits } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cb9cb7a3e0f..fe93dd16ffd 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -275,10 +275,6 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec {} {:?}\n", auto_impls.len(), auto_impls); - } let new_impls: Vec = auto_impls.into_iter() .filter(|i| renderinfo.inlined.insert(i.def_id)).collect(); @@ -340,9 +336,6 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec {} {:?}\n", auto_impls.len(), auto_impls); - } let mut renderinfo = cx.renderinfo.borrow_mut(); let new_impls: Vec = auto_impls.into_iter() diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 408250a259b..7b1817587af 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3584,7 +3584,6 @@ fn render_assoc_items(w: &mut fmt::Formatter, Some(v) => v, None => return Ok(()), }; - //println!("=======> {:?}", containing_item.name); let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { /*if let Some(ref t) = i.inner_impl().trait_ { println!("++++++> {:?}", t); From 3e96ac1178f2350dc35b8d601d3667c6496bf801 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 12:24:55 +0200 Subject: [PATCH 07/17] Cleanup --- src/librustdoc/clean/auto_trait.rs | 60 +----------------------------- src/librustdoc/html/render.rs | 6 --- 2 files changed, 1 insertion(+), 65 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9a6495694c5..ea25ac5c682 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -109,13 +109,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { if self.cx.crate_name != Some("core".to_string()) { if let ty::TyAdt(_adt, _) = ty.sty { let param_env = self.cx.tcx.param_env(def_id); - /*let print = match _adt.adt_kind() { - AdtKind::Struct => { - //println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string()); - true - } - _ => false, - };*/ for &trait_def_id in self.cx.all_traits.iter() { if traits.get(&trait_def_id).is_some() || !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) { @@ -125,22 +118,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { let generics = infcx.tcx.generics_of(impl_def_id); - - /*if generics.count() == 0 { - return; - }*/ let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); - /*if !trait_ref.substs.iter().any(|x| match x.unpack() { - ::rustc::ty::subst::UnpackedKind::Type(ref t) => { - match t.sty { - ::rustc::ty::TypeVariants::TyParam(_) => true, - _ => false, - } - } - _ => false, - }) { - return; - }*/ if !match infcx.tcx.type_of(impl_def_id).sty { ::rustc::ty::TypeVariants::TyParam(_) => true, @@ -169,22 +147,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { param_env, trait_ref.to_predicate(), )); - /*if print { - println!("==> {}", infcx.tcx.item_name(trait_def_id).to_string()); - }*/ if may_apply { - // FIXME: add crate's id before the name to avoid removing a - // trait which doesn't exist. if traits.get(&trait_def_id).is_none() { - if self.cx.crate_name == Some("std".to_string()) { - println!("visibility: ({} {}) [{} {:?}] [{} {:?}]", - self.cx.tcx.item_name(def_id).to_string(), t_name, - impl_def_id.krate, impl_def_id.index, - trait_def_id.krate, trait_def_id.index); - println!("{:?}", infcx.tcx.visibility(impl_def_id)); - println!("{:?}", infcx.tcx.visibility(trait_def_id)); - } - let trait_ = hir::TraitRef { path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), ref_id: ast::DUMMY_NODE_ID, @@ -213,27 +177,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { synthetic: true, }), }); - - /*use ::clean::{self, inline::*}; - - let mut ret = Vec::with_capacity(2); - record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait); - ret.extend(build_impls(self.cx, trait_def_id, false)); - let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id)); - let cx = self.cx; - ret.push(clean::Item { - source: infcx.tcx.def_span(trait_def_id).clean(cx), - name: Some(infcx.tcx.item_name(trait_def_id).to_string()), - attrs: load_attrs(cx, trait_def_id), - inner, - visibility: Some(clean::Public), - stability: cx.tcx.lookup_stability(trait_def_id).clean(cx), - deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx), - def_id: trait_def_id, - }); - traits.insert(trait_def_id, ret);*/ } - //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string()); } debug!("{:?} => {}", trait_ref, may_apply); } @@ -242,8 +186,6 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } } } - //let res = self.cx.tcx.trait_impls_of(def_id); - //println!("=> {:?} {:?}", res.blanket_impls.len(), res.non_blanket_impls.len()); debug!( "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}", @@ -267,7 +209,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) - .chain(traits.into_iter().map(|(_, v)| v))//.flat_map(|(_, v)| v.into_iter())) + .chain(traits.into_iter().map(|(_, v)| v)) .collect(); debug!( diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 7b1817587af..214f2da212e 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3585,12 +3585,6 @@ fn render_assoc_items(w: &mut fmt::Formatter, None => return Ok(()), }; let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| { - /*if let Some(ref t) = i.inner_impl().trait_ { - println!("++++++> {:?}", t); - }*/ - /*if i.inner_impl().trait_.is_some() { - println!("++++++> {:?}", i.name); - }*/ i.inner_impl().trait_.is_none() }); if !non_trait.is_empty() { From 6b830ec23e25f3e325e97fc49b0bec9a7f2a5b53 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 13:19:17 +0200 Subject: [PATCH 08/17] Add new tests and fix old ones --- src/librustdoc/clean/auto_trait.rs | 102 ++++++++++++++-------- src/test/rustdoc/generic-impl.rs | 25 ++++++ src/test/rustdoc/manual_impl.rs | 1 - src/test/rustdoc/sidebar-items.rs | 8 +- src/test/rustdoc/synthetic_auto/basic.rs | 2 +- src/test/rustdoc/synthetic_auto/manual.rs | 2 +- 6 files changed, 96 insertions(+), 44 deletions(-) create mode 100644 src/test/rustdoc/generic-impl.rs diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index ea25ac5c682..f466183bec8 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -105,16 +105,19 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let generics = self.cx.tcx.generics_of(def_id); let ty = self.cx.tcx.type_of(def_id); - let mut traits = FxHashMap(); + let mut traits = Vec::new(); if self.cx.crate_name != Some("core".to_string()) { if let ty::TyAdt(_adt, _) = ty.sty { + let real_name = name.clone().map(|name| Ident::from_str(&name)); let param_env = self.cx.tcx.param_env(def_id); for &trait_def_id in self.cx.all_traits.iter() { - if traits.get(&trait_def_id).is_some() || - !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) { + if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) || + self.cx.generated_synthetics + .borrow_mut() + .get(&(def_id, trait_def_id)) + .is_some() { continue } - let t_name = self.cx.tcx.item_name(trait_def_id).to_string(); self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { let generics = infcx.tcx.generics_of(impl_def_id); @@ -124,7 +127,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { ::rustc::ty::TypeVariants::TyParam(_) => true, _ => false, } { - return; + return } let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); @@ -147,38 +150,63 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { param_env, trait_ref.to_predicate(), )); - if may_apply { - if traits.get(&trait_def_id).is_none() { - let trait_ = hir::TraitRef { - path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), - ref_id: ast::DUMMY_NODE_ID, - }; - let provided_trait_methods = infcx.tcx.provided_trait_methods(impl_def_id) - .into_iter() - .map(|meth| meth.ident.to_string()) - .collect(); - traits.insert(trait_def_id, Item { - source: Span::empty(), - name: None, - attrs: Default::default(), - visibility: None, - def_id: self.next_def_id(impl_def_id.krate), - stability: None, - deprecation: None, - inner: ImplItem(Impl { - unsafety: hir::Unsafety::Normal, - generics: (generics, - &tcx.predicates_of(impl_def_id)).clean(self.cx), - provided_trait_methods, - trait_: Some(trait_.clean(self.cx)), - for_: ty.clean(self.cx), - items: infcx.tcx.associated_items(impl_def_id).collect::>().clean(self.cx), - polarity: None, - synthetic: true, - }), - }); - } + if !may_apply { + return } + self.cx.generated_synthetics.borrow_mut() + .insert((def_id, trait_def_id)); + let trait_ = hir::TraitRef { + path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), + ref_id: ast::DUMMY_NODE_ID, + }; + let provided_trait_methods = infcx.tcx.provided_trait_methods(impl_def_id) + .into_iter() + .map(|meth| meth.ident.to_string()) + .collect(); + + let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); + let mut segments = path.segments.into_vec(); + let last = segments.pop().unwrap(); + + segments.push(hir::PathSegment::new( + real_name.unwrap_or(last.ident), + self.generics_to_path_params(generics.clone()), + false, + )); + + let new_path = hir::Path { + span: path.span, + def: path.def, + segments: HirVec::from_vec(segments), + }; + + let ty = hir::Ty { + id: ast::DUMMY_NODE_ID, + node: hir::Ty_::TyPath(hir::QPath::Resolved(None, P(new_path))), + span: DUMMY_SP, + hir_id: hir::DUMMY_HIR_ID, + }; + + traits.push(Item { + source: Span::empty(), + name: None, + attrs: Default::default(), + visibility: None, + def_id: self.next_def_id(impl_def_id.krate), + stability: None, + deprecation: None, + inner: ImplItem(Impl { + unsafety: hir::Unsafety::Normal, + generics: (generics, + &tcx.predicates_of(impl_def_id)).clean(self.cx), + provided_trait_methods, + trait_: Some(trait_.clean(self.cx)), + for_: ty.clean(self.cx), + items: infcx.tcx.associated_items(impl_def_id).collect::>().clean(self.cx), + polarity: None, + synthetic: true, + }), + }); debug!("{:?} => {}", trait_ref, may_apply); } }); @@ -209,7 +237,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) - .chain(traits.into_iter().map(|(_, v)| v)) + .chain(traits.into_iter()) .collect(); debug!( diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs new file mode 100644 index 00000000000..68277835d2b --- /dev/null +++ b/src/test/rustdoc/generic-impl.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +use std::fmt; + +// @!has foo/struct.Bar.html 'impl ToString for Bar' +pub struct Bar; + +// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl ToString for Foo' +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Foo") + } +} diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs index befd3161ac4..54a8a764833 100644 --- a/src/test/rustdoc/manual_impl.rs +++ b/src/test/rustdoc/manual_impl.rs @@ -56,7 +56,6 @@ impl T for S1 { // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' // @!has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.' // @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.' -// @!has - '//*[@class="docblock"]' 'Read more' pub struct S2(usize); /// Docs associated with the S2 trait implementation. diff --git a/src/test/rustdoc/sidebar-items.rs b/src/test/rustdoc/sidebar-items.rs index 9be40441e9d..3ecd6b63510 100644 --- a/src/test/rustdoc/sidebar-items.rs +++ b/src/test/rustdoc/sidebar-items.rs @@ -31,11 +31,11 @@ pub trait Foo { // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u' -// @!has - '//*[@class="sidebar-links"]/a' 'w' +// @!has - '//*[@class="sidebar-links"]/a' 'waza' pub struct Bar { pub f: u32, pub u: u32, - w: u32, + waza: u32, } // @has foo/enum.En.html @@ -51,9 +51,9 @@ pub enum En { // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2' -// @!has - '//*[@class="sidebar-links"]/a' 'w' +// @!has - '//*[@class="sidebar-links"]/a' 'waza' pub union MyUnion { pub f1: u32, pub f2: f32, - w: u32, + waza: u32, } diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs index 8ff84d11a50..200747bf6cd 100644 --- a/src/test/rustdoc/synthetic_auto/basic.rs +++ b/src/test/rustdoc/synthetic_auto/basic.rs @@ -12,7 +12,7 @@ // @has - '//code' 'impl Send for Foo where T: Send' // @has - '//code' 'impl Sync for Foo where T: Sync' // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 11 pub struct Foo { field: T, } diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index ef6797ecf3c..461b922e28e 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -16,7 +16,7 @@ // 'impl Send for Foo' // // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 1 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 10 pub struct Foo { field: T, } From d64c2ac01a831d9936d155fd38eaa53ffe672893 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 13:35:29 +0200 Subject: [PATCH 09/17] Improve code --- src/librustdoc/clean/auto_trait.rs | 97 ++++++++++------------- src/librustdoc/html/render.rs | 11 +-- src/test/rustdoc/generic-impl.rs | 2 +- src/test/rustdoc/synthetic_auto/basic.rs | 2 +- src/test/rustdoc/synthetic_auto/manual.rs | 2 +- 5 files changed, 47 insertions(+), 67 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index f466183bec8..a4f9444e355 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -10,7 +10,7 @@ use rustc::hir; use rustc::traits::{self, auto_trait as auto}; -use rustc::ty::{ToPredicate, TypeFoldable}; +use rustc::ty::{self, ToPredicate, TypeFoldable}; use rustc::ty::subst::Subst; use rustc::infer::InferOk; use std::fmt::Debug; @@ -80,6 +80,33 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { self.get_auto_trait_impls(did, &def_ctor, Some(name)) } + fn get_real_ty(&self, def_id: DefId, def_ctor: &F, real_name: &Option, + generics: &ty::Generics) -> hir::Ty + where F: Fn(DefId) -> Def { + let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); + let mut segments = path.segments.into_vec(); + let last = segments.pop().unwrap(); + + segments.push(hir::PathSegment::new( + real_name.unwrap_or(last.ident), + self.generics_to_path_params(generics.clone()), + false, + )); + + let new_path = hir::Path { + span: path.span, + def: path.def, + segments: HirVec::from_vec(segments), + }; + + hir::Ty { + id: ast::DUMMY_NODE_ID, + node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))), + span: DUMMY_SP, + hir_id: hir::DUMMY_HIR_ID, + } + } + pub fn get_auto_trait_impls( &self, def_id: DefId, @@ -140,7 +167,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. let cause = traits::ObligationCause::dummy(); - let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2); + let eq_result = infcx.at(&cause, param_env) + .eq(trait_ref.self_ty(), ty2); if let Ok(InferOk { value: (), obligations }) = eq_result { // FIXME(eddyb) ignoring `obligations` might cause false positives. drop(obligations); @@ -156,36 +184,18 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { self.cx.generated_synthetics.borrow_mut() .insert((def_id, trait_def_id)); let trait_ = hir::TraitRef { - path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait), + path: get_path_for_type(infcx.tcx, + trait_def_id, + hir::def::Def::Trait), ref_id: ast::DUMMY_NODE_ID, }; - let provided_trait_methods = infcx.tcx.provided_trait_methods(impl_def_id) - .into_iter() - .map(|meth| meth.ident.to_string()) - .collect(); + let provided_trait_methods = + infcx.tcx.provided_trait_methods(impl_def_id) + .into_iter() + .map(|meth| meth.ident.to_string()) + .collect(); - let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); - let mut segments = path.segments.into_vec(); - let last = segments.pop().unwrap(); - - segments.push(hir::PathSegment::new( - real_name.unwrap_or(last.ident), - self.generics_to_path_params(generics.clone()), - false, - )); - - let new_path = hir::Path { - span: path.span, - def: path.def, - segments: HirVec::from_vec(segments), - }; - - let ty = hir::Ty { - id: ast::DUMMY_NODE_ID, - node: hir::Ty_::TyPath(hir::QPath::Resolved(None, P(new_path))), - span: DUMMY_SP, - hir_id: hir::DUMMY_HIR_ID, - }; + let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); traits.push(Item { source: Span::empty(), @@ -202,7 +212,9 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { provided_trait_methods, trait_: Some(trait_.clean(self.cx)), for_: ty.clean(self.cx), - items: infcx.tcx.associated_items(impl_def_id).collect::>().clean(self.cx), + items: infcx.tcx.associated_items(impl_def_id) + .collect::>() + .clean(self.cx), polarity: None, synthetic: true, }), @@ -312,31 +324,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } _ => unreachable!(), }; - - let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); - let mut segments = path.segments.into_vec(); - let last = segments.pop().unwrap(); - let real_name = name.map(|name| Ident::from_str(&name)); - - segments.push(hir::PathSegment::new( - real_name.unwrap_or(last.ident), - self.generics_to_path_params(generics.clone()), - false, - )); - - let new_path = hir::Path { - span: path.span, - def: path.def, - segments: HirVec::from_vec(segments), - }; - - let ty = hir::Ty { - id: ast::DUMMY_NODE_ID, - node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))), - span: DUMMY_SP, - hir_id: hir::DUMMY_HIR_ID, - }; + let ty = self.get_real_ty(def_id, def_ctor, &real_name, &generics); return Some(Item { source: Span::empty(), diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 214f2da212e..fd39202b87c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3628,16 +3628,7 @@ fn render_assoc_items(w: &mut fmt::Formatter, let (synthetic, concrete) = traits .iter() - .partition::, _>(|t| t.inner_impl().synthetic); - - // ugly hacks to remove duplicates. - let synthetic = synthetic.into_iter() - .filter(|t| { - !concrete.iter() - .any(|tt| { - tt.inner_impl().trait_.def_id() == t.inner_impl().trait_.def_id() - }) - }).collect::>(); + .partition::, _>(|t| t.inner_impl().synthetic); struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item); diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs index 68277835d2b..e69a3277d7f 100644 --- a/src/test/rustdoc/generic-impl.rs +++ b/src/test/rustdoc/generic-impl.rs @@ -12,7 +12,7 @@ use std::fmt; -// @!has foo/struct.Bar.html 'impl ToString for Bar' +// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl ToString for Bar' pub struct Bar; // @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl ToString for Foo' diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs index 200747bf6cd..f9a6c2607cd 100644 --- a/src/test/rustdoc/synthetic_auto/basic.rs +++ b/src/test/rustdoc/synthetic_auto/basic.rs @@ -12,7 +12,7 @@ // @has - '//code' 'impl Send for Foo where T: Send' // @has - '//code' 'impl Sync for Foo where T: Sync' // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 11 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 9 pub struct Foo { field: T, } diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index 461b922e28e..8c7f9d8cc65 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -16,7 +16,7 @@ // 'impl Send for Foo' // // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 10 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 8 pub struct Foo { field: T, } From 8fa6e3fa761ef9092ab5faf3e0ff1650798e2e53 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 22:45:51 +0200 Subject: [PATCH 10/17] Prevent some items to get generic impls listed --- src/librustdoc/clean/auto_trait.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a4f9444e355..1fcedb3b5d2 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -114,7 +114,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { - if self.cx + if !self.cx.access_levels.borrow().is_doc_reachable(def_id) || + self.cx .tcx .get_attrs(def_id) .lists("doc") From bcb5c6fe5fed032fd8ef6b2308a7ff61b1eeca71 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 21 Jul 2018 23:14:37 +0200 Subject: [PATCH 11/17] Fix urls --- src/librustdoc/clean/auto_trait.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 1fcedb3b5d2..4246c8b555a 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -114,8 +114,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { name: Option, ) -> Vec where F: Fn(DefId) -> Def { - if !self.cx.access_levels.borrow().is_doc_reachable(def_id) || - self.cx + if self.cx .tcx .get_attrs(def_id) .lists("doc") @@ -134,7 +133,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let ty = self.cx.tcx.type_of(def_id); let mut traits = Vec::new(); - if self.cx.crate_name != Some("core".to_string()) { + if self.cx.crate_name != Some("core".to_string()) && + self.cx.access_levels.borrow().is_doc_reachable(def_id) { if let ty::TyAdt(_adt, _) = ty.sty { let real_name = name.clone().map(|name| Ident::from_str(&name)); let param_env = self.cx.tcx.param_env(def_id); @@ -191,7 +191,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { ref_id: ast::DUMMY_NODE_ID, }; let provided_trait_methods = - infcx.tcx.provided_trait_methods(impl_def_id) + infcx.tcx.provided_trait_methods(trait_def_id) .into_iter() .map(|meth| meth.ident.to_string()) .collect(); From 459550b5376a98d69313cf4b984a2527a92dbb94 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 23 Jul 2018 00:02:31 +0200 Subject: [PATCH 12/17] Fix style issues --- src/librustdoc/clean/auto_trait.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 4246c8b555a..d1ec7856e61 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -80,8 +80,12 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { self.get_auto_trait_impls(did, &def_ctor, Some(name)) } - fn get_real_ty(&self, def_id: DefId, def_ctor: &F, real_name: &Option, - generics: &ty::Generics) -> hir::Ty + fn get_real_ty(&self, + def_id: DefId, + def_ctor: &F, + real_name: &Option, + generics: &ty::Generics, + ) -> hir::Ty where F: Fn(DefId) -> Def { let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); let mut segments = path.segments.into_vec(); @@ -151,11 +155,9 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let generics = infcx.tcx.generics_of(impl_def_id); let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); - if !match infcx.tcx.type_of(impl_def_id).sty { - ::rustc::ty::TypeVariants::TyParam(_) => true, - _ => false, - } { - return + match infcx.tcx.type_of(impl_def_id).sty { + ::rustc::ty::TypeVariants::TyParam(_) => {}, + _ => return, } let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); From 6eb0b05017267c063df08c74dc221cf761ab75cd Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Jul 2018 00:07:22 +0200 Subject: [PATCH 13/17] Add src and fix generics display issues --- src/librustdoc/clean/auto_trait.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index d1ec7856e61..86511c66de0 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -152,7 +152,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { self.cx.tcx.infer_ctxt().enter(|infcx| { - let generics = infcx.tcx.generics_of(impl_def_id); + let t_generics = infcx.tcx.generics_of(impl_def_id); let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); match infcx.tcx.type_of(impl_def_id).sty { @@ -161,7 +161,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); - let ty2 = ty.subst(infcx.tcx, substs); + let ty = ty.subst(infcx.tcx, substs); let param_env = param_env.subst(infcx.tcx, substs); let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); @@ -171,7 +171,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // our type, and ignore the impl if there was a mismatch. let cause = traits::ObligationCause::dummy(); let eq_result = infcx.at(&cause, param_env) - .eq(trait_ref.self_ty(), ty2); + .eq(trait_ref.self_ty(), ty); if let Ok(InferOk { value: (), obligations }) = eq_result { // FIXME(eddyb) ignoring `obligations` might cause false positives. drop(obligations); @@ -199,9 +199,10 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { .collect(); let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); + let predicates = infcx.tcx.predicates_of(def_id); traits.push(Item { - source: Span::empty(), + source: infcx.tcx.def_span(impl_def_id).clean(self.cx), name: None, attrs: Default::default(), visibility: None, @@ -210,8 +211,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { deprecation: None, inner: ImplItem(Impl { unsafety: hir::Unsafety::Normal, - generics: (generics, - &tcx.predicates_of(impl_def_id)).clean(self.cx), + generics: (t_generics, &predicates).clean(self.cx), provided_trait_methods, trait_: Some(trait_.clean(self.cx)), for_: ty.clean(self.cx), From ef7d6fcbd1b06c85aa1241cb872bbe0f427caccf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 24 Jul 2018 00:23:03 +0200 Subject: [PATCH 14/17] Remove generic-impl rendering filter --- src/librustdoc/clean/auto_trait.rs | 172 ++++++++++++++--------------- 1 file changed, 85 insertions(+), 87 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 86511c66de0..556d8462d3b 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -139,94 +139,92 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let mut traits = Vec::new(); if self.cx.crate_name != Some("core".to_string()) && self.cx.access_levels.borrow().is_doc_reachable(def_id) { - if let ty::TyAdt(_adt, _) = ty.sty { - let real_name = name.clone().map(|name| Ident::from_str(&name)); - let param_env = self.cx.tcx.param_env(def_id); - for &trait_def_id in self.cx.all_traits.iter() { - if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) || - self.cx.generated_synthetics - .borrow_mut() - .get(&(def_id, trait_def_id)) - .is_some() { - continue - } - self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { - self.cx.tcx.infer_ctxt().enter(|infcx| { - let t_generics = infcx.tcx.generics_of(impl_def_id); - let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); - - match infcx.tcx.type_of(impl_def_id).sty { - ::rustc::ty::TypeVariants::TyParam(_) => {}, - _ => return, - } - - let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); - let ty = ty.subst(infcx.tcx, substs); - let param_env = param_env.subst(infcx.tcx, substs); - - let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); - let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); - - // Require the type the impl is implemented on to match - // our type, and ignore the impl if there was a mismatch. - let cause = traits::ObligationCause::dummy(); - let eq_result = infcx.at(&cause, param_env) - .eq(trait_ref.self_ty(), ty); - if let Ok(InferOk { value: (), obligations }) = eq_result { - // FIXME(eddyb) ignoring `obligations` might cause false positives. - drop(obligations); - - let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( - cause.clone(), - param_env, - trait_ref.to_predicate(), - )); - if !may_apply { - return - } - self.cx.generated_synthetics.borrow_mut() - .insert((def_id, trait_def_id)); - let trait_ = hir::TraitRef { - path: get_path_for_type(infcx.tcx, - trait_def_id, - hir::def::Def::Trait), - ref_id: ast::DUMMY_NODE_ID, - }; - let provided_trait_methods = - infcx.tcx.provided_trait_methods(trait_def_id) - .into_iter() - .map(|meth| meth.ident.to_string()) - .collect(); - - let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); - let predicates = infcx.tcx.predicates_of(def_id); - - traits.push(Item { - source: infcx.tcx.def_span(impl_def_id).clean(self.cx), - name: None, - attrs: Default::default(), - visibility: None, - def_id: self.next_def_id(impl_def_id.krate), - stability: None, - deprecation: None, - inner: ImplItem(Impl { - unsafety: hir::Unsafety::Normal, - generics: (t_generics, &predicates).clean(self.cx), - provided_trait_methods, - trait_: Some(trait_.clean(self.cx)), - for_: ty.clean(self.cx), - items: infcx.tcx.associated_items(impl_def_id) - .collect::>() - .clean(self.cx), - polarity: None, - synthetic: true, - }), - }); - debug!("{:?} => {}", trait_ref, may_apply); - } - }); - }); + let real_name = name.clone().map(|name| Ident::from_str(&name)); + let param_env = self.cx.tcx.param_env(def_id); + for &trait_def_id in self.cx.all_traits.iter() { + if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) || + self.cx.generated_synthetics + .borrow_mut() + .get(&(def_id, trait_def_id)) + .is_some() { + continue } + self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { + self.cx.tcx.infer_ctxt().enter(|infcx| { + let t_generics = infcx.tcx.generics_of(impl_def_id); + let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); + + match infcx.tcx.type_of(impl_def_id).sty { + ::rustc::ty::TypeVariants::TyParam(_) => {}, + _ => return, + } + + let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); + let ty = ty.subst(infcx.tcx, substs); + let param_env = param_env.subst(infcx.tcx, substs); + + let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = infcx.at(&cause, param_env) + .eq(trait_ref.self_ty(), ty); + if let Ok(InferOk { value: (), obligations }) = eq_result { + // FIXME(eddyb) ignoring `obligations` might cause false positives. + drop(obligations); + + let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( + cause.clone(), + param_env, + trait_ref.to_predicate(), + )); + if !may_apply { + return + } + self.cx.generated_synthetics.borrow_mut() + .insert((def_id, trait_def_id)); + let trait_ = hir::TraitRef { + path: get_path_for_type(infcx.tcx, + trait_def_id, + hir::def::Def::Trait), + ref_id: ast::DUMMY_NODE_ID, + }; + let provided_trait_methods = + infcx.tcx.provided_trait_methods(trait_def_id) + .into_iter() + .map(|meth| meth.ident.to_string()) + .collect(); + + let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); + let predicates = infcx.tcx.predicates_of(def_id); + + traits.push(Item { + source: infcx.tcx.def_span(impl_def_id).clean(self.cx), + name: None, + attrs: Default::default(), + visibility: None, + def_id: self.next_def_id(impl_def_id.krate), + stability: None, + deprecation: None, + inner: ImplItem(Impl { + unsafety: hir::Unsafety::Normal, + generics: (t_generics, &predicates).clean(self.cx), + provided_trait_methods, + trait_: Some(trait_.clean(self.cx)), + for_: ty.clean(self.cx), + items: infcx.tcx.associated_items(impl_def_id) + .collect::>() + .clean(self.cx), + polarity: None, + synthetic: true, + }), + }); + debug!("{:?} => {}", trait_ref, may_apply); + } + }); + }); } } From 7a3c7b2097961138a92a771145dba7012f5c70f8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Jul 2018 22:59:16 +0200 Subject: [PATCH 15/17] Don't display full blanket implementation and put it into its own section --- src/librustdoc/clean/auto_trait.rs | 7 ++- src/librustdoc/clean/inline.rs | 1 + src/librustdoc/clean/mod.rs | 2 + src/librustdoc/html/format.rs | 6 ++- src/librustdoc/html/render.rs | 59 ++++++++++++++++------- src/test/rustdoc/generic-impl.rs | 4 +- src/test/rustdoc/synthetic_auto/basic.rs | 2 +- src/test/rustdoc/synthetic_auto/manual.rs | 2 +- 8 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 556d8462d3b..d0d5713ec0a 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -198,7 +198,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { .collect(); let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); - let predicates = infcx.tcx.predicates_of(def_id); + let predicates = infcx.tcx.predicates_of(impl_def_id); traits.push(Item { source: infcx.tcx.def_span(impl_def_id).clean(self.cx), @@ -218,7 +218,9 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { .collect::>() .clean(self.cx), polarity: None, - synthetic: true, + synthetic: false, + blanket_impl: Some(infcx.tcx.type_of(impl_def_id) + .clean(self.cx)), }), }); debug!("{:?} => {}", trait_ref, may_apply); @@ -345,6 +347,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { items: Vec::new(), polarity, synthetic: true, + blanket_impl: None, }), }); } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fe93dd16ffd..9245ef3cf50 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -414,6 +414,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec) { items: trait_items, polarity: Some(polarity.clean(cx)), synthetic: false, + blanket_impl: None, }), source: tcx.def_span(did).clean(cx), name: None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 68842522223..89f328016ec 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3881,6 +3881,7 @@ pub struct Impl { pub items: Vec, pub polarity: Option, pub synthetic: bool, + pub blanket_impl: Option, } pub fn get_auto_traits_with_node_id(cx: &DocContext, id: ast::NodeId, name: String) -> Vec { @@ -3948,6 +3949,7 @@ impl Clean> for doctree::Impl { items, polarity: Some(self.polarity.clean(cx)), synthetic: false, + blanket_impl: None, }) }); ret diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 2377354b85f..9c7354a7c63 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -769,7 +769,11 @@ fn fmt_impl(i: &clean::Impl, write!(f, " for ")?; } - fmt_type(&i.for_, f, use_absolute)?; + if let Some(ref ty) = i.blanket_impl { + fmt_type(ty, f, use_absolute)?; + } else { + fmt_type(&i.for_, f, use_absolute)?; + } fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?; Ok(()) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index fd39202b87c..200c961cf5d 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -177,7 +177,7 @@ pub enum ExternalLocation { } /// Metadata about implementations for a type or trait. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Impl { pub impl_item: clean::Item, } @@ -2900,18 +2900,18 @@ fn item_trait( render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?; let cache = cache(); - let impl_header = " -

- Implementors -

-
    + let impl_header = "\ +

    \ + Implementors\ +

    \ +
      \ "; - let synthetic_impl_header = " -

      - Auto implementors -

      -
        + let synthetic_impl_header = "\ +

        \ + Auto implementors\ +

        \ +
          \ "; let mut synthetic_types = Vec::new(); @@ -2942,9 +2942,9 @@ fn item_trait( .map_or(true, |d| cache.paths.contains_key(&d))); - let (synthetic, concrete) = local.iter() - .partition::, _>(|i| i.inner_impl().synthetic); - + let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter() + .filter(|i| i.inner_impl().blanket_impl.is_none()) + .partition(|i| i.inner_impl().synthetic); if !foreign.is_empty() { write!(w, " @@ -3626,9 +3626,12 @@ fn render_assoc_items(w: &mut fmt::Formatter, render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?; } - let (synthetic, concrete) = traits + let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits .iter() - .partition::, _>(|t| t.inner_impl().synthetic); + .partition(|t| t.inner_impl().synthetic); + let (blanket_impl, concrete) = concrete + .into_iter() + .partition(|t| t.inner_impl().blanket_impl.is_some()); struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item); @@ -3658,6 +3661,18 @@ fn render_assoc_items(w: &mut fmt::Formatter, render_impls(cx, w, &synthetic, containing_item)?; write!(w, "
")?; } + + if !blanket_impl.is_empty() { + write!(w, "\ +

\ + Blanket Implementations\ + \ +

\ +
\ + ")?; + render_impls(cx, w, &blanket_impl, containing_item)?; + write!(w, "
")?; + } } Ok(()) } @@ -4203,12 +4218,16 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .collect::() }; - let (synthetic, concrete) = v + let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v .iter() .partition::, _>(|i| i.inner_impl().synthetic); + let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete + .into_iter() + .partition::, _>(|i| i.inner_impl().blanket_impl.is_some()); let concrete_format = format_impls(concrete); let synthetic_format = format_impls(synthetic); + let blanket_format = format_impls(blanket_impl); if !concrete_format.is_empty() { out.push_str("\ @@ -4221,6 +4240,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { Auto Trait Implementations"); out.push_str(&format!("
{}
", synthetic_format)); } + + if !blanket_format.is_empty() { + out.push_str("\ + Blanket Implementations"); + out.push_str(&format!("
{}
", blanket_format)); + } } } diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs index e69a3277d7f..e2665fd8f37 100644 --- a/src/test/rustdoc/generic-impl.rs +++ b/src/test/rustdoc/generic-impl.rs @@ -12,10 +12,10 @@ use std::fmt; -// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl ToString for Bar' +// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl ToString for T' pub struct Bar; -// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl ToString for Foo' +// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl ToString for T' pub struct Foo; impl fmt::Display for Foo { diff --git a/src/test/rustdoc/synthetic_auto/basic.rs b/src/test/rustdoc/synthetic_auto/basic.rs index f9a6c2607cd..8ff84d11a50 100644 --- a/src/test/rustdoc/synthetic_auto/basic.rs +++ b/src/test/rustdoc/synthetic_auto/basic.rs @@ -12,7 +12,7 @@ // @has - '//code' 'impl Send for Foo where T: Send' // @has - '//code' 'impl Sync for Foo where T: Sync' // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 9 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2 pub struct Foo { field: T, } diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index 8c7f9d8cc65..ef6797ecf3c 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -16,7 +16,7 @@ // 'impl Send for Foo' // // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1 -// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 8 +// @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 1 pub struct Foo { field: T, } From bdbb5b946958045e9f3a51224a029637ab1bb087 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 28 Jul 2018 19:06:25 +0200 Subject: [PATCH 16/17] Remove core exclusion condition --- src/librustdoc/clean/auto_trait.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index d0d5713ec0a..425dee8e3d1 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -137,8 +137,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { let ty = self.cx.tcx.type_of(def_id); let mut traits = Vec::new(); - if self.cx.crate_name != Some("core".to_string()) && - self.cx.access_levels.borrow().is_doc_reachable(def_id) { + if self.cx.access_levels.borrow().is_doc_reachable(def_id) { let real_name = name.clone().map(|name| Ident::from_str(&name)); let param_env = self.cx.tcx.param_env(def_id); for &trait_def_id in self.cx.all_traits.iter() { @@ -234,17 +233,18 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}", def_id, generics ); - let auto_traits: Vec<_> = - self.cx.send_trait - .and_then(|send_trait| { - self.get_auto_trait_impl_for( - def_id, - name.clone(), - generics.clone(), - def_ctor, - send_trait, - ) - }).into_iter() + let auto_traits: Vec<_> = self.cx + .send_trait + .and_then(|send_trait| { + self.get_auto_trait_impl_for( + def_id, + name.clone(), + generics.clone(), + def_ctor, + send_trait, + ) + }) + .into_iter() .chain(self.get_auto_trait_impl_for( def_id, name.clone(), From 06364bd46019bc598d5c8eb16ae1481d57827530 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 28 Jul 2018 20:27:10 +0200 Subject: [PATCH 17/17] Move blanket implementations generation into its own function --- src/librustdoc/clean/auto_trait.rs | 48 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 425dee8e3d1..c30d6817b46 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -111,30 +111,14 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } } - pub fn get_auto_trait_impls( + pub fn get_blanket_impls( &self, def_id: DefId, def_ctor: &F, name: Option, + generics: &ty::Generics, ) -> Vec where F: Fn(DefId) -> Def { - if self.cx - .tcx - .get_attrs(def_id) - .lists("doc") - .has_word("hidden") - { - debug!( - "get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \ - aborting", - def_id - ); - return Vec::new(); - } - - let tcx = self.cx.tcx; - let generics = self.cx.tcx.generics_of(def_id); - let ty = self.cx.tcx.type_of(def_id); let mut traits = Vec::new(); if self.cx.access_levels.borrow().is_doc_reachable(def_id) { @@ -228,6 +212,32 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { }); } } + traits + } + + pub fn get_auto_trait_impls( + &self, + def_id: DefId, + def_ctor: &F, + name: Option, + ) -> Vec + where F: Fn(DefId) -> Def { + if self.cx + .tcx + .get_attrs(def_id) + .lists("doc") + .has_word("hidden") + { + debug!( + "get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \ + aborting", + def_id + ); + return Vec::new(); + } + + let tcx = self.cx.tcx; + let generics = self.cx.tcx.generics_of(def_id); debug!( "get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}", @@ -252,7 +262,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) - .chain(traits.into_iter()) + .chain(self.get_blanket_impls(def_id, def_ctor, name, &generics).into_iter()) .collect(); debug!(