Skip to content

Commit c979ef5

Browse files
committed
rustdoc: Remove ResolutionFailure::MalformedGenerics
in favor of `PreprocessingError::MalformedGenerics`
1 parent 51eda74 commit c979ef5

File tree

1 file changed

+61
-81
lines changed

1 file changed

+61
-81
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 61 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,14 @@ enum ResolutionFailure<'a> {
181181
/// In `[std::io::Error::x]`, `x` would be unresolved.
182182
unresolved: Cow<'a, str>,
183183
},
184-
/// This link has malformed generic parameters; e.g., the angle brackets are unbalanced.
185-
MalformedGenerics(MalformedGenerics),
186184
/// Used to communicate that this should be ignored, but shouldn't be reported to the user.
187185
///
188186
/// This happens when there is no disambiguator and one of the namespaces
189187
/// failed to resolve.
190188
Dummy,
191189
}
192190

193-
#[derive(Clone, Debug)]
191+
#[derive(Clone, Copy, Debug)]
194192
enum MalformedGenerics {
195193
/// This link has unbalanced angle brackets.
196194
///
@@ -1088,12 +1086,20 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
10881086
enum PreprocessingError {
10891087
Anchor(AnchorFailure),
10901088
Disambiguator(Range<usize>, String),
1091-
Resolution(ResolutionFailure<'static>, String, Option<Disambiguator>),
1089+
MalformedGenerics(MalformedGenerics, String),
10921090
}
10931091

1094-
impl From<AnchorFailure> for PreprocessingError {
1095-
fn from(err: AnchorFailure) -> Self {
1096-
Self::Anchor(err)
1092+
impl PreprocessingError {
1093+
fn report(&self, cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) {
1094+
match self {
1095+
PreprocessingError::Anchor(err) => anchor_failure(cx, diag_info, *err),
1096+
PreprocessingError::Disambiguator(range, msg) => {
1097+
disambiguator_error(cx, diag_info, range.clone(), msg)
1098+
}
1099+
PreprocessingError::MalformedGenerics(err, path_str) => {
1100+
report_malformed_generics(cx, diag_info, *err, path_str)
1101+
}
1102+
}
10971103
}
10981104
}
10991105

@@ -1138,7 +1144,7 @@ fn preprocess_link(
11381144
let extra_fragment = parts.next();
11391145
if parts.next().is_some() {
11401146
// A valid link can't have multiple #'s
1141-
return Some(Err(AnchorFailure::MultipleAnchors.into()));
1147+
return Some(Err(PreprocessingError::Anchor(AnchorFailure::MultipleAnchors)));
11421148
}
11431149

11441150
// Parse and strip the disambiguator from the link, if present.
@@ -1166,13 +1172,9 @@ fn preprocess_link(
11661172
let path_str = if path_str.contains(['<', '>'].as_slice()) {
11671173
match strip_generics_from_path(path_str) {
11681174
Ok(path) => path,
1169-
Err(err_kind) => {
1175+
Err(err) => {
11701176
debug!("link has malformed generics: {}", path_str);
1171-
return Some(Err(PreprocessingError::Resolution(
1172-
err_kind,
1173-
path_str.to_owned(),
1174-
disambiguator,
1175-
)));
1177+
return Some(Err(PreprocessingError::MalformedGenerics(err, path_str.to_owned())));
11761178
}
11771179
}
11781180
} else {
@@ -1222,32 +1224,10 @@ impl LinkCollector<'_, '_> {
12221224
link_range: ori_link.range.clone(),
12231225
};
12241226

1225-
let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } = match pp_link
1226-
{
1227-
Ok(x) => x,
1228-
Err(err) => {
1229-
match err {
1230-
PreprocessingError::Anchor(err) => anchor_failure(self.cx, diag_info, *err),
1231-
PreprocessingError::Disambiguator(range, msg) => {
1232-
disambiguator_error(self.cx, diag_info, range.clone(), msg)
1233-
}
1234-
PreprocessingError::Resolution(err, path_str, disambiguator) => {
1235-
resolution_failure(
1236-
self,
1237-
diag_info,
1238-
path_str,
1239-
*disambiguator,
1240-
smallvec![err.clone()],
1241-
);
1242-
}
1243-
}
1244-
return None;
1245-
}
1246-
};
1227+
let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } =
1228+
pp_link.as_ref().map_err(|err| err.report(self.cx, diag_info.clone())).ok()?;
12471229
let disambiguator = *disambiguator;
12481230

1249-
let inner_docs = item.inner_docs(self.cx.tcx);
1250-
12511231
// In order to correctly resolve intra-doc links we need to
12521232
// pick a base AST node to work from. If the documentation for
12531233
// this module came from an inner comment (//!) then we anchor
@@ -1259,6 +1239,7 @@ impl LinkCollector<'_, '_> {
12591239
// we've already pushed this node onto the resolution stack but
12601240
// for outer comments we explicitly try and resolve against the
12611241
// parent_node first.
1242+
let inner_docs = item.inner_docs(self.cx.tcx);
12621243
let base_node =
12631244
if item.is_mod() && inner_docs { self.mod_ids.last().copied() } else { parent_node };
12641245
let module_id = base_node.expect("doc link without parent module");
@@ -2121,27 +2102,6 @@ fn resolution_failure(
21212102
expected_ns.descr()
21222103
)
21232104
}
2124-
ResolutionFailure::MalformedGenerics(variant) => match variant {
2125-
MalformedGenerics::UnbalancedAngleBrackets => {
2126-
String::from("unbalanced angle brackets")
2127-
}
2128-
MalformedGenerics::MissingType => {
2129-
String::from("missing type for generic parameters")
2130-
}
2131-
MalformedGenerics::HasFullyQualifiedSyntax => {
2132-
diag.note("see https://github.com/rust-lang/rust/issues/74563 for more information");
2133-
String::from("fully-qualified syntax is unsupported")
2134-
}
2135-
MalformedGenerics::InvalidPathSeparator => {
2136-
String::from("has invalid path separator")
2137-
}
2138-
MalformedGenerics::TooManyAngleBrackets => {
2139-
String::from("too many angle brackets")
2140-
}
2141-
MalformedGenerics::EmptyAngleBrackets => {
2142-
String::from("empty angle brackets")
2143-
}
2144-
},
21452105
};
21462106
if let Some(span) = sp {
21472107
diag.span_label(span, &note);
@@ -2205,6 +2165,40 @@ fn disambiguator_error(
22052165
});
22062166
}
22072167

2168+
fn report_malformed_generics(
2169+
cx: &DocContext<'_>,
2170+
diag_info: DiagnosticInfo<'_>,
2171+
err: MalformedGenerics,
2172+
path_str: &str,
2173+
) {
2174+
report_diagnostic(
2175+
cx.tcx,
2176+
BROKEN_INTRA_DOC_LINKS,
2177+
&format!("unresolved link to `{}`", path_str),
2178+
&diag_info,
2179+
|diag, sp| {
2180+
let note = match err {
2181+
MalformedGenerics::UnbalancedAngleBrackets => "unbalanced angle brackets",
2182+
MalformedGenerics::MissingType => "missing type for generic parameters",
2183+
MalformedGenerics::HasFullyQualifiedSyntax => {
2184+
diag.note(
2185+
"see https://github.com/rust-lang/rust/issues/74563 for more information",
2186+
);
2187+
"fully-qualified syntax is unsupported"
2188+
}
2189+
MalformedGenerics::InvalidPathSeparator => "has invalid path separator",
2190+
MalformedGenerics::TooManyAngleBrackets => "too many angle brackets",
2191+
MalformedGenerics::EmptyAngleBrackets => "empty angle brackets",
2192+
};
2193+
if let Some(span) = sp {
2194+
diag.span_label(span, note);
2195+
} else {
2196+
diag.note(note);
2197+
}
2198+
},
2199+
);
2200+
}
2201+
22082202
/// Report an ambiguity error, where there were multiple possible resolutions.
22092203
fn ambiguity_error(
22102204
cx: &DocContext<'_>,
@@ -2340,7 +2334,7 @@ fn resolve_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
23402334
Some(Res::Primitive(prim))
23412335
}
23422336

2343-
fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<'static>> {
2337+
fn strip_generics_from_path(path_str: &str) -> Result<String, MalformedGenerics> {
23442338
let mut stripped_segments = vec![];
23452339
let mut path = path_str.chars().peekable();
23462340
let mut segment = Vec::new();
@@ -2355,24 +2349,18 @@ fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<
23552349
stripped_segments.push(stripped_segment);
23562350
}
23572351
} else {
2358-
return Err(ResolutionFailure::MalformedGenerics(
2359-
MalformedGenerics::InvalidPathSeparator,
2360-
));
2352+
return Err(MalformedGenerics::InvalidPathSeparator);
23612353
}
23622354
}
23632355
'<' => {
23642356
segment.push(chr);
23652357

23662358
match path.next() {
23672359
Some('<') => {
2368-
return Err(ResolutionFailure::MalformedGenerics(
2369-
MalformedGenerics::TooManyAngleBrackets,
2370-
));
2360+
return Err(MalformedGenerics::TooManyAngleBrackets);
23712361
}
23722362
Some('>') => {
2373-
return Err(ResolutionFailure::MalformedGenerics(
2374-
MalformedGenerics::EmptyAngleBrackets,
2375-
));
2363+
return Err(MalformedGenerics::EmptyAngleBrackets);
23762364
}
23772365
Some(chr) => {
23782366
segment.push(chr);
@@ -2400,16 +2388,10 @@ fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<
24002388

24012389
let stripped_path = stripped_segments.join("::");
24022390

2403-
if !stripped_path.is_empty() {
2404-
Ok(stripped_path)
2405-
} else {
2406-
Err(ResolutionFailure::MalformedGenerics(MalformedGenerics::MissingType))
2407-
}
2391+
if !stripped_path.is_empty() { Ok(stripped_path) } else { Err(MalformedGenerics::MissingType) }
24082392
}
24092393

2410-
fn strip_generics_from_path_segment(
2411-
segment: Vec<char>,
2412-
) -> Result<String, ResolutionFailure<'static>> {
2394+
fn strip_generics_from_path_segment(segment: Vec<char>) -> Result<String, MalformedGenerics> {
24132395
let mut stripped_segment = String::new();
24142396
let mut param_depth = 0;
24152397

@@ -2424,9 +2406,7 @@ fn strip_generics_from_path_segment(
24242406
if latest_generics_chunk.contains(" as ") {
24252407
// The segment tries to use fully-qualified syntax, which is currently unsupported.
24262408
// Give a helpful error message instead of completely ignoring the angle brackets.
2427-
return Err(ResolutionFailure::MalformedGenerics(
2428-
MalformedGenerics::HasFullyQualifiedSyntax,
2429-
));
2409+
return Err(MalformedGenerics::HasFullyQualifiedSyntax);
24302410
}
24312411
} else {
24322412
if param_depth == 0 {
@@ -2441,6 +2421,6 @@ fn strip_generics_from_path_segment(
24412421
Ok(stripped_segment)
24422422
} else {
24432423
// The segment has unbalanced angle brackets, e.g. `Vec<T` or `Vec<T>>`
2444-
Err(ResolutionFailure::MalformedGenerics(MalformedGenerics::UnbalancedAngleBrackets))
2424+
Err(MalformedGenerics::UnbalancedAngleBrackets)
24452425
}
24462426
}

0 commit comments

Comments
 (0)