mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-19 11:12:43 +00:00
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`
This commit is contained in:
commit
2e8c3c3e9e
@ -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 if_chain::if_chain;
|
||||||
use rustc::declare_lint_pass;
|
use rustc::declare_lint_pass;
|
||||||
use rustc::hir::*;
|
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,
|
// check if the component types of the transmuted collection and the result have different ABI,
|
||||||
// size or alignment
|
// size or alignment
|
||||||
fn is_layout_incompatible<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool {
|
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 empty_param_env = ty::ParamEnv::empty();
|
||||||
let to_ty_layout = cx.tcx.layout_of(ty::ParamEnv::empty().and(to));
|
// 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) {
|
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
|
from_layout.size != to_layout.size || from_layout.align != to_layout.align || from_layout.abi != to_layout.abi
|
||||||
} else {
|
} else {
|
||||||
|
@ -1111,6 +1111,15 @@ pub fn match_function_call<'a, 'tcx>(
|
|||||||
None
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{trim_multiline, without_block_comments};
|
use super::{trim_multiline, without_block_comments};
|
||||||
|
15
tests/ui/crashes/auxiliary/use_self_macro.rs
Normal file
15
tests/ui/crashes/auxiliary/use_self_macro.rs
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// run-pass
|
// 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 {
|
pub trait FooMap {
|
||||||
fn map<B, F: Fn() -> B>(&self, f: F) -> B;
|
fn map<B, F: Fn() -> B>(&self, f: F) -> B;
|
20
tests/ui/crashes/ice-4968.rs
Normal file
20
tests/ui/crashes/ice-4968.rs
Normal file
@ -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() {}
|
Loading…
Reference in New Issue
Block a user