Skip to content

Consider parent predicates in ImpossiblePredicates pass. #144233

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions compiler/rustc_mir_transform/src/impossible_predicates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
7 changes: 0 additions & 7 deletions tests/crashes/140100.rs

This file was deleted.

8 changes: 0 additions & 8 deletions tests/crashes/140365.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Original file line number Diff line number Diff line change
@@ -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

Expand Down
5 changes: 2 additions & 3 deletions tests/ui/layout/unknown-when-no-type-parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
7 changes: 2 additions & 5 deletions tests/ui/layout/unknown-when-no-type-parameter.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
3 changes: 2 additions & 1 deletion tests/ui/layout/unknown-when-ptr-metadata-is-DST.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
6 changes: 3 additions & 3 deletions tests/ui/layout/unknown-when-ptr-metadata-is-DST.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
20 changes: 20 additions & 0 deletions tests/ui/mir/meaningless-bound.rs
Original file line number Diff line number Diff line change
@@ -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() {}
19 changes: 19 additions & 0 deletions tests/ui/mir/meaningless-bound.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
Loading