mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #153888 - MaximilianAzendorf:issue-153583, r=Kivooeo
Avoid stack overflow in FindExprBySpan Fixes rust-lang/rust#153583. Deeply nested `?` desugarings can build a very deep HIR expression spine. When `FindExprBySpan` walks that expression during error reporting, the recursive `visit_expr` traversal can overflow the stack before rustc emits the actual diagnostic. This wraps the recursive expression walk in `ensure_sufficient_stack`, which lets the compiler report the expected E0277 instead of crashing. Added a UI regression test for a deeply nested `?` chain.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
use std::{fmt, iter};
|
||||
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::{Applicability, Diag, E0038, E0276, MultiSpan, struct_span_code_err};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
@@ -74,18 +75,20 @@ fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) {
|
||||
if self.span == ex.span {
|
||||
self.result = Some(ex);
|
||||
} else {
|
||||
if let hir::ExprKind::Closure(..) = ex.kind
|
||||
&& self.include_closures
|
||||
&& let closure_header_sp = self.span.with_hi(ex.span.hi())
|
||||
&& closure_header_sp == ex.span
|
||||
{
|
||||
ensure_sufficient_stack(|| {
|
||||
if self.span == ex.span {
|
||||
self.result = Some(ex);
|
||||
} else {
|
||||
if let hir::ExprKind::Closure(..) = ex.kind
|
||||
&& self.include_closures
|
||||
&& let closure_header_sp = self.span.with_hi(ex.span.hi())
|
||||
&& closure_header_sp == ex.span
|
||||
{
|
||||
self.result = Some(ex);
|
||||
}
|
||||
hir::intravisit::walk_expr(self, ex);
|
||||
}
|
||||
hir::intravisit::walk_expr(self, ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &'v hir::Ty<'v, AmbigArg>) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// Regression test for #153583: deeply nested `?` operators should not overflow
|
||||
// the error-reporting visitor.
|
||||
// ignore-tidy-linelength
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
0????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????; //~ ERROR the `?` operator can only be applied to values that implement `Try`
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
error[E0277]: the `?` operator can only be applied to values that implement `Try`
|
||||
--> $DIR/deep-try-chain-issue-153583.rs:6:5
|
||||
|
|
||||
LL | 0???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????...
|
||||
| ^^ the `?` operator cannot be applied to type `{integer}`
|
||||
|
|
||||
= help: the nightly-only, unstable trait `Try` is not implemented for `{integer}`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Reference in New Issue
Block a user