Skip to content

Commit 28c794b

Browse files
authored
Rollup merge of rust-lang#119586 - GuillaumeGomez:jump-to-def-static-methods, r=notriddle
[rustdoc] Fix invalid handling for static method calls in jump to definition feature I realized when working on a clippy lint that static method calls on `Self` could not give me the method `Res`. For that, we need to use `typeck` and so that's what I did in here. It fixes the linking to static method calls. r? ``@notriddle``
2 parents 894cc61 + 5bc7687 commit 28c794b

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

src/librustdoc/html/render/span_map.rs

+32-20
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ impl<'tcx> SpanMapVisitor<'tcx> {
154154
self.matches.insert(new_span, link_from_src);
155155
true
156156
}
157+
158+
fn handle_call(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
159+
let hir = self.tcx.hir();
160+
let body_id = hir.enclosing_body_owner(hir_id);
161+
// FIXME: this is showing error messages for parts of the code that are not
162+
// compiled (because of cfg)!
163+
//
164+
// See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
165+
let typeck_results = self
166+
.tcx
167+
.typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"));
168+
// Interestingly enough, for method calls, we need the whole expression whereas for static
169+
// method/function calls, we need the call expression specifically.
170+
if let Some(def_id) = typeck_results.type_dependent_def_id(expr_hir_id.unwrap_or(hir_id)) {
171+
let link = if def_id.as_local().is_some() {
172+
LinkFromSrc::Local(rustc_span(def_id, self.tcx))
173+
} else {
174+
LinkFromSrc::External(def_id)
175+
};
176+
self.matches.insert(span, link);
177+
}
178+
}
157179
}
158180

159181
impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
@@ -191,27 +213,17 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
191213
}
192214

193215
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
194-
if let ExprKind::MethodCall(segment, ..) = expr.kind {
195-
let hir = self.tcx.hir();
196-
let body_id = hir.enclosing_body_owner(segment.hir_id);
197-
// FIXME: this is showing error messages for parts of the code that are not
198-
// compiled (because of cfg)!
199-
//
200-
// See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
201-
let typeck_results = self
202-
.tcx
203-
.typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"));
204-
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
205-
let link = if def_id.as_local().is_some() {
206-
LinkFromSrc::Local(rustc_span(def_id, self.tcx))
207-
} else {
208-
LinkFromSrc::External(def_id)
209-
};
210-
self.matches.insert(segment.ident.span, link);
216+
match expr.kind {
217+
ExprKind::MethodCall(segment, ..) => {
218+
self.handle_call(segment.hir_id, Some(expr.hir_id), segment.ident.span)
219+
}
220+
ExprKind::Call(call, ..) => self.handle_call(call.hir_id, None, call.span),
221+
_ => {
222+
if self.handle_macro(expr.span) {
223+
// We don't want to go deeper into the macro.
224+
return;
225+
}
211226
}
212-
} else if self.handle_macro(expr.span) {
213-
// We don't want to go deeper into the macro.
214-
return;
215227
}
216228
intravisit::walk_expr(self, expr);
217229
}

tests/rustdoc/check-source-code-urls-to-def.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub trait AnotherTrait2 {}
6262

6363
// @has - '//pre[@class="rust"]//a[@href="#61"]' 'AnotherTrait2'
6464
pub fn foo4() {
65-
let x: Vec<AnotherTrait2> = Vec::new();
65+
let x: Vec<&dyn AnotherTrait2> = Vec::new();
6666
}
6767

6868
// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// compile-flags: -Zunstable-options --generate-link-to-definition
2+
3+
#![crate_name = "foo"]
4+
5+
// @has 'src/foo/jump-to-def-doc-links-calls.rs.html'
6+
7+
// @has - '//a[@href="../../foo/struct.Bar.html"]' 'Bar'
8+
pub struct Bar;
9+
10+
impl std::default::Default for Bar {
11+
// @has - '//a[@href="#20-22"]' 'Self::new'
12+
fn default() -> Self {
13+
Self::new()
14+
}
15+
}
16+
17+
// @has - '//a[@href="#8"]' 'Bar'
18+
impl Bar {
19+
// @has - '//a[@href="#24-26"]' 'Self::bar'
20+
pub fn new()-> Self {
21+
Self::bar()
22+
}
23+
24+
pub fn bar() -> Self {
25+
Self
26+
}
27+
}

0 commit comments

Comments
 (0)