Skip to content

Commit 46df958

Browse files
committed
Support Reference & ReferenceUnknown link lint
1 parent c736989 commit 46df958

File tree

5 files changed

+1130
-62
lines changed

5 files changed

+1130
-62
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ impl LinkCollector<'_, '_> {
10401040
matches!(ori_link.kind, LinkType::Reference | LinkType::Shortcut),
10411041
)?;
10421042

1043-
self.check_redundant_explicit_link(
1043+
self.resolve_display_text(
10441044
path_str,
10451045
ResolutionInfo {
10461046
item_id,
@@ -1384,42 +1384,93 @@ impl LinkCollector<'_, '_> {
13841384
}
13851385
}
13861386

1387-
/// Check if resolution of inline link's display text and explicit link are same.
1388-
fn check_redundant_explicit_link(
1387+
/// Resolve display text if the provided link has separated parts of links.
1388+
///
1389+
/// For example:
1390+
/// Inline link `[display_text](dest_link)` and reference link `[display_text][reference_link]` has
1391+
/// separated parts of links.
1392+
fn resolve_display_text(
13891393
&mut self,
13901394
explicit_link: &Box<str>,
13911395
display_res_info: ResolutionInfo,
13921396
ori_link: &MarkdownLink,
13931397
diag_info: &DiagnosticInfo<'_>,
13941398
) {
13951399
// Check if explicit resolution's path is same as resolution of original link's display text path, e.g.
1400+
//
1401+
// LinkType::Inline:
1402+
//
13961403
// [target](target)
13971404
// [`target`](target)
13981405
// [target](path::to::target)
13991406
// [`target`](path::to::target)
1407+
// [path::to::target](target)
1408+
// [`path::to::target`](target)
14001409
// [path::to::target](path::to::target)
14011410
// [`path::to::target`](path::to::target)
14021411
//
1412+
// LinkType::ReferenceUnknown
1413+
//
1414+
// [target][target]
1415+
// [`target`][target]
1416+
// [target][path::to::target]
1417+
// [`target`][path::to::target]
1418+
// [path::to::target][target]
1419+
// [`path::to::target`][target]
1420+
// [path::to::target][path::to::target]
1421+
// [`path::to::target`][path::to::target]
1422+
//
1423+
// LinkType::Reference
1424+
//
1425+
// [target][target]
1426+
// [`target`][target]
1427+
// [target][path::to::target]
1428+
// [`target`][path::to::target]
1429+
// [path::to::target][target]
1430+
// [`path::to::target`][target]
1431+
// [path::to::target][path::to::target]
1432+
// [`path::to::target`][path::to::target]
1433+
//
1434+
// [target]: target // or [target]: path::to::target
1435+
// [path::to::target]: path::to::target // or [path::to::target]: target
1436+
//
14031437
// To avoid disambiguator from panicking, we check if display text path is possible to be disambiguated
14041438
// into explicit path.
1405-
if ori_link.kind != LinkType::Inline {
1439+
if !matches!(
1440+
ori_link.kind,
1441+
LinkType::Inline | LinkType::Reference | LinkType::ReferenceUnknown
1442+
) {
14061443
return;
14071444
}
14081445

1446+
// Algorithm to check if display text could possibly be the explicit link:
1447+
//
1448+
// Consider 2 links which are display text and explicit link, pick the shorter
1449+
// one as symbol and longer one as full qualified path, and tries to match symbol
1450+
// to the full qualified path's last symbol.
1451+
//
1452+
// Otherwise, check if 2 links are same, if so, skip the resolve process.
1453+
//
1454+
// Notice that this algorithm is passive, might possibly miss actual redudant cases.
1455+
let explicit_link = &explicit_link.to_string();
14091456
let display_text = &ori_link.display_text;
14101457
let display_len = display_text.len();
14111458
let explicit_len = explicit_link.len();
14121459

1413-
if explicit_len >= display_len
1414-
&& &explicit_link[(explicit_len - display_len)..] == display_text
1460+
if display_len == explicit_len {
1461+
// Whether they are same or not, skip the resolve process.
1462+
return;
1463+
}
1464+
1465+
if (explicit_len >= display_len
1466+
&& &explicit_link[(explicit_len - display_len)..] == display_text)
1467+
|| (display_len >= explicit_len
1468+
&& &display_text[(display_len - explicit_len)..] == explicit_link)
14151469
{
14161470
self.resolve_with_disambiguator_cached(
14171471
display_res_info,
14181472
diag_info.clone(), // this struct should really be Copy, but Range is not :(
1419-
// For reference-style links we want to report only one error so unsuccessful
1420-
// resolutions are cached, for other links we want to report an error every
1421-
// time so they are not cached.
1422-
matches!(ori_link.kind, LinkType::Reference),
1473+
false,
14231474
);
14241475
}
14251476
}

0 commit comments

Comments
 (0)