diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index faa41c53d736..9203398dcb35 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 0117e4fde842..cb9cb7a3e0f4 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 ac7dcc130618..d893ec415e8c 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 5dc91882b5c9..408250a259b2 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, "
")?;