Auto merge of #66675 - GuillaumeGomez:support-anchors-intra-doc-links, r=kinnison
Support anchors intra doc links Fixes #62833 Part of #43466. cc @ollie27 r? @kinnison
This commit is contained in:
commit
b5f265eeed
|
@ -38,6 +38,11 @@ pub fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
|||
}
|
||||
}
|
||||
|
||||
enum ErrorKind {
|
||||
ResolutionFailure,
|
||||
AnchorFailure(&'static str),
|
||||
}
|
||||
|
||||
struct LinkCollector<'a, 'tcx> {
|
||||
cx: &'a DocContext<'tcx>,
|
||||
mod_ids: Vec<hir::HirId>,
|
||||
|
@ -53,13 +58,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
|
||||
/// Resolves a string as a path within a particular namespace. Also returns an optional
|
||||
/// URL fragment in the case of variants and methods.
|
||||
fn resolve(&self,
|
||||
fn resolve(
|
||||
&self,
|
||||
path_str: &str,
|
||||
ns: Namespace,
|
||||
current_item: &Option<String>,
|
||||
parent_id: Option<hir::HirId>)
|
||||
-> Result<(Res, Option<String>), ()>
|
||||
{
|
||||
parent_id: Option<hir::HirId>,
|
||||
extra_fragment: &Option<String>,
|
||||
) -> Result<(Res, Option<String>), ErrorKind> {
|
||||
let cx = self.cx;
|
||||
|
||||
// In case we're in a module, try to resolve the relative path.
|
||||
|
@ -69,8 +75,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns, module_id)
|
||||
});
|
||||
let result = match result {
|
||||
Ok((_, Res::Err)) => Err(()),
|
||||
_ => result,
|
||||
Ok((_, Res::Err)) => Err(ErrorKind::ResolutionFailure),
|
||||
_ => result.map_err(|_| ErrorKind::ResolutionFailure),
|
||||
};
|
||||
|
||||
if let Ok((_, res)) = result {
|
||||
|
@ -80,23 +86,36 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
let value = match res {
|
||||
Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssocConst, _) => true,
|
||||
Res::Def(DefKind::AssocTy, _) => false,
|
||||
Res::Def(DefKind::Variant, _) => return handle_variant(cx, res),
|
||||
Res::Def(DefKind::Variant, _) => {
|
||||
return handle_variant(cx, res, extra_fragment);
|
||||
}
|
||||
// Not a trait item; just return what we found.
|
||||
Res::PrimTy(..) => return Ok((res, Some(path_str.to_owned()))),
|
||||
_ => return Ok((res, None))
|
||||
Res::PrimTy(..) => {
|
||||
if extra_fragment.is_some() {
|
||||
return Err(
|
||||
ErrorKind::AnchorFailure(
|
||||
"primitive types cannot be followed by anchors"));
|
||||
}
|
||||
return Ok((res, Some(path_str.to_owned())));
|
||||
}
|
||||
_ => return Ok((res, extra_fragment.clone()))
|
||||
};
|
||||
|
||||
if value != (ns == ValueNS) {
|
||||
return Err(())
|
||||
return Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
} else if let Some(prim) = is_primitive(path_str, ns) {
|
||||
if extra_fragment.is_some() {
|
||||
return Err(
|
||||
ErrorKind::AnchorFailure("primitive types cannot be followed by anchors"));
|
||||
}
|
||||
return Ok((prim, Some(path_str.to_owned())))
|
||||
} else {
|
||||
// If resolution failed, it may still be a method
|
||||
// because methods are not handled by the resolver
|
||||
// If so, bail when we're not looking for a value.
|
||||
if ns != ValueNS {
|
||||
return Err(())
|
||||
return Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,13 +124,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
let item_name = if let Some(first) = split.next() {
|
||||
Symbol::intern(first)
|
||||
} else {
|
||||
return Err(())
|
||||
return Err(ErrorKind::ResolutionFailure)
|
||||
};
|
||||
|
||||
let mut path = if let Some(second) = split.next() {
|
||||
second.to_owned()
|
||||
} else {
|
||||
return Err(())
|
||||
return Err(ErrorKind::ResolutionFailure)
|
||||
};
|
||||
|
||||
if path == "self" || path == "Self" {
|
||||
|
@ -120,7 +139,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
if let Some(prim) = is_primitive(&path, TypeNS) {
|
||||
let did = primitive_impl(cx, &path).ok_or(())?;
|
||||
let did = primitive_impl(cx, &path).ok_or(ErrorKind::ResolutionFailure)?;
|
||||
return cx.tcx.associated_items(did)
|
||||
.find(|item| item.ident.name == item_name)
|
||||
.and_then(|item| match item.kind {
|
||||
|
@ -128,14 +147,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
_ => None,
|
||||
})
|
||||
.map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name))))
|
||||
.ok_or(());
|
||||
.ok_or(ErrorKind::ResolutionFailure);
|
||||
}
|
||||
|
||||
let (_, ty_res) = cx.enter_resolver(|resolver| {
|
||||
resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
|
||||
})?;
|
||||
}).map_err(|_| ErrorKind::ResolutionFailure)?;
|
||||
if let Res::Err = ty_res {
|
||||
return Err(());
|
||||
return Err(ErrorKind::ResolutionFailure);
|
||||
}
|
||||
let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
|
||||
match ty_res {
|
||||
|
@ -151,9 +170,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
let out = match item.kind {
|
||||
ty::AssocKind::Method if ns == ValueNS => "method",
|
||||
ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
|
||||
_ => return Err(())
|
||||
_ => return Err(ErrorKind::ResolutionFailure)
|
||||
};
|
||||
if extra_fragment.is_some() {
|
||||
Err(ErrorKind::AnchorFailure(
|
||||
if item.kind == ty::AssocKind::Method {
|
||||
"methods cannot be followed by anchors"
|
||||
} else {
|
||||
"associated constants cannot be followed by anchors"
|
||||
}))
|
||||
} else {
|
||||
Ok((ty_res, Some(format!("{}.{}", out, item_name))))
|
||||
}
|
||||
} else {
|
||||
match cx.tcx.type_of(did).kind {
|
||||
ty::Adt(def, _) => {
|
||||
|
@ -165,6 +193,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
.iter()
|
||||
.find(|item| item.ident.name == item_name)
|
||||
} {
|
||||
if extra_fragment.is_some() {
|
||||
Err(ErrorKind::AnchorFailure(
|
||||
if def.is_enum() {
|
||||
"enum variants cannot be followed by anchors"
|
||||
} else {
|
||||
"struct fields cannot be followed by anchors"
|
||||
}))
|
||||
} else {
|
||||
Ok((ty_res,
|
||||
Some(format!("{}.{}",
|
||||
if def.is_enum() {
|
||||
|
@ -173,11 +209,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
"structfield"
|
||||
},
|
||||
item.ident))))
|
||||
}
|
||||
} else {
|
||||
Err(())
|
||||
Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
}
|
||||
_ => Err(()),
|
||||
_ => Err(ErrorKind::ResolutionFailure),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,19 +233,30 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
"tymethod"
|
||||
}
|
||||
}
|
||||
_ => return Err(())
|
||||
_ => return Err(ErrorKind::ResolutionFailure)
|
||||
};
|
||||
|
||||
Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
|
||||
if extra_fragment.is_some() {
|
||||
Err(ErrorKind::AnchorFailure(
|
||||
if item.kind == ty::AssocKind::Const {
|
||||
"associated constants cannot be followed by anchors"
|
||||
} else if item.kind == ty::AssocKind::Type {
|
||||
"associated types cannot be followed by anchors"
|
||||
} else {
|
||||
Err(())
|
||||
"methods cannot be followed by anchors"
|
||||
}))
|
||||
} else {
|
||||
Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
|
||||
}
|
||||
} else {
|
||||
Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
}
|
||||
_ => Err(())
|
||||
_ => Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
} else {
|
||||
debug!("attempting to resolve item without parent module: {}", path_str);
|
||||
Err(())
|
||||
Err(ErrorKind::ResolutionFailure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,6 +337,22 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let link = ori_link.replace("`", "");
|
||||
let parts = link.split('#').collect::<Vec<_>>();
|
||||
let (link, extra_fragment) = if parts.len() > 2 {
|
||||
build_diagnostic(cx, &item, &link, &dox, link_range,
|
||||
"has an issue with the link anchor.",
|
||||
"only one `#` is allowed in a link",
|
||||
None);
|
||||
continue;
|
||||
} else if parts.len() == 2 {
|
||||
if parts[0].trim().is_empty() {
|
||||
// This is an anchor to an element of the current page, nothing to do in here!
|
||||
continue;
|
||||
}
|
||||
(parts[0].to_owned(), Some(parts[1].to_owned()))
|
||||
} else {
|
||||
(parts[0].to_owned(), None)
|
||||
};
|
||||
let (res, fragment) = {
|
||||
let mut kind = None;
|
||||
let path_str = if let Some(prefix) =
|
||||
|
@ -341,40 +405,71 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
|
||||
match kind {
|
||||
Some(ns @ ValueNS) => {
|
||||
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, base_node) {
|
||||
res
|
||||
} else {
|
||||
match self.resolve(path_str, ns, ¤t_item, base_node,
|
||||
&extra_fragment) {
|
||||
Ok(res) => res,
|
||||
Err(ErrorKind::ResolutionFailure) => {
|
||||
resolution_failure(cx, &item, path_str, &dox, link_range);
|
||||
// This could just be a normal link or a broken link
|
||||
// we could potentially check if something is
|
||||
// "intra-doc-link-like" and warn in that case.
|
||||
continue;
|
||||
}
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(ns @ TypeNS) => {
|
||||
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, base_node) {
|
||||
res
|
||||
} else {
|
||||
match self.resolve(path_str, ns, ¤t_item, base_node,
|
||||
&extra_fragment) {
|
||||
Ok(res) => res,
|
||||
Err(ErrorKind::ResolutionFailure) => {
|
||||
resolution_failure(cx, &item, path_str, &dox, link_range);
|
||||
// This could just be a normal link.
|
||||
continue;
|
||||
}
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Try everything!
|
||||
let candidates = PerNS {
|
||||
macro_ns: macro_resolve(cx, path_str).map(|res| (res, None)),
|
||||
type_ns: self
|
||||
.resolve(path_str, TypeNS, ¤t_item, base_node)
|
||||
.ok(),
|
||||
value_ns: self
|
||||
.resolve(path_str, ValueNS, ¤t_item, base_node)
|
||||
.ok()
|
||||
macro_ns: macro_resolve(cx, path_str)
|
||||
.map(|res| (res, extra_fragment.clone())),
|
||||
type_ns: match self.resolve(path_str, TypeNS, ¤t_item, base_node,
|
||||
&extra_fragment) {
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
continue;
|
||||
}
|
||||
x => x.ok(),
|
||||
},
|
||||
value_ns: match self.resolve(path_str, ValueNS, ¤t_item,
|
||||
base_node, &extra_fragment) {
|
||||
Err(ErrorKind::AnchorFailure(msg)) => {
|
||||
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
|
||||
continue;
|
||||
}
|
||||
x => x.ok(),
|
||||
}
|
||||
.and_then(|(res, fragment)| {
|
||||
// Constructors are picked up in the type namespace.
|
||||
match res {
|
||||
Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) => None,
|
||||
_ => Some((res, fragment))
|
||||
_ => match (fragment, extra_fragment) {
|
||||
(Some(fragment), Some(_)) => {
|
||||
// Shouldn't happen but who knows?
|
||||
Some((res, Some(fragment)))
|
||||
}
|
||||
(fragment, None) | (None, fragment) => {
|
||||
Some((res, fragment))
|
||||
}
|
||||
},
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
@ -402,7 +497,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||
}
|
||||
Some(MacroNS) => {
|
||||
if let Some(res) = macro_resolve(cx, path_str) {
|
||||
(res, None)
|
||||
(res, extra_fragment)
|
||||
} else {
|
||||
resolution_failure(cx, &item, path_str, &dox, link_range);
|
||||
continue
|
||||
|
@ -462,17 +557,15 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Reports a resolution failure diagnostic.
|
||||
///
|
||||
/// If we cannot find the exact source span of the resolution failure, we use the span of the
|
||||
/// documentation attributes themselves. This is a little heavy-handed, so we display the markdown
|
||||
/// line containing the failure as a note as well.
|
||||
fn resolution_failure(
|
||||
fn build_diagnostic(
|
||||
cx: &DocContext<'_>,
|
||||
item: &Item,
|
||||
path_str: &str,
|
||||
dox: &str,
|
||||
link_range: Option<Range<usize>>,
|
||||
err_msg: &str,
|
||||
short_err_msg: &str,
|
||||
help_msg: Option<&str>,
|
||||
) {
|
||||
let hir_id = match cx.as_local_hir_id(item.def_id) {
|
||||
Some(hir_id) => hir_id,
|
||||
|
@ -488,12 +581,12 @@ fn resolution_failure(
|
|||
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
hir_id,
|
||||
sp,
|
||||
&format!("`[{}]` cannot be resolved, ignoring it...", path_str),
|
||||
&format!("`[{}]` {}", path_str, err_msg),
|
||||
);
|
||||
if let Some(link_range) = link_range {
|
||||
if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) {
|
||||
diag.set_span(sp);
|
||||
diag.span_label(sp, "cannot be resolved, ignoring");
|
||||
diag.span_label(sp, short_err_msg);
|
||||
} else {
|
||||
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
|
||||
// ^ ~~~~
|
||||
|
@ -513,11 +606,44 @@ fn resolution_failure(
|
|||
));
|
||||
}
|
||||
};
|
||||
diag.help("to escape `[` and `]` characters, just add '\\' before them like \
|
||||
`\\[` or `\\]`");
|
||||
if let Some(help_msg) = help_msg {
|
||||
diag.help(help_msg);
|
||||
}
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
/// Reports a resolution failure diagnostic.
|
||||
///
|
||||
/// If we cannot find the exact source span of the resolution failure, we use the span of the
|
||||
/// documentation attributes themselves. This is a little heavy-handed, so we display the markdown
|
||||
/// line containing the failure as a note as well.
|
||||
fn resolution_failure(
|
||||
cx: &DocContext<'_>,
|
||||
item: &Item,
|
||||
path_str: &str,
|
||||
dox: &str,
|
||||
link_range: Option<Range<usize>>,
|
||||
) {
|
||||
build_diagnostic(cx, item, path_str, dox, link_range,
|
||||
"cannot be resolved, ignoring it.",
|
||||
"cannot be resolved, ignoring",
|
||||
Some("to escape `[` and `]` characters, just add '\\' before them like `\\[` or `\\]`"));
|
||||
}
|
||||
|
||||
fn anchor_failure(
|
||||
cx: &DocContext<'_>,
|
||||
item: &Item,
|
||||
path_str: &str,
|
||||
dox: &str,
|
||||
link_range: Option<Range<usize>>,
|
||||
msg: &str,
|
||||
) {
|
||||
build_diagnostic(cx, item, path_str, dox, link_range,
|
||||
"has an issue with the link anchor.",
|
||||
msg,
|
||||
None);
|
||||
}
|
||||
|
||||
fn ambiguity_error(
|
||||
cx: &DocContext<'_>,
|
||||
item: &Item,
|
||||
|
@ -637,13 +763,20 @@ fn ambiguity_error(
|
|||
}
|
||||
|
||||
/// Given an enum variant's res, return the res of its enum and the associated fragment.
|
||||
fn handle_variant(cx: &DocContext<'_>, res: Res) -> Result<(Res, Option<String>), ()> {
|
||||
fn handle_variant(
|
||||
cx: &DocContext<'_>,
|
||||
res: Res,
|
||||
extra_fragment: &Option<String>,
|
||||
) -> Result<(Res, Option<String>), ErrorKind> {
|
||||
use rustc::ty::DefIdTree;
|
||||
|
||||
if extra_fragment.is_some() {
|
||||
return Err(ErrorKind::AnchorFailure("variants cannot be followed by anchors"));
|
||||
}
|
||||
let parent = if let Some(parent) = cx.tcx.parent(res.def_id()) {
|
||||
parent
|
||||
} else {
|
||||
return Err(())
|
||||
return Err(ErrorKind::ResolutionFailure)
|
||||
};
|
||||
let parent_def = Res::Def(DefKind::Enum, parent);
|
||||
let variant = cx.tcx.expect_variant_res(res);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: `[v2]` cannot be resolved, ignoring it...
|
||||
error: `[v2]` cannot be resolved, ignoring it.
|
||||
--> $DIR/deny-intra-link-resolution-failure.rs:3:6
|
||||
|
|
||||
LL | /// [v2]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: `[TypeAlias::hoge]` cannot be resolved, ignoring it...
|
||||
error: `[TypeAlias::hoge]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-doc-alias-ice.rs:5:30
|
||||
|
|
||||
LL | /// [broken cross-reference](TypeAlias::hoge)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/// ## For example:
|
||||
///
|
||||
/// (arr[i])
|
||||
//~^ ERROR `[i]` cannot be resolved, ignoring it...
|
||||
//~^ ERROR `[i]` cannot be resolved, ignoring it.
|
||||
pub fn test_ice() {
|
||||
unimplemented!();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
error: `[i]` cannot be resolved, ignoring it...
|
||||
error: `[i]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-link-span-ice-55723.rs:9:10
|
||||
|
|
||||
LL | /// (arr[i])
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#![deny(intra_doc_link_resolution_failure)]
|
||||
|
||||
// A few tests on anchors.
|
||||
|
||||
/// Hello people.
|
||||
///
|
||||
/// You can anchors? Here's one!
|
||||
///
|
||||
/// # hola
|
||||
///
|
||||
/// Isn't it amazing?
|
||||
pub struct Foo {
|
||||
pub f: u8,
|
||||
}
|
||||
|
||||
pub enum Enum {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
/// Have you heard about stuff?
|
||||
///
|
||||
/// Like [Foo#hola].
|
||||
///
|
||||
/// Or maybe [Foo::f#hola].
|
||||
//~^ ERROR `[Foo::f#hola]` has an issue with the link anchor.
|
||||
pub fn foo() {}
|
||||
|
||||
/// Empty.
|
||||
///
|
||||
/// Another anchor error: [hello#people#!].
|
||||
//~^ ERROR `[hello#people#!]` has an issue with the link anchor.
|
||||
pub fn bar() {}
|
||||
|
||||
/// Empty?
|
||||
///
|
||||
/// Damn enum's variants: [Enum::A#whatever].
|
||||
//~^ ERROR `[Enum::A#whatever]` has an issue with the link anchor.
|
||||
pub fn enum_link() {}
|
||||
|
||||
/// Primitives?
|
||||
///
|
||||
/// [u32#hello]
|
||||
//~^ ERROR `[u32#hello]` has an issue with the link anchor.
|
||||
pub fn x() {}
|
|
@ -0,0 +1,32 @@
|
|||
error: `[Foo::f#hola]` has an issue with the link anchor.
|
||||
--> $DIR/intra-links-anchors.rs:25:15
|
||||
|
|
||||
LL | /// Or maybe [Foo::f#hola].
|
||||
| ^^^^^^^^^^^ struct fields cannot be followed by anchors
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/intra-links-anchors.rs:1:9
|
||||
|
|
||||
LL | #![deny(intra_doc_link_resolution_failure)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `[hello#people#!]` has an issue with the link anchor.
|
||||
--> $DIR/intra-links-anchors.rs:31:28
|
||||
|
|
||||
LL | /// Another anchor error: [hello#people#!].
|
||||
| ^^^^^^^^^^^^^^ only one `#` is allowed in a link
|
||||
|
||||
error: `[Enum::A#whatever]` has an issue with the link anchor.
|
||||
--> $DIR/intra-links-anchors.rs:37:28
|
||||
|
|
||||
LL | /// Damn enum's variants: [Enum::A#whatever].
|
||||
| ^^^^^^^^^^^^^^^^ variants cannot be followed by anchors
|
||||
|
||||
error: `[u32#hello]` has an issue with the link anchor.
|
||||
--> $DIR/intra-links-anchors.rs:43:6
|
||||
|
|
||||
LL | /// [u32#hello]
|
||||
| ^^^^^^^^^ primitive types cannot be followed by anchors
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning-crlf.rs:7:6
|
||||
|
|
||||
LL | /// [error]
|
||||
|
@ -7,7 +7,7 @@ LL | /// [error]
|
|||
= note: `#[warn(intra_doc_link_resolution_failure)]` on by default
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error1]` cannot be resolved, ignoring it...
|
||||
warning: `[error1]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning-crlf.rs:12:11
|
||||
|
|
||||
LL | /// docs [error1]
|
||||
|
@ -15,7 +15,7 @@ LL | /// docs [error1]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error2]` cannot be resolved, ignoring it...
|
||||
warning: `[error2]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning-crlf.rs:15:11
|
||||
|
|
||||
LL | /// docs [error2]
|
||||
|
@ -23,7 +23,7 @@ LL | /// docs [error2]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning-crlf.rs:23:20
|
||||
|
|
||||
LL | * It also has an [error].
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
warning: `[Foo::baz]` cannot be resolved, ignoring it...
|
||||
warning: `[Foo::baz]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:3:23
|
||||
|
|
||||
LL | //! Test with [Foo::baz], [Bar::foo], ...
|
||||
|
@ -7,7 +7,7 @@ LL | //! Test with [Foo::baz], [Bar::foo], ...
|
|||
= note: `#[warn(intra_doc_link_resolution_failure)]` on by default
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Bar::foo]` cannot be resolved, ignoring it...
|
||||
warning: `[Bar::foo]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:3:35
|
||||
|
|
||||
LL | //! Test with [Foo::baz], [Bar::foo], ...
|
||||
|
@ -15,7 +15,7 @@ LL | //! Test with [Foo::baz], [Bar::foo], ...
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
|
||||
warning: `[Uniooon::X]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:6:13
|
||||
|
|
||||
LL | //! , [Uniooon::X] and [Qux::Z].
|
||||
|
@ -23,7 +23,7 @@ LL | //! , [Uniooon::X] and [Qux::Z].
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Qux::Z]` cannot be resolved, ignoring it...
|
||||
warning: `[Qux::Z]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:6:30
|
||||
|
|
||||
LL | //! , [Uniooon::X] and [Qux::Z].
|
||||
|
@ -31,7 +31,7 @@ LL | //! , [Uniooon::X] and [Qux::Z].
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Uniooon::X]` cannot be resolved, ignoring it...
|
||||
warning: `[Uniooon::X]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:10:14
|
||||
|
|
||||
LL | //! , [Uniooon::X] and [Qux::Z].
|
||||
|
@ -39,7 +39,7 @@ LL | //! , [Uniooon::X] and [Qux::Z].
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Qux::Z]` cannot be resolved, ignoring it...
|
||||
warning: `[Qux::Z]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:10:31
|
||||
|
|
||||
LL | //! , [Uniooon::X] and [Qux::Z].
|
||||
|
@ -47,7 +47,7 @@ LL | //! , [Uniooon::X] and [Qux::Z].
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[Qux:Y]` cannot be resolved, ignoring it...
|
||||
warning: `[Qux:Y]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:14:13
|
||||
|
|
||||
LL | /// [Qux:Y]
|
||||
|
@ -55,7 +55,7 @@ LL | /// [Qux:Y]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:58:30
|
||||
|
|
||||
LL | * time to introduce a link [error]*/
|
||||
|
@ -63,7 +63,7 @@ LL | * time to introduce a link [error]*/
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:64:30
|
||||
|
|
||||
LL | * time to introduce a link [error]
|
||||
|
@ -71,7 +71,7 @@ LL | * time to introduce a link [error]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:68:1
|
||||
|
|
||||
LL | #[doc = "single line [error]"]
|
||||
|
@ -83,7 +83,7 @@ LL | #[doc = "single line [error]"]
|
|||
^^^^^
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:71:1
|
||||
|
|
||||
LL | #[doc = "single line with \"escaping\" [error]"]
|
||||
|
@ -95,7 +95,7 @@ LL | #[doc = "single line with \"escaping\" [error]"]
|
|||
^^^^^
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error]` cannot be resolved, ignoring it...
|
||||
warning: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:74:1
|
||||
|
|
||||
LL | / /// Item docs.
|
||||
|
@ -109,7 +109,7 @@ LL | | /// [error]
|
|||
^^^^^
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error1]` cannot be resolved, ignoring it...
|
||||
warning: `[error1]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:80:11
|
||||
|
|
||||
LL | /// docs [error1]
|
||||
|
@ -117,7 +117,7 @@ LL | /// docs [error1]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[error2]` cannot be resolved, ignoring it...
|
||||
warning: `[error2]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:82:11
|
||||
|
|
||||
LL | /// docs [error2]
|
||||
|
@ -125,7 +125,7 @@ LL | /// docs [error2]
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[BarA]` cannot be resolved, ignoring it...
|
||||
warning: `[BarA]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:21:10
|
||||
|
|
||||
LL | /// bar [BarA] bar
|
||||
|
@ -133,7 +133,7 @@ LL | /// bar [BarA] bar
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[BarB]` cannot be resolved, ignoring it...
|
||||
warning: `[BarB]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:27:9
|
||||
|
|
||||
LL | * bar [BarB] bar
|
||||
|
@ -141,7 +141,7 @@ LL | * bar [BarB] bar
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[BarC]` cannot be resolved, ignoring it...
|
||||
warning: `[BarC]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:34:6
|
||||
|
|
||||
LL | bar [BarC] bar
|
||||
|
@ -149,7 +149,7 @@ LL | bar [BarC] bar
|
|||
|
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[BarD]` cannot be resolved, ignoring it...
|
||||
warning: `[BarD]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:45:1
|
||||
|
|
||||
LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
|
||||
|
@ -161,7 +161,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
|
|||
^^^^
|
||||
= help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
|
||||
|
||||
warning: `[BarF]` cannot be resolved, ignoring it...
|
||||
warning: `[BarF]` cannot be resolved, ignoring it.
|
||||
--> $DIR/intra-links-warning.rs:50:9
|
||||
|
|
||||
LL | #[doc = $f]
|
||||
|
|
|
@ -15,7 +15,7 @@ LL | #![deny(rustdoc)]
|
|||
| ^^^^^^^
|
||||
= note: `#[deny(private_doc_tests)]` implied by `#[deny(rustdoc)]`
|
||||
|
||||
error: `[error]` cannot be resolved, ignoring it...
|
||||
error: `[error]` cannot be resolved, ignoring it.
|
||||
--> $DIR/lint-group.rs:9:29
|
||||
|
|
||||
LL | /// what up, let's make an [error]
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/// I want...
|
||||
///
|
||||
/// # Anchor!
|
||||
pub struct Something;
|
||||
|
||||
// @has intra_links_anchors/struct.SomeOtherType.html
|
||||
// @has - '//a/@href' '../intra_links_anchors/struct.Something.html#Anchor!'
|
||||
|
||||
/// I want...
|
||||
///
|
||||
/// To link to [Something#Anchor!]
|
||||
pub struct SomeOtherType;
|
Loading…
Reference in New Issue