diff options
| author | bors <bors@rust-lang.org> | 2020-01-03 08:48:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-01-03 08:48:05 +0000 |
| commit | 2e8c3c3e9eb81bc2be047b1d4b2f9f31b869b6f5 (patch) | |
| tree | 920b722eac49b8415c45fed685b42e80584d2de0 | |
| parent | 304edf39c3ebb6fac9b4db3c8e05fee1bbc1543b (diff) | |
| parent | c6aeda7bd52e490148ae34242f09de66d0af9841 (diff) | |
| download | rust-2e8c3c3e9eb81bc2be047b1d4b2f9f31b869b6f5.tar.gz rust-2e8c3c3e9eb81bc2be047b1d4b2f9f31b869b6f5.zip | |
Auto merge of #4975 - JohnTitor:fix-4968, r=phansch
Fix ICE on `unsound_collection_transmute` Fixes #4968 Check if `Ty`s are normalizable. It might show hidden false negative, I'm not sure. Also, the regression tests are placed on two dirs, so move them to `/crashes`. I think it will be easier to find the right place. changelog: Fix ICE on `unsound_collection_transmute`
| -rw-r--r-- | clippy_lints/src/transmute.rs | 13 | ||||
| -rw-r--r-- | clippy_lints/src/utils/mod.rs | 9 | ||||
| -rw-r--r-- | tests/ui/crashes/auxiliary/use_self_macro.rs | 15 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-2636.rs (renamed from tests/ui/ice-2636.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-2636.stderr (renamed from tests/ui/ice-2636.stderr) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-2862.rs (renamed from tests/ui/crashes/issue-2862.rs) | 2 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-360.rs (renamed from tests/ui/ice-360.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-360.stderr (renamed from tests/ui/ice-360.stderr) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-3717.rs (renamed from tests/ui/ice-3717.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-3717.stderr (renamed from tests/ui/ice-3717.stderr) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4121.rs (renamed from tests/ui/ice-4121.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4545.rs (renamed from tests/ui/ice-4545.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4579.rs (renamed from tests/ui/ice-4579.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4671.rs (renamed from tests/ui/ice-4671.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4775.rs (renamed from tests/ui/ice-4775.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/crashes/ice-4968.rs | 20 |
16 files changed, 55 insertions, 4 deletions
diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index b4fed7ae812..b6ae611da12 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -1,4 +1,6 @@ -use crate::utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then, sugg}; +use crate::utils::{ + is_normalizable, last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then, sugg, +}; use if_chain::if_chain; use rustc::declare_lint_pass; use rustc::hir::*; @@ -639,8 +641,13 @@ fn get_type_snippet(cx: &LateContext<'_, '_>, path: &QPath<'_>, to_ref_ty: Ty<'_ // check if the component types of the transmuted collection and the result have different ABI, // size or alignment fn is_layout_incompatible<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool { - let from_ty_layout = cx.tcx.layout_of(ty::ParamEnv::empty().and(from)); - let to_ty_layout = cx.tcx.layout_of(ty::ParamEnv::empty().and(to)); + let empty_param_env = ty::ParamEnv::empty(); + // check if `from` and `to` are normalizable to avoid ICE (#4968) + if !(is_normalizable(cx, empty_param_env, from) && is_normalizable(cx, empty_param_env, to)) { + return false; + } + let from_ty_layout = cx.tcx.layout_of(empty_param_env.and(from)); + let to_ty_layout = cx.tcx.layout_of(empty_param_env.and(to)); if let (Ok(from_layout), Ok(to_layout)) = (from_ty_layout, to_ty_layout) { from_layout.size != to_layout.size || from_layout.align != to_layout.align || from_layout.abi != to_layout.abi } else { diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index ebfa88fabfd..0680f627bbb 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1111,6 +1111,15 @@ pub fn match_function_call<'a, 'tcx>( None } +/// Checks if `Ty` is normalizable. This function is useful +/// to avoid crashes on `layout_of`. +pub fn is_normalizable<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { + cx.tcx.infer_ctxt().enter(|infcx| { + let cause = rustc::traits::ObligationCause::dummy(); + infcx.at(&cause, param_env).normalize(&ty).is_ok() + }) +} + #[cfg(test)] mod test { use super::{trim_multiline, without_block_comments}; diff --git a/tests/ui/crashes/auxiliary/use_self_macro.rs b/tests/ui/crashes/auxiliary/use_self_macro.rs new file mode 100644 index 00000000000..a8a85b4baef --- /dev/null +++ b/tests/ui/crashes/auxiliary/use_self_macro.rs @@ -0,0 +1,15 @@ +macro_rules! use_self { + ( + impl $ty:ident { + fn func(&$this:ident) { + [fields($($field:ident)*)] + } + } + ) => ( + impl $ty { + fn func(&$this) { + let $ty { $($field),* } = $this; + } + } + ) +} diff --git a/tests/ui/ice-2636.rs b/tests/ui/crashes/ice-2636.rs index e0b58157590..e0b58157590 100644 --- a/tests/ui/ice-2636.rs +++ b/tests/ui/crashes/ice-2636.rs diff --git a/tests/ui/ice-2636.stderr b/tests/ui/crashes/ice-2636.stderr index aba8be4adcc..aba8be4adcc 100644 --- a/tests/ui/ice-2636.stderr +++ b/tests/ui/crashes/ice-2636.stderr diff --git a/tests/ui/crashes/issue-2862.rs b/tests/ui/crashes/ice-2862.rs index 3587a08eab7..47324ce1831 100644 --- a/tests/ui/crashes/issue-2862.rs +++ b/tests/ui/crashes/ice-2862.rs @@ -1,6 +1,6 @@ // run-pass -/// Test for https://github.com/rust-lang/rust-clippy/issues/2826 +/// Test for https://github.com/rust-lang/rust-clippy/issues/2862 pub trait FooMap { fn map<B, F: Fn() -> B>(&self, f: F) -> B; diff --git a/tests/ui/ice-360.rs b/tests/ui/crashes/ice-360.rs index 6555c19ca6a..6555c19ca6a 100644 --- a/tests/ui/ice-360.rs +++ b/tests/ui/crashes/ice-360.rs diff --git a/tests/ui/ice-360.stderr b/tests/ui/crashes/ice-360.stderr index 84e31eaf2e9..84e31eaf2e9 100644 --- a/tests/ui/ice-360.stderr +++ b/tests/ui/crashes/ice-360.stderr diff --git a/tests/ui/ice-3717.rs b/tests/ui/crashes/ice-3717.rs index 21c48f4749c..21c48f4749c 100644 --- a/tests/ui/ice-3717.rs +++ b/tests/ui/crashes/ice-3717.rs diff --git a/tests/ui/ice-3717.stderr b/tests/ui/crashes/ice-3717.stderr index 08c53c399c2..08c53c399c2 100644 --- a/tests/ui/ice-3717.stderr +++ b/tests/ui/crashes/ice-3717.stderr diff --git a/tests/ui/ice-4121.rs b/tests/ui/crashes/ice-4121.rs index e1a142fdcb6..e1a142fdcb6 100644 --- a/tests/ui/ice-4121.rs +++ b/tests/ui/crashes/ice-4121.rs diff --git a/tests/ui/ice-4545.rs b/tests/ui/crashes/ice-4545.rs index d9c9c2096d9..d9c9c2096d9 100644 --- a/tests/ui/ice-4545.rs +++ b/tests/ui/crashes/ice-4545.rs diff --git a/tests/ui/ice-4579.rs b/tests/ui/crashes/ice-4579.rs index 2e7e279f847..2e7e279f847 100644 --- a/tests/ui/ice-4579.rs +++ b/tests/ui/crashes/ice-4579.rs diff --git a/tests/ui/ice-4671.rs b/tests/ui/crashes/ice-4671.rs index 64e8e776941..64e8e776941 100644 --- a/tests/ui/ice-4671.rs +++ b/tests/ui/crashes/ice-4671.rs diff --git a/tests/ui/ice-4775.rs b/tests/ui/crashes/ice-4775.rs index 31e53e846d5..31e53e846d5 100644 --- a/tests/ui/ice-4775.rs +++ b/tests/ui/crashes/ice-4775.rs diff --git a/tests/ui/crashes/ice-4968.rs b/tests/ui/crashes/ice-4968.rs new file mode 100644 index 00000000000..3822f174598 --- /dev/null +++ b/tests/ui/crashes/ice-4968.rs @@ -0,0 +1,20 @@ +// check-pass + +// Test for https://github.com/rust-lang/rust-clippy/issues/4968 + +#![warn(clippy::unsound_collection_transmute)] + +trait Trait { + type Assoc; +} + +use std::mem::{self, ManuallyDrop}; + +#[allow(unused)] +fn func<T: Trait>(slice: Vec<T::Assoc>) { + unsafe { + let _: Vec<ManuallyDrop<T::Assoc>> = mem::transmute(slice); + } +} + +fn main() {} |
