Fix ICE with trivial_bounds feature
This commit is contained in:
parent
187bbf0e7b
commit
a3d9355bef
@ -1,5 +1,5 @@
|
||||
use crate::utils::{
|
||||
match_def_path,
|
||||
fn_has_unsatisfiable_preds, match_def_path,
|
||||
paths::{BEGIN_PANIC, BEGIN_PANIC_FMT},
|
||||
snippet_opt, span_lint_and_then,
|
||||
};
|
||||
@ -133,6 +133,12 @@ fn check_fn(
|
||||
_: HirId,
|
||||
) {
|
||||
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
|
||||
|
||||
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
|
||||
if fn_has_unsatisfiable_preds(cx, def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mir = cx.tcx.optimized_mir(def_id);
|
||||
|
||||
// checking return type through MIR, HIR is not able to determine inferred closure return types
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::utils::{has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
|
||||
use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
|
||||
use rustc::lint::in_external_macro;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
@ -88,6 +88,11 @@ fn check_fn(
|
||||
return;
|
||||
}
|
||||
|
||||
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
|
||||
if fn_has_unsatisfiable_preds(cx, def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform some preliminary checks that rule out constness on the Clippy side. This way we
|
||||
// can skip the actual const check and return early.
|
||||
match kind {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::utils::{
|
||||
has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir, span_lint_hir_and_then,
|
||||
walk_ptrs_ty_depth,
|
||||
fn_has_unsatisfiable_preds, has_drop, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir,
|
||||
span_lint_hir_and_then, walk_ptrs_ty_depth,
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
@ -79,6 +79,12 @@ fn check_fn(
|
||||
_: HirId,
|
||||
) {
|
||||
let def_id = cx.tcx.hir().body_owner_def_id(body.id());
|
||||
|
||||
// Building MIR for `fn`s with unsatisfiable preds results in ICE.
|
||||
if fn_has_unsatisfiable_preds(cx, def_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mir = cx.tcx.optimized_mir(def_id);
|
||||
let mir_read_only = mir.unwrap_read_only();
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
self,
|
||||
layout::{self, IntegerExt},
|
||||
subst::GenericArg,
|
||||
Binder, Ty, TyCtxt,
|
||||
Binder, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_ast::ast::{self, Attribute, LitKind};
|
||||
use rustc_attr as attr;
|
||||
@ -1377,6 +1377,27 @@ pub fn is_trait_impl_item(cx: &LateContext<'_, '_>, hir_id: HirId) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if it's even possible to satisfy the `where` clause for the item.
|
||||
///
|
||||
/// `trivial_bounds` feature allows functions with unsatisfiable bounds, for example:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn foo() i32: Iterator {
|
||||
/// for _ in 2i32 {}
|
||||
/// }
|
||||
/// ```
|
||||
pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_, '_>, did: DefId) -> bool {
|
||||
use rustc_infer::traits;
|
||||
let predicates = cx
|
||||
.tcx
|
||||
.predicates_of(did)
|
||||
.predicates
|
||||
.iter()
|
||||
.filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None })
|
||||
.collect();
|
||||
!traits::normalize_and_test_predicates(cx.tcx, traits::elaborate_predicates(cx.tcx, predicates).collect())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{trim_multiline, without_block_comments};
|
||||
|
13
tests/ui/crashes/trivial_bounds.rs
Normal file
13
tests/ui/crashes/trivial_bounds.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(trivial_bounds)]
|
||||
#![allow(unused, trivial_bounds)]
|
||||
|
||||
fn test_trivial_bounds()
|
||||
where
|
||||
i32: Iterator,
|
||||
{
|
||||
for _ in 2i32 {}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user