Skip to content

Commit a5b7511

Browse files
committed
Auto merge of rust-lang#86645 - FabianWolff:issue-82328, r=LeSeulArtichaut
Fix ICE with `-Zunpretty=hir,typed` This PR fixes rust-lang#82328. The `-Zunpretty=hir,typed` pretty-printer maintains an `Option` with type-checking results and sets the `Option` to `Some` when entering a body. However, this leads to an ICE if an expression occurs in a function signature (i.e. outside of a body), such as `128` in ```rust fn foo(-128..=127: i8) {} ``` This PR fixes the ICE by checking (if necessary) whether the expression's owner has a body, and retrieving type-checking results for that on the fly.
2 parents a1411de + e8ebf98 commit a5b7511

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

compiler/rustc_driver/src/pretty.rs

+14-16
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,6 @@ struct TypedAnnotation<'tcx> {
293293
maybe_typeck_results: Cell<Option<&'tcx ty::TypeckResults<'tcx>>>,
294294
}
295295

296-
impl<'tcx> TypedAnnotation<'tcx> {
297-
/// Gets the type-checking results for the current body.
298-
/// As this will ICE if called outside bodies, only call when working with
299-
/// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
300-
#[track_caller]
301-
fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> {
302-
self.maybe_typeck_results
303-
.get()
304-
.expect("`TypedAnnotation::typeck_results` called outside of body")
305-
}
306-
}
307-
308296
impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> {
309297
fn sess(&self) -> &Session {
310298
&self.tcx.sess
@@ -336,10 +324,20 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> {
336324
}
337325
fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) {
338326
if let pprust_hir::AnnNode::Expr(expr) = node {
339-
s.s.space();
340-
s.s.word("as");
341-
s.s.space();
342-
s.s.word(self.typeck_results().expr_ty(expr).to_string());
327+
let typeck_results = self.maybe_typeck_results.get().or_else(|| {
328+
self.tcx
329+
.hir()
330+
.maybe_body_owned_by(self.tcx.hir().local_def_id_to_hir_id(expr.hir_id.owner))
331+
.map(|body_id| self.tcx.typeck_body(body_id))
332+
});
333+
334+
if let Some(typeck_results) = typeck_results {
335+
s.s.space();
336+
s.s.word("as");
337+
s.s.space();
338+
s.s.word(typeck_results.expr_ty(expr).to_string());
339+
}
340+
343341
s.pclose();
344342
}
345343
}

src/test/ui/unpretty-expr-fn-arg.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Regression test for the ICE described in #82328. The pretty-printer for
2+
// `-Zunpretty=hir,typed` would previously retrieve type-checking results
3+
// when entering a body, which means that type information was not available
4+
// for expressions occurring in function signatures, as in the `foo` example
5+
// below, leading to an ICE.
6+
7+
// check-pass
8+
// compile-flags: -Zunpretty=hir,typed
9+
#![allow(dead_code)]
10+
11+
fn main() {}
12+
13+
fn foo(-128..=127: i8) {}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Regression test for the ICE described in #82328. The pretty-printer for
2+
// `-Zunpretty=hir,typed` would previously retrieve type-checking results
3+
// when entering a body, which means that type information was not available
4+
// for expressions occurring in function signatures, as in the `foo` example
5+
// below, leading to an ICE.
6+
7+
// check-pass
8+
// compile-flags: -Zunpretty=hir,typed
9+
#![allow(dead_code)]
10+
#[prelude_import]
11+
use ::std::prelude::rust_2015::*;
12+
#[macro_use]
13+
extern crate std;
14+
15+
fn main() ({ } as ())
16+
17+
fn foo((-(128 as i8) as i8) ...(127 as i8): i8) ({ } as ())

0 commit comments

Comments
 (0)