Skip to content

Commit e8cca55

Browse files
Working generic impl
1 parent 73cb823 commit e8cca55

File tree

4 files changed

+198
-137
lines changed

4 files changed

+198
-137
lines changed

src/librustdoc/clean/auto_trait.rs

Lines changed: 165 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -85,152 +85,203 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
8585
name: Option<String>,
8686
) -> Vec<Item>
8787
where F: Fn(DefId) -> Def {
88+
if self.cx
89+
.tcx
90+
.get_attrs(def_id)
91+
.lists("doc")
92+
.has_word("hidden")
93+
{
94+
debug!(
95+
"get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
96+
aborting",
97+
def_id
98+
);
99+
return Vec::new();
100+
}
101+
88102
let tcx = self.cx.tcx;
89103
let generics = self.cx.tcx.generics_of(def_id);
90104

91105
let ty = self.cx.tcx.type_of(def_id);
92106
let mut traits = FxHashMap();
93-
if let ty::TyAdt(_adt, _) = ty.sty {
94-
let param_env = self.cx.tcx.param_env(def_id);
95-
match _adt.adt_kind() {
96-
AdtKind::Struct => println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string()),
97-
_ => {}
98-
}
99-
for &trait_def_id in self.cx.all_traits.iter() {
100-
self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
101-
self.cx.tcx.infer_ctxt().enter(|infcx| {
102-
let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap();
103-
let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id);
104-
let ty2 = ty.subst(infcx.tcx, substs);
105-
let param_env = param_env.subst(infcx.tcx, substs);
106-
107-
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
108-
let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
109-
110-
// Require the type the impl is implemented on to match
111-
// our type, and ignore the impl if there was a mismatch.
112-
let cause = traits::ObligationCause::dummy();
113-
let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2);
114-
if let Ok(InferOk { value: (), obligations }) = eq_result {
115-
// FIXME(eddyb) ignoring `obligations` might cause false positives.
116-
drop(obligations);
117-
118-
let may_apply = infcx.predicate_may_hold(&traits::Obligation::new(
119-
cause.clone(),
120-
param_env,
121-
trait_ref.to_predicate(),
122-
));
123-
if may_apply {
124-
// FIXME: add crate's id before the name to avoid removing a
125-
// trait which doesn't exist.
126-
if traits.get(&trait_def_id).is_none() {
127-
println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string());
128-
/*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx);
129-
get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/
130-
/*if let Some(i) = self.get_auto_trait_impl_for(
131-
def_id,
132-
name.clone(),
133-
generics.clone(),
134-
def_ctor,
135-
trait_def_id,
136-
) {
137-
traits.insert(trait_name, i);
138-
}*/
139-
140-
let mut impls = Vec::new();
141-
::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls);
142-
/*if ::std::env::var("LOL").is_ok() {
143-
println!("=> {} ::> {}",
144-
infcx.tcx.item_name(trait_def_id).to_string(),
145-
impls.len());
146-
println!("{:?}", impls);
147-
}*/
148-
for impl_ in &mut impls {
149-
if let ImplItem(ref mut i) = impl_.inner {
150-
i.synthetic = true;
151-
i.for_ = ty.clean(&self.cx);
107+
if self.cx.crate_name != Some("core".to_string()) {
108+
if let ty::TyAdt(_adt, _) = ty.sty {
109+
let param_env = self.cx.tcx.param_env(def_id);
110+
/*let print = match _adt.adt_kind() {
111+
AdtKind::Struct => {
112+
//println!("|||||> {}", self.cx.tcx.item_name(def_id).to_string());
113+
true
114+
}
115+
_ => false,
116+
};*/
117+
for &trait_def_id in self.cx.all_traits.iter() {
118+
if traits.get(&trait_def_id).is_some() {
119+
continue
120+
}
121+
let t_name = self.cx.tcx.item_name(trait_def_id).to_string();
122+
self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
123+
self.cx.tcx.infer_ctxt().enter(|infcx| {
124+
let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap();
125+
let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id);
126+
let ty2 = ty.subst(infcx.tcx, substs);
127+
let param_env = param_env.subst(infcx.tcx, substs);
128+
129+
let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
130+
let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
131+
132+
// Require the type the impl is implemented on to match
133+
// our type, and ignore the impl if there was a mismatch.
134+
let cause = traits::ObligationCause::dummy();
135+
let eq_result = infcx.at(&cause, param_env).eq(trait_ref.self_ty(), ty2);
136+
if let Ok(InferOk { value: (), obligations }) = eq_result {
137+
// FIXME(eddyb) ignoring `obligations` might cause false positives.
138+
drop(obligations);
139+
140+
let may_apply = infcx.predicate_may_hold(&traits::Obligation::new(
141+
cause.clone(),
142+
param_env,
143+
trait_ref.to_predicate(),
144+
));
145+
/*if print {
146+
println!("==> {}", infcx.tcx.item_name(trait_def_id).to_string());
147+
}*/
148+
if may_apply {
149+
if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" {
150+
println!("may_apply: {:?}", t_name);
151+
}
152+
// FIXME: add crate's id before the name to avoid removing a
153+
// trait which doesn't exist.
154+
if traits.get(&trait_def_id).is_none() {
155+
if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" {
156+
println!("in!");
157+
}
158+
/*if print {
159+
println!("> {}", infcx.tcx.item_name(trait_def_id).to_string());
160+
}*/
161+
/*let generics = (infcx.tcx.generics_of(trait_def_id), &predicates).clean(cx);
162+
get_path_for_type(self.cx.tcx, trait_def_id, hir::def::Def::Trait)*/
163+
/*if let Some(i) = self.get_auto_trait_impl_for(
164+
def_id,
165+
name.clone(),
166+
generics.clone(),
167+
def_ctor,
168+
trait_def_id,
169+
) {
170+
traits.insert(trait_name, i);
171+
}*/
172+
173+
let mut impls = Vec::new();
174+
::clean::inline::build_impl(&self.cx, impl_def_id, &mut impls);
175+
/*if ::std::env::var("LOL").is_ok() {
176+
println!("=> {} ::> {}",
177+
infcx.tcx.item_name(trait_def_id).to_string(),
178+
impls.len());
179+
println!("{:?}", impls);
180+
}*/
181+
for impl_ in &mut impls {
182+
if let ImplItem(ref mut i) = impl_.inner {
183+
i.synthetic = true;
184+
i.for_ = ty.clean(&self.cx);
185+
//i.visibility = None;
186+
}
187+
//impl_.visibility = None;
188+
if self.cx.crate_name == Some("std".to_string()) && t_name == "ToString" {
189+
println!("**> {:?}", impl_);
190+
}
152191
}
192+
//traits.insert(trait_def_id, impls);
193+
let trait_ = hir::TraitRef {
194+
path: get_path_for_type(infcx.tcx, trait_def_id, hir::def::Def::Trait),
195+
ref_id: ast::DUMMY_NODE_ID,
196+
};
197+
let provided_trait_methods = infcx.tcx.provided_trait_methods(impl_def_id)
198+
.into_iter()
199+
.map(|meth| meth.ident.to_string())
200+
.collect();
201+
println!("|||> {}", t_name);
202+
traits.insert(trait_def_id, Item {
203+
source: Span::empty(),
204+
name: None,
205+
attrs: Default::default(),
206+
visibility: None,
207+
def_id: self.next_def_id(impl_def_id.krate),
208+
stability: None,
209+
deprecation: None,
210+
inner: ImplItem(Impl {
211+
unsafety: hir::Unsafety::Normal,
212+
generics: (infcx.tcx.generics_of(trait_def_id), &Default::default()).clean(self.cx),
213+
provided_trait_methods,
214+
trait_: Some(trait_.clean(self.cx)),
215+
for_: ty.clean(self.cx),
216+
items: infcx.tcx.associated_items(impl_def_id).collect::<Vec<_>>().clean(self.cx),
217+
polarity: None,
218+
synthetic: true,
219+
}),
220+
});
221+
222+
/*use ::clean::{self, inline::*};
223+
224+
let mut ret = Vec::with_capacity(2);
225+
record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait);
226+
ret.extend(build_impls(self.cx, trait_def_id, false));
227+
let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id));
228+
let cx = self.cx;
229+
ret.push(clean::Item {
230+
source: infcx.tcx.def_span(trait_def_id).clean(cx),
231+
name: Some(infcx.tcx.item_name(trait_def_id).to_string()),
232+
attrs: load_attrs(cx, trait_def_id),
233+
inner,
234+
visibility: Some(clean::Public),
235+
stability: cx.tcx.lookup_stability(trait_def_id).clean(cx),
236+
deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx),
237+
def_id: trait_def_id,
238+
});
239+
traits.insert(trait_def_id, ret);*/
153240
}
154-
traits.insert(trait_def_id, impls);
155-
156-
/*use ::clean::{self, inline::*};
157-
158-
let mut ret = Vec::with_capacity(2);
159-
record_extern_fqn(self.cx, trait_def_id, clean::TypeKind::Trait);
160-
ret.extend(build_impls(self.cx, trait_def_id, false));
161-
let inner = clean::TraitItem(build_external_trait(self.cx, trait_def_id));
162-
let cx = self.cx;
163-
ret.push(clean::Item {
164-
source: infcx.tcx.def_span(trait_def_id).clean(cx),
165-
name: Some(infcx.tcx.item_name(trait_def_id).to_string()),
166-
attrs: load_attrs(cx, trait_def_id),
167-
inner,
168-
visibility: Some(clean::Public),
169-
stability: cx.tcx.lookup_stability(trait_def_id).clean(cx),
170-
deprecation: cx.tcx.lookup_deprecation(trait_def_id).clean(cx),
171-
def_id: trait_def_id,
172-
});
173-
traits.insert(trait_def_id, ret);*/
241+
//println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string());
174242
}
175-
//println!("=> {}", infcx.tcx.item_name(trait_def_id).to_string());
243+
debug!("{:?} => {}", trait_ref, may_apply);
176244
}
177-
debug!("{:?} => {}", trait_ref, may_apply);
178-
}
245+
});
179246
});
180-
});
247+
}
181248
}
182249
}
183250
//let res = self.cx.tcx.trait_impls_of(def_id);
184251
//println!("=> {:?} {:?}", res.blanket_impls.len(), res.non_blanket_impls.len());
185-
if self.cx
186-
.tcx
187-
.get_attrs(def_id)
188-
.lists("doc")
189-
.has_word("hidden")
190-
{
191-
debug!(
192-
"get_auto_trait_impls(def_id={:?}, def_ctor=...): item has doc('hidden'), \
193-
aborting",
194-
def_id
195-
);
196-
return Vec::new();
197-
}
198252

