Skip to content

Commit 49317cd

Browse files
committed
Auto merge of #49130 - smmalis37:range, r=alexcrichton
Move Range*::contains to a single default impl on RangeBounds Per the ongoing discussion in #32311. This is my first PR to Rust (woo!), so I don't know if this requires an amendment to the original range_contains RFC, or not, or if we can just do a psuedo-RFC here. While this may no longer follow the explicit decision made in that RFC, I believe this better follows its spirit by adding the new contains method to all Ranges. It also allows users to be generic over all ranges and use this method without writing it themselves (my personal desired use case). This also somewhat answers the unanswered question about Wrapping ranges in the above issue by instead just punting it to the question of what those types should return for start() & end(), or if they should implement RangeArgument at all. Those types could also implement their own contains method without implementing this trait, in which case the question remains the same. This does add a new contains method to types that already implemented RangeArgument but not contains. These types are RangeFull, (Bound<T>, Bound<T>), (Bound<&'a T>, Bound<&'a T>). No tests have been added for these types yet. No inherent method has been added either. r? @alexcrichton
2 parents 1ef1563 + 51f24ec commit 49317cd

File tree

3 files changed

+129
-40
lines changed

3 files changed

+129
-40
lines changed

src/libcore/ops/range.rs

+123-34
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,28 @@ impl<Idx: PartialOrd<Idx>> Range<Idx> {
100100
/// ```
101101
/// #![feature(range_contains)]
102102
///
103-
/// assert!(!(3..5).contains(2));
104-
/// assert!( (3..5).contains(3));
105-
/// assert!( (3..5).contains(4));
106-
/// assert!(!(3..5).contains(5));
103+
/// use std::f32;
107104
///
108-
/// assert!(!(3..3).contains(3));
109-
/// assert!(!(3..2).contains(3));
105+
/// assert!(!(3..5).contains(&2));
106+
/// assert!( (3..5).contains(&3));
107+
/// assert!( (3..5).contains(&4));
108+
/// assert!(!(3..5).contains(&5));
109+
///
110+
/// assert!(!(3..3).contains(&3));
111+
/// assert!(!(3..2).contains(&3));
112+
///
113+
/// assert!( (0.0..1.0).contains(&0.5));
114+
/// assert!(!(0.0..1.0).contains(&f32::NAN));
115+
/// assert!(!(0.0..f32::NAN).contains(&0.5));
116+
/// assert!(!(f32::NAN..1.0).contains(&0.5));
110117
/// ```
111118
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
112-
pub fn contains(&self, item: Idx) -> bool {
113-
(self.start <= item) && (item < self.end)
119+
pub fn contains<U>(&self, item: &U) -> bool
120+
where
121+
Idx: PartialOrd<U>,
122+
U: ?Sized + PartialOrd<Idx>,
123+
{
124+
<Self as RangeBounds<Idx>>::contains(self, item)
114125
}
115126

116127
/// Returns `true` if the range contains no items.
@@ -179,7 +190,6 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
179190
}
180191
}
181192

182-
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
183193
impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
184194
/// Returns `true` if `item` is contained in the range.
185195
///
@@ -188,12 +198,23 @@ impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
188198
/// ```
189199
/// #![feature(range_contains)]
190200
///
191-
/// assert!(!(3..).contains(2));
192-
/// assert!( (3..).contains(3));
193-
/// assert!( (3..).contains(1_000_000_000));
201+
/// use std::f32;
202+
///
203+
/// assert!(!(3..).contains(&2));
204+
/// assert!( (3..).contains(&3));
205+
/// assert!( (3..).contains(&1_000_000_000));
206+
///
207+
/// assert!( (0.0..).contains(&0.5));
208+
/// assert!(!(0.0..).contains(&f32::NAN));
209+
/// assert!(!(f32::NAN..).contains(&0.5));
194210
/// ```
195-
pub fn contains(&self, item: Idx) -> bool {
196-
(self.start <= item)
211+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
212+
pub fn contains<U>(&self, item: &U) -> bool
213+
where
214+
Idx: PartialOrd<U>,
215+
U: ?Sized + PartialOrd<Idx>,
216+
{
217+
<Self as RangeBounds<Idx>>::contains(self, item)
197218
}
198219
}
199220

