Skip to content

Commit 557f684

Browse files
committed
Auto merge of #5296 - sinkuu:fix_ice_trivial_bounds, r=flip1995
Fix ICE with trivial_bounds feature #69874 (comment) changelog: Fix ICE with trivial_bounds feature
2 parents 3aa8da3 + 227ef60 commit 557f684

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

clippy_lints/src/implicit_return.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::{
2-
match_def_path,
2+
fn_has_unsatisfiable_preds, match_def_path,
33
paths::{BEGIN_PANIC, BEGIN_PANIC_FMT},
44
snippet_opt, span_lint_and_then,
55
};
@@ -133,6 +133,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitReturn {
133133
_: HirId,
134134
) {
135135
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
136+
137+
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
138+
if fn_has_unsatisfiable_preds(cx, def_id) {
139+
return;
140+
}
141+
136142
let mir = cx.tcx.optimized_mir(def_id);
137143

138144
// checking return type through MIR, HIR is not able to determine inferred closure return types

clippy_lints/src/missing_const_for_fn.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
1+
use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
22
use rustc::lint::in_external_macro;
33
use rustc_hir as hir;
44
use rustc_hir::intravisit::FnKind;
@@ -88,6 +88,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingConstForFn {
8888
return;
8989
}
9090

91+
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
92+
if fn_has_unsatisfiable_preds(cx, def_id) {
93+
return;
94+
}
95+
9196
// Perform some preliminary checks that rule out constness on the Clippy side. This way we
9297
// can skip the actual const check and return early.
9398
match kind {

clippy_lints/src/redundant_clone.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::{
2-
has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir, span_lint_hir_and_then,
3-
walk_ptrs_ty_depth,
2+
fn_has_unsatisfiable_preds, has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir,
3+
span_lint_hir_and_then, walk_ptrs_ty_depth,
44
};
55
use if_chain::if_chain;
66
use matches::matches;
@@ -79,6 +79,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
7979
_: HirId,
8080
) {
8181
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
82+
83+
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
84+
if fn_has_unsatisfiable_preds(cx, def_id) {
85+
return;
86+
}
87+
8288
let mir = cx.tcx.optimized_mir(def_id);
8389
let mir_read_only = mir.unwrap_read_only();
8490

clippy_lints/src/utils/mod.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustc::ty::{
3232
self,
3333
layout::{self, IntegerExt},
3434
subst::GenericArg,
35-
Binder, Ty, TyCtxt,
35+
Binder, Ty, TyCtxt, TypeFoldable,
3636
};
3737
use rustc_ast::ast::{self, Attribute, LitKind};
3838
use rustc_attr as attr;
@@ -1377,6 +1377,27 @@ pub fn is_trait_impl_item(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool {
13771377
}
13781378
}
13791379

1380+
/// Check if it's even possible to satisfy the `where` clause for the item.
1381+
///
1382+
/// `trivial_bounds` feature allows functions with unsatisfiable bounds, for example:
1383+
///
1384+
/// ```ignore
1385+
/// fn foo() where i32: Iterator {
1386+
/// for _ in 2i32 {}
1387+
/// }
1388+
/// ```
1389+
pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_, '_>, did: DefId) -> bool {
1390+
use rustc_infer::traits;
1391+
let predicates = cx
1392+
.tcx
1393+
.predicates_of(did)
1394+
.predicates
1395+
.iter()
1396+
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
1397+
.collect();
1398+
!traits::normalize_and_test_predicates(cx.tcx, traits::elaborate_predicates(cx.tcx, predicates).collect())
1399+
}
1400+
13801401
#[cfg(test)]
13811402
mod test {
13821403
use super::{trim_multiline, without_block_comments};

tests/ui/crashes/trivial_bounds.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// run-pass
2+
3+
#![feature(trivial_bounds)]
4+
#![allow(unused, trivial_bounds)]
5+
6+
fn test_trivial_bounds()
7+
where
8+
i32: Iterator,
9+
{
10+
for _ in 2i32 {}
11+
}
12+
13+
fn main() {}

0 commit comments

Comments
 (0)