about summary refs log tree commit diff
path: root/src/librustdoc/scrape_examples.rs
diff options
context:
space:
mode:
authorWill Crichton <wcrichto@cs.stanford.edu>2021-10-29 13:21:50 -0700
committerWill Crichton <wcrichto@cs.stanford.edu>2021-10-29 13:21:50 -0700
commitb8ecc9fefa4c9c763cf74e9c9659ecc00f30ba3a (patch)
tree16cd23569e2eff56aee692ee68fcac6dd8be35b4 /src/librustdoc/scrape_examples.rs
parentfd5d614b7708c2bbd0a7c796af3c3b63f31a19ac (diff)
downloadrust-b8ecc9fefa4c9c763cf74e9c9659ecc00f30ba3a.tar.gz
rust-b8ecc9fefa4c9c763cf74e9c9659ecc00f30ba3a.zip
Fix rare ICE during typeck in rustdoc scrape_examples
Diffstat (limited to 'src/librustdoc/scrape_examples.rs')
-rw-r--r--src/librustdoc/scrape_examples.rs20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index fc54e55b876..05e746573f4 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -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);