199253
debug!(
200254
"get_auto_trait_impls(def_id={:?}, def_ctor=..., generics={:?}",
201255
def_id, generics
202256
);
203-
let auto_traits: Vec<_> = self.cx
204-
.send_trait
205-
.and_then(|send_trait| {
206-
self.get_auto_trait_impl_for(
207-
def_id,
208-
name.clone(),
209-
generics.clone(),
210-
def_ctor,
211-
send_trait,
212-
)
213-
})
214-
.into_iter()
257+
let auto_traits: Vec<_> =
258+
self.cx.send_trait
259+
.and_then(|send_trait| {
260+
self.get_auto_trait_impl_for(
261+
def_id,
262+
name.clone(),
263+
generics.clone(),
264+
def_ctor,
265+
send_trait,
266+
)
267+
}).into_iter()
215268
.chain(self.get_auto_trait_impl_for(
216269
def_id,
217270
name.clone(),
218271
generics.clone(),
219272
def_ctor,
220273
tcx.require_lang_item(lang_items::SyncTraitLangItem),
221274
).into_iter())
222-
.chain(traits.into_iter().flat_map(|(_, v)| v.into_iter()))
275+
.chain(traits.into_iter().map(|(_, v)| v))//.flat_map(|(_, v)| v.into_iter()))
223276
.collect();
224277

