Skip to content

Commit

Permalink
Rollup merge of rust-lang#60542 - timvermeulen:step_sub_usize, r=scot…
Browse files Browse the repository at this point in the history
…tmcm

Add Step::sub_usize

Required for rust-lang#54054.

I'm aware that the `Step` trait needs a rework, but this still seems like a reasonable addition?

This currently doesn't compile because Chalk contains a type that implement this trait, and this is a breaking change. How can that be fixed?
  • Loading branch information
Centril authored May 29, 2019
2 parents 8e3f003 + f1d0829 commit 85c975b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/libcore/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ pub trait Step: Clone + PartialOrd + Sized {

/// Adds a `usize`, returning `None` on overflow.
fn add_usize(&self, n: usize) -> Option<Self>;

/// Subtracts a `usize`, returning `None` on underflow.
fn sub_usize(&self, n: usize) -> Option<Self> {
// this default implementation makes the addition of `sub_usize` a non-breaking change
let _ = n;
unimplemented!()
}
}

// These are still macro-generated because the integer literals resolve to different types.
Expand Down Expand Up @@ -85,6 +92,15 @@ macro_rules! step_impl_unsigned {
}
}

#[inline]
#[allow(unreachable_patterns)]
fn sub_usize(&self, n: usize) -> Option<Self> {
match <$t>::try_from(n) {
Ok(n_as_t) => self.checked_sub(n_as_t),
Err(_) => None,
}
}

step_identical_methods!();
}
)*)
Expand Down Expand Up @@ -125,6 +141,25 @@ macro_rules! step_impl_signed {
}
}

#[inline]
#[allow(unreachable_patterns)]
fn sub_usize(&self, n: usize) -> Option<Self> {
match <$unsigned>::try_from(n) {
Ok(n_as_unsigned) => {
// Wrapping in unsigned space handles cases like
// `80_i8.sub_usize(200) == Some(-120_i8)`,
// even though 200_usize is out of range for i8.
let wrapped = (*self as $unsigned).wrapping_sub(n_as_unsigned) as $t;
if wrapped <= *self {
Some(wrapped)
} else {
None // Subtraction underflowed
}
}
Err(_) => None,
}
}

step_identical_methods!();
}
)*)
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_data_structures/indexed_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ macro_rules! newtype_index {
fn add_usize(&self, u: usize) -> Option<Self> {
Idx::index(*self).checked_add(u).map(Self::new)
}

#[inline]
fn sub_usize(&self, u: usize) -> Option<Self> {
Idx::index(*self).checked_sub(u).map(Self::new)
}
}

impl From<$type> for u32 {
Expand Down
4 changes: 4 additions & 0 deletions src/test/run-pass/impl-trait/example-calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ impl std::iter::Step for NaiveDate {
fn add_usize(&self, _: usize) -> Option<Self> {
unimplemented!()
}

fn sub_usize(&self, _: usize) -> Option<Self> {
unimplemented!()
}
}

#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
Expand Down

0 comments on commit 85c975b

Please sign in to comment.