Skip to content

Commit f465222

Browse files
author
Lukas Markeffsky
committed
skip known panics lint for impossible items
1 parent 551abd6 commit f465222

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed

compiler/rustc_middle/src/query/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2116,6 +2116,13 @@ rustc_queries! {
21162116
}
21172117
}
21182118

2119+
query is_impossible_item(def_id: DefId) -> bool {
2120+
desc { |tcx|
2121+
"checking if `{}` has predicates that are impossible to satisfy",
2122+
tcx.def_path_str(def_id),
2123+
}
2124+
}
2125+
21192126
query is_impossible_associated_item(key: (DefId, DefId)) -> bool {
21202127
desc { |tcx|
21212128
"checking if `{}` is impossible to reference within `{}`",

compiler/rustc_mir_transform/src/known_panics_lint.rs

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
5151
return;
5252
}
5353

54+
if tcx.is_impossible_item(def_id) {
55+
trace!("KnownPanicsLint skipped for impossible item {:?}", def_id);
56+
return;
57+
}
58+
5459
trace!("KnownPanicsLint starting for {:?}", def_id);
5560

5661
let mut linter = ConstPropagator::new(body, tcx);

compiler/rustc_trait_selection/src/traits/mod.rs

+25
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,30 @@ fn instantiate_and_check_impossible_predicates<'tcx>(
421421
result
422422
}
423423

424+
/// Checks whether an item is impossible to reference.
425+
#[instrument(level = "debug", skip(tcx), ret)]
426+
fn is_impossible_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
427+
let item_param_env = tcx.param_env(def_id);
428+
let predicates = tcx
429+
.predicates_of(def_id)
430+
.predicates
431+
.iter()
432+
.filter_map(|&(clause, _)| tcx.try_normalize_erasing_regions(item_param_env, clause).ok())
433+
.filter(|clause| clause.is_global());
434+
435+
let global_param_env = ty::ParamEnv::reveal_all();
436+
let infcx = tcx.infer_ctxt().build();
437+
let ocx = ObligationCtxt::new(&infcx);
438+
for predicate in predicates {
439+
let obligation =
440+
Obligation::new(tcx, ObligationCause::dummy(), global_param_env, predicate);
441+
ocx.register_obligation(obligation);
442+
}
443+
444+
let errors = ocx.select_all_or_error();
445+
!errors.is_empty()
446+
}
447+
424448
/// Checks whether a trait's associated item is impossible to reference on a given impl.
425449
///
426450
/// This only considers predicates that reference the impl's generics, and not
@@ -506,6 +530,7 @@ pub fn provide(providers: &mut Providers) {
506530
specializes: specialize::specializes,
507531
instantiate_and_check_impossible_predicates,
508532
check_tys_might_be_eq: misc::check_tys_might_be_eq,
533+
is_impossible_item,
509534
is_impossible_associated_item,
510535
..*providers
511536
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//@ build-pass
2+
// Regression test for an ICE: https://github.com/rust-lang/rust/issues/123134
3+
4+
trait Api: Sized {
5+
type Device: ?Sized;
6+
}
7+
8+
struct OpenDevice<A: Api>
9+
where
10+
A::Device: Sized,
11+
{
12+
device: A::Device,
13+
queue: (),
14+
}
15+
16+
trait Adapter {
17+
type A: Api;
18+
19+
fn open() -> OpenDevice<Self::A>
20+
where
21+
<Self::A as Api>::Device: Sized;
22+
}
23+
24+
struct ApiS;
25+
26+
impl Api for ApiS {
27+
type Device = [u8];
28+
}
29+
30+
impl<T> Adapter for T
31+
{
32+
type A = ApiS;
33+
34+
// This function has the impossible predicate `[u8]: Sized`.
35+
fn open() -> OpenDevice<Self::A>
36+
where
37+
<Self::A as Api>::Device: Sized,
38+
{
39+
unreachable!()
40+
}
41+
}
42+
43+
fn main() {}

0 commit comments

Comments
 (0)