about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-15 22:28:51 +0200
committerGitHub <noreply@github.com>2025-05-15 22:28:51 +0200
commitd0ea3424406c4ca5e61746359a4f87fef5868efb (patch)
tree151812c6ee6c24d260b4bfe8309560c47a953fd9 /compiler/rustc_trait_selection
parentf5fb0d3ea0599cb75065b9ad3103c860e83734c2 (diff)
parenta508011b1f0ae84930e2bcd0f6261f7e8843db6d (diff)
downloadrust-d0ea3424406c4ca5e61746359a4f87fef5868efb.tar.gz
rust-d0ea3424406c4ca5e61746359a4f87fef5868efb.zip
Rollup merge of #140947 - compiler-errors:pending-norm, r=lcnr
Flush errors before deep normalize in `dropck_outlives`

Deep normalization doesn't allow the ocx to have pending obligations, so process them before deeply normalizing.

Fixes https://github.com/rust-lang/rust/issues/140931
Fixes https://github.com/rust-lang/rust/issues/140462
Diffstat (limited to 'compiler/rustc_trait_selection')
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs28
1 files changed, 24 insertions, 4 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index f04a5feba30..38cfdcdc22d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -196,11 +196,31 @@ where
                 debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
                 ty
             } else {
-                ocx.deeply_normalize(&cause, param_env, ty)?;
+                // Flush errors b/c `deeply_normalize` doesn't expect pending
+                // obligations, and we may have pending obligations from the
+                // branch above (from other types).
+                let errors = ocx.select_all_or_error();
+                if !errors.is_empty() {
+                    return Err(errors);
+                }
 
-                let errors = ocx.select_where_possible();
-                debug!("normalize errors: {ty} ~> {errors:#?}");
-                return Err(errors);
+                // When query normalization fails, we don't get back an interesting
+                // reason that we could use to report an error in borrowck. In order to turn
+                // this into a reportable error, we deeply normalize again. We don't expect
+                // this to succeed, so delay a bug if it does.
+                match ocx.deeply_normalize(&cause, param_env, ty) {
+                    Ok(_) => {
+                        tcx.dcx().span_delayed_bug(
+                            span,
+                            format!(
+                                "query normalize succeeded of {ty}, \
+                                but deep normalize failed",
+                            ),
+                        );
+                        ty
+                    }
+                    Err(errors) => return Err(errors),
+                }
             };
 
             match ty.kind() {