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:
Jacob Pratt
2026-04-08 23:03:58 -04:00
committed by GitHub
3 changed files with 32 additions and 10 deletions
@@ -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`.