summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/clean
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /src/librustdoc/clean
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/librustdoc/clean')
-rw-r--r--src/librustdoc/clean/auto_trait.rs20
-rw-r--r--src/librustdoc/clean/blanket_impl.rs8
-rw-r--r--src/librustdoc/clean/cfg.rs2
-rw-r--r--src/librustdoc/clean/cfg/tests.rs20
-rw-r--r--src/librustdoc/clean/inline.rs41
-rw-r--r--src/librustdoc/clean/mod.rs272
-rw-r--r--src/librustdoc/clean/simplify.rs2
-rw-r--r--src/librustdoc/clean/types.rs80
-rw-r--r--src/librustdoc/clean/utils.rs33
9 files changed, 300 insertions, 178 deletions
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 953f4aa8a..a302750aa 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -44,7 +44,7 @@ where
discard_positive_impl: bool,
) -> Option<Item> {
let tcx = self.cx.tcx;
- let trait_ref = tcx.mk_trait_ref(trait_def_id, [ty]);
+ let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, [ty]));
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
return None;
@@ -124,7 +124,7 @@ where
unsafety: hir::Unsafety::Normal,
generics: new_generics,
trait_: Some(clean_trait_ref_with_bindings(self.cx, trait_ref, ThinVec::new())),
- for_: clean_middle_ty(ty, self.cx, None),
+ for_: clean_middle_ty(ty::Binder::dummy(ty), self.cx, None),
items: Vec::new(),
polarity,
kind: ImplKind::Auto,
@@ -402,15 +402,13 @@ where
bound_params: Vec::new(),
})
})
- .chain(
- lifetime_to_bounds.into_iter().filter(|&(_, ref bounds)| !bounds.is_empty()).map(
- |(lifetime, bounds)| {
- let mut bounds_vec = bounds.into_iter().collect();
- self.sort_where_bounds(&mut bounds_vec);
- WherePredicate::RegionPredicate { lifetime, bounds: bounds_vec }
- },
- ),
- )
+ .chain(lifetime_to_bounds.into_iter().filter(|(_, bounds)| !bounds.is_empty()).map(
+ |(lifetime, bounds)| {
+ let mut bounds_vec = bounds.into_iter().collect();
+ self.sort_where_bounds(&mut bounds_vec);
+ WherePredicate::RegionPredicate { lifetime, bounds: bounds_vec }
+ },
+ ))
.collect()
}
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index a1145b90d..e6b2b2349 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -33,7 +33,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
trait_def_id,
impl_def_id
);
- let trait_ref = cx.tcx.bound_impl_trait_ref(impl_def_id).unwrap();
+ let trait_ref = cx.tcx.impl_trait_ref(impl_def_id).unwrap();
if !matches!(trait_ref.0.self_ty().kind(), ty::Param(_)) {
continue;
}
@@ -105,10 +105,10 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
// the post-inference `trait_ref`, as it's more accurate.
trait_: Some(clean_trait_ref_with_bindings(
cx,
- trait_ref.0,
+ ty::Binder::dummy(trait_ref.0),
ThinVec::new(),
)),
- for_: clean_middle_ty(ty.0, cx, None),
+ for_: clean_middle_ty(ty::Binder::dummy(ty.0), cx, None),
items: cx
.tcx
.associated_items(impl_def_id)
@@ -117,7 +117,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.collect::<Vec<_>>(),
polarity: ty::ImplPolarity::Positive,
kind: ImplKind::Blanket(Box::new(clean_middle_ty(
- trait_ref.0.self_ty(),
+ ty::Binder::dummy(trait_ref.0.self_ty()),
cx,
None,
))),
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 1843a2120..f1853f369 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -507,7 +507,9 @@ impl<'a> fmt::Display for Display<'a> {
"openbsd" => "OpenBSD",
"redox" => "Redox",
"solaris" => "Solaris",
+ "tvos" => "tvOS",
"wasi" => "WASI",
+ "watchos" => "watchOS",
"windows" => "Windows",
_ => "",
},
diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs
index 7f72d5d39..81f676724 100644
--- a/src/librustdoc/clean/cfg/tests.rs
+++ b/src/librustdoc/clean/cfg/tests.rs
@@ -1,9 +1,8 @@
use super::*;
-use rustc_ast::attr;
-use rustc_ast::Path;
+use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle};
use rustc_span::create_default_session_globals_then;
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::DUMMY_SP;
fn word_cfg(s: &str) -> Cfg {
@@ -22,6 +21,15 @@ fn dummy_meta_item_word(name: &str) -> MetaItem {
}
}
+fn dummy_meta_item_name_value(name: &str, symbol: Symbol, kind: LitKind) -> MetaItem {
+ let lit = MetaItemLit { symbol, suffix: None, kind, span: DUMMY_SP };
+ MetaItem {
+ path: Path::from_ident(Ident::from_str(name)),
+ kind: MetaItemKind::NameValue(lit),
+ span: DUMMY_SP,
+ }
+}
+
macro_rules! dummy_meta_item_list {
($name:ident, [$($list:ident),* $(,)?]) => {
MetaItem {
@@ -242,8 +250,8 @@ fn test_parse_ok() {
let mi = dummy_meta_item_word("all");
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
- let mi =
- attr::mk_name_value_item_str(Ident::from_str("all"), Symbol::intern("done"), DUMMY_SP);
+ let done = Symbol::intern("done");
+ let mi = dummy_meta_item_name_value("all", done, LitKind::Str(done, StrStyle::Cooked));
assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done")));
let mi = dummy_meta_item_list!(all, [a, b]);
@@ -272,7 +280,7 @@ fn test_parse_ok() {
#[test]
fn test_parse_err() {
create_default_session_globals_then(|| {
- let mi = attr::mk_name_value_item(Ident::from_str("foo"), LitKind::Bool(false), DUMMY_SP);
+ let mi = dummy_meta_item_name_value("foo", kw::False, LitKind::Bool(false));
assert!(Cfg::parse(&mi).is_err());
let mi = dummy_meta_item_list!(not, [a, b]);
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e7c3e5a45..b3b093312 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -9,7 +9,7 @@ use rustc_ast as ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Mutability;
use rustc_metadata::creader::{CStore, LoadedMacro};
use rustc_middle::ty::{self, TyCtxt};
@@ -162,6 +162,7 @@ pub(crate) fn try_inline(
pub(crate) fn try_inline_glob(
cx: &mut DocContext<'_>,
res: Res,
+ current_mod: LocalDefId,
visited: &mut FxHashSet<DefId>,
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
) -> Option<Vec<clean::Item>> {
@@ -172,7 +173,16 @@ pub(crate) fn try_inline_glob(
match res {
Res::Def(DefKind::Mod, did) => {
- let mut items = build_module_items(cx, did, visited, inlined_names);
+ // Use the set of module reexports to filter away names that are not actually
+ // reexported by the glob, e.g. because they are shadowed by something else.
+ let reexports = cx
+ .tcx
+ .module_reexports(current_mod)
+ .unwrap_or_default()
+ .iter()
+ .filter_map(|child| child.res.opt_def_id())
+ .collect();
+ let mut items = build_module_items(cx, did, visited, inlined_names, Some(&reexports));
items.drain_filter(|item| {
if let Some(name) = item.name {
// If an item with the same type and name already exists,
@@ -293,7 +303,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> {
let predicates = cx.tcx.explicit_predicates_of(did);
- let type_ = clean_middle_ty(cx.tcx.type_of(did), cx, Some(did));
+ let type_ = clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did)), cx, Some(did));
Box::new(clean::Typedef {
type_,
@@ -325,7 +335,7 @@ pub(crate) fn build_impls(
// * https://github.com/rust-lang/rust/pull/99917 — where the feature got used
// * https://github.com/rust-lang/rust/issues/53487 — overall tracking issue for Error
if tcx.has_attr(did, sym::rustc_has_incoherent_inherent_impls) {
- use rustc_middle::ty::fast_reject::SimplifiedTypeGen::*;
+ use rustc_middle::ty::fast_reject::SimplifiedType::*;
let type_ =
if tcx.is_trait(did) { TraitSimplifiedType(did) } else { AdtSimplifiedType(did) };
for &did in tcx.incoherent_impls(type_) {
@@ -376,7 +386,7 @@ pub(crate) fn build_impl(
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_impl");
let tcx = cx.tcx;
- let associated_trait = tcx.impl_trait_ref(did);
+ let associated_trait = tcx.impl_trait_ref(did).map(ty::EarlyBinder::skip_binder);
// Only inline impl if the implemented trait is
// reachable in rustdoc generated documentation
@@ -405,7 +415,7 @@ pub(crate) fn build_impl(
let for_ = match &impl_item {
Some(impl_) => clean_ty(impl_.self_ty, cx),
- None => clean_middle_ty(tcx.type_of(did), cx, Some(did)),
+ None => clean_middle_ty(ty::Binder::dummy(tcx.type_of(did)), cx, Some(did)),
};
// Only inline impl if the implementing type is
@@ -496,7 +506,8 @@ pub(crate) fn build_impl(
),
};
let polarity = tcx.impl_polarity(did);
- let trait_ = associated_trait.map(|t| clean_trait_ref_with_bindings(cx, t, ThinVec::new()));
+ let trait_ = associated_trait
+ .map(|t| clean_trait_ref_with_bindings(cx, ty::Binder::dummy(t), ThinVec::new()));
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
super::build_deref_target_impls(cx, &trait_items, ret);
}
@@ -562,7 +573,7 @@ fn build_module(
did: DefId,
visited: &mut FxHashSet<DefId>,
) -> clean::Module {
- let items = build_module_items(cx, did, visited, &mut FxHashSet::default());
+ let items = build_module_items(cx, did, visited, &mut FxHashSet::default(), None);
let span = clean::Span::new(cx.tcx.def_span(did));
clean::Module { items, span }
@@ -573,6 +584,7 @@ fn build_module_items(
did: DefId,
visited: &mut FxHashSet<DefId>,
inlined_names: &mut FxHashSet<(ItemType, Symbol)>,
+ allowed_def_ids: Option<&FxHashSet<DefId>>,
) -> Vec<clean::Item> {
let mut items = Vec::new();
@@ -582,6 +594,11 @@ fn build_module_items(
for &item in cx.tcx.module_children(did).iter() {
if item.vis.is_public() {
let res = item.res.expect_non_local();
+ if let Some(def_id) = res.opt_def_id()
+ && let Some(allowed_def_ids) = allowed_def_ids
+ && !allowed_def_ids.contains(&def_id) {
+ continue;
+ }
if let Some(def_id) = res.mod_def_id() {
// If we're inlining a glob import, it's possible to have
// two distinct modules with the same name. We don't want to
@@ -599,7 +616,9 @@ fn build_module_items(
items.push(clean::Item {
name: None,
attrs: Box::new(clean::Attributes::default()),
- item_id: ItemId::Primitive(prim_ty, did.krate),
+ // We can use the item's `DefId` directly since the only information ever used
+ // from it is `DefId.krate`.
+ item_id: ItemId::DefId(did),
kind: Box::new(clean::ImportItem(clean::Import::new_simple(
item.ident.name,
clean::ImportSource {
@@ -640,14 +659,14 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String {
fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant {
clean::Constant {
- type_: clean_middle_ty(cx.tcx.type_of(def_id), cx, Some(def_id)),
+ type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(def_id)), cx, Some(def_id)),
kind: clean::ConstantKind::Extern { def_id },
}
}
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
clean::Static {
- type_: clean_middle_ty(cx.tcx.type_of(did), cx, Some(did)),
+ type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(did)), cx, Some(did)),
mutability: if mutable { Mutability::Mut } else { Mutability::Not },
expr: None,
}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2a2a9470d..0f0e16265 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -22,6 +22,7 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::InternalSubsts;
+use rustc_middle::ty::TypeVisitable;
use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{AstPass, MacroKind};
@@ -127,7 +128,7 @@ fn clean_generic_bound<'tcx>(
hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
- let trait_ref = ty::TraitRef::identity(cx.tcx, def_id).skip_binder();
+ let trait_ref = ty::TraitRef::identity(cx.tcx, def_id);
let generic_args = clean_generic_args(generic_args, cx);
let GenericArgs::AngleBracketed { bindings, .. } = generic_args
@@ -156,17 +157,18 @@ fn clean_generic_bound<'tcx>(
pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
cx: &mut DocContext<'tcx>,
- trait_ref: ty::TraitRef<'tcx>,
+ trait_ref: ty::PolyTraitRef<'tcx>,
bindings: ThinVec<TypeBinding>,
) -> Path {
- let kind = cx.tcx.def_kind(trait_ref.def_id).into();
+ let kind = cx.tcx.def_kind(trait_ref.def_id()).into();
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
- span_bug!(cx.tcx.def_span(trait_ref.def_id), "`TraitRef` had unexpected kind {:?}", kind);
+ span_bug!(cx.tcx.def_span(trait_ref.def_id()), "`TraitRef` had unexpected kind {:?}", kind);
}
- inline::record_extern_fqn(cx, trait_ref.def_id, kind);
- let path = external_path(cx, trait_ref.def_id, true, bindings, trait_ref.substs);
+ inline::record_extern_fqn(cx, trait_ref.def_id(), kind);
+ let path =
+ external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.substs));
- debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs);
+ debug!(?trait_ref);
path
}
@@ -187,7 +189,7 @@ fn clean_poly_trait_ref_with_bindings<'tcx>(
})
.collect();
- let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref.skip_binder(), bindings);
+ let trait_ = clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings);
GenericBound::TraitBound(
PolyTrait { trait_, generic_params: late_bound_regions },
hir::TraitBoundModifier::None,
@@ -212,19 +214,19 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) ->
pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'tcx>) -> Constant {
let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id();
Constant {
- type_: clean_middle_ty(cx.tcx.type_of(def_id), cx, Some(def_id)),
+ type_: clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(def_id)), cx, Some(def_id)),
kind: ConstantKind::Anonymous { body: constant.value.body },
}
}
pub(crate) fn clean_middle_const<'tcx>(
- constant: ty::Const<'tcx>,
+ constant: ty::Binder<'tcx, ty::Const<'tcx>>,
cx: &mut DocContext<'tcx>,
) -> Constant {
// FIXME: instead of storing the stringified expression, store `self` directly instead.
Constant {
- type_: clean_middle_ty(constant.ty(), cx, None),
- kind: ConstantKind::TyConst { expr: constant.to_string().into() },
+ type_: clean_middle_ty(constant.map_bound(|c| c.ty()), cx, None),
+ kind: ConstantKind::TyConst { expr: constant.skip_binder().to_string().into() },
}
}
@@ -333,7 +335,7 @@ fn clean_poly_trait_predicate<'tcx>(
let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
Some(WherePredicate::BoundPredicate {
- ty: clean_middle_ty(poly_trait_ref.skip_binder().self_ty(), cx, None),
+ ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None),
bounds: vec![clean_poly_trait_ref_with_bindings(cx, poly_trait_ref, ThinVec::new())],
bound_params: Vec::new(),
})
@@ -359,7 +361,7 @@ fn clean_type_outlives_predicate<'tcx>(
let ty::OutlivesPredicate(ty, lt) = pred;
Some(WherePredicate::BoundPredicate {
- ty: clean_middle_ty(ty, cx, None),
+ ty: clean_middle_ty(ty::Binder::dummy(ty), cx, None),
bounds: vec![GenericBound::Outlives(
clean_middle_region(lt).expect("failed to clean lifetimes"),
)],
@@ -367,10 +369,13 @@ fn clean_type_outlives_predicate<'tcx>(
})
}
-fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
- match term.unpack() {
- ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
- ty::TermKind::Const(c) => Term::Constant(clean_middle_const(c, cx)),
+fn clean_middle_term<'tcx>(
+ term: ty::Binder<'tcx, ty::Term<'tcx>>,
+ cx: &mut DocContext<'tcx>,
+) -> Term {
+ match term.skip_binder().unpack() {
+ ty::TermKind::Ty(ty) => Term::Type(clean_middle_ty(term.rebind(ty), cx, None)),
+ ty::TermKind::Const(c) => Term::Constant(clean_middle_const(term.rebind(c), cx)),
}
}
@@ -379,7 +384,10 @@ fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Te
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
hir::Term::Const(c) => {
let def_id = cx.tcx.hir().local_def_id(c.hir_id);
- Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx))
+ Term::Constant(clean_middle_const(
+ ty::Binder::dummy(ty::Const::from_anon_const(cx.tcx, def_id)),
+ cx,
+ ))
}
}
}
@@ -398,32 +406,31 @@ fn clean_projection_predicate<'tcx>(
})
.collect();
- let ty::ProjectionPredicate { projection_ty, term } = pred.skip_binder();
-
WherePredicate::EqPredicate {
- lhs: Box::new(clean_projection(projection_ty, cx, None)),
- rhs: Box::new(clean_middle_term(term, cx)),
+ lhs: Box::new(clean_projection(pred.map_bound(|p| p.projection_ty), cx, None)),
+ rhs: Box::new(clean_middle_term(pred.map_bound(|p| p.term), cx)),
bound_params: late_bound_regions,
}
}
fn clean_projection<'tcx>(
- ty: ty::ProjectionTy<'tcx>,
+ ty: ty::Binder<'tcx, ty::AliasTy<'tcx>>,
cx: &mut DocContext<'tcx>,
def_id: Option<DefId>,
) -> Type {
- if cx.tcx.def_kind(ty.item_def_id) == DefKind::ImplTraitPlaceholder {
+ if cx.tcx.def_kind(ty.skip_binder().def_id) == DefKind::ImplTraitPlaceholder {
let bounds = cx
.tcx
- .explicit_item_bounds(ty.item_def_id)
+ .explicit_item_bounds(ty.skip_binder().def_id)
.iter()
- .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.substs))
+ .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.skip_binder().substs))
.collect::<Vec<_>>();
return clean_middle_opaque_bounds(cx, bounds);
}
- let trait_ = clean_trait_ref_with_bindings(cx, ty.trait_ref(cx.tcx), ThinVec::new());
- let self_type = clean_middle_ty(ty.self_ty(), cx, None);
+ let trait_ =
+ clean_trait_ref_with_bindings(cx, ty.map_bound(|ty| ty.trait_ref(cx.tcx)), ThinVec::new());
+ let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None);
let self_def_id = if let Some(def_id) = def_id {
cx.tcx.opt_parent(def_id).or(Some(def_id))
} else {
@@ -446,15 +453,16 @@ fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type
}
fn projection_to_path_segment<'tcx>(
- ty: ty::ProjectionTy<'tcx>,
+ ty: ty::Binder<'tcx, ty::AliasTy<'tcx>>,
cx: &mut DocContext<'tcx>,
) -> PathSegment {
- let item = cx.tcx.associated_item(ty.item_def_id);
- let generics = cx.tcx.generics_of(ty.item_def_id);
+ let item = cx.tcx.associated_item(ty.skip_binder().def_id);
+ let generics = cx.tcx.generics_of(ty.skip_binder().def_id);
PathSegment {
name: item.name,
args: GenericArgs::AngleBracketed {
- args: substs_to_args(cx, &ty.substs[generics.parent_count..], false).into(),
+ args: substs_to_args(cx, ty.map_bound(|ty| &ty.substs[generics.parent_count..]), false)
+ .into(),
bindings: Default::default(),
},
}
@@ -470,7 +478,11 @@ fn clean_generic_param_def<'tcx>(
}
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
let default = if has_default {
- Some(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id)))
+ Some(clean_middle_ty(
+ ty::Binder::dummy(cx.tcx.type_of(def.def_id)),
+ cx,
+ Some(def.def_id),
+ ))
} else {
None
};
@@ -488,9 +500,15 @@ fn clean_generic_param_def<'tcx>(
def.name,
GenericParamDefKind::Const {
did: def.def_id,
- ty: Box::new(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id))),
+ ty: Box::new(clean_middle_ty(
+ ty::Binder::dummy(cx.tcx.type_of(def.def_id)),
+ cx,
+ Some(def.def_id),
+ )),
default: match has_default {
- true => Some(Box::new(cx.tcx.const_param_default(def.def_id).to_string())),
+ true => Some(Box::new(
+ cx.tcx.const_param_default(def.def_id).subst_identity().to_string(),
+ )),
false => None,
},
},
@@ -733,8 +751,10 @@ fn clean_ty_generics<'tcx>(
.collect::<ThinVec<GenericParamDef>>();
// param index -> [(trait DefId, associated type name & generics, type, higher-ranked params)]
- let mut impl_trait_proj =
- FxHashMap::<u32, Vec<(DefId, PathSegment, Ty<'_>, Vec<GenericParamDef>)>>::default();
+ let mut impl_trait_proj = FxHashMap::<
+ u32,
+ Vec<(DefId, PathSegment, ty::Binder<'_, Ty<'_>>, Vec<GenericParamDef>)>,
+ >::default();
let where_predicates = preds
.predicates
@@ -783,8 +803,8 @@ fn clean_ty_generics<'tcx>(
let proj = projection.map(|p| {
(
- clean_projection(p.skip_binder().projection_ty, cx, None),
- p.skip_binder().term,
+ clean_projection(p.map_bound(|p| p.projection_ty), cx, None),
+ p.map_bound(|p| p.term),
)
});
if let Some(((_, trait_did, name), rhs)) = proj
@@ -795,7 +815,7 @@ fn clean_ty_generics<'tcx>(
impl_trait_proj.entry(param_idx).or_default().push((
trait_did,
name,
- rhs.ty().unwrap(),
+ rhs.map_bound(|rhs| rhs.ty().unwrap()),
p.get_bound_params()
.into_iter()
.flatten()
@@ -1066,7 +1086,7 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
// We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
// but shouldn't change any code meaning.
- let output = match clean_middle_ty(sig.skip_binder().output(), cx, None) {
+ let output = match clean_middle_ty(sig.output(), cx, None) {
Type::Tuple(inner) if inner.is_empty() => DefaultReturn,
ty => Return(ty),
};
@@ -1076,11 +1096,10 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
c_variadic: sig.skip_binder().c_variadic,
inputs: Arguments {
values: sig
- .skip_binder()
.inputs()
.iter()
.map(|t| Argument {
- type_: clean_middle_ty(*t, cx, None),
+ type_: clean_middle_ty(t.map_bound(|t| *t), cx, None),
name: names
.next()
.map(|i| i.name)
@@ -1134,7 +1153,8 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
hir::TraitItemKind::Type(bounds, Some(default)) => {
let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx));
let bounds = bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect();
- let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, default), cx, None);
+ let item_type =
+ clean_middle_ty(ty::Binder::dummy(hir_ty_to_ty(cx.tcx, default)), cx, None);
AssocTypeItem(
Box::new(Typedef {
type_: clean_ty(default, cx),
@@ -1173,7 +1193,8 @@ pub(crate) fn clean_impl_item<'tcx>(
hir::ImplItemKind::Type(hir_ty) => {
let type_ = clean_ty(hir_ty, cx);
let generics = clean_generics(impl_.generics, cx);
- let item_type = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
+ let item_type =
+ clean_middle_ty(ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)), cx, None);
AssocTypeItem(
Box::new(Typedef { type_, generics, item_type: Some(item_type) }),
Vec::new(),
@@ -1192,7 +1213,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
let tcx = cx.tcx;
let kind = match assoc_item.kind {
ty::AssocKind::Const => {
- let ty = clean_middle_ty(tcx.type_of(assoc_item.def_id), cx, Some(assoc_item.def_id));
+ let ty = clean_middle_ty(
+ ty::Binder::dummy(tcx.type_of(assoc_item.def_id)),
+ cx,
+ Some(assoc_item.def_id),
+ );
let provided = match assoc_item.container {
ty::ImplContainer => true,
@@ -1375,7 +1400,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
AssocTypeItem(
Box::new(Typedef {
type_: clean_middle_ty(
- tcx.type_of(assoc_item.def_id),
+ ty::Binder::dummy(tcx.type_of(assoc_item.def_id)),
cx,
Some(assoc_item.def_id),
),
@@ -1393,7 +1418,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
AssocTypeItem(
Box::new(Typedef {
type_: clean_middle_ty(
- tcx.type_of(assoc_item.def_id),
+ ty::Binder::dummy(tcx.type_of(assoc_item.def_id)),
cx,
Some(assoc_item.def_id),
),
@@ -1437,8 +1462,11 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
hir::QPath::Resolved(Some(qself), p) => {
// Try to normalize `<X as Y>::T` to a type
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
- if let Some(normalized_value) = normalize(cx, ty) {
- return clean_middle_ty(normalized_value, cx, None);
+ // `hir_to_ty` can return projection types with escaping vars for GATs, e.g. `<() as Trait>::Gat<'_>`
+ if !ty.has_escaping_bound_vars() {
+ if let Some(normalized_value) = normalize(cx, ty::Binder::dummy(ty)) {
+ return clean_middle_ty(normalized_value, cx, None);
+ }
}
let trait_segments = &p.segments[..p.segments.len() - 1];
@@ -1461,11 +1489,13 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
hir::QPath::TypeRelative(qself, segment) => {
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
let res = match ty.kind() {
- ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
+ ty::Alias(ty::Projection, proj) => {
+ Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id)
+ }
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
ty::Error(_) => return Type::Infer,
// Otherwise, this is an inherent associated type.
- _ => return clean_middle_ty(ty, cx, None),
+ _ => return clean_middle_ty(ty::Binder::dummy(ty), cx, None),
};
let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
register_res(cx, trait_.res);
@@ -1584,7 +1614,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
match ty.kind {
TyKind::Never => Primitive(PrimitiveType::Never),
TyKind::Ptr(ref m) => RawPointer(m.mutbl, Box::new(clean_ty(m.ty, cx))),
- TyKind::Rptr(ref l, ref m) => {
+ TyKind::Ref(ref l, ref m) => {
let lifetime = if l.is_anonymous() { None } else { Some(clean_lifetime(*l, cx)) };
BorrowedRef { lifetime, mutability: m.mutbl, type_: Box::new(clean_ty(m.ty, cx)) }
}
@@ -1632,7 +1662,10 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
}
/// Returns `None` if the type could not be normalized
-fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
+fn normalize<'tcx>(
+ cx: &mut DocContext<'tcx>,
+ ty: ty::Binder<'tcx, Ty<'tcx>>,
+) -> Option<ty::Binder<'tcx, Ty<'tcx>>> {
// HACK: low-churn fix for #79459 while we wait for a trait normalization fix
if !cx.tcx.sess.opts.unstable_opts.normalize_docs {
return None;
@@ -1660,14 +1693,14 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>>
}
}
+#[instrument(level = "trace", skip(cx), ret)]
pub(crate) fn clean_middle_ty<'tcx>(
- ty: Ty<'tcx>,
+ bound_ty: ty::Binder<'tcx, Ty<'tcx>>,
cx: &mut DocContext<'tcx>,
def_id: Option<DefId>,
) -> Type {
- trace!("cleaning type: {:?}", ty);
- let ty = normalize(cx, ty).unwrap_or(ty);
- match *ty.kind() {
+ let bound_ty = normalize(cx, bound_ty).unwrap_or(bound_ty);
+ match *bound_ty.skip_binder().kind() {
ty::Never => Primitive(PrimitiveType::Never),
ty::Bool => Primitive(PrimitiveType::Bool),
ty::Char => Primitive(PrimitiveType::Char),
@@ -1675,20 +1708,23 @@ pub(crate) fn clean_middle_ty<'tcx>(
ty::Uint(uint_ty) => Primitive(uint_ty.into()),
ty::Float(float_ty) => Primitive(float_ty.into()),
ty::Str => Primitive(PrimitiveType::Str),
- ty::Slice(ty) => Slice(Box::new(clean_middle_ty(ty, cx, None))),
+ ty::Slice(ty) => Slice(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None))),
ty::Array(ty, mut n) => {
n = n.eval(cx.tcx, ty::ParamEnv::reveal_all());
let n = print_const(cx, n);
- Array(Box::new(clean_middle_ty(ty, cx, None)), n.into())
+ Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None)), n.into())
+ }
+ ty::RawPtr(mt) => {
+ RawPointer(mt.mutbl, Box::new(clean_middle_ty(bound_ty.rebind(mt.ty), cx, None)))
}
- ty::RawPtr(mt) => RawPointer(mt.mutbl, Box::new(clean_middle_ty(mt.ty, cx, None))),
ty::Ref(r, ty, mutbl) => BorrowedRef {
lifetime: clean_middle_region(r),
mutability: mutbl,
- type_: Box::new(clean_middle_ty(ty, cx, None)),
+ type_: Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None)),
},
ty::FnDef(..) | ty::FnPtr(_) => {
- let sig = ty.fn_sig(cx.tcx);
+ // FIXME: should we merge the outer and inner binders somehow?
+ let sig = bound_ty.skip_binder().fn_sig(cx.tcx);
let decl = clean_fn_decl_from_did_and_sig(cx, None, sig);
BareFunction(Box::new(BareFunctionDecl {
unsafety: sig.unsafety(),
@@ -1705,12 +1741,18 @@ pub(crate) fn clean_middle_ty<'tcx>(
AdtKind::Enum => ItemType::Enum,
};
inline::record_extern_fqn(cx, did, kind);
- let path = external_path(cx, did, false, ThinVec::new(), substs);
+ let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(substs));
Type::Path { path }
}
ty::Foreign(did) => {
inline::record_extern_fqn(cx, did, ItemType::ForeignType);
- let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
+ let path = external_path(
+ cx,
+ did,
+ false,
+ ThinVec::new(),
+ ty::Binder::dummy(InternalSubsts::empty()),
+ );
Type::Path { path }
}
ty::Dynamic(obj, ref reg, _) => {
@@ -1721,11 +1763,11 @@ pub(crate) fn clean_middle_ty<'tcx>(
let did = obj
.principal_def_id()
.or_else(|| dids.next())
- .unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", ty));
+ .unwrap_or_else(|| panic!("found trait object `{bound_ty:?}` with no traits?"));
let substs = match obj.principal() {
- Some(principal) => principal.skip_binder().substs,
+ Some(principal) => principal.map_bound(|p| p.substs),
// marker traits have no substs.
- _ => cx.tcx.intern_substs(&[]),
+ _ => ty::Binder::dummy(InternalSubsts::empty()),
};
inline::record_extern_fqn(cx, did, ItemType::Trait);
@@ -1736,7 +1778,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
let lifetime = clean_middle_region(*reg);
let mut bounds = dids
.map(|did| {
- let empty = cx.tcx.intern_substs(&[]);
+ let empty = ty::Binder::dummy(InternalSubsts::empty());
let path = external_path(cx, did, false, ThinVec::new(), empty);
inline::record_extern_fqn(cx, did, ItemType::Trait);
PolyTrait { trait_: path, generic_params: Vec::new() }
@@ -1747,15 +1789,17 @@ pub(crate) fn clean_middle_ty<'tcx>(
.projection_bounds()
.map(|pb| TypeBinding {
assoc: projection_to_path_segment(
- pb.skip_binder()
- // HACK(compiler-errors): Doesn't actually matter what self
- // type we put here, because we're only using the GAT's substs.
- .with_self_ty(cx.tcx, cx.tcx.types.self_param)
- .projection_ty,
+ pb.map_bound(|pb| {
+ pb
+ // HACK(compiler-errors): Doesn't actually matter what self
+ // type we put here, because we're only using the GAT's substs.
+ .with_self_ty(cx.tcx, cx.tcx.types.self_param)
+ .projection_ty
+ }),
cx,
),
kind: TypeBindingKind::Equality {
- term: clean_middle_term(pb.skip_binder().term, cx),
+ term: clean_middle_term(pb.map_bound(|pb| pb.term), cx),
},
})
.collect();
@@ -1779,9 +1823,11 @@ pub(crate) fn clean_middle_ty<'tcx>(
DynTrait(bounds, lifetime)
}
- ty::Tuple(t) => Tuple(t.iter().map(|t| clean_middle_ty(t, cx, None)).collect()),
+ ty::Tuple(t) => {
+ Tuple(t.iter().map(|t| clean_middle_ty(bound_ty.rebind(t), cx, None)).collect())
+ }
- ty::Projection(ref data) => clean_projection(*data, cx, def_id),
+ ty::Alias(ty::Projection, ref data) => clean_projection(bound_ty.rebind(*data), cx, def_id),
ty::Param(ref p) => {
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
@@ -1791,7 +1837,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
}
}
- ty::Opaque(def_id, substs) => {
+ ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
// by looking up the bounds associated with the def_id.
let bounds = cx
@@ -1809,7 +1855,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
ty::Placeholder(..) => panic!("Placeholder"),
ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
ty::Infer(..) => panic!("Infer"),
- ty::Error(_) => panic!("Error"),
+ ty::Error(_) => rustc_errors::FatalError.raise(),
}
}
@@ -1854,9 +1900,12 @@ fn clean_middle_opaque_bounds<'tcx>(
{
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
Some(TypeBinding {
- assoc: projection_to_path_segment(proj.projection_ty, cx),
+ assoc: projection_to_path_segment(
+ bound.kind().rebind(proj.projection_ty),
+ cx,
+ ),
kind: TypeBindingKind::Equality {
- term: clean_middle_term(proj.term, cx),
+ term: clean_middle_term(bound.kind().rebind(proj.term), cx),
},
})
} else {
@@ -1887,7 +1936,7 @@ pub(crate) fn clean_middle_field<'tcx>(field: &ty::FieldDef, cx: &mut DocContext
clean_field_with_def_id(
field.did,
field.name,
- clean_middle_ty(cx.tcx.type_of(field.did), cx, Some(field.did)),
+ clean_middle_ty(ty::Binder::dummy(cx.tcx.type_of(field.did)), cx, Some(field.did)),
cx,
)
}
@@ -1902,20 +1951,27 @@ pub(crate) fn clean_field_with_def_id(
}
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
+ let discriminant = match variant.discr {
+ ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
+ ty::VariantDiscr::Relative(_) => None,
+ };
+
let kind = match variant.ctor_kind() {
- Some(CtorKind::Const) => Variant::CLike(match variant.discr {
- ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
- ty::VariantDiscr::Relative(_) => None,
- }),
- Some(CtorKind::Fn) => Variant::Tuple(
+ Some(CtorKind::Const) => VariantKind::CLike,
+ Some(CtorKind::Fn) => VariantKind::Tuple(
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
),
- None => Variant::Struct(VariantStruct {
- ctor_kind: None,
+ None => VariantKind::Struct(VariantStruct {
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
}),
};
- Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx)
+
+ Item::from_def_id_and_parts(
+ variant.def_id,
+ Some(variant.name),
+ VariantItem(Variant { kind, discriminant }),
+ cx,
+ )
}
fn clean_variant_data<'tcx>(
@@ -1923,19 +1979,22 @@ fn clean_variant_data<'tcx>(
disr_expr: &Option<hir::AnonConst>,
cx: &mut DocContext<'tcx>,
) -> Variant {
- match variant {
- hir::VariantData::Struct(..) => Variant::Struct(VariantStruct {
- ctor_kind: None,
+ let discriminant = disr_expr.map(|disr| Discriminant {
+ expr: Some(disr.body),
+ value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(),
+ });
+
+ let kind = match variant {
+ hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct {
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
hir::VariantData::Tuple(..) => {
- Variant::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
+ VariantKind::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
}
- hir::VariantData::Unit(..) => Variant::CLike(disr_expr.map(|disr| Discriminant {
- expr: Some(disr.body),
- value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(),
- })),
- }
+ hir::VariantData::Unit(..) => VariantKind::CLike,
+ };
+
+ Variant { discriminant, kind }
}
fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {
@@ -2052,10 +2111,12 @@ fn get_all_import_attributes<'hir>(
) {
let hir_map = tcx.hir();
let mut visitor = OneLevelVisitor::new(hir_map, target_hir_id);
+ let mut visited = FxHashSet::default();
// If the item is an import and has at least a path with two parts, we go into it.
while let hir::ItemKind::Use(path, _) = item.kind &&
path.segments.len() > 1 &&
- let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res
+ let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res &&
+ visited.insert(def_id)
{
if let Some(hir::Node::Item(parent_item)) = hir_map.get_if_local(def_id) {
// We add the attributes from this import into the list.
@@ -2100,7 +2161,7 @@ fn clean_maybe_renamed_item<'tcx>(
}),
ItemKind::TyAlias(hir_ty, generics) => {
let rustdoc_ty = clean_ty(hir_ty, cx);
- let ty = clean_middle_ty(hir_ty_to_ty(cx.tcx, hir_ty), cx, None);
+ let ty = clean_middle_ty(ty::Binder::dummy(hir_ty_to_ty(cx.tcx, hir_ty)), cx, None);
TypedefItem(Box::new(Typedef {
type_: rustdoc_ty,
generics: clean_generics(generics, cx),
@@ -2211,7 +2272,9 @@ fn clean_impl<'tcx>(
let for_ = clean_ty(impl_.self_ty, cx);
let type_alias = for_.def_id(&cx.cache).and_then(|did| match tcx.def_kind(did) {
- DefKind::TyAlias => Some(clean_middle_ty(tcx.type_of(did), cx, Some(did))),
+ DefKind::TyAlias => {
+ Some(clean_middle_ty(ty::Binder::dummy(tcx.type_of(did)), cx, Some(did)))
+ }
_ => None,
});
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
@@ -2380,7 +2443,8 @@ fn clean_use_statement_inner<'tcx>(
let inner = if kind == hir::UseKind::Glob {
if !denied {
let mut visited = FxHashSet::default();
- if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited, inlined_names)
+ if let Some(items) =
+ inline::try_inline_glob(cx, path.res, current_mod, &mut visited, inlined_names)
{
return items;
}
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index e96a9bab7..dbbc25739 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -46,7 +46,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> ThinVec<WP
// Look for equality predicates on associated types that can be merged into
// general bound predicates.
- equalities.retain(|&(ref lhs, ref rhs, ref bound_params)| {
+ equalities.retain(|(lhs, rhs, bound_params)| {
let Some((ty, trait_did, name)) = lhs.projection() else { return true; };
let Some((bounds, _)) = tybounds.get_mut(ty) else { return true };
let bound_params = bound_params
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 2590bb0df..87de41fde 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -10,7 +10,6 @@ use std::{cmp, fmt, iter};
use arrayvec::ArrayVec;
use thin_vec::ThinVec;
-use rustc_ast::attr;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_ast::{self as ast, AttrStyle};
use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
@@ -27,7 +26,6 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility};
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
-use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, FileName, Loc};
use rustc_target::abi::VariantIdx;
@@ -64,8 +62,6 @@ pub(crate) enum ItemId {
Auto { trait_: DefId, for_: DefId },
/// Identifier that is used for blanket implementations.
Blanket { impl_id: DefId, for_: DefId },
- /// Identifier for primitive types.
- Primitive(PrimitiveType, CrateNum),
}
impl ItemId {
@@ -75,7 +71,6 @@ impl ItemId {
ItemId::Auto { for_: id, .. }
| ItemId::Blanket { for_: id, .. }
| ItemId::DefId(id) => id.is_local(),
- ItemId::Primitive(_, krate) => krate == LOCAL_CRATE,
}
}
@@ -100,7 +95,6 @@ impl ItemId {
ItemId::Auto { for_: id, .. }
| ItemId::Blanket { for_: id, .. }
| ItemId::DefId(id) => id.krate,
- ItemId::Primitive(_, krate) => krate,
}
}
}
@@ -682,7 +676,8 @@ impl Item {
}
let header = match *self.kind {
ItemKind::ForeignFunctionItem(_) => {
- let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi();
+ let def_id = self.item_id.as_def_id().unwrap();
+ let abi = tcx.fn_sig(def_id).abi();
hir::FnHeader {
unsafety: if abi == Abi::RustIntrinsic {
intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap())
@@ -690,7 +685,14 @@ impl Item {
hir::Unsafety::Unsafe
},
abi,
- constness: hir::Constness::NotConst,
+ constness: if abi == Abi::RustIntrinsic
+ && tcx.is_const_fn(def_id)
+ && is_unstable_const_fn(tcx, def_id).is_none()
+ {
+ hir::Constness::Const
+ } else {
+ hir::Constness::NotConst
+ },
asyncness: hir::IsAsync::NotAsync,
}
}
@@ -709,15 +711,13 @@ impl Item {
let def_id = match self.item_id {
// Anything but DefId *shouldn't* matter, but return a reasonable value anyway.
ItemId::Auto { .. } | ItemId::Blanket { .. } => return None,
- // Primitives and Keywords are written in the source code as private modules.
- // The modules need to be private so that nobody actually uses them, but the
- // keywords and primitives that they are documenting are public.
- ItemId::Primitive(..) => return Some(Visibility::Public),
ItemId::DefId(def_id) => def_id,
};
match *self.kind {
- // Explication on `ItemId::Primitive` just above.
+ // Primitives and Keywords are written in the source code as private modules.
+ // The modules need to be private so that nobody actually uses them, but the
+ // keywords and primitives that they are documenting are public.
ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public),
// Variant fields inherit their enum's visibility.
StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => {
@@ -809,8 +809,11 @@ impl ItemKind {
match self {
StructItem(s) => s.fields.iter(),
UnionItem(u) => u.fields.iter(),
- VariantItem(Variant::Struct(v)) => v.fields.iter(),
- VariantItem(Variant::Tuple(v)) => v.iter(),
+ VariantItem(v) => match &v.kind {
+ VariantKind::CLike => [].iter(),
+ VariantKind::Tuple(t) => t.iter(),
+ VariantKind::Struct(s) => s.fields.iter(),
+ },
EnumItem(e) => e.variants.iter(),
TraitItem(t) => t.items.iter(),
ImplItem(i) => i.items.iter(),
@@ -826,7 +829,6 @@ impl ItemKind {
| TyMethodItem(_)
| MethodItem(_, _)
| StructFieldItem(_)
- | VariantItem(_)
| ForeignFunctionItem(_)
| ForeignStaticItem(_)
| ForeignTypeItem
@@ -982,12 +984,12 @@ impl AttributesExt for [ast::Attribute] {
// #[doc(cfg(target_feature = "feat"))] attributes as well
for attr in self.lists(sym::target_feature) {
if attr.has_name(sym::enable) {
- if let Some(feat) = attr.value_str() {
- let meta = attr::mk_name_value_item_str(
- Ident::with_dummy_span(sym::target_feature),
- feat,
- DUMMY_SP,
- );
+ if attr.value_str().is_some() {
+ // Clone `enable = "feat"`, change to `target_feature = "feat"`.
+ // Unwrap is safe because `value_str` succeeded above.
+ let mut meta = attr.meta_item().unwrap().clone();
+ meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
+
if let Ok(feat_cfg) = Cfg::parse(&meta) {
cfg &= feat_cfg;
}
@@ -1345,7 +1347,7 @@ pub(crate) enum GenericBound {
impl GenericBound {
pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
let did = cx.tcx.require_lang_item(LangItem::Sized, None);
- let empty = cx.tcx.intern_substs(&[]);
+ let empty = ty::Binder::dummy(ty::InternalSubsts::empty());
let path = external_path(cx, did, false, ThinVec::new(), empty);
inline::record_extern_fqn(cx, did, ItemType::Trait);
GenericBound::TraitBound(
@@ -1742,7 +1744,7 @@ impl Type {
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
let t: PrimitiveType = match *self {
Type::Path { ref path } => return Some(path.def_id()),
- DynTrait(ref bounds, _) => return Some(bounds[0].trait_.def_id()),
+ DynTrait(ref bounds, _) => return bounds.get(0).map(|b| b.trait_.def_id()),
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
@@ -1872,7 +1874,7 @@ impl PrimitiveType {
}
pub(crate) fn simplified_types() -> &'static SimplifiedTypes {
- use ty::fast_reject::SimplifiedTypeGen::*;
+ use ty::fast_reject::SimplifiedType::*;
use ty::{FloatTy, IntTy, UintTy};
use PrimitiveType::*;
static CELL: OnceCell<SimplifiedTypes> = OnceCell::new();
@@ -2111,7 +2113,6 @@ impl Union {
/// only as a variant in an enum.
#[derive(Clone, Debug)]
pub(crate) struct VariantStruct {
- pub(crate) ctor_kind: Option<CtorKind>,
pub(crate) fields: Vec<Item>,
}
@@ -2138,17 +2139,23 @@ impl Enum {
}
#[derive(Clone, Debug)]
-pub(crate) enum Variant {
- CLike(Option<Discriminant>),
+pub(crate) struct Variant {
+ pub kind: VariantKind,
+ pub discriminant: Option<Discriminant>,
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum VariantKind {
+ CLike,
Tuple(Vec<Item>),
Struct(VariantStruct),
}
impl Variant {
pub(crate) fn has_stripped_entries(&self) -> Option<bool> {
- match *self {
- Self::Struct(ref struct_) => Some(struct_.has_stripped_entries()),
- Self::CLike(..) | Self::Tuple(_) => None,
+ match &self.kind {
+ VariantKind::Struct(struct_) => Some(struct_.has_stripped_entries()),
+ VariantKind::CLike | VariantKind::Tuple(_) => None,
}
}
}
@@ -2489,6 +2496,17 @@ impl Import {
pub(crate) fn new_glob(source: ImportSource, should_be_displayed: bool) -> Self {
Self { kind: ImportKind::Glob, source, should_be_displayed }
}
+
+ pub(crate) fn imported_item_is_doc_hidden(&self, tcx: TyCtxt<'_>) -> bool {
+ match self.source.did {
+ Some(did) => tcx
+ .get_attrs(did, sym::doc)
+ .filter_map(ast::Attribute::meta_item_list)
+ .flatten()
+ .has_word(sym::hidden),
+ None => false,
+ }
+ }
}
#[derive(Clone, Debug)]
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 246560bad..a12f764fa 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -78,12 +78,16 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
pub(crate) fn substs_to_args<'tcx>(
cx: &mut DocContext<'tcx>,
- substs: &[ty::subst::GenericArg<'tcx>],
+ substs: ty::Binder<'tcx, &[ty::subst::GenericArg<'tcx>]>,
mut skip_first: bool,
) -> Vec<GenericArg> {
let mut ret_val =
- Vec::with_capacity(substs.len().saturating_sub(if skip_first { 1 } else { 0 }));
- ret_val.extend(substs.iter().filter_map(|kind| match kind.unpack() {
+ Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
+ 1
+ } else {
+ 0
+ }));
+ ret_val.extend(substs.iter().filter_map(|kind| match kind.skip_binder().unpack() {
GenericArgKind::Lifetime(lt) => {
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
}
@@ -91,8 +95,12 @@ pub(crate) fn substs_to_args<'tcx>(
skip_first = false;
None
}
- GenericArgKind::Type(ty) => Some(GenericArg::Type(clean_middle_ty(ty, cx, None))),
- GenericArgKind::Const(ct) => Some(GenericArg::Const(Box::new(clean_middle_const(ct, cx)))),
+ GenericArgKind::Type(ty) => {
+ Some(GenericArg::Type(clean_middle_ty(kind.rebind(ty), cx, None)))
+ }
+ GenericArgKind::Const(ct) => {
+ Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx))))
+ }
}));
ret_val
}
@@ -102,15 +110,20 @@ fn external_generic_args<'tcx>(
did: DefId,
has_self: bool,
bindings: ThinVec<TypeBinding>,
- substs: SubstsRef<'tcx>,
+ substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
) -> GenericArgs {
- let args = substs_to_args(cx, substs, has_self);
+ let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self);
if cx.tcx.fn_trait_kind_from_def_id(did).is_some() {
+ let ty = substs
+ .iter()
+ .nth(if has_self { 1 } else { 0 })
+ .unwrap()
+ .map_bound(|arg| arg.expect_ty());
let inputs =
// The trait's first substitution is the one after self, if there is one.
- match substs.iter().nth(if has_self { 1 } else { 0 }).unwrap().expect_ty().kind() {
- ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(t, cx, None)).collect::<Vec<_>>().into(),
+ match ty.skip_binder().kind() {
+ ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None)).collect::<Vec<_>>().into(),
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
};
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
@@ -130,7 +143,7 @@ pub(super) fn external_path<'tcx>(
did: DefId,
has_self: bool,
bindings: ThinVec<TypeBinding>,
- substs: SubstsRef<'tcx>,
+ substs: ty::Binder<'tcx, SubstsRef<'tcx>>,
) -> Path {
let def_kind = cx.tcx.def_kind(did);
let name = cx.tcx.item_name(did);