about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-07-23 20:16:03 +0000
committerbors <bors@rust-lang.org>2025-07-23 20:16:03 +0000
commitace633090349fc5075b5b0d56294de985e7d1191 (patch)
tree2a2779f150b176783ad4d053e4b649cf91a92b1e
parent29a58723b05d004c2e19ddcf2be80d514401f22e (diff)
parentb1d88ba086ee6f34584ed4e8eb09761a03fe249d (diff)
downloadrust-ace633090349fc5075b5b0d56294de985e7d1191.tar.gz
rust-ace633090349fc5075b5b0d56294de985e7d1191.zip
Auto merge of #144233 - cjgillot:unsat-mir, r=oli-obk
Consider parent predicates in ImpossiblePredicates pass.

This pass is double edged. It avoids some ICEs (yay!) but also degrades diagnostics from constant evaluation.

Fixes rust-lang/rust#121363
Fixes rust-lang/rust#131507
Fixes rust-lang/rust#140100
Fixes rust-lang/rust#140365
-rw-r--r--compiler/rustc_mir_transform/src/impossible_predicates.rs25
-rw-r--r--tests/crashes/140100.rs7
-rw-r--r--tests/crashes/140365.rs8
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr25
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs1
-rw-r--r--tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs3
-rw-r--r--tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr6
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.rs5
-rw-r--r--tests/ui/layout/unknown-when-no-type-parameter.stderr7
-rw-r--r--tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs3
-rw-r--r--tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr6
-rw-r--r--tests/ui/mir/meaningless-bound.rs20
-rw-r--r--tests/ui/mir/meaningless-bound.stderr19
-rw-r--r--tests/ui/trivial-bounds/everybody-copies.rs (renamed from tests/crashes/131507.rs)7
-rw-r--r--tests/ui/trivial-bounds/two-sized-strs.rs (renamed from tests/crashes/121363.rs)4
15 files changed, 95 insertions, 51 deletions
diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs
index 86e2bf6cb3c..b03518de00a 100644
--- a/compiler/rustc_mir_transform/src/impossible_predicates.rs
+++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs
@@ -27,7 +27,7 @@
 //! it's usually never invoked in this way.
 
 use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind};
-use rustc_middle::ty::{TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt};
 use rustc_trait_selection::traits;
 use tracing::trace;
 
