std: Stabilize APIs for the 1.16.0 release

This commit applies the stabilization/deprecations of the 1.16.0 release, as
tracked by the rust-lang/rust issue tracker and the final-comment-period tag.

The following APIs were stabilized:

* `VecDeque::truncate`
* `VecDeque::resize`
* `String::insert_str`
* `Duration::checked_{add,sub,div,mul}`
* `str::replacen`
* `SocketAddr::is_ipv{4,6}`
* `IpAddr::is_ipv{4,6}`
* `str::repeat`
* `Vec::dedup_by`
* `Vec::dedup_by_key`
* `Result::unwrap_or_default`
* `<*const T>::wrapping_offset`
* `<*mut T>::wrapping_offset`
* `CommandExt::creation_flags` (on Windows)
* `File::set_permissions`
* `String::split_off`

The following APIs were deprecated

* `EnumSet` - replaced with other ecosystem abstractions, long since unstable

Closes #27788
Closes #35553
Closes #35774
Closes #36436
Closes #36949
Closes #37079
Closes #37087
Closes #37516
Closes #37827
Closes #37916
Closes #37966
Closes #38080
This commit is contained in:
Alex Crichton 2017-01-25 15:37:20 -08:00
parent 1283c02955
commit 671b1c1d89
18 changed files with 26 additions and 371 deletions

View File

@ -17,6 +17,8 @@
reason = "matches collection reform specification, \
waiting for dust to settle",
issue = "37966")]
#![rustc_deprecated(since = "1.16.0", reason = "long since replaced")]
#![allow(deprecated)]
use core::marker;
use core::fmt;

View File

@ -79,6 +79,7 @@
#[doc(no_inline)]
pub use linked_list::LinkedList;
#[doc(no_inline)]
#[allow(deprecated)]
pub use enum_set::EnumSet;
#[doc(no_inline)]
pub use vec_deque::VecDeque;

View File