@@ -250,7 +271,6 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
250271
}
251272
}
252273

253-
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
254274
impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
255275
/// Returns `true` if `item` is contained in the range.
256276
///
@@ -259,12 +279,23 @@ impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
259279
/// ```
260280
/// #![feature(range_contains)]
261281
///
262-
/// assert!( (..5).contains(-1_000_000_000));
263-
/// assert!( (..5).contains(4));
264-
/// assert!(!(..5).contains(5));
282+
/// use std::f32;
283+
///
284+
/// assert!( (..5).contains(&-1_000_000_000));
285+
/// assert!( (..5).contains(&4));
286+
/// assert!(!(..5).contains(&5));
287+
///
288+
/// assert!( (..1.0).contains(&0.5));
289+
/// assert!(!(..1.0).contains(&f32::NAN));
290+
/// assert!(!(..f32::NAN).contains(&0.5));
265291
/// ```
266-
pub fn contains(&self, item: Idx) -> bool {
267-
(item < self.end)
292+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
293+
pub fn contains<U>(&self, item: &U) -> bool
294+
where
295+
Idx: PartialOrd<U>,
296+
U: ?Sized + PartialOrd<Idx>,
297+
{
298+
<Self as RangeBounds<Idx>>::contains(self, item)
268299
}
269300
}
270301

