Skip to content

Commit 9acd813

Browse files
committed
Use Res instead of Disambiguator for resolved in report_mismatch
This allows simplifying a lot of code. It also fixes a subtle bug, exemplified by the test output changes.
1 parent 977a7ca commit 9acd813

File tree

3 files changed

+52
-67
lines changed

3 files changed

+52
-67
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,45 @@ impl Res {
109109
Res::Primitive(_) => None,
110110
}
111111
}
112+
113+
/// Used for error reporting.
114+
fn disambiguator_suggestion(self) -> Suggestion {
115+
let kind = match self {
116+
Res::Primitive(_) => return Suggestion::Prefix("prim"),
117+
Res::Def(kind, _) => kind,
118+
};
119+
if kind == DefKind::Macro(MacroKind::Bang) {
120+
return Suggestion::Macro;
121+
} else if kind == DefKind::Fn || kind == DefKind::AssocFn {
122+
return Suggestion::Function;
123+
} else if kind == DefKind::Field {
124+
return Suggestion::RemoveDisambiguator;
125+
}
126+
127+
let prefix = match kind {
128+
DefKind::Struct => "struct",
129+
DefKind::Enum => "enum",
130+
DefKind::Trait => "trait",
131+
DefKind::Union => "union",
132+
DefKind::Mod => "mod",
133+
DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst => {
134+
"const"
135+
}
136+
DefKind::Static => "static",
137+
DefKind::Macro(MacroKind::Derive) => "derive",
138+
// Now handle things that don't have a specific disambiguator
139+
_ => match kind
140+
.ns()
141+
.expect("tried to calculate a disambiguator for a def without a namespace?")
142+
{
143+
Namespace::TypeNS => "type",
144+
Namespace::ValueNS => "value",
145+
Namespace::MacroNS => "macro",
146+
},
147+
};
148+
149+
Suggestion::Prefix(prefix)
150+
}
112151
}
113152

114153
impl TryFrom<ResolveRes> for Res {
@@ -1267,7 +1306,7 @@ impl LinkCollector<'_, '_> {
12671306
}
12681307
}
12691308

