Skip to content

Commit

Permalink
Merge pull request #99 from rodrimati1992/master
Browse files Browse the repository at this point in the history
Fixed lifetime unsoundness in `arr` macro.

Fixes #98
  • Loading branch information
novacrazy authored Apr 10, 2020
2 parents 171bc5c + 100b0f6 commit 8ef64f9
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 6 deletions.
79 changes: 74 additions & 5 deletions src/arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,30 @@ pub type Inc<T, U> = <U as AddLength<T, U1>>::Output;
#[doc(hidden)]
#[macro_export]
macro_rules! arr_impl {
(@replace_expr $e:expr)=>{
1
};
($T:ty; $N:ty, [$($x:expr),*], []) => ({
unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) }
const __ARR_LENGTH:usize=0 $(+ $crate::arr_impl!(@replace_expr $x) )*;
fn __do_transmute<'a, T, N: $crate::ArrayLength<T>>(arr: [T; __ARR_LENGTH]) -> $crate::GenericArray<T, N> {
unsafe { $crate::transmute(arr) }
}

let _:[();<$N as $crate::typenum::Unsigned>::USIZE]=[();__ARR_LENGTH];

__do_transmute::<$T,$N>([$($x),*])
});
($T:ty; $N:ty, [], [$x1:expr]) => (
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [])
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [])
);
($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),+])
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1], [$($x),+])
);
($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [])
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [])
);
($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [$($x),+])
$crate::arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1], [$($x),+])
);
}

Expand All @@ -55,3 +65,62 @@ macro_rules! arr {
($($x:expr,)+) => (arr![$($x),+]);
() => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
}


mod doctests_only{
///
/// # With ellision
///
/// Testing that lifetimes aren't transmuted when they're ellided.
///
/// ```compile_fail
/// #[macro_use] extern crate generic_array;
/// fn main() {
/// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
/// arr![&A; a][0]
/// }
/// }
/// ```
///
/// ```rust
/// #[macro_use] extern crate generic_array;
/// fn main() {
/// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
/// arr![&A; a][0]
/// }
/// }
/// ```
///
/// # Without ellision
///
/// Testing that lifetimes aren't transmuted when they're specified explicitly.
///
/// ```compile_fail
/// #[macro_use] extern crate generic_array;
/// fn main() {
/// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
/// arr![&'a A; a][0]
/// }
/// }
/// ```
///
/// ```compile_fail
/// #[macro_use] extern crate generic_array;
/// fn main() {
/// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'static A {
/// arr![&'static A; a][0]
/// }
/// }
/// ```
///
/// ```rust
/// #[macro_use] extern crate generic_array;
/// fn main() {
/// fn unsound_lifetime_extension<'a, A>(a: &'a A) -> &'a A {
/// arr![&'a A; a][0]
/// }
/// }
/// ```
#[allow(dead_code)]
pub enum DocTests{}
}
2 changes: 1 addition & 1 deletion tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::cell::Cell;
use core::ops::{Add, Drop};
use generic_array::functional::*;
use generic_array::sequence::*;
use generic_array::typenum::{U1, U3, U4, U97};
use generic_array::typenum::{U3, U4, U97};
use generic_array::GenericArray;

#[test]
Expand Down

0 comments on commit 8ef64f9

Please sign in to comment.