Generate blanket implementations for reexported items as well
This commit is contained in:
parent
afd0a2f249
commit
985da801b0
2 changed files with 107 additions and 91 deletions
|
@ -65,98 +65,96 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> {
|
||||||
return impls;
|
return impls;
|
||||||
}
|
}
|
||||||
let ty = self.cx.tcx.type_of(def_id);
|
let ty = self.cx.tcx.type_of(def_id);
|
||||||
if self.cx.access_levels.borrow().is_doc_reachable(def_id) || ty.is_primitive() {
|
let generics = self.cx.tcx.generics_of(def_id);
|
||||||
let generics = self.cx.tcx.generics_of(def_id);
|
let real_name = name.clone().map(|name| Ident::from_str(&name));
|
||||||
let real_name = name.clone().map(|name| Ident::from_str(&name));
|
let param_env = self.cx.tcx.param_env(def_id);
|
||||||
let param_env = self.cx.tcx.param_env(def_id);
|
for &trait_def_id in self.cx.all_traits.iter() {
|
||||||
for &trait_def_id in self.cx.all_traits.iter() {
|
if !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
|
||||||
self.cx.generated_synthetics
|
.borrow_mut()
|
||||||
.borrow_mut()
|
.get(&(def_id, trait_def_id))
|
||||||
.get(&(def_id, trait_def_id))
|
.is_some() {
|
||||||
.is_some() {
|
continue
|
||||||
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)
|
|
||||||
.expect("Cannot get impl trait");
|
|
||||||
|
|
||||||
match trait_ref.self_ty().sty {
|
|
||||||
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,
|
|
||||||
hir_ref_id: hir::DUMMY_HIR_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.cx.get_real_ty(def_id, def_ctor, &real_name, generics);
|
|
||||||
let predicates = infcx.tcx.predicates_of(impl_def_id);
|
|
||||||
|
|
||||||
impls.push(Item {
|
|
||||||
source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
|
|
||||||
name: None,
|
|
||||||
attrs: Default::default(),
|
|
||||||
visibility: None,
|
|
||||||
def_id: self.cx.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::<Vec<_>>()
|
|
||||||
.clean(self.cx),
|
|
||||||
polarity: None,
|
|
||||||
synthetic: false,
|
|
||||||
blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
|
|
||||||
.clean(self.cx)),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
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)
|
||||||
|
.expect("Cannot get impl trait");
|
||||||
|
|
||||||
|
match trait_ref.self_ty().sty {
|
||||||
|
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,
|
||||||
|
hir_ref_id: hir::DUMMY_HIR_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.cx.get_real_ty(def_id, def_ctor, &real_name, generics);
|
||||||
|
let predicates = infcx.tcx.predicates_of(impl_def_id);
|
||||||
|
|
||||||
|
impls.push(Item {
|
||||||
|
source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
|
||||||
|
name: None,
|
||||||
|
attrs: Default::default(),
|
||||||
|
visibility: None,
|
||||||
|
def_id: self.cx.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::<Vec<_>>()
|
||||||
|
.clean(self.cx),
|
||||||
|
polarity: None,
|
||||||
|
synthetic: false,
|
||||||
|
blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
|
||||||
|
.clean(self.cx)),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
impls
|
impls
|
||||||
}
|
}
|
||||||
|
|
18
src/test/rustdoc/blanket-reexport-item.rs
Normal file
18
src/test/rustdoc/blanket-reexport-item.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
// @has foo/struct.S.html '//h3[@id="impl-Into"]//code' 'impl<T, U> Into for T'
|
||||||
|
pub struct S2 {}
|
||||||
|
mod m {
|
||||||
|
pub struct S {}
|
||||||
|
}
|
||||||
|
pub use m::*;
|
Loading…
Add table
Add a link
Reference in a new issue