@@ -318,18 +349,29 @@ impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
318349
/// ```
319350
/// #![feature(range_contains)]
320351
///
321-
/// assert!(!(3..=5).contains(2));
322-
/// assert!( (3..=5).contains(3));
323-
/// assert!( (3..=5).contains(4));
324-
/// assert!( (3..=5).contains(5));
325-
/// assert!(!(3..=5).contains(6));
352+
/// use std::f32;
353+
///
354+
/// assert!(!(3..=5).contains(&2));
355+
/// assert!( (3..=5).contains(&3));
356+
/// assert!( (3..=5).contains(&4));
357+
/// assert!( (3..=5).contains(&5));
358+
/// assert!(!(3..=5).contains(&6));
326359
///
327-
/// assert!( (3..=3).contains(3));
328-
/// assert!(!(3..=2).contains(3));
360+
/// assert!( (3..=3).contains(&3));
361+
/// assert!(!(3..=2).contains(&3));
362+
///
363+
/// assert!( (0.0..=1.0).contains(&1.0));
364+
/// assert!(!(0.0..=1.0).contains(&f32::NAN));
365+
/// assert!(!(0.0..=f32::NAN).contains(&0.0));
366+
/// assert!(!(f32::NAN..=1.0).contains(&1.0));
329367
/// ```
330368
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
331-
pub fn contains(&self, item: Idx) -> bool {
332-
self.start <= item && item <= self.end
369+
pub fn contains<U>(&self, item: &U) -> bool
370+
where
371+
Idx: PartialOrd<U>,
372+
U: ?Sized + PartialOrd<Idx>,
373+
{
374+
<Self as RangeBounds<Idx>>::contains(self, item)
333375
}
334376

335377
/// Returns `true` if the range contains no items.
@@ -431,12 +473,23 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
431473
/// ```
432474
/// #![feature(range_contains)]
433475
///
434-
/// assert!( (..=5).contains(-1_000_000_000));
435-
/// assert!( (..=5).contains(5));
436-
/// assert!(!(..=5).contains(6));
476+
/// use std::f32;
477+
///
478+
/// assert!( (..=5).contains(&-1_000_000_000));
479+
/// assert!( (..=5).contains(&5));
480+
/// assert!(!(..=5).contains(&6));
481+
///
482+
/// assert!( (..=1.0).contains(&1.0));
483+
/// assert!(!(..=1.0).contains(&f32::NAN));
484+
/// assert!(!(..=f32::NAN).contains(&0.5));
437485
/// ```
438-
pub fn contains(&self, item: Idx) -> bool {
439-
(item <= self.end)
486+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
487+
pub fn contains<U>(&self, item: &U) -> bool
488+
where
489+
Idx: PartialOrd<U>,
490+
U: ?Sized + PartialOrd<Idx>,
491+
{
492+
<Self as RangeBounds<Idx>>::contains(self, item)
440493
}
441494
}
442495

@@ -537,6 +590,42 @@ pub trait RangeBounds<T: ?Sized> {
537590
/// # }
538591
/// ```
539592
fn end(&self) -> Bound<&T>;
593+
594+
595+
/// Returns `true` if `item` is contained in the range.
596+
///
597+
/// # Examples
598+
///
599+
/// ```
600+
/// #![feature(range_contains)]
601+
///
602+
/// use std::f32;
603+
///
604+
/// assert!( (3..5).contains(&4));
605+
/// assert!(!(3..5).contains(&2));
606+
///
607+
/// assert!( (0.0..1.0).contains(&0.5));
608+
/// assert!(!(0.0..1.0).contains(&f32::NAN));
609+
/// assert!(!(0.0..f32::NAN).contains(&0.5));
610+
/// assert!(!(f32::NAN..1.0).contains(&0.5));
611+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
612+
fn contains<U>(&self, item: &U) -> bool
613+
where
614+
T: PartialOrd<U>,
615+
U: ?Sized + PartialOrd<T>,
616+
{
617+
(match self.start() {
618+
Included(ref start) => *start <= item,
619+
Excluded(ref start) => *start < item,
620+
Unbounded => true,
621+
})
622+
&&
623+
(match self.end() {
624+
Included(ref end) => item <= *end,
625+
Excluded(ref end) => item < *end,
626+
Unbounded => true,
627+
})
628+
}
540629
}
541630

542631
use self::Bound::{Excluded, Included, Unbounded};

src/librustc_errors/emitter.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1389,8 +1389,8 @@ fn num_overlap(a_start: usize, a_end: usize, b_start: usize, b_end:usize, inclus
13891389
} else {
13901390
0
13911391
};
1392-
(b_start..b_end + extra).contains(a_start) ||
1393-
(a_start..a_end + extra).contains(b_start)
1392+
(b_start..b_end + extra).contains(&a_start) ||
1393+
(a_start..a_end + extra).contains(&b_start)
13941394
}
13951395
fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
13961396
num_overlap(a1.start_col, a1.end_col + padding, a2.start_col, a2.end_col, false)

src/librustc_mir/borrow_check/nll/universal_regions.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -259,18 +259,18 @@ impl<'tcx> UniversalRegions<'tcx> {
259259

260260
/// True if `r` is a member of this set of universal regions.
261261
pub fn is_universal_region(&self, r: RegionVid) -> bool {
262-
(FIRST_GLOBAL_INDEX..self.num_universals).contains(r.index())
262+
(FIRST_GLOBAL_INDEX..self.num_universals).contains(&r.index())
263263
}
264264

265265
/// Classifies `r` as a universal region, returning `None` if this
266266
/// is not a member of this set of universal regions.
267267
pub fn region_classification(&self, r: RegionVid) -> Option<RegionClassification> {
268268
let index = r.index();
269-
if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(index) {
269+
if (FIRST_GLOBAL_INDEX..self.first_extern_index).contains(&index) {
270270
Some(RegionClassification::Global)
271-
} else if (self.first_extern_index..self.first_local_index).contains(index) {
271+
} else if (self.first_extern_index..self.first_local_index).contains(&index) {
272272
Some(RegionClassification::External)
273-
} else if (self.first_local_index..self.num_universals).contains(index) {
273+
} else if (self.first_local_index..self.num_universals).contains(&index) {
274274
Some(RegionClassification::Local)
275275
} else {
276276
None

0 commit comments

Comments
 (0)