From 7682e87c6d29520dfdea6a2a772c31150dbfa7d4 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sat, 26 Jun 2021 16:05:53 +0200 Subject: [PATCH 1/3] Fix ICE with `-Zunpretty=hir,typed` when an expression occurs in a function signature --- compiler/rustc_driver/src/pretty.rs | 34 +++++++++++++------------ src/test/ui/unpretty-expr-fn-arg.rs | 13 ++++++++++ src/test/ui/unpretty-expr-fn-arg.stdout | 17 +++++++++++++ 3 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/unpretty-expr-fn-arg.rs create mode 100644 src/test/ui/unpretty-expr-fn-arg.stdout diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index a2b4f3fcf734a..2a11d62ac15f2 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -293,18 +293,6 @@ struct TypedAnnotation<'tcx> { maybe_typeck_results: Cell>>, } -impl<'tcx> TypedAnnotation<'tcx> { - /// Gets the type-checking results for the current body. - /// As this will ICE if called outside bodies, only call when working with - /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies). - #[track_caller] - fn typeck_results(&self) -> &'tcx ty::TypeckResults<'tcx> { - self.maybe_typeck_results - .get() - .expect("`TypedAnnotation::typeck_results` called outside of body") - } -} - impl<'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'tcx> { fn sess(&self) -> &Session { &self.tcx.sess @@ -336,10 +324,24 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { } fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(expr) = node { - s.s.space(); - s.s.word("as"); - s.s.space(); - s.s.word(self.typeck_results().expr_ty(expr).to_string()); + let typeck_results = + self.maybe_typeck_results.get().or_else(|| { + if let Some(body_id) = self.tcx.hir().maybe_body_owned_by( + self.tcx.hir().local_def_id_to_hir_id(expr.hir_id.owner), + ) { + Some(self.tcx.typeck_body(body_id)) + } else { + None + } + }); + + if let Some(typeck_results) = typeck_results { + s.s.space(); + s.s.word("as"); + s.s.space(); + s.s.word(typeck_results.expr_ty(expr).to_string()); + } + s.pclose(); } } diff --git a/src/test/ui/unpretty-expr-fn-arg.rs b/src/test/ui/unpretty-expr-fn-arg.rs new file mode 100644 index 0000000000000..fd8eee44a9f6b --- /dev/null +++ b/src/test/ui/unpretty-expr-fn-arg.rs @@ -0,0 +1,13 @@ +// Regression test for the ICE described in #82328. The pretty-printer for +// compile-flags: -Zunpretty=hir,typed +// would previously retrieve type-checking results when entering a body, +// which means that type information was not available for expressions +// occurring in function signatures, as in the `foo` example below, leading +// to an ICE. + +// check-pass +#![allow(dead_code)] + +fn main() {} + +fn foo(-128..=127: i8) {} diff --git a/src/test/ui/unpretty-expr-fn-arg.stdout b/src/test/ui/unpretty-expr-fn-arg.stdout new file mode 100644 index 0000000000000..aa6ea4a8f9759 --- /dev/null +++ b/src/test/ui/unpretty-expr-fn-arg.stdout @@ -0,0 +1,17 @@ +// Regression test for the ICE described in #82328. The pretty-printer for +// compile-flags: -Zunpretty=hir,typed +// would previously retrieve type-checking results when entering a body, +// which means that type information was not available for expressions +// occurring in function signatures, as in the `foo` example below, leading +// to an ICE. + +// check-pass +#![allow(dead_code)] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; + +fn main() ({ } as ()) + +fn foo((-(128 as i8) as i8) ...(127 as i8): i8) ({ } as ()) From a8b57723d41d5f8b58bc4796ecb4bde0ed00e639 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sat, 26 Jun 2021 22:26:26 +0200 Subject: [PATCH 2/3] Use `Option::map()` instead of `if let` --- compiler/rustc_driver/src/pretty.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index 2a11d62ac15f2..bf131914b97cf 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -324,16 +324,12 @@ impl<'tcx> pprust_hir::PpAnn for TypedAnnotation<'tcx> { } fn post(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { if let pprust_hir::AnnNode::Expr(expr) = node { - let typeck_results = - self.maybe_typeck_results.get().or_else(|| { - if let Some(body_id) = self.tcx.hir().maybe_body_owned_by( - self.tcx.hir().local_def_id_to_hir_id(expr.hir_id.owner), - ) { - Some(self.tcx.typeck_body(body_id)) - } else { - None - } - }); + let typeck_results = self.maybe_typeck_results.get().or_else(|| { + self.tcx + .hir() + .maybe_body_owned_by(self.tcx.hir().local_def_id_to_hir_id(expr.hir_id.owner)) + .map(|body_id| self.tcx.typeck_body(body_id)) + }); if let Some(typeck_results) = typeck_results { s.s.space(); From e8ebf98742a46aef11d382d5cbad3d9bb9098b19 Mon Sep 17 00:00:00 2001 From: Fabian Wolff Date: Sat, 26 Jun 2021 22:43:27 +0200 Subject: [PATCH 3/3] Reorder some lines in `unpretty-expr-fn-arg.rs` --- src/test/ui/unpretty-expr-fn-arg.rs | 10 +++++----- src/test/ui/unpretty-expr-fn-arg.stdout | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/ui/unpretty-expr-fn-arg.rs b/src/test/ui/unpretty-expr-fn-arg.rs index fd8eee44a9f6b..6e1132a337286 100644 --- a/src/test/ui/unpretty-expr-fn-arg.rs +++ b/src/test/ui/unpretty-expr-fn-arg.rs @@ -1,11 +1,11 @@ // Regression test for the ICE described in #82328. The pretty-printer for -// compile-flags: -Zunpretty=hir,typed -// would previously retrieve type-checking results when entering a body, -// which means that type information was not available for expressions -// occurring in function signatures, as in the `foo` example below, leading -// to an ICE. +// `-Zunpretty=hir,typed` would previously retrieve type-checking results +// when entering a body, which means that type information was not available +// for expressions occurring in function signatures, as in the `foo` example +// below, leading to an ICE. // check-pass +// compile-flags: -Zunpretty=hir,typed #![allow(dead_code)] fn main() {} diff --git a/src/test/ui/unpretty-expr-fn-arg.stdout b/src/test/ui/unpretty-expr-fn-arg.stdout index aa6ea4a8f9759..cb04dfead7321 100644 --- a/src/test/ui/unpretty-expr-fn-arg.stdout +++ b/src/test/ui/unpretty-expr-fn-arg.stdout @@ -1,11 +1,11 @@ // Regression test for the ICE described in #82328. The pretty-printer for -// compile-flags: -Zunpretty=hir,typed -// would previously retrieve type-checking results when entering a body, -// which means that type information was not available for expressions -// occurring in function signatures, as in the `foo` example below, leading -// to an ICE. +// `-Zunpretty=hir,typed` would previously retrieve type-checking results +// when entering a body, which means that type information was not available +// for expressions occurring in function signatures, as in the `foo` example +// below, leading to an ICE. // check-pass +// compile-flags: -Zunpretty=hir,typed #![allow(dead_code)] #[prelude_import] use ::std::prelude::rust_2015::*;