Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
623 changes: 341 additions & 282 deletions src/librustdoc/clean/mod.rs

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use rustc_interface::interface;
use rustc_middle::hir::map::Map;
use rustc_middle::middle::cstore::CrateStore;
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
use rustc_resolve as resolve;
use rustc_session::config::{self, CrateType, ErrorOutputType};
use rustc_session::lint;
@@ -25,7 +25,7 @@ use rustc_span::source_map;
use rustc_span::symbol::sym;
use rustc_span::DUMMY_SP;

use std::cell::RefCell;
use std::cell::{Cell, RefCell};
use std::mem;
use std::rc::Rc;

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

crate fn with_param_env<T, F: FnOnce() -> T>(&self, def_id: DefId, f: F) -> T {
let old_param_env = self.param_env.replace(self.tcx.param_env(def_id));
let ret = f();
self.param_env.set(old_param_env);
ret
}

crate fn enter_resolver<F, R>(&self, f: F) -> R
where
F: FnOnce(&mut resolve::Resolver<'_>) -> R,
@@ -524,6 +535,7 @@ fn run_global_ctxt(
let mut ctxt = DocContext {
tcx,
resolver,
param_env: Cell::new(ParamEnv::empty()),
external_traits: Default::default(),
active_extern_traits: Default::default(),
renderinfo: RefCell::new(renderinfo),
12 changes: 12 additions & 0 deletions src/test/rustdoc/auxiliary/normalize-assoc-item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![crate_name = "inner"]
pub trait MyTrait {
type Y;
}

impl MyTrait for u32 {
type Y = i32;
}

pub fn foo() -> <u32 as MyTrait>::Y {
0
}
68 changes: 68 additions & 0 deletions src/test/rustdoc/normalize-assoc-item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// ignore-tidy-linelength
// aux-build:normalize-assoc-item.rs
// build-aux-docs

pub trait Trait {
type X;
}

impl Trait for usize {
type X = isize;
}

// @has 'normalize_assoc_item/fn.f.html' '//pre[@class="rust fn"]' 'pub fn f() -> isize'
pub fn f() -> <usize as Trait>::X {
0
}

pub struct S {
// @has 'normalize_assoc_item/struct.S.html' '//span[@id="structfield.box_me_up"]' 'box_me_up: Box<S, Global>'
pub box_me_up: <S as Trait>::X,
// @has 'normalize_assoc_item/struct.S.html' '//span[@id="structfield.generic"]' 'generic: (usize, isize)'
pub generic: <Generic<usize> as Trait>::X,
}

impl Trait for S {
type X = Box<S>;
}

pub struct Generic<Inner>(Inner);

impl<Inner: Trait> Trait for Generic<Inner> {
type X = (Inner, Inner::X);
}

// These can't be normalized because they depend on a generic parameter.
// However the user can choose whether the text should be displayed as `Inner::X` or `<Inner as Trait>::X`.

// @has 'normalize_assoc_item/struct.Unknown.html' '//pre[@class="rust struct"]' 'pub struct Unknown<Inner: Trait>(pub <Inner as Trait>::X);'
pub struct Unknown<Inner: Trait>(pub <Inner as Trait>::X);

// @has 'normalize_assoc_item/struct.Unknown2.html' '//pre[@class="rust struct"]' 'pub struct Unknown2<Inner: Trait>(pub Inner::X);'
pub struct Unknown2<Inner: Trait>(pub Inner::X);

trait Lifetimes<'a> {
type Y;
}

impl<'a> Lifetimes<'a> for usize {
type Y = &'a isize;
}

// @has 'normalize_assoc_item/fn.g.html' '//pre[@class="rust fn"]' "pub fn g() -> &isize"
pub fn g() -> <usize as Lifetimes<'static>>::Y {
&0
}

// @has 'normalize_assoc_item/constant.A.html' '//pre[@class="rust const"]' "pub const A: &isize"
pub const A: <usize as Lifetimes<'static>>::Y = &0;

// test cross-crate re-exports
extern crate inner;
// @has 'normalize_assoc_item/fn.foo.html' '//pre[@class="rust fn"]' "pub fn foo() -> i32"
pub use inner::foo;

// @has 'normalize_assoc_item/fn.h.html' '//pre[@class="rust fn"]' "pub fn h<T>() -> IntoIter<T, Global>"
pub fn h<T>() -> <Vec<T> as IntoIterator>::IntoIter {
vec![].into_iter()
}