librustdoc
: flatten nested ifs
This commit is contained in:
parent
4559163ccb
commit
fde37335aa
14 changed files with 203 additions and 220 deletions
|
@ -563,11 +563,13 @@ pub(crate) fn build_impl(
|
||||||
// Return if the trait itself or any types of the generic parameters are doc(hidden).
|
// Return if the trait itself or any types of the generic parameters are doc(hidden).
|
||||||
let mut stack: Vec<&Type> = vec![&for_];
|
let mut stack: Vec<&Type> = vec![&for_];
|
||||||
|
|
||||||
if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
|
if let Some(did) = trait_.as_ref().map(|t| t.def_id())
|
||||||
if !document_hidden && tcx.is_doc_hidden(did) {
|
&& !document_hidden
|
||||||
return;
|
&& tcx.is_doc_hidden(did)
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
|
if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
|
||||||
stack.extend(generics);
|
stack.extend(generics);
|
||||||
}
|
}
|
||||||
|
|
|
@ -828,30 +828,26 @@ fn clean_ty_generics<'tcx>(
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(pred, _)| {
|
.flat_map(|(pred, _)| {
|
||||||
let mut projection = None;
|
let mut projection = None;
|
||||||
let param_idx = (|| {
|
let param_idx = {
|
||||||
let bound_p = pred.kind();
|
let bound_p = pred.kind();
|
||||||
match bound_p.skip_binder() {
|
match bound_p.skip_binder() {
|
||||||
ty::ClauseKind::Trait(pred) => {
|
ty::ClauseKind::Trait(pred) if let ty::Param(param) = pred.self_ty().kind() => {
|
||||||
if let ty::Param(param) = pred.self_ty().kind() {
|
Some(param.index)
|
||||||
return Some(param.index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg))
|
||||||
if let ty::Param(param) = ty.kind() {
|
if let ty::Param(param) = ty.kind() =>
|
||||||
return Some(param.index);
|
{
|
||||||
}
|
Some(param.index)
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Projection(p) => {
|
ty::ClauseKind::Projection(p)
|
||||||
if let ty::Param(param) = p.projection_term.self_ty().kind() {
|
if let ty::Param(param) = p.projection_term.self_ty().kind() =>
|
||||||
projection = Some(bound_p.rebind(p));
|
{
|
||||||
return Some(param.index);
|
projection = Some(bound_p.rebind(p));
|
||||||
}
|
Some(param.index)
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => None,
|
||||||
}
|
}
|
||||||
|
};
|
||||||
None
|
|
||||||
})();
|
|
||||||
|
|
||||||
if let Some(param_idx) = param_idx
|
if let Some(param_idx) = param_idx
|
||||||
&& let Some(bounds) = impl_trait.get_mut(¶m_idx)
|
&& let Some(bounds) = impl_trait.get_mut(¶m_idx)
|
||||||
|
@ -1378,12 +1374,12 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
||||||
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
|
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
|
||||||
if self_arg_ty == self_ty {
|
if self_arg_ty == self_ty {
|
||||||
item.decl.inputs.values[0].type_ = SelfTy;
|
item.decl.inputs.values[0].type_ = SelfTy;
|
||||||
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
|
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind()
|
||||||
if ty == self_ty {
|
&& ty == self_ty
|
||||||
match item.decl.inputs.values[0].type_ {
|
{
|
||||||
BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
|
match item.decl.inputs.values[0].type_ {
|
||||||
_ => unreachable!(),
|
BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
|
||||||
}
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2331,25 +2327,22 @@ fn clean_middle_opaque_bounds<'tcx>(
|
||||||
let bindings: ThinVec<_> = bounds
|
let bindings: ThinVec<_> = bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(bound, _)| {
|
.filter_map(|(bound, _)| {
|
||||||
if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
|
if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder()
|
||||||
if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() {
|
&& proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder()
|
||||||
Some(AssocItemConstraint {
|
{
|
||||||
assoc: projection_to_path_segment(
|
return Some(AssocItemConstraint {
|
||||||
// FIXME: This needs to be made resilient for `AliasTerm`s that
|
assoc: projection_to_path_segment(
|
||||||
// are associated consts.
|
// FIXME: This needs to be made resilient for `AliasTerm`s that
|
||||||
bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
|
// are associated consts.
|
||||||
cx,
|
bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
|
||||||
),
|
cx,
|
||||||
kind: AssocItemConstraintKind::Equality {
|
),
|
||||||
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
|
kind: AssocItemConstraintKind::Equality {
|
||||||
},
|
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
|
||||||
})
|
},
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -2743,23 +2736,20 @@ fn add_without_unwanted_attributes<'hir>(
|
||||||
}
|
}
|
||||||
let mut attr = attr.clone();
|
let mut attr = attr.clone();
|
||||||
match attr {
|
match attr {
|
||||||
hir::Attribute::Unparsed(ref mut normal) => {
|
hir::Attribute::Unparsed(ref mut normal) if let [ident] = &*normal.path.segments => {
|
||||||
if let [ident] = &*normal.path.segments {
|
let ident = ident.name;
|
||||||
let ident = ident.name;
|
if ident == sym::doc {
|
||||||
if ident == sym::doc {
|
filter_doc_attr(&mut normal.args, is_inline);
|
||||||
filter_doc_attr(&mut normal.args, is_inline);
|
attrs.push((Cow::Owned(attr), import_parent));
|
||||||
attrs.push((Cow::Owned(attr), import_parent));
|
} else if is_inline || ident != sym::cfg {
|
||||||
} else if is_inline || ident != sym::cfg {
|
// If it's not a `cfg()` attribute, we keep it.
|
||||||
// If it's not a `cfg()` attribute, we keep it.
|
|
||||||
attrs.push((Cow::Owned(attr), import_parent));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hir::Attribute::Parsed(..) => {
|
|
||||||
if is_inline {
|
|
||||||
attrs.push((Cow::Owned(attr), import_parent));
|
attrs.push((Cow::Owned(attr), import_parent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hir::Attribute::Parsed(..) if is_inline => {
|
||||||
|
attrs.push((Cow::Owned(attr), import_parent));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2961,16 +2951,16 @@ fn clean_extern_crate<'tcx>(
|
||||||
&& !cx.is_json_output();
|
&& !cx.is_json_output();
|
||||||
|
|
||||||
let krate_owner_def_id = krate.owner_id.def_id;
|
let krate_owner_def_id = krate.owner_id.def_id;
|
||||||
if please_inline {
|
if please_inline
|
||||||
if let Some(items) = inline::try_inline(
|
&& let Some(items) = inline::try_inline(
|
||||||
cx,
|
cx,
|
||||||
Res::Def(DefKind::Mod, crate_def_id),
|
Res::Def(DefKind::Mod, crate_def_id),
|
||||||
name,
|
name,
|
||||||
Some((attrs, Some(krate_owner_def_id))),
|
Some((attrs, Some(krate_owner_def_id))),
|
||||||
&mut Default::default(),
|
&mut Default::default(),
|
||||||
) {
|
)
|
||||||
return items;
|
{
|
||||||
}
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec![Item::from_def_id_and_parts(
|
vec![Item::from_def_id_and_parts(
|
||||||
|
|
|
@ -208,11 +208,11 @@ impl ExternalCrate {
|
||||||
.get_attrs(def_id, sym::doc)
|
.get_attrs(def_id, sym::doc)
|
||||||
.flat_map(|attr| attr.meta_item_list().unwrap_or_default());
|
.flat_map(|attr| attr.meta_item_list().unwrap_or_default());
|
||||||
for meta in meta_items {
|
for meta in meta_items {
|
||||||
if meta.has_name(sym::keyword) {
|
if meta.has_name(sym::keyword)
|
||||||
if let Some(v) = meta.value_str() {
|
&& let Some(v) = meta.value_str()
|
||||||
keyword = Some(v);
|
{
|
||||||
break;
|
keyword = Some(v);
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return keyword.map(|p| (def_id, p));
|
return keyword.map(|p| (def_id, p));
|
||||||
|
@ -1071,16 +1071,14 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
|
||||||
// treat #[target_feature(enable = "feat")] attributes as if they were
|
// treat #[target_feature(enable = "feat")] attributes as if they were
|
||||||
// #[doc(cfg(target_feature = "feat"))] attributes as well
|
// #[doc(cfg(target_feature = "feat"))] attributes as well
|
||||||
for attr in hir_attr_lists(attrs, sym::target_feature) {
|
for attr in hir_attr_lists(attrs, sym::target_feature) {
|
||||||
if attr.has_name(sym::enable) {
|
if attr.has_name(sym::enable) && attr.value_str().is_some() {
|
||||||
if attr.value_str().is_some() {
|
// Clone `enable = "feat"`, change to `target_feature = "feat"`.
|
||||||
// Clone `enable = "feat"`, change to `target_feature = "feat"`.
|
// Unwrap is safe because `value_str` succeeded above.
|
||||||
// Unwrap is safe because `value_str` succeeded above.
|
let mut meta = attr.meta_item().unwrap().clone();
|
||||||
let mut meta = attr.meta_item().unwrap().clone();
|
meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
|
||||||
meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
|
|
||||||
|
|
||||||
if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) {
|
if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) {
|
||||||
cfg &= feat_cfg;
|
cfg &= feat_cfg;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1160,10 +1158,10 @@ impl Attributes {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(items) = attr.meta_item_list() {
|
if let Some(items) = attr.meta_item_list()
|
||||||
if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) {
|
&& items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag))
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -645,10 +645,10 @@ impl Options {
|
||||||
|
|
||||||
let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
|
let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
|
||||||
|
|
||||||
if let Some(ref p) = extension_css {
|
if let Some(ref p) = extension_css
|
||||||
if !p.is_file() {
|
&& !p.is_file()
|
||||||
dcx.fatal("option --extend-css argument must be a file");
|
{
|
||||||
}
|
dcx.fatal("option --extend-css argument must be a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut themes = Vec::new();
|
let mut themes = Vec::new();
|
||||||
|
@ -720,10 +720,10 @@ impl Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
|
let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
|
||||||
if let Some(ref index_page) = index_page {
|
if let Some(ref index_page) = index_page
|
||||||
if !index_page.is_file() {
|
&& !index_page.is_file()
|
||||||
dcx.fatal("option `--index-page` argument must be a file");
|
{
|
||||||
}
|
dcx.fatal("option `--index-page` argument must be a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = parse_target_triple(early_dcx, matches);
|
let target = parse_target_triple(early_dcx, matches);
|
||||||
|
|
|
@ -98,10 +98,9 @@ impl HirCollector<'_> {
|
||||||
let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
|
let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
|
||||||
if let Some(ref cfg) =
|
if let Some(ref cfg) =
|
||||||
extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default())
|
extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default())
|
||||||
|
&& !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features()))
|
||||||
{
|
{
|
||||||
if !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_name = !name.is_empty();
|
let has_name = !name.is_empty();
|
||||||
|
|
|
@ -419,7 +419,9 @@ impl DocFolder for CacheBuilder<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
|
if let Some(trait_) = &i.trait_
|
||||||
|
&& let Some(generics) = trait_.generics()
|
||||||
|
{
|
||||||
for bound in generics {
|
for bound in generics {
|
||||||
dids.extend(bound.def_id(self.cache));
|
dids.extend(bound.def_id(self.cache));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1102,53 +1102,52 @@ fn string_without_closing_tag<T: Display>(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(href_context) = href_context {
|
if let Some(href_context) = href_context
|
||||||
if let Some(href) =
|
&& let Some(href) = href_context.context.shared.span_correspondence_map.get(&def_span)
|
||||||
href_context.context.shared.span_correspondence_map.get(&def_span).and_then(|href| {
|
&& let Some(href) = {
|
||||||
let context = href_context.context;
|
let context = href_context.context;
|
||||||
// FIXME: later on, it'd be nice to provide two links (if possible) for all items:
|
// FIXME: later on, it'd be nice to provide two links (if possible) for all items:
|
||||||
// one to the documentation page and one to the source definition.
|
// one to the documentation page and one to the source definition.
|
||||||
// FIXME: currently, external items only generate a link to their documentation,
|
// FIXME: currently, external items only generate a link to their documentation,
|
||||||
// a link to their definition can be generated using this:
|
// a link to their definition can be generated using this:
|
||||||
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
|
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
|
||||||
match href {
|
match href {
|
||||||
LinkFromSrc::Local(span) => {
|
LinkFromSrc::Local(span) => {
|
||||||
context.href_from_span_relative(*span, &href_context.current_href)
|
context.href_from_span_relative(*span, &href_context.current_href)
|
||||||
}
|
|
||||||
LinkFromSrc::External(def_id) => {
|
|
||||||
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
|
|
||||||
.ok()
|
|
||||||
.map(|(url, _, _)| url)
|
|
||||||
}
|
|
||||||
LinkFromSrc::Primitive(prim) => format::href_with_root_path(
|
|
||||||
PrimitiveType::primitive_locations(context.tcx())[prim],
|
|
||||||
context,
|
|
||||||
Some(href_context.root_path),
|
|
||||||
)
|
|
||||||
.ok()
|
|
||||||
.map(|(url, _, _)| url),
|
|
||||||
LinkFromSrc::Doc(def_id) => {
|
|
||||||
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
|
|
||||||
.ok()
|
|
||||||
.map(|(doc_link, _, _)| doc_link)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
LinkFromSrc::External(def_id) => {
|
||||||
{
|
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
|
||||||
if !open_tag {
|
.ok()
|
||||||
// We're already inside an element which has the same klass, no need to give it
|
.map(|(url, _, _)| url)
|
||||||
// again.
|
}
|
||||||
write!(out, "<a href=\"{href}\">{text_s}").unwrap();
|
LinkFromSrc::Primitive(prim) => format::href_with_root_path(
|
||||||
} else {
|
PrimitiveType::primitive_locations(context.tcx())[prim],
|
||||||
let klass_s = klass.as_html();
|
context,
|
||||||
if klass_s.is_empty() {
|
Some(href_context.root_path),
|
||||||
write!(out, "<a href=\"{href}\">{text_s}").unwrap();
|
)
|
||||||
} else {
|
.ok()
|
||||||
write!(out, "<a class=\"{klass_s}\" href=\"{href}\">{text_s}").unwrap();
|
.map(|(url, _, _)| url),
|
||||||
|
LinkFromSrc::Doc(def_id) => {
|
||||||
|
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
|
||||||
|
.ok()
|
||||||
|
.map(|(doc_link, _, _)| doc_link)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Some("</a>");
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
if !open_tag {
|
||||||
|
// We're already inside an element which has the same klass, no need to give it
|
||||||
|
// again.
|
||||||
|
write!(out, "<a href=\"{href}\">{text_s}").unwrap();
|
||||||
|
} else {
|
||||||
|
let klass_s = klass.as_html();
|
||||||
|
if klass_s.is_empty() {
|
||||||
|
write!(out, "<a href=\"{href}\">{text_s}").unwrap();
|
||||||
|
} else {
|
||||||
|
write!(out, "<a class=\"{klass_s}\" href=\"{href}\">{text_s}").unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Some("</a>");
|
||||||
}
|
}
|
||||||
if !open_tag {
|
if !open_tag {
|
||||||
write!(out, "{}", text_s).unwrap();
|
write!(out, "{}", text_s).unwrap();
|
||||||
|
|
|
@ -1308,18 +1308,17 @@ impl LangString {
|
||||||
seen_other_tags = true;
|
seen_other_tags = true;
|
||||||
data.unknown.push(x.to_owned());
|
data.unknown.push(x.to_owned());
|
||||||
}
|
}
|
||||||
LangStringToken::KeyValueAttribute(key, value) => {
|
LangStringToken::KeyValueAttribute("class", value) => {
|
||||||
if key == "class" {
|
data.added_classes.push(value.to_owned());
|
||||||
data.added_classes.push(value.to_owned());
|
}
|
||||||
} else if let Some(extra) = extra {
|
LangStringToken::KeyValueAttribute(key, ..) if let Some(extra) = extra => {
|
||||||
extra.error_invalid_codeblock_attr(format!(
|
extra
|
||||||
"unsupported attribute `{key}`"
|
.error_invalid_codeblock_attr(format!("unsupported attribute `{key}`"));
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LangStringToken::ClassAttribute(class) => {
|
LangStringToken::ClassAttribute(class) => {
|
||||||
data.added_classes.push(class.to_owned());
|
data.added_classes.push(class.to_owned());
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,10 +95,8 @@ impl SpanMapVisitor<'_> {
|
||||||
.unwrap_or(path.span);
|
.unwrap_or(path.span);
|
||||||
self.matches.insert(span, link);
|
self.matches.insert(span, link);
|
||||||
}
|
}
|
||||||
Res::Local(_) => {
|
Res::Local(_) if let Some(span) = self.tcx.hir().res_span(path.res) => {
|
||||||
if let Some(span) = self.tcx.hir().res_span(path.res) {
|
self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span)));
|
||||||
self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Res::PrimTy(p) => {
|
Res::PrimTy(p) => {
|
||||||
// FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
|
// FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
|
||||||
|
@ -111,15 +109,15 @@ impl SpanMapVisitor<'_> {
|
||||||
|
|
||||||
/// Used to generate links on items' definition to go to their documentation page.
|
/// Used to generate links on items' definition to go to their documentation page.
|
||||||
pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
|
pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
|
||||||
if let Node::Item(item) = self.tcx.hir_node(hir_id) {
|
if let Node::Item(item) = self.tcx.hir_node(hir_id)
|
||||||
if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
|
&& let Some(span) = self.tcx.def_ident_span(item.owner_id)
|
||||||
let cspan = clean::Span::new(span);
|
{
|
||||||
// If the span isn't from the current crate, we ignore it.
|
let cspan = clean::Span::new(span);
|
||||||
if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
|
// If the span isn't from the current crate, we ignore it.
|
||||||
return;
|
if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
|
||||||
}
|
return;
|
||||||
self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
|
|
||||||
}
|
}
|
||||||
|
self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1334,14 +1334,12 @@ impl LinkCollector<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]`
|
// item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]`
|
||||||
if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
|
if let Some(dst_id) = id.as_local()
|
||||||
diag_info.item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
|
&& let Some(src_id) = diag_info.item.item_id.expect_def_id().as_local()
|
||||||
}) {
|
&& self.cx.tcx.effective_visibilities(()).is_exported(src_id)
|
||||||
if self.cx.tcx.effective_visibilities(()).is_exported(src_id)
|
&& !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
|
||||||
&& !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
|
{
|
||||||
{
|
privacy_error(self.cx, diag_info, path_str);
|
||||||
privacy_error(self.cx, diag_info, path_str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(())
|
Some(())
|
||||||
|
@ -1405,10 +1403,10 @@ impl LinkCollector<'_, '_> {
|
||||||
// which we want in some cases but not in others.
|
// which we want in some cases but not in others.
|
||||||
cache_errors: bool,
|
cache_errors: bool,
|
||||||
) -> Option<Vec<(Res, Option<UrlFragment>)>> {
|
) -> Option<Vec<(Res, Option<UrlFragment>)>> {
|
||||||
if let Some(res) = self.visited_links.get(&key) {
|
if let Some(res) = self.visited_links.get(&key)
|
||||||
if res.is_some() || cache_errors {
|
&& (res.is_some() || cache_errors)
|
||||||
return res.clone().map(|r| vec![r]);
|
{
|
||||||
}
|
return res.clone().map(|r| vec![r]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut candidates = self.resolve_with_disambiguator(&key, diag.clone());
|
let mut candidates = self.resolve_with_disambiguator(&key, diag.clone());
|
||||||
|
@ -1432,10 +1430,10 @@ impl LinkCollector<'_, '_> {
|
||||||
// and after removing duplicated kinds, only one remains, the `ambiguity_error` function
|
// and after removing duplicated kinds, only one remains, the `ambiguity_error` function
|
||||||
// won't emit an error. So at this point, we can just take the first candidate as it was
|
// won't emit an error. So at this point, we can just take the first candidate as it was
|
||||||
// the first retrieved and use it to generate the link.
|
// the first retrieved and use it to generate the link.
|
||||||
if let [candidate, _candidate2, ..] = *candidates {
|
if let [candidate, _candidate2, ..] = *candidates
|
||||||
if !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) {
|
&& !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false)
|
||||||
candidates = vec![candidate];
|
{
|
||||||
}
|
candidates = vec![candidate];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut out = Vec::with_capacity(candidates.len());
|
let mut out = Vec::with_capacity(candidates.len());
|
||||||
|
@ -1480,17 +1478,16 @@ impl LinkCollector<'_, '_> {
|
||||||
// See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach.
|
// See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach.
|
||||||
let mut err = ResolutionFailure::NotResolved(err);
|
let mut err = ResolutionFailure::NotResolved(err);
|
||||||
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
||||||
if other_ns != expected_ns {
|
if other_ns != expected_ns
|
||||||
if let Ok(&[res, ..]) = self
|
&& let Ok(&[res, ..]) = self
|
||||||
.resolve(path_str, other_ns, None, item_id, module_id)
|
.resolve(path_str, other_ns, None, item_id, module_id)
|
||||||
.as_deref()
|
.as_deref()
|
||||||
{
|
{
|
||||||
err = ResolutionFailure::WrongNamespace {
|
err = ResolutionFailure::WrongNamespace {
|
||||||
res: full_res(self.cx.tcx, res),
|
res: full_res(self.cx.tcx, res),
|
||||||
expected_ns,
|
expected_ns,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolution_failure(self, diag, path_str, disambiguator, smallvec![err]);
|
resolution_failure(self, diag, path_str, disambiguator, smallvec![err]);
|
||||||
|
@ -1674,11 +1671,11 @@ impl Disambiguator {
|
||||||
Ok(Some((d, &rest[1..], &rest[1..])))
|
Ok(Some((d, &rest[1..], &rest[1..])))
|
||||||
} else {
|
} else {
|
||||||
for (suffix, kind) in suffixes {
|
for (suffix, kind) in suffixes {
|
||||||
if let Some(path_str) = link.strip_suffix(suffix) {
|
// Avoid turning `!` or `()` into an empty string
|
||||||
// Avoid turning `!` or `()` into an empty string
|
if let Some(path_str) = link.strip_suffix(suffix)
|
||||||
if !path_str.is_empty() {
|
&& !path_str.is_empty()
|
||||||
return Ok(Some((Kind(kind), path_str, link)));
|
{
|
||||||
}
|
return Ok(Some((Kind(kind), path_str, link)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
|
|
@ -177,23 +177,22 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
||||||
} else if let Some(did) = target.def_id(&cx.cache) {
|
} else if let Some(did) = target.def_id(&cx.cache) {
|
||||||
cleaner.items.insert(did.into());
|
cleaner.items.insert(did.into());
|
||||||
}
|
}
|
||||||
if let Some(for_did) = for_.def_id(&cx.cache) {
|
if let Some(for_did) = for_.def_id(&cx.cache)
|
||||||
if type_did_to_deref_target.insert(for_did, target).is_none() {
|
&& type_did_to_deref_target.insert(for_did, target).is_none()
|
||||||
// Since only the `DefId` portion of the `Type` instances is known to be same for both the
|
// Since only the `DefId` portion of the `Type` instances is known to be same for both the
|
||||||
// `Deref` target type and the impl for type positions, this map of types is keyed by
|
// `Deref` target type and the impl for type positions, this map of types is keyed by
|
||||||
// `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
|
// `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
|
||||||
if cleaner.keep_impl_with_def_id(for_did.into()) {
|
&& cleaner.keep_impl_with_def_id(for_did.into())
|
||||||
let mut targets = DefIdSet::default();
|
{
|
||||||
targets.insert(for_did);
|
let mut targets = DefIdSet::default();
|
||||||
add_deref_target(
|
targets.insert(for_did);
|
||||||
cx,
|
add_deref_target(
|
||||||
&type_did_to_deref_target,
|
cx,
|
||||||
&mut cleaner,
|
&type_did_to_deref_target,
|
||||||
&mut targets,
|
&mut cleaner,
|
||||||
for_did,
|
&mut targets,
|
||||||
);
|
for_did,
|
||||||
}
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,9 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
|
||||||
// We don't try to detect stuff `<like, this>` because that's not valid HTML,
|
// We don't try to detect stuff `<like, this>` because that's not valid HTML,
|
||||||
// and we don't try to detect stuff `<like this>` because that's not valid Rust.
|
// and we don't try to detect stuff `<like this>` because that's not valid Rust.
|
||||||
let mut generics_end = range.end;
|
let mut generics_end = range.end;
|
||||||
if let Some(Some(mut generics_start)) = (is_open_tag
|
if is_open_tag
|
||||||
&& dox[..generics_end].ends_with('>'))
|
&& dox[..generics_end].ends_with('>')
|
||||||
.then(|| extract_path_backwards(dox, range.start))
|
&& let Some(mut generics_start) = extract_path_backwards(dox, range.start)
|
||||||
{
|
{
|
||||||
while generics_start != 0
|
while generics_start != 0
|
||||||
&& generics_end < dox.len()
|
&& generics_end < dox.len()
|
||||||
|
|
|
@ -73,15 +73,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
|
||||||
}
|
}
|
||||||
let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter();
|
let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter();
|
||||||
for (event, span) in parser_old {
|
for (event, span) in parser_old {
|
||||||
if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event {
|
if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event
|
||||||
if !dox[span.clone()].starts_with("> ") {
|
&& !dox[span.clone()].starts_with("> ")
|
||||||
spaceless_block_quotes.remove(&span.start);
|
{
|
||||||
}
|
spaceless_block_quotes.remove(&span.start);
|
||||||
}
|
}
|
||||||
if let cmarko::Event::FootnoteReference(_) = event {
|
if let cmarko::Event::FootnoteReference(_) = event
|
||||||
if !found_footnote_references.contains(&(span.start + 1)) {
|
&& !found_footnote_references.contains(&(span.start + 1))
|
||||||
missing_footnote_references.insert(span.start + 1, span);
|
{
|
||||||
}
|
missing_footnote_references.insert(span.start + 1, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,10 @@ impl LibEmbargoVisitor<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in self.tcx.module_children(def_id).iter() {
|
for item in self.tcx.module_children(def_id).iter() {
|
||||||
if let Some(def_id) = item.res.opt_def_id() {
|
if let Some(def_id) = item.res.opt_def_id()
|
||||||
if item.vis.is_public() {
|
&& item.vis.is_public()
|
||||||
self.visit_item(def_id);
|
{
|
||||||
}
|
self.visit_item(def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue