]> git.lizzy.rs Git - rust.git/commitdiff
Working generic impl
authorGuillaume Gomez <guillaume1.gomez@gmail.com>
Fri, 20 Jul 2018 22:15:08 +0000 (00:15 +0200)
committerGuillaume Gomez <guillaume1.gomez@gmail.com>
Sun, 22 Jul 2018 19:02:23 +0000 (21:02 +0200)
src/librustdoc/clean/auto_trait.rs
src/librustdoc/clean/inline.rs
src/librustdoc/core.rs
src/librustdoc/html/render.rs

index faa41c53d7360618437805a627683e1346623e43..9203398dcb357e7c67b55ba9ec1231459b8b7c37 100644 (file)
@@ -85,133 +85,186 @@ pub fn get_auto_trait_impls<F>(
         name: Option<String>,
     ) -> Vec<Item>
     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 = 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);
+        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::<Vec<_>>().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);*/
                                     }
-                                    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());
                                 }
-                                //println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string());
+                                debug!("{:?} => {}", trait_ref, may_apply);
                             }
-                            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)
-            .lists("doc")
-            .has_word("hidden")
-        {
-            debug!(
-                "get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
-                 aborting",
-                def_id
-            );
-            return Vec::new();
-        }
 
         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 @@ pub fn get_auto_trait_impls<F>(
                 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
     }
 
index 0117e4fde842d412fd5c2bdeca3c5d74751622c4..cb9cb7a3e0f480aae06d3d376937df71cb6aa466 100644 (file)
@@ -276,6 +276,9 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
         let auto_impls = get_auto_traits_with_def_id(cx, did);
         let mut renderinfo = cx.renderinfo.borrow_mut();
 
+        if cx.crate_name == Some("std".to_string()) {
+            println!("=====> {} {:?}\n", auto_impls.len(), auto_impls);
+        }
         let new_impls: Vec<clean::Item> = 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<clean:
             build_impl(cx, def_id, &mut impls);
 
             let auto_impls = get_auto_traits_with_def_id(cx, def_id);
+            if cx.crate_name == Some("std".to_string()) {
+                println!("-----> {} {:?}\n", auto_impls.len(), auto_impls);
+            }
             let mut renderinfo = cx.renderinfo.borrow_mut();
 
             let new_impls: Vec<clean::Item> = auto_impls.into_iter()
index ac7dcc1306181b5b20c7057a0abf125761d904ca..d893ec415e8c7b7425d1059cb3ec79139f5e3606 100644 (file)
@@ -84,7 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     /// Maps (type_id, trait_id) -> auto trait impl
     pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>,
     pub current_item_name: RefCell<Option<Name>>,
-    pub all_traits: Lrc<Vec<DefId>>,
+    pub all_traits: Vec<DefId>,
 }
 
 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());
 
index 5dc91882b5c9ae3019b833ac1685ecc2d0e46179..408250a259b276a139313750b8d302c329bdf54f 100644 (file)
@@ -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, "
-                    <h2 id='methods' class='small-section-header'>
-                      Methods<a href='#methods' class='anchor'></a>
-                    </h2>
+                write!(w, "\
+                    <h2 id='methods' class='small-section-header'>\
+                      Methods<a href='#methods' class='anchor'></a>\
+                    </h2>\
                 ")?;
                 RenderMode::Normal
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
-                write!(w, "
-                    <h2 id='deref-methods' class='small-section-header'>
-                      Methods from {}&lt;Target = {}&gt;<a href='#deref-methods' class='anchor'></a>
-                    </h2>
+                write!(w, "\
+                    <h2 id='deref-methods' class='small-section-header'>\
+                      Methods from {}&lt;Target = {}&gt;\
+                      <a href='#deref-methods' class='anchor'></a>\
+                    </h2>\
                 ", trait_, type_)?;
                 RenderMode::ForDeref { mut_: deref_mut_ }
             }
@@ -3653,19 +3656,20 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
         let impls = format!("{}", RendererStruct(cx, concrete, containing_item));
         if !impls.is_empty() {
-            write!(w, "
-                <h2 id='implementations' class='small-section-header'>
-                  Trait Implementations<a href='#implementations' class='anchor'></a>
-                </h2>
+            write!(w, "\
+                <h2 id='implementations' class='small-section-header'>\
+                  Trait Implementations<a href='#implementations' class='anchor'></a>\
+                </h2>\
                 <div id='implementations-list'>{}</div>", impls)?;
         }
 
         if !synthetic.is_empty() {
-            write!(w, "
-                <h2 id='synthetic-implementations' class='small-section-header'>
-                  Auto Trait Implementations<a href='#synthetic-implementations' class='anchor'></a>
-                </h2>
-                <div id='synthetic-implementations-list'>
+            write!(w, "\
+                <h2 id='synthetic-implementations' class='small-section-header'>\
+                  Auto Trait Implementations\
+                  <a href='#synthetic-implementations' class='anchor'></a>\
+                </h2>\
+                <div id='synthetic-implementations-list'>\
             ")?;
             render_impls(cx, w, &synthetic, containing_item)?;
             write!(w, "</div>")?;