Skip to content

Commit 287b29b

Browse files
committed
Resolve impl Trait in argument position
1 parent 5dfa5f0 commit 287b29b

File tree

2 files changed

+54
-10
lines changed

2 files changed

+54
-10
lines changed

Diff for: src/librustdoc/clean/mod.rs

+51-10
Original file line numberDiff line numberDiff line change
@@ -1774,11 +1774,12 @@ pub struct Method {
17741774

17751775
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
17761776
fn clean(&self, cx: &DocContext) -> Method {
1777+
let generics = self.1.clean(cx);
17771778
Method {
1778-
generics: self.1.clean(cx),
1779+
decl: enter_impl_trait(cx, &generics.params, || (&*self.0.decl, self.2).clean(cx)),
1780+
generics,
17791781
unsafety: self.0.unsafety,
17801782
constness: self.0.constness,
1781-
decl: (&*self.0.decl, self.2).clean(cx),
17821783
abi: self.0.abi
17831784
}
17841785
}
@@ -1803,6 +1804,8 @@ pub struct Function {
18031804

18041805
impl Clean<Item> for doctree::Function {
18051806
fn clean(&self, cx: &DocContext) -> Item {
1807+
let generics = self.generics.clean(cx);
1808+
let decl = enter_impl_trait(cx, &generics.params, || (&self.decl, self.body).clean(cx));
18061809
Item {
18071810
name: Some(self.name.clean(cx)),
18081811
attrs: self.attrs.clean(cx),
@@ -1812,8 +1815,8 @@ impl Clean<Item> for doctree::Function {
18121815
deprecation: self.depr.clean(cx),
18131816
def_id: cx.tcx.hir.local_def_id(self.id),
18141817
inner: FunctionItem(Function {
1815-
decl: (&self.decl, self.body).clean(cx),
1816-
generics: self.generics.clean(cx),
1818+
decl,
1819+
generics,
18171820
unsafety: self.unsafety,
18181821
constness: self.constness,
18191822
abi: self.abi,
@@ -2040,10 +2043,13 @@ impl Clean<Item> for hir::TraitItem {
20402043
MethodItem((sig, &self.generics, body).clean(cx))
20412044
}
20422045
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
2046+
let generics = self.generics.clean(cx);
20432047
TyMethodItem(TyMethod {
20442048
unsafety: sig.unsafety.clone(),
2045-
decl: (&*sig.decl, &names[..]).clean(cx),
2046-
generics: self.generics.clean(cx),
2049+
decl: enter_impl_trait(cx, &generics.params, || {
2050+
(&*sig.decl, &names[..]).clean(cx)
2051+
}),
2052+
generics,
20472053
abi: sig.abi
20482054
})
20492055
}
@@ -2547,6 +2553,12 @@ impl Clean<Type> for hir::Ty {
25472553
return new_ty;
25482554
}
25492555

2556+
if let Def::TyParam(did) = path.def {
2557+
if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did) {
2558+
return ImplTrait(bounds);
2559+
}
2560+
}
2561+
25502562
let mut alias = None;
25512563
if let Def::TyAlias(def_id) = path.def {
25522564
// Substitute private type aliases
@@ -3259,10 +3271,13 @@ pub struct BareFunctionDecl {
32593271

32603272
impl Clean<BareFunctionDecl> for hir::BareFnTy {
32613273
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
3274+
let generic_params = self.generic_params.clean(cx);
32623275
BareFunctionDecl {
32633276
unsafety: self.unsafety,
3264-
generic_params: self.generic_params.clean(cx),
3265-
decl: (&*self.decl, &self.arg_names[..]).clean(cx),
3277+
decl: enter_impl_trait(cx, &generic_params, || {
3278+
(&*self.decl, &self.arg_names[..]).clean(cx)
3279+
}),
3280+
generic_params,
32663281
abi: self.abi,
32673282
}
32683283
}
@@ -3563,9 +3578,12 @@ impl Clean<Item> for hir::ForeignItem {
35633578
fn clean(&self, cx: &DocContext) -> Item {
35643579
let inner = match self.node {
35653580
hir::ForeignItemFn(ref decl, ref names, ref generics) => {
3581+
let generics = generics.clean(cx);
35663582
ForeignFunctionItem(Function {
3567-
decl: (&**decl, &names[..]).clean(cx),
3568-
generics: generics.clean(cx),
3583+
decl: enter_impl_trait(cx, &generics.params, || {
3584+
(&**decl, &names[..]).clean(cx)
3585+
}),
3586+
generics,
35693587
unsafety: hir::Unsafety::Unsafe,
35703588
abi: Abi::Rust,
35713589
constness: hir::Constness::NotConst,
@@ -3867,6 +3885,29 @@ pub fn def_id_to_path(cx: &DocContext, did: DefId, name: Option<String>) -> Vec<
38673885
once(crate_name).chain(relative).collect()
38683886
}
38693887

3888+
pub fn enter_impl_trait<F, R>(cx: &DocContext, gps: &[GenericParam], f: F) -> R
3889+
where
3890+
F: FnOnce() -> R,
3891+
{
3892+
let bounds = gps.iter()
3893+
.filter_map(|p| {
3894+
if let GenericParam::Type(ref tp) = *p {
3895+
if tp.synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
3896+
return Some((tp.did, tp.bounds.clone()));
3897+
}
3898+
}
3899+
3900+
None
3901+
})
3902+
.collect::<FxHashMap<DefId, Vec<TyParamBound>>>();
3903+
3904+
let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), bounds);
3905+
let r = f();
3906+
assert!(cx.impl_trait_bounds.borrow().is_empty());
3907+
*cx.impl_trait_bounds.borrow_mut() = old_bounds;
3908+
r
3909+
}
3910+
38703911
// Start of code copied from rust-clippy
38713912

38723913
pub fn get_trait_def_id(tcx: &TyCtxt, path: &[&str], use_local: bool) -> Option<DefId> {

Diff for: src/librustdoc/core.rs

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
7272
pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
7373
/// Table node id of lifetime parameter definition -> substituted lifetime
7474
pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
75+
/// Table DefId of `impl Trait` in argument position -> bounds
76+
pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::TyParamBound>>>,
7577
pub send_trait: Option<DefId>,
7678
pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
7779
pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
@@ -261,6 +263,7 @@ pub fn run_core(search_paths: SearchPaths,
261263
renderinfo: Default::default(),
262264
ty_substs: Default::default(),
263265
lt_substs: Default::default(),
266+
impl_trait_bounds: Default::default(),
264267
mod_ids: Default::default(),
265268
send_trait: send_trait,
266269
fake_def_ids: RefCell::new(FxHashMap()),

0 commit comments

Comments
 (0)