225278
debug!(
226279
"get_auto_traits: type {:?} auto_traits {:?}",
227280
def_id, auto_traits
228281
);
229-
/*if ::std::env::var("LOL").is_ok() {
230-
for x in &auto_traits {
231-
println!("\n=> {:?}", x);
232-
}
233-
}*/
282+
if self.cx.crate_name == Some("std".to_string()) {
283+
println!("((((((> {} {:?}", auto_traits.len(), auto_traits);
284+
}
234285
auto_traits
235286
}
236287

src/librustdoc/clean/inline.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
276276
let auto_impls = get_auto_traits_with_def_id(cx, did);
277277
let mut renderinfo = cx.renderinfo.borrow_mut();
278278

279+
if cx.crate_name == Some("std".to_string()) {
280+
println!("=====> {} {:?}\n", auto_impls.len(), auto_impls);
281+
}
279282
let new_impls: Vec<clean::Item> = auto_impls.into_iter()
280283
.filter(|i| renderinfo.inlined.insert(i.def_id)).collect();
281284

@@ -337,6 +340,9 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
337340
build_impl(cx, def_id, &mut impls);
338341

339342
let auto_impls = get_auto_traits_with_def_id(cx, def_id);
343+
if cx.crate_name == Some("std".to_string()) {
344+
println!("-----> {} {:?}\n", auto_impls.len(), auto_impls);
345+
}
340346
let mut renderinfo = cx.renderinfo.borrow_mut();
341347

342348
let new_impls: Vec<clean::Item> = auto_impls.into_iter()

src/librustdoc/core.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
8484
/// Maps (type_id, trait_id) -> auto trait impl
8585
pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>,
8686
pub current_item_name: RefCell<Option<Name>>,
87-
pub all_traits: Lrc<Vec<DefId>>,
87+
pub all_traits: Vec<DefId>,
8888
}
8989

9090
impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> {
@@ -386,7 +386,7 @@ pub fn run_core(search_paths: SearchPaths,
386386
all_fake_def_ids: RefCell::new(FxHashSet()),
387387
generated_synthetics: RefCell::new(FxHashSet()),
388388
current_item_name: RefCell::new(None),
389-
all_traits: tcx.all_traits(LOCAL_CRATE),
389+
all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(),
390390
};
391391
debug!("crate: {:?}", tcx.hir.krate());
392392

0 commit comments

Comments
 (0)