@@ -36,14 +36,23 @@ use crate::pass_manager::MirPass;
 pub(crate) struct ImpossiblePredicates;
 
 impl<'tcx> MirPass<'tcx> for ImpossiblePredicates {
+    #[tracing::instrument(level = "trace", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let predicates = tcx
-            .predicates_of(body.source.def_id())
-            .predicates
-            .iter()
-            .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });
-        if traits::impossible_predicates(tcx, traits::elaborate(tcx, predicates).collect()) {
-            trace!("found unsatisfiable predicates for {:?}", body.source);
+        tracing::trace!(def_id = ?body.source.def_id());
+        let predicates = tcx.predicates_of(body.source.def_id()).instantiate_identity(tcx);
+        tracing::trace!(?predicates);
+        let predicates = predicates.predicates.into_iter().filter(|p| {
+            !p.has_type_flags(
+                // Only consider global clauses to simplify.
+                TypeFlags::HAS_FREE_LOCAL_NAMES
+                // Clauses that refer to unevaluated constants as they cause cycles.
+                | TypeFlags::HAS_CT_PROJECTION,
+            )
+        });
+        let predicates: Vec<_> = traits::elaborate(tcx, predicates).collect();
+        tracing::trace!(?predicates);
+        if predicates.references_error() || traits::impossible_predicates(tcx, predicates) {
+            trace!("found unsatisfiable predicates");
             // Clear the body to only contain a single `unreachable` statement.
             let bbs = body.basic_blocks.as_mut();
             bbs.raw.truncate(1);
diff --git a/tests/crashes/140100.rs b/tests/crashes/140100.rs
deleted file mode 100644
index 0836ffe2d92..00000000000
--- a/tests/crashes/140100.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//@ known-bug: #140100
-fn a()
-where
-    b: Sized,
-{
-    println!()
-}
diff --git a/tests/crashes/140365.rs b/tests/crashes/140365.rs
deleted file mode 100644
index 809ceaf35a0..00000000000
--- a/tests/crashes/140365.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #140365
-//@compile-flags: -C opt-level=1 -Zvalidate-mir
-fn f() -> &'static str
-where
-    Self: Sized,
-{
-    ""
-}
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
index fa12dd14753..364fecb96ea 100644
--- a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr
@@ -10,8 +10,14 @@ note: required by a bound in `ct_unused_0::AliasConstUnused`
 LL |     type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
    |                              ^^^^ required by this bound in `AliasConstUnused`
 
+error[E0080]: entering unreachable code
+  --> $DIR/type-alias-bounds.rs:29:52
+   |
+LL |     type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+   |                                                    ^^^^^^^^ evaluation of `ct_unused_1::AliasConstUnused::{constant#0}` failed here
+
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/type-alias-bounds.rs:31:12
+  --> $DIR/type-alias-bounds.rs:32:12
    |
 LL |     let _: AliasConstUnused;
    |            ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
@@ -23,41 +29,42 @@ LL |     type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
    |                                         ^^^^ required by this bound in `AliasConstUnused`
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/type-alias-bounds.rs:39:12
+  --> $DIR/type-alias-bounds.rs:40:12
    |
 LL |     let _: AliasFnUnused<String>;
    |            ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
 note: required by a bound in `AliasFnUnused`
-  --> $DIR/type-alias-bounds.rs:36:27
+  --> $DIR/type-alias-bounds.rs:37:27
    |
 LL |     type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
    |                           ^^^^ required by this bound in `AliasFnUnused`
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/type-alias-bounds.rs:57:12
+  --> $DIR/type-alias-bounds.rs:58:12
    |
 LL |     let _: AliasAssocConstUsed<String>;
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
 note: required by a bound in `AliasAssocConstUsed`
-  --> $DIR/type-alias-bounds.rs:55:41
+  --> $DIR/type-alias-bounds.rs:56:41
    |
 LL |     type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
    |                                         ^^^^ required by this bound in `AliasAssocConstUsed`
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/type-alias-bounds.rs:65:12
+  --> $DIR/type-alias-bounds.rs:66:12
    |
 LL |     let _: AliasFnUsed<String>;
    |            ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
 note: required by a bound in `AliasFnUsed`
-  --> $DIR/type-alias-bounds.rs:62:33
+  --> $DIR/type-alias-bounds.rs:63:33
    |
 LL |     type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
    |                                 ^^^^ required by this bound in `AliasFnUsed`
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0080, E0277.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
index f16e646129c..775b28f8c73 100644
--- a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
+++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs
@@ -27,6 +27,7 @@ fn ct_unused_0() {
 fn ct_unused_1() {
     #[allow(trivial_bounds)]
     type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
+    //[neg]~^ ERROR entering unreachable code
     #[cfg(neg)]
     let _: AliasConstUnused;
     //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
diff --git a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs
index 4423b83e24d..8015a2fe081 100644
--- a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs
+++ b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.rs
@@ -5,7 +5,8 @@ where
     str: Sized,
 {
     [(); { let _a: Option<str> = None; 0 }];
-    //~^ ERROR the type `Option<str>` has an unknown layout
+    //~^ ERROR entering unreachable code
+    //~| NOTE evaluation of `return_str::{constant#0}` failed here
 }
 
 fn main() {}
diff --git a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
index 43fe9e3a7a7..cad73b603c1 100644
--- a/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
+++ b/tests/ui/layout/uncomputable-due-to-trivial-bounds-ice-135138.stderr
@@ -1,8 +1,8 @@
-error[E0080]: the type `Option<str>` has an unknown layout
-  --> $DIR/uncomputable-due-to-trivial-bounds-ice-135138.rs:7:16
+error[E0080]: entering unreachable code
+  --> $DIR/uncomputable-due-to-trivial-bounds-ice-135138.rs:7:10
    |
 LL |     [(); { let _a: Option<str> = None; 0 }];
-   |                ^^ evaluation of `return_str::{constant#0}` failed here
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `return_str::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.rs b/tests/ui/layout/unknown-when-no-type-parameter.rs
index f787998868d..8579593c65c 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.rs
+++ b/tests/ui/layout/unknown-when-no-type-parameter.rs
@@ -9,9 +9,8 @@ where
     (): Project,
 {
     [(); size_of::<<() as Project>::Assoc>()];
-    //~^ ERROR the type `<() as Project>::Assoc` has an unknown layout
-    //~| NOTE inside `std::mem::size_of::<<() as Project>::Assoc>`
-    //~| NOTE failed inside this call
+    //~^ ERROR entering unreachable code
+    //~| NOTE evaluation of `foo::{constant#0}` failed here
 }
 
 fn main() {}
diff --git a/tests/ui/layout/unknown-when-no-type-parameter.stderr b/tests/ui/layout/unknown-when-no-type-parameter.stderr
index 9bb42c46ec3..7c382c7a855 100644
--- a/tests/ui/layout/unknown-when-no-type-parameter.stderr
+++ b/tests/ui/layout/unknown-when-no-type-parameter.stderr
@@ -1,11 +1,8 @@
-error[E0080]: the type `<() as Project>::Assoc` has an unknown layout
+error[E0080]: entering unreachable code
   --> $DIR/unknown-when-no-type-parameter.rs:11:10
    |
 LL |     [(); size_of::<<() as Project>::Assoc>()];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `foo::{constant#0}` failed inside this call
-   |
-note: inside `std::mem::size_of::<<() as Project>::Assoc>`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `foo::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs
index 54f339711d5..da11804c226 100644
--- a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs
+++ b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs
@@ -6,7 +6,8 @@ where
     str: std::ptr::Pointee<Metadata = str>,
 {
     [(); { let _a: Option<&str> = None; 0 }];
-    //~^ ERROR the type `str` has an unknown layout
+    //~^ ERROR entering unreachable code
+    //~| NOTE evaluation of `return_str::{constant#0}` failed here
 }
 
 fn main() {}
diff --git a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
index fd9eedc9267..888e2574119 100644
--- a/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
+++ b/tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
@@ -1,8 +1,8 @@
-error[E0080]: the type `str` has an unknown layout
-  --> $DIR/unknown-when-ptr-metadata-is-DST.rs:8:16
+error[E0080]: entering unreachable code
+  --> $DIR/unknown-when-ptr-metadata-is-DST.rs:8:10
    |
 LL |     [(); { let _a: Option<&str> = None; 0 }];
-   |                ^^ evaluation of `return_str::{constant#0}` failed here
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `return_str::{constant#0}` failed here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/mir/meaningless-bound.rs b/tests/ui/mir/meaningless-bound.rs
new file mode 100644
index 00000000000..c9427e7ece5
--- /dev/null
+++ b/tests/ui/mir/meaningless-bound.rs
@@ -0,0 +1,20 @@
+//! Regression test for #140100 and #140365
+//@compile-flags: -C opt-level=1 -Zvalidate-mir
+
+fn a()
+where
+    b: Sized,
+    //~^ ERROR cannot find type `b` in this scope
+{
+    println!()
+}
+
+fn f() -> &'static str
+where
+    Self: Sized,
+    //~^ ERROR cannot find type `Self` in this scope
+{
+    ""
+}
+
+fn main() {}
diff --git a/tests/ui/mir/meaningless-bound.stderr b/tests/ui/mir/meaningless-bound.stderr
new file mode 100644
index 00000000000..dc08def83b6
--- /dev/null
+++ b/tests/ui/mir/meaningless-bound.stderr
@@ -0,0 +1,19 @@
+error[E0412]: cannot find type `b` in this scope
+  --> $DIR/meaningless-bound.rs:6:5
+   |
+LL |     b: Sized,
+   |     ^ not found in this scope
+
+error[E0411]: cannot find type `Self` in this scope
+  --> $DIR/meaningless-bound.rs:14:5
+   |
+LL | fn f() -> &'static str
+   |    - `Self` not allowed in a function
+LL | where
+LL |     Self: Sized,
+   |     ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0411, E0412.
+For more information about an error, try `rustc --explain E0411`.
diff --git a/tests/crashes/131507.rs b/tests/ui/trivial-bounds/everybody-copies.rs
index 05b5e76bed7..3469fa1f1da 100644
--- a/tests/crashes/131507.rs
+++ b/tests/ui/trivial-bounds/everybody-copies.rs
@@ -1,5 +1,8 @@
-//@ known-bug: #131507
-//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
+//! Regression test for #131507
+//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir --crate-type lib
+//@ build-pass
+
+#![expect(incomplete_features)]
 #![feature(non_lifetime_binders)]
 
 fn brick()
diff --git a/tests/crashes/121363.rs b/tests/ui/trivial-bounds/two-sized-strs.rs
index 38796342284..5cb82eac417 100644
--- a/tests/crashes/121363.rs
+++ b/tests/ui/trivial-bounds/two-sized-strs.rs
@@ -1,7 +1,9 @@
-//@ known-bug: #121363
+//! Regression test for #121363
 //@ compile-flags: -Zmir-enable-passes=+GVN --crate-type lib
+//@ build-pass
 
 #![feature(trivial_bounds)]
+#![expect(trivial_bounds)]
 
 #[derive(Debug)]
 struct TwoStrs(str, str)