From 5e68056b13984546f56edc13cbb5007319c3b4d5 Mon Sep 17 00:00:00 2001 From: Toby Scrace Date: Mon, 9 Nov 2015 09:15:39 +0000 Subject: [PATCH 1/8] Add examples to methods on integer types --- src/libcore/num/mod.rs | 373 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 342 insertions(+), 31 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d3f63ab4a8c4f..3afc89c984142 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -141,6 +141,8 @@ macro_rules! int_impl { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// assert_eq!(u32::from_str_radix("A", 16), Ok(10)); /// ``` @@ -153,7 +155,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b01001100u8; /// /// assert_eq!(n.count_ones(), 3); @@ -166,7 +170,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b01001100u8; /// /// assert_eq!(n.count_zeros(), 5); @@ -182,7 +188,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b0101000u16; /// /// assert_eq!(n.leading_zeros(), 10); @@ -198,7 +206,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b0101000u16; /// /// assert_eq!(n.trailing_zeros(), 3); @@ -214,7 +224,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF012u64; /// @@ -232,7 +244,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0xDEF0123456789ABCu64; /// @@ -248,7 +262,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0xEFCDAB8967452301u64; /// @@ -267,7 +283,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -289,7 +307,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -311,7 +331,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -333,7 +355,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -353,7 +377,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!(5u16.checked_add(65530), Some(65535)); /// assert_eq!(6u16.checked_add(65530), None); /// ``` @@ -368,7 +394,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!((-127i8).checked_sub(1), Some(-128)); /// assert_eq!((-128i8).checked_sub(1), None); /// ``` @@ -383,7 +411,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!(5u8.checked_mul(51), Some(255)); /// assert_eq!(5u8.checked_mul(52), None); /// ``` @@ -398,7 +428,9 @@ macro_rules! int_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!((-127i8).checked_div(-1), Some(127)); /// assert_eq!((-128i8).checked_div(-1), None); /// assert_eq!((1i8).checked_div(0), None); @@ -416,6 +448,15 @@ macro_rules! int_impl { /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_add(1), 101); + /// assert_eq!(100i8.saturating_add(127), 127); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_add(self, other: Self) -> Self { @@ -428,6 +469,15 @@ macro_rules! int_impl { /// Saturating integer subtraction. Computes `self - other`, saturating /// at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_sub(127), -27); + /// assert_eq!((-100i8).saturating_sub(127), -128); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_sub(self, other: Self) -> Self { @@ -440,6 +490,15 @@ macro_rules! int_impl { /// Wrapping (modular) addition. Computes `self + other`, /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_add(27), 127); + /// assert_eq!(100i8.wrapping_add(127), -29); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_add(self, rhs: Self) -> Self { @@ -450,6 +509,15 @@ macro_rules! int_impl { /// Wrapping (modular) subtraction. Computes `self - other`, /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0i8.wrapping_sub(127), -127); + /// assert_eq!((-2i8).wrapping_sub(127), 127); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_sub(self, rhs: Self) -> Self { @@ -460,6 +528,15 @@ macro_rules! int_impl { /// Wrapping (modular) multiplication. Computes `self * /// other`, wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.wrapping_mul(12), 120); + /// assert_eq!(11i8.wrapping_mul(12), -124); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_mul(self, rhs: Self) -> Self { @@ -477,6 +554,15 @@ macro_rules! int_impl { /// to `-MIN`, a positive value that is too large to represent /// in the type. In such a case, this function returns `MIN` /// itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_div(10), 10); + /// assert_eq!((-128i8).wrapping_div(-1), -128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_div(self, rhs: Self) -> Self { @@ -490,6 +576,15 @@ macro_rules! int_impl { /// implementation artifacts make `x % y` invalid for `MIN / /// -1` on a signed type (where `MIN` is the negative /// minimal value). In such a case, this function returns `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_rem(10), 0); + /// assert_eq!((-128i8).wrapping_rem(-1), 0); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_rem(self, rhs: Self) -> Self { @@ -504,6 +599,15 @@ macro_rules! int_impl { /// negative minimal value for the type); this is a positive /// value that is too large to represent in the type. In such /// a case, this function returns `MIN` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_neg(), -100); + /// assert_eq!((-128i8).wrapping_neg(), -128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_neg(self) -> Self { @@ -513,6 +617,15 @@ macro_rules! int_impl { /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(1u8.wrapping_shl(7), 128); + /// assert_eq!(1u8.wrapping_shl(8), 1); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_shl(self, rhs: u32) -> Self { @@ -522,6 +635,15 @@ macro_rules! int_impl { /// Panic-free bitwise shift-left; yields `self >> mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(128u8.wrapping_shr(7), 1); + /// assert_eq!(128u8.wrapping_shr(8), 128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_shr(self, rhs: u32) -> Self { @@ -532,6 +654,8 @@ macro_rules! int_impl { /// /// # Examples /// + /// Basic usage: + /// /// ``` /// let x: i32 = 2; // or any other integer type /// @@ -569,6 +693,15 @@ macro_rules! int_impl { /// `i32`, and attempting to calculate it will cause an overflow. This /// means that code in debug mode will trigger a panic on this case and /// optimized code will return `i32::min_value()` without a panic. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.abs(), 10); + /// assert_eq!((-10i8).abs(), 10); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn abs(self) -> Self { @@ -587,6 +720,16 @@ macro_rules! int_impl { /// - `0` if the number is zero /// - `1` if the number is positive /// - `-1` if the number is negative + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.signum(), 1); + /// assert_eq!(0i8.signum(), 0); + /// assert_eq!((-10i8).signum(), -1); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn signum(self) -> Self { @@ -599,12 +742,30 @@ macro_rules! int_impl { /// Returns `true` if `self` is positive and `false` if the number /// is zero or negative. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!(10i8.is_positive()); + /// assert!(!(-10i8).is_positive()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_positive(self) -> bool { self > 0 } /// Returns `true` if `self` is negative and `false` if the number /// is zero or positive. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!((-10i8).is_negative()); + /// assert!(!10i8.is_negative()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_negative(self) -> bool { self < 0 } @@ -759,7 +920,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b01001100u8; /// /// assert_eq!(n.count_ones(), 3); @@ -774,7 +937,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b01001100u8; /// /// assert_eq!(n.count_zeros(), 5); @@ -790,7 +955,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b0101000u16; /// /// assert_eq!(n.leading_zeros(), 10); @@ -825,7 +992,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0b0101000u16; /// /// assert_eq!(n.trailing_zeros(), 3); @@ -855,7 +1024,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0x3456789ABCDEF012u64; /// @@ -875,7 +1046,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0xDEF0123456789ABCu64; /// @@ -893,7 +1066,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// let m = 0xEFCDAB8967452301u64; /// @@ -912,7 +1087,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -934,7 +1111,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -956,7 +1135,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "big") { @@ -978,7 +1159,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// let n = 0x0123456789ABCDEFu64; /// /// if cfg!(target_endian = "little") { @@ -998,7 +1181,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!(5u16.checked_add(65530), Some(65535)); /// assert_eq!(6u16.checked_add(65530), None); /// ``` @@ -1013,7 +1198,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!((-127i8).checked_sub(1), Some(-128)); /// assert_eq!((-128i8).checked_sub(1), None); /// ``` @@ -1028,7 +1215,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!(5u8.checked_mul(51), Some(255)); /// assert_eq!(5u8.checked_mul(52), None); /// ``` @@ -1043,7 +1232,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!((-127i8).checked_div(-1), Some(127)); /// assert_eq!((-128i8).checked_div(-1), None); /// assert_eq!((1i8).checked_div(0), None); @@ -1059,6 +1250,15 @@ macro_rules! uint_impl { /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_add(1), 101); + /// assert_eq!(100i8.saturating_add(127), 127); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_add(self, other: Self) -> Self { @@ -1071,6 +1271,15 @@ macro_rules! uint_impl { /// Saturating integer subtraction. Computes `self - other`, saturating /// at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.saturating_sub(127), -27); + /// assert_eq!((-100i8).saturating_sub(127), -128); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn saturating_sub(self, other: Self) -> Self { @@ -1083,6 +1292,15 @@ macro_rules! uint_impl { /// Wrapping (modular) addition. Computes `self + other`, /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_add(27), 127); + /// assert_eq!(100i8.wrapping_add(127), -29); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_add(self, rhs: Self) -> Self { @@ -1093,6 +1311,15 @@ macro_rules! uint_impl { /// Wrapping (modular) subtraction. Computes `self - other`, /// wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(0i8.wrapping_sub(127), -127); + /// assert_eq!((-2i8).wrapping_sub(127), 127); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_sub(self, rhs: Self) -> Self { @@ -1103,6 +1330,15 @@ macro_rules! uint_impl { /// Wrapping (modular) multiplication. Computes `self * /// other`, wrapping around at the boundary of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(10i8.wrapping_mul(12), 120); + /// assert_eq!(11i8.wrapping_mul(12), -124); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn wrapping_mul(self, rhs: Self) -> Self { @@ -1120,6 +1356,15 @@ macro_rules! uint_impl { /// to `-MIN`, a positive value that is too large to represent /// in the type. In such a case, this function returns `MIN` /// itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100u8.wrapping_div(10), 10); + /// assert_eq!((-128i8).wrapping_div(-1), -128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_div(self, rhs: Self) -> Self { @@ -1133,6 +1378,15 @@ macro_rules! uint_impl { /// implementation artifacts make `x % y` invalid for `MIN / /// -1` on a signed type (where `MIN` is the negative /// minimal value). In such a case, this function returns `0`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_rem(10), 0); + /// assert_eq!((-128i8).wrapping_rem(-1), 0); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_rem(self, rhs: Self) -> Self { @@ -1147,6 +1401,15 @@ macro_rules! uint_impl { /// negative minimal value for the type); this is a positive /// value that is too large to represent in the type. In such /// a case, this function returns `MIN` itself. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(100i8.wrapping_neg(), -100); + /// assert_eq!((-128i8).wrapping_neg(), -128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_neg(self) -> Self { @@ -1156,6 +1419,15 @@ macro_rules! uint_impl { /// Panic-free bitwise shift-left; yields `self << mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(1u8.wrapping_shl(7), 128); + /// assert_eq!(1u8.wrapping_shl(8), 1); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_shl(self, rhs: u32) -> Self { @@ -1165,6 +1437,15 @@ macro_rules! uint_impl { /// Panic-free bitwise shift-left; yields `self >> mask(rhs)`, /// where `mask` removes any high-order bits of `rhs` that /// would cause the shift to exceed the bitwidth of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(128u8.wrapping_shr(7), 1); + /// assert_eq!(128u8.wrapping_shr(8), 128); + /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline(always)] pub fn wrapping_shr(self, rhs: u32) -> Self { @@ -1175,7 +1456,9 @@ macro_rules! uint_impl { /// /// # Examples /// - /// ```rust + /// Basic usage: + /// + /// ``` /// assert_eq!(2i32.pow(4), 16); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1207,6 +1490,15 @@ macro_rules! uint_impl { } /// Returns `true` if and only if `self == 2^k` for some `k`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!(16u8.is_power_of_two()); + /// assert!(!10u8.is_power_of_two()); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_power_of_two(self) -> bool { @@ -1216,6 +1508,15 @@ macro_rules! uint_impl { /// Returns the smallest power of two greater than or equal to `self`. /// Unspecified behavior on overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(2u8.next_power_of_two(), 2); + /// assert_eq!(3u8.next_power_of_two(), 4); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn next_power_of_two(self) -> Self { @@ -1227,6 +1528,16 @@ macro_rules! uint_impl { /// Returns the smallest power of two greater than or equal to `n`. If /// the next power of two is greater than the type's maximum value, /// `None` is returned, otherwise the power of two is wrapped in `Some`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!(2u8.checked_next_power_of_two(), Some(2)); + /// assert_eq!(3u8.checked_next_power_of_two(), Some(4)); + /// assert_eq!(200u8.checked_next_power_of_two(), None); + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn checked_next_power_of_two(self) -> Option { let npot = self.next_power_of_two(); From 9c9f95c2d9d224c9c5978ae5b1e65f92a969413e Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 11 Nov 2015 17:29:22 -0500 Subject: [PATCH 2/8] trpl: get all examples in ffi.md compiling --- src/doc/trpl/ffi.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index 7a58a327b9f95..d0d2215ba8236 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -16,11 +16,14 @@ compile if snappy is installed: extern crate libc; use libc::size_t; +#[cfg(nope)] #[link(name = "snappy")] extern { fn snappy_max_compressed_length(source_length: size_t) -> size_t; } +# #[cfg(not(nope))] unsafe fn snappy_max_compressed_length(_: size_t) -> size_t { 0 } + fn main() { let x = unsafe { snappy_max_compressed_length(100) }; println!("max compressed length of a 100 byte buffer: {}", x); @@ -50,6 +53,7 @@ The `extern` block can be extended to cover the entire snappy API: extern crate libc; use libc::{c_int, size_t}; +# #[cfg(nope)] #[link(name = "snappy")] extern { fn snappy_compress(input: *const u8, @@ -67,6 +71,7 @@ extern { fn snappy_validate_compressed_buffer(compressed: *const u8, compressed_length: size_t) -> c_int; } + # fn main() {} ``` @@ -85,8 +90,11 @@ the allocated memory. The length is less than or equal to the capacity. # #![feature(libc)] # extern crate libc; # use libc::{c_int, size_t}; +# # unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 } +# # fn main() {} +# pub fn validate_compressed_buffer(src: &[u8]) -> bool { unsafe { snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0 @@ -110,10 +118,13 @@ the true length after compression for setting the length. # #![feature(libc)] # extern crate libc; # use libc::{size_t, c_int}; +# # unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8, # d: *mut size_t) -> c_int { 0 } # unsafe fn snappy_max_compressed_length(a: size_t) -> size_t { a } +# # fn main() {} +# pub fn compress(src: &[u8]) -> Vec { unsafe { let srclen = src.len() as size_t; @@ -137,6 +148,7 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ # #![feature(libc)] # extern crate libc; # use libc::{size_t, c_int}; +# # unsafe fn snappy_uncompress(compressed: *const u8, # compressed_length: size_t, # uncompressed: *mut u8, @@ -145,6 +157,7 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ # compressed_length: size_t, # result: *mut size_t) -> c_int { 0 } # fn main() {} +# pub fn uncompress(src: &[u8]) -> Option> { unsafe { let srclen = src.len() as size_t; @@ -197,11 +210,16 @@ extern fn callback(a: i32) { println!("I'm called from C with value {0}", a); } +# #[cfg(nope)] #[link(name = "extlib")] extern { fn register_callback(cb: extern fn(i32)) -> i32; fn trigger_callback(); } +# +# #[cfg(not(nope))] static mut CALLBACK: Option = None; +# #[cfg(not(nope))] unsafe fn register_callback(cb: extern fn(i32)) -> i32 { CALLBACK = Some(cb); 1 } +# #[cfg(not(nope))] unsafe fn trigger_callback() { CALLBACK.unwrap()(7); } fn main() { unsafe { @@ -260,12 +278,17 @@ extern "C" fn callback(target: *mut RustObject, a: i32) { } } +# #[cfg(nope)] #[link(name = "extlib")] extern { fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32; fn trigger_callback(); } +# +# #[cfg(not(nope))] static mut CALLBACK: Option<(*mut RustObject, extern fn(*mut RustObject, i32))> = None; +# #[cfg(not(nope))] unsafe fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32 { CALLBACK = Some((target, cb)); 1 } +# #[cfg(not(nope))] unsafe fn trigger_callback() { let (target, cb) = CALLBACK.unwrap(); cb(target, 7); } fn main() { // Create the object that will be referenced in the callback @@ -379,6 +402,8 @@ this: ```rust unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr } + +# fn main() {} ``` This function can only be called from an `unsafe` block or another `unsafe` function. @@ -451,6 +476,7 @@ extern crate libc; extern "stdcall" { fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int; } + # fn main() { } ``` @@ -525,6 +551,7 @@ fairly easy, but requires a few things: pub extern fn hello_rust() -> *const u8 { "Hello, world!\0".as_ptr() } + # fn main() {} ``` @@ -554,6 +581,7 @@ pub extern fn oh_no() -> i32 { Err(_) => 0, } } + # fn main() {} ``` @@ -578,6 +606,7 @@ extern "C" { pub fn foo(arg: *mut libc::c_void); pub fn bar(arg: *mut libc::c_void); } + # fn main() {} ``` @@ -603,6 +632,7 @@ extern "C" { pub fn foo(arg: *mut Foo); pub fn bar(arg: *mut Bar); } + # fn main() {} ``` From 566330bc2b0059f196a657f4dac310c66f959a7d Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Wed, 11 Nov 2015 18:26:16 -0500 Subject: [PATCH 3/8] trpl: push cargo in FFI chapter --- src/doc/trpl/ffi.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index d0d2215ba8236..81a09d7164316 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -5,8 +5,19 @@ This guide will use the [snappy](https://github.com/google/snappy) compression/decompression library as an introduction to writing bindings for foreign code. Rust is currently unable to call directly into a C++ library, but -snappy includes a C interface (documented in -[`snappy-c.h`](https://github.com/google/snappy/blob/master/snappy-c.h)). +snappy includes a C interface (documented in [`snappy-c.h`][snappy-header]). + +[snappy-header]: https://github.com/google/snappy/blob/master/snappy-c.h + +Often when writing these bindings, types and functions from the C standard +library will be necessary. These can be found in the +[libc crate on crates.io][libc], which can be accessed in a Cargo project +by [adding it as a dependency][cargo-add]. (Note that if you click the examples +here to load them in the [playground](https://play.rust-lang.org), which doesn't +support Cargo, you'll see extra lines of code to keep them compiling while +remaining self-contained... but in your own projects you should use Cargo.) + +[cargo-add]: http://doc.crates.io/guide.html#adding-a-dependency The following is a minimal example of calling a foreign function which will compile if snappy is installed: @@ -23,7 +34,7 @@ extern { } # #[cfg(not(nope))] unsafe fn snappy_max_compressed_length(_: size_t) -> size_t { 0 } - +# fn main() { let x = unsafe { snappy_max_compressed_length(100) }; println!("max compressed length of a 100 byte buffer: {}", x); From 39c50f74e1d4d46e48a7d491d65e1ef9dd6f46b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20Ker=C3=A4nen?= Date: Thu, 12 Nov 2015 16:03:55 +0200 Subject: [PATCH 4/8] Add feature gate test for #[fundamental] attribute --- src/test/compile-fail/feature-gate-fundamental.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/compile-fail/feature-gate-fundamental.rs diff --git a/src/test/compile-fail/feature-gate-fundamental.rs b/src/test/compile-fail/feature-gate-fundamental.rs new file mode 100644 index 0000000000000..18718a0d0be93 --- /dev/null +++ b/src/test/compile-fail/feature-gate-fundamental.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[fundamental] //~ ERROR the `#[fundamental]` attribute is an experimental feature +struct Fundamental; + +fn main() { } From 371567294e05be31490e677bc83056282bba3cce Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Thu, 12 Nov 2015 10:56:31 -0500 Subject: [PATCH 5/8] Revert "trpl: get all examples in ffi.md compiling" This reverts commit 9c9f95c2d9d224c9c5978ae5b1e65f92a969413e. --- src/doc/trpl/ffi.md | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index 81a09d7164316..625c72f928da1 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -27,14 +27,11 @@ compile if snappy is installed: extern crate libc; use libc::size_t; -#[cfg(nope)] #[link(name = "snappy")] extern { fn snappy_max_compressed_length(source_length: size_t) -> size_t; } -# #[cfg(not(nope))] unsafe fn snappy_max_compressed_length(_: size_t) -> size_t { 0 } -# fn main() { let x = unsafe { snappy_max_compressed_length(100) }; println!("max compressed length of a 100 byte buffer: {}", x); @@ -64,7 +61,6 @@ The `extern` block can be extended to cover the entire snappy API: extern crate libc; use libc::{c_int, size_t}; -# #[cfg(nope)] #[link(name = "snappy")] extern { fn snappy_compress(input: *const u8, @@ -82,7 +78,6 @@ extern { fn snappy_validate_compressed_buffer(compressed: *const u8, compressed_length: size_t) -> c_int; } - # fn main() {} ``` @@ -101,11 +96,8 @@ the allocated memory. The length is less than or equal to the capacity. # #![feature(libc)] # extern crate libc; # use libc::{c_int, size_t}; -# # unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 } -# # fn main() {} -# pub fn validate_compressed_buffer(src: &[u8]) -> bool { unsafe { snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0 @@ -129,13 +121,10 @@ the true length after compression for setting the length. # #![feature(libc)] # extern crate libc; # use libc::{size_t, c_int}; -# # unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8, # d: *mut size_t) -> c_int { 0 } # unsafe fn snappy_max_compressed_length(a: size_t) -> size_t { a } -# # fn main() {} -# pub fn compress(src: &[u8]) -> Vec { unsafe { let srclen = src.len() as size_t; @@ -159,7 +148,6 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ # #![feature(libc)] # extern crate libc; # use libc::{size_t, c_int}; -# # unsafe fn snappy_uncompress(compressed: *const u8, # compressed_length: size_t, # uncompressed: *mut u8, @@ -168,7 +156,6 @@ format and `snappy_uncompressed_length` will retrieve the exact buffer size requ # compressed_length: size_t, # result: *mut size_t) -> c_int { 0 } # fn main() {} -# pub fn uncompress(src: &[u8]) -> Option> { unsafe { let srclen = src.len() as size_t; @@ -221,16 +208,11 @@ extern fn callback(a: i32) { println!("I'm called from C with value {0}", a); } -# #[cfg(nope)] #[link(name = "extlib")] extern { fn register_callback(cb: extern fn(i32)) -> i32; fn trigger_callback(); } -# -# #[cfg(not(nope))] static mut CALLBACK: Option = None; -# #[cfg(not(nope))] unsafe fn register_callback(cb: extern fn(i32)) -> i32 { CALLBACK = Some(cb); 1 } -# #[cfg(not(nope))] unsafe fn trigger_callback() { CALLBACK.unwrap()(7); } fn main() { unsafe { @@ -289,17 +271,12 @@ extern "C" fn callback(target: *mut RustObject, a: i32) { } } -# #[cfg(nope)] #[link(name = "extlib")] extern { fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32; fn trigger_callback(); } -# -# #[cfg(not(nope))] static mut CALLBACK: Option<(*mut RustObject, extern fn(*mut RustObject, i32))> = None; -# #[cfg(not(nope))] unsafe fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32 { CALLBACK = Some((target, cb)); 1 } -# #[cfg(not(nope))] unsafe fn trigger_callback() { let (target, cb) = CALLBACK.unwrap(); cb(target, 7); } fn main() { // Create the object that will be referenced in the callback @@ -413,8 +390,6 @@ this: ```rust unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr } - -# fn main() {} ``` This function can only be called from an `unsafe` block or another `unsafe` function. @@ -487,7 +462,6 @@ extern crate libc; extern "stdcall" { fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int; } - # fn main() { } ``` @@ -562,7 +536,6 @@ fairly easy, but requires a few things: pub extern fn hello_rust() -> *const u8 { "Hello, world!\0".as_ptr() } - # fn main() {} ``` @@ -592,7 +565,6 @@ pub extern fn oh_no() -> i32 { Err(_) => 0, } } - # fn main() {} ``` @@ -617,7 +589,6 @@ extern "C" { pub fn foo(arg: *mut libc::c_void); pub fn bar(arg: *mut libc::c_void); } - # fn main() {} ``` @@ -643,7 +614,6 @@ extern "C" { pub fn foo(arg: *mut Foo); pub fn bar(arg: *mut Bar); } - # fn main() {} ``` From 9454fd45dec402c5b93863693c42bd2b60b73a73 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Thu, 12 Nov 2015 11:03:46 -0500 Subject: [PATCH 6/8] trpl: make FFI examples compile using comments and shims --- src/doc/trpl/ffi.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index 625c72f928da1..0122ad056c641 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -22,15 +22,18 @@ remaining self-contained... but in your own projects you should use Cargo.) The following is a minimal example of calling a foreign function which will compile if snappy is installed: -```no_run +```rust # #![feature(libc)] extern crate libc; use libc::size_t; +# /* #[link(name = "snappy")] extern { fn snappy_max_compressed_length(source_length: size_t) -> size_t; } +# */ +# unsafe fn snappy_max_compressed_length(_: size_t) -> size_t { 0 } fn main() { let x = unsafe { snappy_max_compressed_length(100) }; @@ -56,12 +59,14 @@ keeping the binding correct at runtime. The `extern` block can be extended to cover the entire snappy API: -```no_run +```rust # #![feature(libc)] extern crate libc; use libc::{c_int, size_t}; +# /* #[link(name = "snappy")] +# */ extern { fn snappy_compress(input: *const u8, input_length: size_t, @@ -203,16 +208,21 @@ A basic example is: Rust code: -```no_run +```rust extern fn callback(a: i32) { println!("I'm called from C with value {0}", a); } +# /* #[link(name = "extlib")] extern { fn register_callback(cb: extern fn(i32)) -> i32; fn trigger_callback(); } +# */ +# static mut CALLBACK: Option = None; +# unsafe fn register_callback(cb: extern fn(i32)) -> i32 { CALLBACK = Some(cb); 0 } +# unsafe fn trigger_callback() { CALLBACK.unwrap()(7); } fn main() { unsafe { @@ -256,7 +266,7 @@ referenced Rust object. Rust code: -```no_run +```rust #[repr(C)] struct RustObject { a: i32, @@ -271,12 +281,17 @@ extern "C" fn callback(target: *mut RustObject, a: i32) { } } +# /* #[link(name = "extlib")] extern { fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32; fn trigger_callback(); } +# */ +# static mut CALLBACK: Option<(*mut RustObject, extern fn(*mut RustObject, i32))> = None; +# unsafe fn register_callback(target: *mut RustObject, cb: extern fn(*mut RustObject, i32)) -> i32 { CALLBACK = Some((target, cb)); 0 } +# unsafe fn trigger_callback() { let (target, cb) = CALLBACK.unwrap(); cb(target, 7); } fn main() { // Create the object that will be referenced in the callback @@ -390,6 +405,7 @@ this: ```rust unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr } +# fn main() {} ``` This function can only be called from an `unsafe` block or another `unsafe` function. @@ -400,7 +416,7 @@ Foreign APIs often export a global variable which could do something like track global state. In order to access these variables, you declare them in `extern` blocks with the `static` keyword: -```no_run +```rust # #![feature(libc)] extern crate libc; @@ -419,7 +435,7 @@ Alternatively, you may need to alter global state provided by a foreign interface. To do this, statics can be declared with `mut` so we can mutate them. -```no_run +```rust # #![feature(libc)] extern crate libc; From 7b9b9df309f4508cd81d50d443d8c74f30fcec30 Mon Sep 17 00:00:00 2001 From: Ashkan Kiani Date: Thu, 12 Nov 2015 10:35:53 -0800 Subject: [PATCH 7/8] Update references and borrowing (Fixes #29730) Fixes #29730 --- src/doc/trpl/references-and-borrowing.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md index 944417d1096b0..d8758e0c695c2 100644 --- a/src/doc/trpl/references-and-borrowing.md +++ b/src/doc/trpl/references-and-borrowing.md @@ -171,9 +171,9 @@ to the definition of a data race: > operations are not synchronized. With references, you may have as many as you’d like, since none of them are -writing. If you are writing, you need two or more pointers to the same memory, -and you can only have one `&mut` at a time. This is how Rust prevents data -races at compile time: we’ll get errors if we break the rules. +writing. However, as we can only have one `&mut` at a time, it is impossible to +have a data race. This is how Rust prevents data races at compile time: we’ll +get errors if we break the rules. With this in mind, let’s consider our example again. @@ -378,3 +378,4 @@ statement 1 at 3:14 In the above example, `y` is declared before `x`, meaning that `y` lives longer than `x`, which is not allowed. + From 83af140b40b010efa1d73cd9083c6bb6a11f8f7a Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Thu, 12 Nov 2015 14:18:11 -0600 Subject: [PATCH 8/8] Make the mir_map available to the after_analysis CompileController step. --- src/librustc_driver/driver.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f2ca36526595b..2d7f5544402a2 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -150,6 +150,7 @@ pub fn compile_input(sess: Session, &expanded_crate, tcx.map.krate(), &analysis, + &mir_map, tcx, &lcx, &id); @@ -275,6 +276,7 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> { pub expanded_crate: Option<&'a ast::Crate>, pub hir_crate: Option<&'a hir::Crate>, pub ast_map: Option<&'a hir_map::Map<'ast>>, + pub mir_map: Option<&'a MirMap<'tcx>>, pub analysis: Option<&'a ty::CrateAnalysis<'a>>, pub tcx: Option<&'a ty::ctxt<'tcx>>, pub lcx: Option<&'a LoweringContext<'a>>, @@ -298,6 +300,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { hir_crate: None, ast_map: None, analysis: None, + mir_map: None, tcx: None, lcx: None, trans: None, @@ -350,12 +353,14 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> { krate: &'a ast::Crate, hir_crate: &'a hir::Crate, analysis: &'a ty::CrateAnalysis, + mir_map: &'a MirMap<'tcx>, tcx: &'a ty::ctxt<'tcx>, lcx: &'a LoweringContext<'a>, crate_name: &'a str) -> CompileState<'a, 'ast, 'tcx> { CompileState { analysis: Some(analysis), + mir_map: Some(mir_map), tcx: Some(tcx), krate: Some(krate), hir_crate: Some(hir_crate),