Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 65ecc48

Browse files
committedNov 26, 2020
Auto merge of #77467 - jyn514:query-docs, r=oli-obk
Normalize `<X as Y>::T` for rustdoc - Only run for `QPath::Resolved` with `Some` self parameter (`<X as Y>::T`) - Fall back to the previous behavior if the path can't be resolved The first commit is a pure refactor and should probably be reviewed by `@GuillaumeGomez.` I recommend reviewing the second commit on its own. Fixes #77459. r? `@eddyb` cc `@danielhenrymantilla` , `@lcnr`
2 parents 0beba93 + 277bdbc commit 65ecc48

File tree

4 files changed

+435
-284
lines changed

4 files changed

+435
-284
lines changed
 

‎src/librustdoc/clean/mod.rs

Lines changed: 341 additions & 282 deletions
Large diffs are not rendered by default.

‎src/librustdoc/core.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_interface::interface;
1515
use rustc_middle::hir::map::Map;
1616
use rustc_middle::middle::cstore::CrateStore;
1717
use rustc_middle::middle::privacy::AccessLevels;
18-
use rustc_middle::ty::{Ty, TyCtxt};
18+
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
1919
use rustc_resolve as resolve;
2020
use rustc_session::config::{self, CrateType, ErrorOutputType};
2121
use rustc_session::lint;
@@ -25,7 +25,7 @@ use rustc_span::source_map;
2525
use rustc_span::symbol::sym;
2626
use rustc_span::DUMMY_SP;
2727

28-
use std::cell::RefCell;
28+
use std::cell::{Cell, RefCell};
2929
use std::mem;
3030
use std::rc::Rc;
3131

@@ -42,6 +42,10 @@ crate type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>;
4242
crate struct DocContext<'tcx> {
4343
crate tcx: TyCtxt<'tcx>,
4444
crate resolver: Rc<RefCell<interface::BoxedResolver>>,
45+
/// Used for normalization.
46+
///
47+
/// Most of this logic is copied from rustc_lint::late.
48+
crate param_env: Cell<ParamEnv<'tcx>>,
4549
/// Later on moved into `CACHE_KEY`
4650
crate renderinfo: RefCell<RenderInfo>,
4751
/// Later on moved through `clean::Crate` into `CACHE_KEY`
@@ -79,6 +83,13 @@ impl<'tcx> DocContext<'tcx> {
7983
&self.tcx.sess
8084
}
8185

86+
crate fn with_param_env<T, F: FnOnce() -> T>(&self, def_id: DefId, f: F) -> T {
87+
let old_param_env = self.param_env.replace(self.tcx.param_env(def_id));
88+
let ret = f();
89+
self.param_env.set(old_param_env);
90+
ret
91+
}
92+
8293
crate fn enter_resolver<F, R>(&self, f: F) -> R
8394
where
8495
F: FnOnce(&mut resolve::Resolver<'_>) -> R,
@@ -524,6 +535,7 @@ fn run_global_ctxt(
524535
let mut ctxt = DocContext {
525536
tcx,
526537
resolver,
538+
param_env: Cell::new(ParamEnv::empty()),
527539
external_traits: Default::default(),
528540
active_extern_traits: Default::default(),
529541
renderinfo: RefCell::new(renderinfo),
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![crate_name = "inner"]
2+
pub trait MyTrait {
3+
type Y;
4+
}
5+
6+
impl MyTrait for u32 {
7+
type Y = i32;
8+
}
9+
10+
pub fn foo() -> <u32 as MyTrait>::Y {
11+
0
12+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// ignore-tidy-linelength
2+
// aux-build:normalize-assoc-item.rs
3+
// build-aux-docs
4+
5+
pub trait Trait {
6+
type X;
7+
}
8+
9+
impl Trait for usize {
10+
type X = isize;
11+
}
12+
13+
// @has 'normalize_assoc_item/fn.f.html' '//pre[@class="rust fn"]' 'pub fn f() -> isize'
14+
pub fn f() -> <usize as Trait>::X {
15+
0
16+
}
17+
18+
pub struct S {
19+
// @has 'normalize_assoc_item/struct.S.html' '//span[@id="structfield.box_me_up"]' 'box_me_up: Box<S, Global>'
20+
pub box_me_up: <S as Trait>::X,
21+
// @has 'normalize_assoc_item/struct.S.html' '//span[@id="structfield.generic"]' 'generic: (usize, isize)'
22+
pub generic: <Generic<usize> as Trait>::X,
23+
}
24+
25+
impl Trait for S {
26+
type X = Box<S>;
27+
}
28+
29+
pub struct Generic<Inner>(Inner);
30+
31+
impl<Inner: Trait> Trait for Generic<Inner> {
32+
type X = (Inner, Inner::X);
33+
}
34+
35+
// These can't be normalized because they depend on a generic parameter.
36+
// However the user can choose whether the text should be displayed as `Inner::X` or `<Inner as Trait>::X`.
37+
38+
// @has 'normalize_assoc_item/struct.Unknown.html' '//pre[@class="rust struct"]' 'pub struct Unknown<Inner: Trait>(pub <Inner as Trait>::X);'
39+
pub struct Unknown<Inner: Trait>(pub <Inner as Trait>::X);
40+
41+
// @has 'normalize_assoc_item/struct.Unknown2.html' '//pre[@class="rust struct"]' 'pub struct Unknown2<Inner: Trait>(pub Inner::X);'
42+
pub struct Unknown2<Inner: Trait>(pub Inner::X);
43+
44+
trait Lifetimes<'a> {
45+
type Y;
46+
}
47+
48+
impl<'a> Lifetimes<'a> for usize {
49+
type Y = &'a isize;
50+
}
51+
52+
// @has 'normalize_assoc_item/fn.g.html' '//pre[@class="rust fn"]' "pub fn g() -> &isize"
53+
pub fn g() -> <usize as Lifetimes<'static>>::Y {
54+
&0
55+
}
56+
57+
// @has 'normalize_assoc_item/constant.A.html' '//pre[@class="rust const"]' "pub const A: &isize"
58+
pub const A: <usize as Lifetimes<'static>>::Y = &0;
59+
60+
// test cross-crate re-exports
61+
extern crate inner;
62+
// @has 'normalize_assoc_item/fn.foo.html' '//pre[@class="rust fn"]' "pub fn foo() -> i32"
63+
pub use inner::foo;
64+
65+
// @has 'normalize_assoc_item/fn.h.html' '//pre[@class="rust fn"]' "pub fn h<T>() -> IntoIter<T, Global>"
66+
pub fn h<T>() -> <Vec<T> as IntoIterator>::IntoIter {
67+
vec![].into_iter()
68+
}

0 commit comments

Comments
 (0)
Please sign in to comment.