Skip to content

Commit

Permalink
Auto merge of rust-lang#123169 - lukas-code:known-panics-ice, r=<try>
Browse files Browse the repository at this point in the history
skip known panics lint for impossible items

fixes rust-lang#123134

For items with impossible predicates like `[u8]: Sized` it's possible to have locals that are "Sized", but cannot be const-propped in any meaningful way. To avoid this issue, we can just skip the known panics lint for items that have impossible predicates.
  • Loading branch information
bors committed Mar 28, 2024
2 parents 4ea92e3 + 7b46e02 commit 76192f0
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,13 @@ rustc_queries! {
}
}

query is_impossible_item(def_id: DefId) -> bool {
desc { |tcx|
"checking if `{}` is impossible to reference",
tcx.def_path_str(def_id),
}
}

query is_impossible_associated_item(key: (DefId, DefId)) -> bool {
desc { |tcx|
"checking if `{}` is impossible to reference within `{}`",
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_mir_transform/src/known_panics_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
return;
}

if tcx.is_impossible_item(def_id) {
trace!("KnownPanicsLint skipped for impossible item {:?}", def_id);
return;
}

trace!("KnownPanicsLint starting for {:?}", def_id);

let mut linter = ConstPropagator::new(body, tcx);
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,16 @@ fn instantiate_and_check_impossible_predicates<'tcx>(
result
}

/// Checks whether an item is impossible to reference.
#[instrument(level = "debug", skip(tcx), ret)]
fn is_impossible_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
let param_env = tcx.param_env_reveal_all_normalized(def_id);
impossible_predicates(
tcx,
param_env.caller_bounds().iter().filter(|predicate| !predicate.has_param()).collect(),
)
}

/// Checks whether a trait's associated item is impossible to reference on a given impl.
///
/// This only considers predicates that reference the impl's generics, and not
Expand Down Expand Up @@ -506,6 +516,7 @@ pub fn provide(providers: &mut Providers) {
specializes: specialize::specializes,
instantiate_and_check_impossible_predicates,
check_tys_might_be_eq: misc::check_tys_might_be_eq,
is_impossible_item,
is_impossible_associated_item,
..*providers
};
Expand Down
43 changes: 43 additions & 0 deletions tests/ui/mir/lint/known-panics-impossible-pred-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//@ build-pass
// Regression test for an ICE: https://github.com/rust-lang/rust/issues/123134

trait Api: Sized {
type Device: ?Sized;
}

struct OpenDevice<A: Api>
where
A::Device: Sized,
{
device: A::Device,
queue: (),
}

trait Adapter {
type A: Api;

fn open() -> OpenDevice<Self::A>
where
<Self::A as Api>::Device: Sized;
}

struct ApiS;

impl Api for ApiS {
type Device = [u8];
}

impl<T> Adapter for T
{
type A = ApiS;

// This function has the impossible predicate `[u8]: Sized`.
fn open() -> OpenDevice<Self::A>
where
<Self::A as Api>::Device: Sized,
{
unreachable!()
}
}

fn main() {}

0 comments on commit 76192f0

Please sign in to comment.