Skip to content

Commit

Permalink
Rollup merge of rust-lang#90349 - willcrichton:example-analyzer, r=jy…
Browse files Browse the repository at this point in the history
…n514

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`
  • Loading branch information
matthiaskrgr authored Oct 31, 2021
2 parents bdbad5f + b8ecc9f commit 5ad3512
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/librustdoc/scrape_examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,28 @@ where
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
intravisit::walk_expr(self, ex);

// Get type of function if expression is a function call
let tcx = self.tcx;

// If we visit an item that contains an expression outside a function body,
// then we need to exit before calling typeck (which will panic). See
// test/run-make/rustdoc-scrape-examples-invalid-expr for an example.
let hir = tcx.hir();
let owner = hir.local_def_id_to_hir_id(ex.hir_id.owner);
if hir.maybe_body_owned_by(owner).is_none() {
return;
}

// Get type of function if expression is a function call
let (ty, span) = match ex.kind {
hir::ExprKind::Call(f, _) => {
let types = tcx.typeck(ex.hir_id.owner);
(types.node_type(f.hir_id), ex.span)

match types.node_type_opt(f.hir_id) {
Some(ty) => (ty, ex.span),
None => {
return;
}
}
}
hir::ExprKind::MethodCall(_, _, _, span) => {
let types = tcx.typeck(ex.hir_id.owner);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
deps := ex

-include ../rustdoc-scrape-examples-multiple/scrape.mk

all: scrape
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub struct Foo([usize; foobar::f()]);
fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const fn f() -> usize { 5 }
2 changes: 2 additions & 0 deletions src/test/run-make/rustdoc-scrape-examples-multiple/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' ''
// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' ''
// @has src/ex/ex.rs.html
// @has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' ''

pub fn ok() {}

0 comments on commit 5ad3512

Please sign in to comment.