From 9ec68e875800b4eed15d0093d0e023f3faac6de0 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 22 Aug 2026 07:57:17 -0400 Subject: [PATCH] Fix large_futures ICE with the next solver With the new trait solver enabled by default in nightly-2026-08-22 [1], large_futures can ICE while inspecting an awaited future. The lint switches to Codegen mode to obtain coroutine layouts but passes a type whose opaque aliases are still marked rigid from type checking. Because layout_of receives an already-Codegen environment, its environment-change path does not clear those markers. Clear alias rigidity and normalize the awaited type in that environment before querying its layout. Codegen mode must remain: post-analysis layout queries cannot compute coroutine sizes [2]. The regression covers direct and pinned futures under both solvers, without other lint errors that could hide a delayed ICE. Fixes rust-lang/rust#161495. [1]: https://github.com/rust-lang/rust/pull/160619 [2]: https://github.com/rust-lang/rust/pull/145477 --- clippy_lints/src/large_futures.rs | 11 ++++++++--- tests/ui/large_futures_next_solver.rs | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/ui/large_futures_next_solver.rs diff --git a/clippy_lints/src/large_futures.rs b/clippy_lints/src/large_futures.rs index 98516cfd4cb7..7f39f23b362a 100644 --- a/clippy_lints/src/large_futures.rs +++ b/clippy_lints/src/large_futures.rs @@ -7,6 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::attrs::lang_items::LangItem; use rustc_hir::{Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::impl_lint_pass; declare_clippy_lint! { @@ -65,9 +66,13 @@ impl<'tcx> LateLintPass<'tcx> for LargeFuture { && let ty = cx.typeck_results().expr_ty(arg) && let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() && implements_trait(cx, ty, future_trait_def_id, &[]) - && let Ok(layout) = cx - .tcx - .layout_of(cx.typing_env().with_codegen_normalized(cx.tcx).as_query_input(ty)) + && let typing_env = cx.typing_env().with_codegen_normalized(cx.tcx) + // Aliases that were rigid during type checking can be revealed in codegen mode. + && let Ok(ty) = cx.tcx.try_normalize_erasing_regions( + typing_env, + ty::set_aliases_to_non_rigid(cx.tcx, ty), + ) + && let Ok(layout) = cx.tcx.layout_of(typing_env.as_query_input(ty)) && let size = layout.layout.size() && size >= Size::from_bytes(self.future_size_threshold) { diff --git a/tests/ui/large_futures_next_solver.rs b/tests/ui/large_futures_next_solver.rs new file mode 100644 index 000000000000..86017484f5b4 --- /dev/null +++ b/tests/ui/large_futures_next_solver.rs @@ -0,0 +1,16 @@ +//@ check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver=globally + +// https://github.com/rust-lang/rust/issues/161495 + +#![warn(clippy::large_futures)] + +async fn callee() {} + +async fn caller() { + callee().await; + std::pin::pin!(callee()).await; +} + +fn main() {}