]> git.lizzy.rs Git - rust.git/blobdiff - tests/ui/transmute.rs
Auto merge of #3603 - xfix:random-state-lint, r=phansch
[rust.git] / tests / ui / transmute.rs
index 48b89c33ab91f46778e89cf36a4a2c868bb2e7f5..b27014201cd76510a702fae0847779fc3b4995f8 100644 (file)
@@ -1,5 +1,11 @@
-
-
+// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 #![allow(dead_code)]
 
@@ -16,8 +22,8 @@ fn my_vec() -> MyVec<i32> {
     vec![]
 }
 
-#[allow(needless_lifetimes)]
-#[warn(useless_transmute)]
+#[allow(clippy::needless_lifetimes, clippy::transmute_ptr_to_ptr)]
+#[warn(clippy::useless_transmute)]
 unsafe fn _generic<'a, T, U: 'a>(t: &'a T) {
     let _: &'a T = core::intrinsics::transmute(t);
 
@@ -30,7 +36,7 @@ unsafe fn _generic<'a, T, U: 'a>(t: &'a T) {
     let _: *const U = core::intrinsics::transmute(t);
 }
 
-#[warn(transmute_ptr_to_ref)]
+#[warn(clippy::transmute_ptr_to_ref)]
 unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
     let _: &T = std::mem::transmute(p);
     let _: &T = &*p;
@@ -54,7 +60,7 @@ unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
     let _: &T = &*(om as *const T);
 }
 
-#[warn(transmute_ptr_to_ref)]
+#[warn(clippy::transmute_ptr_to_ref)]
 fn issue1231() {
     struct Foo<'a, T: 'a> {
         bar: &'a T,
@@ -70,7 +76,7 @@ struct Foo<'a, T: 'a> {
     unsafe { std::mem::transmute::<_, Bar>(raw) };
 }
 
-#[warn(useless_transmute)]
+#[warn(clippy::useless_transmute)]
 fn useless() {
     unsafe {
         let _: Vec<i32> = core::intrinsics::transmute(my_vec());
@@ -91,17 +97,17 @@ fn useless() {
 
         let _: *const usize = std::mem::transmute(5_isize);
 
-        let _  = 5_isize as *const usize;
+        let _ = 5_isize as *const usize;
 
-        let _: *const usize = std::mem::transmute(1+1usize);
+        let _: *const usize = std::mem::transmute(1 + 1usize);
 
-        let _  = (1+1_usize) as *const usize;
+        let _ = (1 + 1_usize) as *const usize;
     }
 }
 
 struct Usize(usize);
 
-#[warn(crosspointer_transmute)]
+#[warn(clippy::crosspointer_transmute)]
 fn crosspointer() {
     let mut int: Usize = Usize(0);
     let int_const_ptr: *const Usize = &int as *const Usize;
@@ -118,18 +124,18 @@ fn crosspointer() {
     }
 }
 
-#[warn(transmute_int_to_char)]
+#[warn(clippy::transmute_int_to_char)]
 fn int_to_char() {
     let _: char = unsafe { std::mem::transmute(0_u32) };
     let _: char = unsafe { std::mem::transmute(0_i32) };
 }
 
-#[warn(transmute_int_to_bool)]
+#[warn(clippy::transmute_int_to_bool)]
 fn int_to_bool() {
     let _: bool = unsafe { std::mem::transmute(0_u8) };
 }
 
-#[warn(transmute_int_to_float)]
+#[warn(clippy::transmute_int_to_float)]
 fn int_to_float() {
     let _: f32 = unsafe { std::mem::transmute(0_u32) };
     let _: f32 = unsafe { std::mem::transmute(0_i32) };
@@ -140,11 +146,58 @@ fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
     let _: &mut str = unsafe { std::mem::transmute(mb) };
 }
 
-#[warn(misaligned_transmute)]
-fn misaligned_transmute() {
-    let _: u32 = unsafe { std::mem::transmute([0u8; 4]) }; // err
-    let _: u32 = unsafe { std::mem::transmute(0f32) }; // ok (alignment-wise)
-    let _: [u8; 4] = unsafe { std::mem::transmute(0u32) }; // ok (alignment-wise)
+// Make sure we can modify lifetimes, which is one of the recommended uses
+// of transmute
+
+// Make sure we can do static lifetime transmutes
+#[warn(clippy::transmute_ptr_to_ptr)]
+unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
+    std::mem::transmute::<&'a T, &'static T>(t)
+}
+
+// Make sure we can do non-static lifetime transmutes
+#[warn(clippy::transmute_ptr_to_ptr)]
+unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
+    std::mem::transmute::<&'a T, &'b T>(t)
+}
+
+struct LifetimeParam<'a> {
+    s: &'a str,
+}
+
+struct GenericParam<T> {
+    t: T,
+}
+
+#[warn(clippy::transmute_ptr_to_ptr)]
+fn transmute_ptr_to_ptr() {
+    let ptr = &1u32 as *const u32;
+    let mut_ptr = &mut 1u32 as *mut u32;
+    unsafe {
+        // pointer-to-pointer transmutes; bad
+        let _: *const f32 = std::mem::transmute(ptr);
+        let _: *mut f32 = std::mem::transmute(mut_ptr);
+        // ref-ref transmutes; bad
+        let _: &f32 = std::mem::transmute(&1u32);
+        let _: &f64 = std::mem::transmute(&1f32);
+        // ^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
+        // the same type
+        let _: &mut f32 = std::mem::transmute(&mut 1u32);
+        let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
+    }
+
+    // these are recommendations for solving the above; if these lint we need to update
+    // those suggestions
+    let _ = ptr as *const f32;
+    let _ = mut_ptr as *mut f32;
+    let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
+    let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
+
+    // transmute internal lifetimes, should not lint
+    let s = "hello world".to_owned();
+    let lp = LifetimeParam { s: &s };
+    let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
+    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
 }
 
-fn main() { }
+fn main() {}