Skip to content

Commit 5ad3512

Browse files
authored
Rollup merge of rust-lang#90349 - willcrichton:example-analyzer, r=jyn514
Fix rare ICE during typeck in rustdoc scrape_examples While testing the `--scrape-examples` extension on the [wasmtime](https://github.com/bytecodealliance/wasmtime) repository, I found some additional edge cases. Specifically, when asking to typecheck a body containing a function call, I would sometimes get an ICE if: * The body doesn't exist * The function's HIR node didn't have a type This adds checks for both of those conditions. (Also this updates a test to check that the sources of a reverse-dependency are correctly generated and linked.) r? `@jyn514`
2 parents bdbad5f + b8ecc9f commit 5ad3512

File tree

5 files changed

+28
-2
lines changed

5 files changed

+28
-2
lines changed

src/librustdoc/scrape_examples.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,28 @@ where
132132
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
133133
intravisit::walk_expr(self, ex);
134134

135-
// Get type of function if expression is a function call
136135
let tcx = self.tcx;
136+
137+
// If we visit an item that contains an expression outside a function body,
138+
// then we need to exit before calling typeck (which will panic). See
139+
// test/run-make/rustdoc-scrape-examples-invalid-expr for an example.
140+
let hir = tcx.hir();
141+
let owner = hir.local_def_id_to_hir_id(ex.hir_id.owner);
142+
if hir.maybe_body_owned_by(owner).is_none() {
143+
return;
144+
}
145+
146+
// Get type of function if expression is a function call
137147
let (ty, span) = match ex.kind {
138148
hir::ExprKind::Call(f, _) => {
139149
let types = tcx.typeck(ex.hir_id.owner);
140-
(types.node_type(f.hir_id), ex.span)
150+
151+
match types.node_type_opt(f.hir_id) {
152+
Some(ty) => (ty, ex.span),
153+
None => {
154+
return;
155+
}
156+
}
141157
}
142158
hir::ExprKind::MethodCall(_, _, _, span) => {
143159
let types = tcx.typeck(ex.hir_id.owner);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
deps := ex
2+
3+
-include ../rustdoc-scrape-examples-multiple/scrape.mk
4+
5+
all: scrape
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub struct Foo([usize; foobar::f()]);
2+
fn main() {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub const fn f() -> usize { 5 }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' ''
22
// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' ''
3+
// @has src/ex/ex.rs.html
4+
// @has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' ''
35

46
pub fn ok() {}

0 commit comments

Comments
 (0)