1270-
let report_mismatch = |specified: Disambiguator, resolved: Disambiguator| {
1309+
let report_mismatch = |specified: Disambiguator, resolved: Res| {
12711310
// The resolved item did not match the disambiguator; give a better error than 'not found'
12721311
let msg = format!("incompatible link kind for `{}`", path_str);
12731312
let callback = |diag: &mut DiagnosticBuilder<'_>, sp: Option<rustc_span::Span>| {
@@ -1276,7 +1315,7 @@ impl LinkCollector<'_, '_> {
12761315
resolved.article(),
12771316
resolved.descr(),
12781317
specified.article(),
1279-
specified.descr()
1318+
specified.descr(),
12801319
);
12811320
if let Some(sp) = sp {
12821321
diag.span_label(sp, &note);
@@ -1311,7 +1350,7 @@ impl LinkCollector<'_, '_> {
13111350
=> {}
13121351
(actual, Some(Disambiguator::Kind(expected))) if actual == expected => {}
13131352
(_, Some(specified @ Disambiguator::Kind(_) | specified @ Disambiguator::Primitive)) => {
1314-
report_mismatch(specified, Disambiguator::Kind(kind));
1353+
report_mismatch(specified, Res::Def(kind, id));
13151354
return None;
13161355
}
13171356
}
@@ -1362,7 +1401,7 @@ impl LinkCollector<'_, '_> {
13621401
match disambiguator {
13631402
Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => {}
13641403
Some(other) => {
1365-
report_mismatch(other, Disambiguator::Primitive);
1404+
report_mismatch(other, res);
13661405
return None;
13671406
}
13681407
}
@@ -1676,53 +1715,6 @@ impl Disambiguator {
16761715
}
16771716
}
16781717

1679-
fn from_res(res: Res) -> Self {
1680-
match res {
1681-
Res::Def(kind, _) => Disambiguator::Kind(kind),
1682-
Res::Primitive(_) => Disambiguator::Primitive,
1683-
}
1684-
}
1685-
1686-
/// Used for error reporting.
1687-
fn suggestion(self) -> Suggestion {
1688-
let kind = match self {
1689-
Disambiguator::Primitive => return Suggestion::Prefix("prim"),
1690-
Disambiguator::Kind(kind) => kind,
1691-
Disambiguator::Namespace(_) => panic!("display_for cannot be used on namespaces"),
1692-
};
1693-
if kind == DefKind::Macro(MacroKind::Bang) {
1694-
return Suggestion::Macro;
1695-
} else if kind == DefKind::Fn || kind == DefKind::AssocFn {
1696-
return Suggestion::Function;
1697-
} else if kind == DefKind::Field {
1698-
return Suggestion::RemoveDisambiguator;
1699-
}
1700-
1701-
let prefix = match kind {
1702-
DefKind::Struct => "struct",
1703-
DefKind::Enum => "enum",
1704-
DefKind::Trait => "trait",
1705-
DefKind::Union => "union",
1706-
DefKind::Mod => "mod",
1707-
DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst => {
1708-
"const"
1709-
}
1710-
DefKind::Static => "static",
1711-
DefKind::Macro(MacroKind::Derive) => "derive",
1712-
// Now handle things that don't have a specific disambiguator
1713-
_ => match kind
1714-
.ns()
1715-
.expect("tried to calculate a disambiguator for a def without a namespace?")
1716-
{
1717-
Namespace::TypeNS => "type",
1718-
Namespace::ValueNS => "value",
1719-
Namespace::MacroNS => "macro",
1720-
},
1721-
};
1722-
1723-
Suggestion::Prefix(prefix)
1724-
}
1725-
17261718
fn ns(self) -> Namespace {
17271719
match self {
17281720
Self::Namespace(n) => n,
@@ -2070,15 +2062,9 @@ fn resolution_failure(
20702062
ResolutionFailure::NotResolved { .. } => unreachable!("handled above"),
20712063
ResolutionFailure::Dummy => continue,
20722064
ResolutionFailure::WrongNamespace { res, expected_ns } => {
2073-
if let Res::Def(kind, _) = res {
2074-
let disambiguator = Disambiguator::Kind(kind);
2075-
suggest_disambiguator(
2076-
disambiguator,
2077-
diag,
2078-
path_str,
2079-
diag_info.ori_link,
2080-
sp,
2081-
)
2065+
// FIXME: does this need to be behind an `if`?
2066+
if matches!(res, Res::Def(..)) {
2067+
suggest_disambiguator(res, diag, path_str, diag_info.ori_link, sp);
20822068
}
20832069

20842070
format!(
@@ -2214,23 +2200,22 @@ fn ambiguity_error(
22142200
}
22152201

22162202
for res in candidates {
2217-
let disambiguator = Disambiguator::from_res(res);
2218-
suggest_disambiguator(disambiguator, diag, path_str, diag_info.ori_link, sp);
2203+
suggest_disambiguator(res, diag, path_str, diag_info.ori_link, sp);
22192204
}
22202205
});
22212206
}
22222207

22232208
/// In case of an ambiguity or mismatched disambiguator, suggest the correct
22242209
/// disambiguator.
22252210
fn suggest_disambiguator(
2226-
disambiguator: Disambiguator,
2211+
res: Res,
22272212
diag: &mut DiagnosticBuilder<'_>,
22282213
path_str: &str,
22292214
ori_link: &str,
22302215
sp: Option<rustc_span::Span>,
22312216
) {
2232-
let suggestion = disambiguator.suggestion();
2233-
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
2217+
let suggestion = res.disambiguator_suggestion();
2218+
let help = format!("to link to the {}, {}", res.descr(), suggestion.descr());
22342219

22352220
if let Some(sp) = sp {
22362221
let mut spans = suggestion.as_help_span(path_str, ori_link, sp);

src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,5 @@ trait T {}
7777
/// Link to [fn@std]
7878
//~^ ERROR unresolved link to `std`
7979
//~| NOTE this link resolves to the crate `std`
80-
//~| HELP to link to the module, prefix with `mod@`
80+
//~| HELP to link to the crate, prefix with `mod@`
8181
pub fn f() {}

src/test/rustdoc-ui/intra-doc/disambiguator-mismatch.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ error: unresolved link to `std`
144144
LL | /// Link to [fn@std]
145145
| ^^^^^^ this link resolves to the crate `std`, which is not in the value namespace
146146
|
147-
help: to link to the module, prefix with `mod@`
147+
help: to link to the crate, prefix with `mod@`
148148
|
149149
LL | /// Link to [mod@std]
150150
| ~~~~

0 commit comments

Comments
 (0)