Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 687ac3f

Browse files
Fix panic if an item does not have a body
1 parent 9457a32 commit 687ac3f

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

‎src/librustdoc/html/render/span_map.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};
22

33
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
44
use rustc_hir::def::{DefKind, Res};
5-
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
5+
use rustc_hir::def_id::{DefId, LOCAL_CRATE,LocalDefId};
66
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
77
use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, QPath};
88
use rustc_middle::hir::nested_filter;
@@ -201,6 +201,17 @@ impl SpanMapVisitor<'_> {
201201
}
202202
}
203203

204+
// This is a reimplementation of `hir_enclosing_body_owner` which allows to fail without
205+
// panicking.
206+
fn hir_enclosing_body_owner(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<LocalDefId> {
207+
for (_, node) in tcx.hir_parent_iter(hir_id) {
208+
if let Some((def_id, _)) = node.associated_body() {
209+
return Some(def_id);
210+
}
211+
}
212+
None
213+
}
214+
204215
impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
205216
type NestedFilter = nested_filter::All;
206217

@@ -221,15 +232,16 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
221232
QPath::TypeRelative(qself, path) => {
222233
if matches!(path.res, Res::Err) {
223234
let tcx = self.tcx;
224-
let body_id = tcx.hir_enclosing_body_owner(id);
225-
let typeck_results = tcx.typeck_body(tcx.hir_body_owned_by(body_id).id());
226-
let path = rustc_hir::Path {
227-
// We change the span to not include parens.
228-
span: path.ident.span,
229-
res: typeck_results.qpath_res(qpath, id),
230-
segments: &[],
231-
};
232-
self.handle_path(&path, false);
235+
if let Some(body_id) = hir_enclosing_body_owner(tcx, id) {
236+
let typeck_results = tcx.typeck_body(tcx.hir_body_owned_by(body_id).id());
237+
let path = rustc_hir::Path {
238+
// We change the span to not include parens.
239+
span: path.ident.span,
240+
res: typeck_results.qpath_res(qpath, id),
241+
segments: &[],
242+
};
243+
self.handle_path(&path, false);
244+
}
233245
} else {
234246
self.infer_id(path.hir_id, Some(id), path.ident.span);
235247
}

‎tests/rustdoc/jump-to-def-ice.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// This test ensures that items with no body don't panic when generating
2+
// jump to def links.
3+
4+
//@ compile-flags: -Zunstable-options --generate-link-to-definition
5+
6+
#![crate_name = "foo"]
7+
8+
//@ has 'src/foo/jump-to-def-ice.rs.html'
9+
10+
pub trait A {
11+
type T;
12+
type U;
13+
}
14+
15+
impl A for () {
16+
type T = Self::U;
17+
type U = ();
18+
}
19+
20+
pub trait C {
21+
type X;
22+
}
23+
24+
pub struct F<T: C>(pub T::X);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /