From ca8020a7c4d07d7348eced07f01841a05c327344 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 9 Oct 2025 16:35:35 +0800 Subject: [PATCH] Fix ice 141592, change diverge assertion to struct error with delay --- compiler/rustc_hir_typeck/src/expr.rs | 10 +++++++- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 ++-- .../never-pattern-as-closure-param-141592.rs | 24 +++++++++++++++++++ ...ver-pattern-as-closure-param-141592.stderr | 18 ++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/ui/never_type/never-pattern-as-closure-param-141592.rs create mode 100644 tests/ui/never_type/never-pattern-as-closure-param-141592.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f9cdc923670f0..8cdcacd339a46 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1817,12 +1817,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let element_ty = if !args.is_empty() { + // This shouldn't happen unless there's another error + // (e.g., never patterns in inappropriate contexts). + if self.diverges.get() != Diverges::Maybe { + self.dcx() + .struct_span_err(expr.span, "unexpected divergence state in checking array") + .delay_as_bug(); + } + let coerce_to = expected .to_option(self) .and_then(|uty| self.try_structurally_resolve_type(expr.span, uty).builtin_index()) .unwrap_or_else(|| self.next_ty_var(expr.span)); let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); - assert_eq!(self.diverges.get(), Diverges::Maybe); + for e in args { let e_ty = self.check_expr_with_hint(e, coerce_to); let cause = self.misc(e.span); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 7a060cafeab1c..5983d25e802b9 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -104,8 +104,8 @@ pub(crate) struct FnCtxt<'a, 'tcx> { /// the diverges flag is set to something other than `Maybe`. pub(super) diverges: Cell, - /// If one of the function arguments is a never pattern, this counts as diverging code. This - /// affect typechecking of the function body. + /// If one of the function arguments is a never pattern, this counts as diverging code. + /// This affect typechecking of the function body. pub(super) function_diverges_because_of_empty_arguments: Cell, /// Whether the currently checked node is the whole body of the function. diff --git a/tests/ui/never_type/never-pattern-as-closure-param-141592.rs b/tests/ui/never_type/never-pattern-as-closure-param-141592.rs new file mode 100644 index 0000000000000..78939199d09cc --- /dev/null +++ b/tests/ui/never_type/never-pattern-as-closure-param-141592.rs @@ -0,0 +1,24 @@ +#![feature(never_patterns)] +#![allow(incomplete_features)] + +enum Never {} + +fn example(x: Never) -> [i32; 1] { + let ! = x; + [1] +} + +fn function_param_never(!: Never) -> [i32; 1] { + [1] +} + +fn generic_never(!: T) -> [i32; 1] //~ ERROR mismatched types +where + T: Copy, +{ + [1] +} + +fn main() { + let _ = "12".lines().map(|!| [1]); //~ ERROR mismatched types +} diff --git a/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr b/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr new file mode 100644 index 0000000000000..ce5d3a57862bf --- /dev/null +++ b/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr @@ -0,0 +1,18 @@ +error: mismatched types + --> $DIR/never-pattern-as-closure-param-141592.rs:15:21 + | +LL | fn generic_never(!: T) -> [i32; 1] + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `T` + +error: mismatched types + --> $DIR/never-pattern-as-closure-param-141592.rs:23:31 + | +LL | let _ = "12".lines().map(|!| [1]); + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `str` + +error: aborting due to 2 previous errors +