@ -1607,7 +1607,6 @@ pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
/// Basic usage:
///
/// ```
/// # #![feature(str_replacen)]
/// let s = "foo foo 123 foo";
/// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
/// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
@ -1617,13 +1616,10 @@ pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
/// When the pattern doesn't match:
///
/// ```
/// # #![feature(str_replacen)]
/// let s = "this is old";
/// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
/// ```
#[unstable(feature = "str_replacen",
issue = "36436",
reason = "only need to replace first N matches")]
#[stable(feature = "str_replacen", since = "1.16.0")]
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
// Hope to reduce the times of re-allocation
let mut result = String::with_capacity(32);
@ -1795,11 +1791,9 @@ pub fn into_string(self: Box<str>) -> String {
/// Basic usage:
///
/// ```
/// #![feature(repeat_str)]
///
/// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
/// ```
#[unstable(feature = "repeat_str", issue = "37079")]
#[stable(feature = "repeat_str", since = "1.16.0")]
pub fn repeat(&self, n: usize) -> String {
let mut s = String::with_capacity(self.len() * n);
s.extend((0..n).map(|_| self));

View File

@ -1166,8 +1166,6 @@ unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
/// Basic usage:
///
/// ```
/// #![feature(insert_str)]
///
/// let mut s = String::from("bar");
///
/// s.insert_str(0, "foo");
@ -1175,9 +1173,7 @@ unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
/// assert_eq!("foobar", s);
/// ```
#[inline]
#[unstable(feature = "insert_str",
reason = "recent addition",
issue = "35553")]
#[stable(feature = "insert_str", since = "1.16.0")]
pub fn insert_str(&mut self, idx: usize, string: &str) {
assert!(self.is_char_boundary(idx));
@ -1270,7 +1266,6 @@ pub fn is_empty(&self) -> bool {
/// # Examples
///
/// ```
/// # #![feature(string_split_off)]
/// # fn main() {
/// let mut hello = String::from("Hello, World!");
/// let world = hello.split_off(7);
@ -1279,7 +1274,7 @@ pub fn is_empty(&self) -> bool {
/// # }
/// ```
#[inline]
#[unstable(feature = "string_split_off", issue = "38080")]
#[stable(feature = "string_split_off", since = "1.16.0")]
pub fn split_off(&mut self, mid: usize) -> String {
assert!(self.is_char_boundary(mid));
let other = self.vec.split_off(mid);

View File

@ -820,15 +820,13 @@ pub fn retain<F>(&mut self, mut f: F)
/// # Examples
///
/// ```
/// #![feature(dedup_by)]
///
/// let mut vec = vec![10, 20, 21, 30, 20];
///
/// vec.dedup_by_key(|i| *i / 10);
///
/// assert_eq!(vec, [10, 20, 30, 20]);
/// ```
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
#[stable(feature = "dedup_by", since = "1.16.0")]
#[inline]
pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq {
self.dedup_by(|a, b| key(a) == key(b))
@ -841,7 +839,6 @@ pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K:
/// # Examples
///
/// ```
/// #![feature(dedup_by)]
/// use std::ascii::AsciiExt;
///
/// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
@ -850,7 +847,7 @@ pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K:
///
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
/// ```
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
#[stable(feature = "dedup_by", since = "1.16.0")]
pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
unsafe {
// Although we have a mutable reference to `self`, we cannot make

View File

@ -643,8 +643,6 @@ pub fn shrink_to_fit(&mut self) {
/// # Examples
///
/// ```
/// #![feature(deque_extras)]
///
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -655,9 +653,7 @@ pub fn shrink_to_fit(&mut self) {
/// assert_eq!(buf.len(), 1);
/// assert_eq!(Some(&5), buf.get(0));
/// ```
#[unstable(feature = "deque_extras",
reason = "matches collection reform specification; waiting on panic semantics",
issue = "27788")]
#[stable(feature = "deque_extras", since = "1.16.0")]
pub fn truncate(&mut self, len: usize) {
for _ in len..self.len() {
self.pop_back();
@ -1779,8 +1775,6 @@ impl<T: Clone> VecDeque<T> {
/// # Examples
///
/// ```
/// #![feature(deque_extras)]
///
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -1793,9 +1787,7 @@ impl<T: Clone> VecDeque<T> {
/// assert_eq!(a, b);
/// }
/// ```
#[unstable(feature = "deque_extras",
reason = "matches collection reform specification; waiting on panic semantics",
issue = "27788")]
#[stable(feature = "deque_extras", since = "1.16.0")]
pub fn resize(&mut self, new_len: usize, value: T) {
let len = self.len();

View File

@ -1,268 +0,0 @@
// Copyright 2012 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 <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.
use std::mem;
use collections::enum_set::{CLike, EnumSet};
use self::Foo::*;
#[derive(Copy, Clone, PartialEq, Debug)]
#[repr(usize)]
enum Foo {
A,
B,
C,
}
impl CLike for Foo {
fn to_usize(&self) -> usize {
*self as usize
}
fn from_usize(v: usize) -> Foo {
unsafe { mem::transmute(v) }
}
}
#[test]
fn test_new() {
let e: EnumSet<Foo> = EnumSet::new();
assert!(e.is_empty());
}
#[test]
fn test_show() {
let mut e = EnumSet::new();
assert!(format!("{:?}", e) == "{}");
e.insert(A);
assert!(format!("{:?}", e) == "{A}");
e.insert(C);
assert!(format!("{:?}", e) == "{A, C}");
}
#[test]
fn test_len() {
let mut e = EnumSet::new();
assert_eq!(e.len(), 0);
e.insert(A);
e.insert(B);
e.insert(C);
assert_eq!(e.len(), 3);
e.remove(&A);
assert_eq!(e.len(), 2);
e.clear();
assert_eq!(e.len(), 0);
}
///////////////////////////////////////////////////////////////////////////
// intersect
#[test]
fn test_two_empties_do_not_intersect() {
let e1: EnumSet<Foo> = EnumSet::new();
let e2: EnumSet<Foo> = EnumSet::new();
assert!(e1.is_disjoint(&e2));
}
#[test]
fn test_empty_does_not_intersect_with_full() {
let e1: EnumSet<Foo> = EnumSet::new();
let mut e2: EnumSet<Foo> = EnumSet::new();
e2.insert(A);
e2.insert(B);
e2.insert(C);
assert!(e1.is_disjoint(&e2));
}
#[test]
fn test_disjoint_intersects() {
let mut e1: EnumSet<Foo> = EnumSet::new();
e1.insert(A);
let mut e2: EnumSet<Foo> = EnumSet::new();
e2.insert(B);
assert!(e1.is_disjoint(&e2));
}
#[test]
fn test_overlapping_intersects() {
let mut e1: EnumSet<Foo> = EnumSet::new();
e1.insert(A);
let mut e2: EnumSet<Foo> = EnumSet::new();
e2.insert(A);
e2.insert(B);
assert!(!e1.is_disjoint(&e2));
}
///////////////////////////////////////////////////////////////////////////
// contains and contains_elem
#[test]
fn test_superset() {
let mut e1: EnumSet<Foo> = EnumSet::new();
e1.insert(A);
let mut e2: EnumSet<Foo> = EnumSet::new();
e2.insert(A);
e2.insert(B);
let mut e3: EnumSet<Foo> = EnumSet::new();
e3.insert(C);
assert!(e1.is_subset(&e2));
assert!(e2.is_superset(&e1));
assert!(!e3.is_superset(&e2));
assert!(!e2.is_superset(&e3))
}
#[test]
fn test_contains() {
let mut e1: EnumSet<Foo> = EnumSet::new();
e1.insert(A);
assert!(e1.contains(&A));
assert!(!e1.contains(&B));
assert!(!e1.contains(&C));
e1.insert(A);
e1.insert(B);
assert!(e1.contains(&A));
assert!(e1.contains(&B));
assert!(!e1.contains(&C));
}
///////////////////////////////////////////////////////////////////////////
// iter
#[test]
fn test_iterator() {
let mut e1: EnumSet<Foo> = EnumSet::new();
let elems: Vec<Foo> = e1.iter().collect();
assert!(elems.is_empty());
e1.insert(A);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, C]);
e1.insert(C);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, C]);
e1.insert(B);
let elems: Vec<_> = e1.iter().collect();
assert_eq!(elems, [A, B, C]);
}
///////////////////////////////////////////////////////////////////////////
// operators
#[test]
fn test_operators() {
let mut e1: EnumSet<Foo> = EnumSet::new();
e1.insert(A);
e1.insert(C);
let mut e2: EnumSet<Foo> = EnumSet::new();
e2.insert(B);
e2.insert(C);
let e_union = e1 | e2;
let elems: Vec<_> = e_union.iter().collect();
assert_eq!(elems, [A, B, C]);
let e_intersection = e1 & e2;
let elems: Vec<_> = e_intersection.iter().collect();
assert_eq!(elems, [C]);
// Another way to express intersection
let e_intersection = e1 - (e1 - e2);
let elems: Vec<_> = e_intersection.iter().collect();
assert_eq!(elems, [C]);
let e_subtract = e1 - e2;
let elems: Vec<_> = e_subtract.iter().collect();
assert_eq!(elems, [A]);
// Bitwise XOR of two sets, aka symmetric difference
let e_symmetric_diff = e1 ^ e2;
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
// Another way to express symmetric difference
let e_symmetric_diff = (e1 - e2) | (e2 - e1);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
// Yet another way to express symmetric difference
let e_symmetric_diff = (e1 | e2) - (e1 & e2);
let elems: Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(elems, [A, B]);
}
#[test]
#[should_panic]
fn test_overflow() {
#[allow(dead_code)]
#[derive(Copy, Clone)]
#[repr(usize)]
enum Bar {
V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
}
impl CLike for Bar {
fn to_usize(&self) -> usize {
*self as usize
}
fn from_usize(v: usize) -> Bar {
unsafe { mem::transmute(v) }
}
}
let mut set = EnumSet::new();
set.insert(Bar::V64);
}
#[test]
fn test_extend_ref() {
let mut a = EnumSet::new();
a.insert(A);
a.extend(&[A, C]);
assert_eq!(a.len(), 2);
assert!(a.contains(&A));
assert!(a.contains(&C));
let mut b = EnumSet::new();
b.insert(B);
a.extend(&b);
assert_eq!(a.len(), 3);
assert!(a.contains(&A));
assert!(a.contains(&B));
assert!(a.contains(&C));
}

View File

@ -18,17 +18,12 @@
#![feature(collections)]
#![feature(collections_bound)]
#![feature(const_fn)]
#![feature(dedup_by)]
#![feature(enumset)]
#![feature(exact_size_is_empty)]
#![feature(pattern)]
#![feature(placement_in_syntax)]
#![feature(rand)]
#![feature(repeat_str)]
#![feature(step_by)]
#![feature(str_escape)]
#![feature(str_replacen)]
#![feature(string_split_off)]
#![feature(test)]
#![feature(unboxed_closures)]
#![feature(unicode)]
@ -47,7 +42,6 @@
mod binary_heap;
mod btree;
mod cow_str;
mod enum_set;
mod fmt;
mod linked_list;
mod slice;

View File

@ -448,7 +448,6 @@ pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
/// Basic usage:
///
/// ```
/// #![feature(ptr_wrapping_offset)]
/// // Iterate using a raw pointer in increments of two elements
/// let data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *const u8 = data.as_ptr();
@ -463,7 +462,7 @@ pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
/// ptr = ptr.wrapping_offset(step);
/// }
/// ```
#[unstable(feature = "ptr_wrapping_offset", issue = "37570")]
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized {
unsafe {
@ -572,7 +571,6 @@ pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
/// Basic usage:
///
/// ```
/// #![feature(ptr_wrapping_offset)]
/// // Iterate using a raw pointer in increments of two elements
/// let mut data = [1u8, 2, 3, 4, 5];
/// let mut ptr: *mut u8 = data.as_mut_ptr();
@ -587,7 +585,7 @@ pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
/// }
/// assert_eq!(&data, &[0, 2, 0, 4, 0]);
/// ```
#[unstable(feature = "ptr_wrapping_offset", issue = "37570")]
#[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
#[inline]
pub fn wrapping_offset(self, count: isize) -> *mut T where T: Sized {
unsafe {

View File

@ -840,8 +840,6 @@ impl<T: Default, E> Result<T, E> {
/// `Err` on error.
///
/// ```
/// #![feature(result_unwrap_or_default)]
///
/// let good_year_from_input = "1909";
/// let bad_year_from_input = "190blarg";
/// let good_year = good_year_from_input.parse().unwrap_or_default();
@ -854,7 +852,7 @@ impl<T: Default, E> Result<T, E> {
/// [`FromStr`]: ../../std/str/trait.FromStr.html
/// ```
#[inline]
#[unstable(feature = "result_unwrap_or_default", issue = "37516")]
#[stable(feature = "result_unwrap_or_default", since = "1.16.0")]
pub fn unwrap_or_default(self) -> T {
match self {
Ok(x) => x,

View File

@ -32,7 +32,6 @@
#![feature(unicode)]
#![feature(unique)]
#![feature(ordering_chaining)]
#![feature(result_unwrap_or_default)]
#![feature(ptr_unaligned)]
extern crate core;

View File

@ -11,11 +11,9 @@
//! Implementations of serialization for structures found in libcollections
use std::hash::{Hash, BuildHasher};
use std::mem;
use {Decodable, Encodable, Decoder, Encoder};
use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet};
use collections::enum_set::{EnumSet, CLike};
impl<
T: Encodable
@ -128,33 +126,6 @@ fn decode<D: Decoder>(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
}
}
impl<
T: Encodable + CLike
> Encodable for EnumSet<T> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
let mut bits = 0;
for item in self {
bits |= 1 << item.to_usize();
}
s.emit_usize(bits)
}
}
impl<
T: Decodable + CLike
> Decodable for EnumSet<T> {
fn decode<D: Decoder>(d: &mut D) -> Result<EnumSet<T>, D::Error> {
let bits = d.read_usize()?;
let mut set = EnumSet::new();
for bit in 0..(mem::size_of::<usize>()*8) {
if bits & (1 << bit) != 0 {
set.insert(CLike::from_usize(bit));
}
}
Ok(set)
}
}
impl<K, V, S> Encodable for HashMap<K, V, S>
where K: Encodable + Hash + Eq,
V: Encodable,

View File

@ -30,7 +30,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core_intrinsics)]
#![feature(enumset)]
#![feature(specialization)]
#![feature(staged_api)]
#![cfg_attr(test, feature(test))]

View File

@ -404,7 +404,6 @@ pub fn try_clone(&self) -> io::Result<File> {
/// # Examples
///
/// ```
/// #![feature(set_permissions_atomic)]
/// # fn foo() -> std::io::Result<()> {
/// use std::fs::File;
///
@ -415,7 +414,7 @@ pub fn try_clone(&self) -> io::Result<File> {
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "set_permissions_atomic", issue="37916")]
#[stable(feature = "set_permissions_atomic", since = "1.16.0")]
pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
self.inner.set_permissions(perm.0)
}

View File

@ -148,8 +148,6 @@ pub fn set_port(&mut self, new_port: u16) {
/// # Examples
///
/// ```
/// #![feature(sockaddr_checker)]
///
/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
///
/// fn main() {
@ -158,7 +156,7 @@ pub fn set_port(&mut self, new_port: u16) {
/// assert_eq!(socket.is_ipv6(), false);
/// }
/// ```
#[unstable(feature = "sockaddr_checker", issue = "36949")]
#[stable(feature = "sockaddr_checker", since = "1.16.0")]
pub fn is_ipv4(&self) -> bool {
match *self {
SocketAddr::V4(_) => true,
@ -172,8 +170,6 @@ pub fn is_ipv4(&self) -> bool {
/// # Examples
///
/// ```
/// #![feature(sockaddr_checker)]
///
/// use std::net::{IpAddr, Ipv6Addr, SocketAddr};
///
/// fn main() {
@ -183,7 +179,7 @@ pub fn is_ipv4(&self) -> bool {
/// assert_eq!(socket.is_ipv6(), true);
/// }
/// ```
#[unstable(feature = "sockaddr_checker", issue = "36949")]
#[stable(feature = "sockaddr_checker", since = "1.16.0")]
pub fn is_ipv6(&self) -> bool {
match *self {
SocketAddr::V4(_) => false,

View File

@ -196,8 +196,6 @@ pub fn is_documentation(&self) -> bool {
/// # Examples
///
/// ```
/// #![feature(ipaddr_checker)]
///
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
///
/// fn main() {
@ -206,7 +204,7 @@ pub fn is_documentation(&self) -> bool {
/// false);
/// }
/// ```
#[unstable(feature = "ipaddr_checker", issue = "36949")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")]
pub fn is_ipv4(&self) -> bool {
match *self {
IpAddr::V4(_) => true,
@ -219,8 +217,6 @@ pub fn is_ipv4(&self) -> bool {
/// # Examples
///
/// ```
/// #![feature(ipaddr_checker)]
///
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
///
/// fn main() {
@ -229,7 +225,7 @@ pub fn is_ipv4(&self) -> bool {
/// true);
/// }
/// ```
#[unstable(feature = "ipaddr_checker", issue = "36949")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")]
pub fn is_ipv6(&self) -> bool {
match *self {
IpAddr::V4(_) => false,

View File

@ -99,17 +99,17 @@ fn from_raw(raw: u32) -> Self {
}
/// Windows-specific extensions to the `std::process::Command` builder
#[unstable(feature = "windows_process_extensions", issue = "37827")]
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
pub trait CommandExt {
/// Sets the [process creation flags][1] to be passed to `CreateProcess`.
///
/// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
/// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
#[unstable(feature = "windows_process_extensions", issue = "37827")]
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
fn creation_flags(&mut self, flags: u32) -> &mut process::Command;
}
#[unstable(feature = "windows_process_extensions", issue = "37827")]
#[stable(feature = "windows_process_extensions", since = "1.16.0")]
impl CommandExt for process::Command {
fn creation_flags(&mut self, flags: u32) -> &mut process::Command {
self.as_inner_mut().creation_flags(flags);

View File

@ -154,14 +154,12 @@ pub fn subsec_nanos(&self) -> u32 { self.nanos }
/// Basic usage:
///
/// ```
/// #![feature(duration_checked_ops)]
///
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)), Some(Duration::new(0, 1)));
/// assert_eq!(Duration::new(1, 0).checked_add(Duration::new(std::u64::MAX, 0)), None);
/// ```
#[unstable(feature = "duration_checked_ops", issue = "35774")]
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
if let Some(mut secs) = self.secs.checked_add(rhs.secs) {
@ -194,14 +192,12 @@ pub fn checked_add(self, rhs: Duration) -> Option<Duration> {
/// Basic usage:
///
/// ```
/// #![feature(duration_checked_ops)]
///
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 1).checked_sub(Duration::new(0, 0)), Some(Duration::new(0, 1)));
/// assert_eq!(Duration::new(0, 0).checked_sub(Duration::new(0, 1)), None);
/// ```
#[unstable(feature = "duration_checked_ops", issue = "35774")]
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
if let Some(mut secs) = self.secs.checked_sub(rhs.secs) {
@ -232,14 +228,12 @@ pub fn checked_sub(self, rhs: Duration) -> Option<Duration> {
/// Basic usage:
///
/// ```
/// #![feature(duration_checked_ops)]
///
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(0, 500_000_001).checked_mul(2), Some(Duration::new(1, 2)));
/// assert_eq!(Duration::new(std::u64::MAX - 1, 0).checked_mul(2), None);
/// ```
#[unstable(feature = "duration_checked_ops", issue = "35774")]
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
// Multiply nanoseconds as u64, because it cannot overflow that way.
@ -269,15 +263,13 @@ pub fn checked_mul(self, rhs: u32) -> Option<Duration> {
/// Basic usage:
///
/// ```
/// #![feature(duration_checked_ops)]
///
/// use std::time::Duration;
///
/// assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
/// assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
/// assert_eq!(Duration::new(2, 0).checked_div(0), None);
/// ```
#[unstable(feature = "duration_checked_ops", issue = "35774")]
#[stable(feature = "duration_checked_ops", since = "1.16.0")]
#[inline]
pub fn checked_div(self, rhs: u32) -> Option<Duration> {
if rhs != 0 {