diff options
| author | bors <bors@rust-lang.org> | 2021-06-27 00:15:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-06-27 00:15:49 +0000 |
| commit | a5b7511a6ccf241ba2ce6ad0b04e79f1e3d85686 (patch) | |
| tree | 848a00993d06d9cefdda7a3367e60945f0f2335a | |
| parent | a1411de9de38e0fed728874580218338160eb185 (diff) | |
| parent | e8ebf98742a46aef11d382d5cbad3d9bb9098b19 (diff) | |
| download | rust-a5b7511a6ccf241ba2ce6ad0b04e79f1e3d85686.tar.gz rust-a5b7511a6ccf241ba2ce6ad0b04e79f1e3d85686.zip | |
Auto merge of #86645 - FabianWolff:issue-82328, r=LeSeulArtichaut
Fix ICE with `-Zunpretty=hir,typed`
This PR fixes #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.
| -rw-r--r-- | compiler/rustc_driver/src/pretty.rs | 30 | ||||
| -rw-r--r-- | src/test/ui/unpretty-expr-fn-arg.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/unpretty-expr-fn-arg.stdout | 17 |
3 files changed, 44 insertions, 16 deletions
diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index a2b4f3fcf73..bf131914b97 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<Option<&'tcx ty::TypeckResults<'tcx>>>, } -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,20 @@ 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(|| { + 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(); + 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 00000000000..6e1132a3372 --- /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 +// `-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() {} + +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 00000000000..cb04dfead73 --- /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 +// `-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::*; +#[macro_use] +extern crate std; + +fn main() ({ } as ()) + +fn foo((-(128 as i8) as i8) ...(127 as i8): i8) ({ } as ()) |
