Skip to content

Commit 516bace

Browse files
committed
Don't create a path with zero segments
1 parent d11c8a6 commit 516bace

1 file changed

Lines changed: 15 additions & 28 deletions

File tree

src/librustdoc/html/render/span_map.rs

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -135,37 +135,26 @@ impl<'tcx> SpanMapVisitor<'tcx> {
135135
/// This function is where we handle `hir::Path` elements and add them into the "span map".
136136
fn handle_path(&mut self, path: &hir::Path<'_>, only_use_last_segment: bool) {
137137
match path.res {
138-
// FIXME: For now, we handle `DefKind` if it's not a `DefKind::TyParam`.
139-
// Would be nice to support them too alongside the other `DefKind`
140-
// (such as primitive types!).
141-
Res::Def(kind, def_id) if kind != DefKind::TyParam => {
138+
// FIXME: Properly support type parameters. Note they resolve just fine. The issue is
139+
// that our highlighter would then also linkify their *definition site* for some reason
140+
// linking them to themselves. Const parameters don't exhibit this issue.
141+
Res::Def(DefKind::TyParam, _) => {}
142+
Res::Def(_, def_id) => {
143+
// The segments can be empty for `use *;` in a non-crate-root scope in Rust 2015.
144+
let span = path.segments.last().map_or(path.span, |seg| seg.ident.span);
142145
// In case the path ends with generics, we remove them from the span.
143-
let span = if only_use_last_segment
144-
&& let Some(path_span) = path.segments.last().map(|segment| segment.ident.span)
145-
{
146-
path_span
146+
let span = if only_use_last_segment {
147+
span
147148
} else {
148-
path.segments
149-
.last()
150-
.map(|last| {
151-
// In `use` statements, the included item is not in the path segments.
152-
// However, it doesn't matter because you can't have generics on `use`
153-
// statements.
154-
if path.span.contains(last.ident.span) {
155-
path.span.with_hi(last.ident.span.hi())
156-
} else {
157-
path.span
158-
}
159-
})
160-
.unwrap_or(path.span)
149+
// In `use` statements, the included item is not in the path segments. However,
150+
// it doesn't matter because you can't have generics on `use` statements.
151+
if path.span.contains(span) { path.span.with_hi(span.hi()) } else { path.span }
161152
};
162153
self.matches.insert(span.into(), self.link_for_def(def_id));
163154
}
164155
Res::Local(_) if let Some(span) = self.tcx.hir_res_span(path.res) => {
165-
let path_span = if only_use_last_segment
166-
&& let Some(path_span) = path.segments.last().map(|segment| segment.ident.span)
167-
{
168-
path_span
156+
let path_span = if only_use_last_segment {
157+
path.segments.last().unwrap().ident.span
169158
} else {
170159
path.span
171160
};
@@ -176,7 +165,6 @@ impl<'tcx> SpanMapVisitor<'tcx> {
176165
self.matches
177166
.insert(path.span.into(), LinkFromSrc::Primitive(PrimitiveType::from(p)));
178167
}
179-
Res::Err => {}
180168
_ => {}
181169
}
182170
}
@@ -288,8 +276,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
288276
// We change the span to not include parens.
289277
span: segment.ident.span,
290278
res: typeck_results.qpath_res(qpath, id),
291-
// FIXME(fmease): Don't create a path with zero segments!
292-
segments: &[],
279+
segments: std::slice::from_ref(segment),
293280
};
294281
self.handle_path(&path, false);
295282
}

0 commit comments

Comments
 (0)