mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 12:18:33 +00:00
Auto merge of #49163 - SimonSapin:range-bounds, r=alexcrichton
Rename RangeArgument to RangeBounds, move it and Bound to libcore As proposed in the tracking issue: https://github.com/rust-lang/rust/issues/30877 Changes to *stable* items: * `core::ops::Bound` / `std::ops::Bound` is new * `std::collections::Bound` is a deprecated reexport of it (does this actually cause a warning?) Changes to *unstable* items * `alloc::Bound` is gone * `alloc::range::RangeArgument` is moved to `core::ops::RangeBounds` / `std::ops::RangeBounds` * `alloc::range` is gone * `std::collections::range::RangeArgument` is deprecated reexport, to be removed later * `std::collections::range` is deprecated, to be removed later * `impl RangeBounds<T> for Range{,From,To,Inclusive,ToInclusive}<&T>` are added The idea of replacing this trait with a type to be used with `Into<_>` is left for future consideration / work. (Fixes https://github.com/rust-lang-nursery/rust-clippy/issues/2552.)
This commit is contained in:
commit
ae544ee1c9
@ -13,12 +13,12 @@ use core::fmt::Debug;
|
|||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::iter::{FromIterator, Peekable, FusedIterator};
|
use core::iter::{FromIterator, Peekable, FusedIterator};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
use core::ops::Index;
|
use core::ops::Index;
|
||||||
|
use core::ops::RangeBounds;
|
||||||
use core::{fmt, intrinsics, mem, ptr};
|
use core::{fmt, intrinsics, mem, ptr};
|
||||||
|
|
||||||
use borrow::Borrow;
|
use borrow::Borrow;
|
||||||
use Bound::{Excluded, Included, Unbounded};
|
|
||||||
use range::RangeArgument;
|
|
||||||
|
|
||||||
use super::node::{self, Handle, NodeRef, marker};
|
use super::node::{self, Handle, NodeRef, marker};
|
||||||
use super::search;
|
use super::search;
|
||||||
@ -804,7 +804,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::collections::BTreeMap;
|
/// use std::collections::BTreeMap;
|
||||||
/// use std::collections::Bound::Included;
|
/// use std::ops::Bound::Included;
|
||||||
///
|
///
|
||||||
/// let mut map = BTreeMap::new();
|
/// let mut map = BTreeMap::new();
|
||||||
/// map.insert(3, "a");
|
/// map.insert(3, "a");
|
||||||
@ -817,7 +817,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "btree_range", since = "1.17.0")]
|
#[stable(feature = "btree_range", since = "1.17.0")]
|
||||||
pub fn range<T: ?Sized, R>(&self, range: R) -> Range<K, V>
|
pub fn range<T: ?Sized, R>(&self, range: R) -> Range<K, V>
|
||||||
where T: Ord, K: Borrow<T>, R: RangeArgument<T>
|
where T: Ord, K: Borrow<T>, R: RangeBounds<T>
|
||||||
{
|
{
|
||||||
let root1 = self.root.as_ref();
|
let root1 = self.root.as_ref();
|
||||||
let root2 = self.root.as_ref();
|
let root2 = self.root.as_ref();
|
||||||
@ -857,7 +857,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "btree_range", since = "1.17.0")]
|
#[stable(feature = "btree_range", since = "1.17.0")]
|
||||||
pub fn range_mut<T: ?Sized, R>(&mut self, range: R) -> RangeMut<K, V>
|
pub fn range_mut<T: ?Sized, R>(&mut self, range: R) -> RangeMut<K, V>
|
||||||
where T: Ord, K: Borrow<T>, R: RangeArgument<T>
|
where T: Ord, K: Borrow<T>, R: RangeBounds<T>
|
||||||
{
|
{
|
||||||
let root1 = self.root.as_mut();
|
let root1 = self.root.as_mut();
|
||||||
let root2 = unsafe { ptr::read(&root1) };
|
let root2 = unsafe { ptr::read(&root1) };
|
||||||
@ -1812,7 +1812,7 @@ fn last_leaf_edge<BorrowType, K, V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn range_search<BorrowType, K, V, Q: ?Sized, R: RangeArgument<Q>>(
|
fn range_search<BorrowType, K, V, Q: ?Sized, R: RangeBounds<Q>>(
|
||||||
root1: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
root1: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
||||||
root2: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
root2: NodeRef<BorrowType, K, V, marker::LeafOrInternal>,
|
||||||
range: R
|
range: R
|
||||||
|
@ -16,12 +16,11 @@ use core::cmp::{min, max};
|
|||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::iter::{Peekable, FromIterator, FusedIterator};
|
use core::iter::{Peekable, FromIterator, FusedIterator};
|
||||||
use core::ops::{BitOr, BitAnd, BitXor, Sub};
|
use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds};
|
||||||
|
|
||||||
use borrow::Borrow;
|
use borrow::Borrow;
|
||||||
use btree_map::{BTreeMap, Keys};
|
use btree_map::{BTreeMap, Keys};
|
||||||
use super::Recover;
|
use super::Recover;
|
||||||
use range::RangeArgument;
|
|
||||||
|
|
||||||
// FIXME(conventions): implement bounded iterators
|
// FIXME(conventions): implement bounded iterators
|
||||||
|
|
||||||
@ -240,7 +239,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::collections::BTreeSet;
|
/// use std::collections::BTreeSet;
|
||||||
/// use std::collections::Bound::Included;
|
/// use std::ops::Bound::Included;
|
||||||
///
|
///
|
||||||
/// let mut set = BTreeSet::new();
|
/// let mut set = BTreeSet::new();
|
||||||
/// set.insert(3);
|
/// set.insert(3);
|
||||||
@ -253,7 +252,7 @@ impl<T: Ord> BTreeSet<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "btree_range", since = "1.17.0")]
|
#[stable(feature = "btree_range", since = "1.17.0")]
|
||||||
pub fn range<K: ?Sized, R>(&self, range: R) -> Range<T>
|
pub fn range<K: ?Sized, R>(&self, range: R) -> Range<T>
|
||||||
where K: Ord, T: Borrow<K>, R: RangeArgument<K>
|
where K: Ord, T: Borrow<K>, R: RangeBounds<K>
|
||||||
{
|
{
|
||||||
Range { iter: self.map.range(range) }
|
Range { iter: self.map.range(range) }
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,7 @@
|
|||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(cfg_target_has_atomic)]
|
#![feature(cfg_target_has_atomic)]
|
||||||
#![feature(coerce_unsized)]
|
#![feature(coerce_unsized)]
|
||||||
|
#![feature(collections_range)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(custom_attribute)]
|
#![feature(custom_attribute)]
|
||||||
@ -178,7 +179,6 @@ mod btree;
|
|||||||
pub mod borrow;
|
pub mod borrow;
|
||||||
pub mod fmt;
|
pub mod fmt;
|
||||||
pub mod linked_list;
|
pub mod linked_list;
|
||||||
pub mod range;
|
|
||||||
pub mod slice;
|
pub mod slice;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod string;
|
pub mod string;
|
||||||
@ -204,57 +204,6 @@ mod std {
|
|||||||
pub use core::ops; // RangeFull
|
pub use core::ops; // RangeFull
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An endpoint of a range of keys.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// `Bound`s are range endpoints:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(collections_range)]
|
|
||||||
///
|
|
||||||
/// use std::collections::range::RangeArgument;
|
|
||||||
/// use std::collections::Bound::*;
|
|
||||||
///
|
|
||||||
/// assert_eq!((..100).start(), Unbounded);
|
|
||||||
/// assert_eq!((1..12).start(), Included(&1));
|
|
||||||
/// assert_eq!((1..12).end(), Excluded(&12));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
|
|
||||||
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::collections::BTreeMap;
|
|
||||||
/// use std::collections::Bound::{Excluded, Included, Unbounded};
|
|
||||||
///
|
|
||||||
/// let mut map = BTreeMap::new();
|
|
||||||
/// map.insert(3, "a");
|
|
||||||
/// map.insert(5, "b");
|
|
||||||
/// map.insert(8, "c");
|
|
||||||
///
|
|
||||||
/// for (key, value) in map.range((Excluded(3), Included(8))) {
|
|
||||||
/// println!("{}: {}", key, value);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
|
|
||||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
|
||||||
pub enum Bound<T> {
|
|
||||||
/// An inclusive bound.
|
|
||||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
|
||||||
Included(#[stable(feature = "collections_bound", since = "1.17.0")] T),
|
|
||||||
/// An exclusive bound.
|
|
||||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
|
||||||
Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T),
|
|
||||||
/// An infinite endpoint. Indicates that there is no bound in this direction.
|
|
||||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
|
||||||
Unbounded,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An intermediate trait for specialization of `Extend`.
|
/// An intermediate trait for specialization of `Extend`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
trait SpecExtend<I: IntoIterator> {
|
trait SpecExtend<I: IntoIterator> {
|
||||||
|
@ -1,152 +0,0 @@
|
|||||||
// 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 <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.
|
|
||||||
|
|
||||||
#![unstable(feature = "collections_range",
|
|
||||||
reason = "waiting for dust to settle on inclusive ranges",
|
|
||||||
issue = "30877")]
|
|
||||||
|
|
||||||
//! Range syntax.
|
|
||||||
|
|
||||||
use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive};
|
|
||||||
use Bound::{self, Excluded, Included, Unbounded};
|
|
||||||
|
|
||||||
/// `RangeArgument` is implemented by Rust's built-in range types, produced
|
|
||||||
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
|
|
||||||
pub trait RangeArgument<T: ?Sized> {
|
|
||||||
/// Start index bound.
|
|
||||||
///
|
|
||||||
/// Returns the start value as a `Bound`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(alloc)]
|
|
||||||
/// #![feature(collections_range)]
|
|
||||||
///
|
|
||||||
/// extern crate alloc;
|
|
||||||
///
|
|
||||||
/// # fn main() {
|
|
||||||
/// use alloc::range::RangeArgument;
|
|
||||||
/// use alloc::Bound::*;
|
|
||||||
///
|
|
||||||
/// assert_eq!((..10).start(), Unbounded);
|
|
||||||
/// assert_eq!((3..10).start(), Included(&3));
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
fn start(&self) -> Bound<&T>;
|
|
||||||
|
|
||||||
/// End index bound.
|
|
||||||
///
|
|
||||||
/// Returns the end value as a `Bound`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(alloc)]
|
|
||||||
/// #![feature(collections_range)]
|
|
||||||
///
|
|
||||||
/// extern crate alloc;
|
|
||||||
///
|
|
||||||
/// # fn main() {
|
|
||||||
/// use alloc::range::RangeArgument;
|
|
||||||
/// use alloc::Bound::*;
|
|
||||||
///
|
|
||||||
/// assert_eq!((3..).end(), Unbounded);
|
|
||||||
/// assert_eq!((3..10).end(), Excluded(&10));
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
fn end(&self) -> Bound<&T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME add inclusive ranges to RangeArgument
|
|
||||||
|
|
||||||
impl<T: ?Sized> RangeArgument<T> for RangeFull {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Unbounded
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Unbounded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for RangeFrom<T> {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Included(&self.start)
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Unbounded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for RangeTo<T> {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Unbounded
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Excluded(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for Range<T> {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Included(&self.start)
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Excluded(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
|
||||||
impl<T> RangeArgument<T> for RangeInclusive<T> {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Included(&self.start)
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Included(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
|
||||||
impl<T> RangeArgument<T> for RangeToInclusive<T> {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
Unbounded
|
|
||||||
}
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
Included(&self.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> RangeArgument<T> for (Bound<T>, Bound<T>) {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
match *self {
|
|
||||||
(Included(ref start), _) => Included(start),
|
|
||||||
(Excluded(ref start), _) => Excluded(start),
|
|
||||||
(Unbounded, _) => Unbounded,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
match *self {
|
|
||||||
(_, Included(ref end)) => Included(end),
|
|
||||||
(_, Excluded(ref end)) => Excluded(end),
|
|
||||||
(_, Unbounded) => Unbounded,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T: ?Sized + 'a> RangeArgument<T> for (Bound<&'a T>, Bound<&'a T>) {
|
|
||||||
fn start(&self) -> Bound<&T> {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&self) -> Bound<&T> {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
@ -59,15 +59,14 @@
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::hash;
|
use core::hash;
|
||||||
use core::iter::{FromIterator, FusedIterator};
|
use core::iter::{FromIterator, FusedIterator};
|
||||||
use core::ops::{self, Add, AddAssign, Index, IndexMut};
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::str::pattern::Pattern;
|
use core::str::pattern::Pattern;
|
||||||
use std_unicode::lossy;
|
use std_unicode::lossy;
|
||||||
use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
||||||
|
|
||||||
use borrow::{Cow, ToOwned};
|
use borrow::{Cow, ToOwned};
|
||||||
use range::RangeArgument;
|
|
||||||
use Bound::{Excluded, Included, Unbounded};
|
|
||||||
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
|
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
|
||||||
use vec::Vec;
|
use vec::Vec;
|
||||||
use boxed::Box;
|
use boxed::Box;
|
||||||
@ -1484,7 +1483,7 @@ impl String {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain
|
pub fn drain<R>(&mut self, range: R) -> Drain
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
// Memory safety
|
// Memory safety
|
||||||
//
|
//
|
||||||
@ -1548,7 +1547,7 @@ impl String {
|
|||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "splice", reason = "recently added", issue = "44643")]
|
#[unstable(feature = "splice", reason = "recently added", issue = "44643")]
|
||||||
pub fn splice<R>(&mut self, range: R, replace_with: &str)
|
pub fn splice<R>(&mut self, range: R, replace_with: &str)
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
// Memory safety
|
// Memory safety
|
||||||
//
|
//
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::Bound::{self, Excluded, Included, Unbounded};
|
|
||||||
use std::collections::btree_map::Entry::{Occupied, Vacant};
|
use std::collections::btree_map::Entry::{Occupied, Vacant};
|
||||||
|
use std::ops::Bound::{self, Excluded, Included, Unbounded};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
@ -75,7 +75,8 @@ use core::marker::PhantomData;
|
|||||||
use core::mem;
|
use core::mem;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use core::num::Float;
|
use core::num::Float;
|
||||||
use core::ops::{InPlace, Index, IndexMut, Place, Placer};
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
use core::ops::{InPlace, Index, IndexMut, Place, Placer, RangeBounds};
|
||||||
use core::ops;
|
use core::ops;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
@ -85,9 +86,7 @@ use borrow::ToOwned;
|
|||||||
use borrow::Cow;
|
use borrow::Cow;
|
||||||
use boxed::Box;
|
use boxed::Box;
|
||||||
use raw_vec::RawVec;
|
use raw_vec::RawVec;
|
||||||
use super::range::RangeArgument;
|
|
||||||
use super::allocator::CollectionAllocErr;
|
use super::allocator::CollectionAllocErr;
|
||||||
use Bound::{Excluded, Included, Unbounded};
|
|
||||||
|
|
||||||
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
||||||
///
|
///
|
||||||
@ -1176,7 +1175,7 @@ impl<T> Vec<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain<T>
|
pub fn drain<R>(&mut self, range: R) -> Drain<T>
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
// Memory safety
|
// Memory safety
|
||||||
//
|
//
|
||||||
@ -1950,7 +1949,7 @@ impl<T> Vec<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||||
pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<I::IntoIter>
|
pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<I::IntoIter>
|
||||||
where R: RangeArgument<usize>, I: IntoIterator<Item=T>
|
where R: RangeBounds<usize>, I: IntoIterator<Item=T>
|
||||||
{
|
{
|
||||||
Splice {
|
Splice {
|
||||||
drain: self.drain(range),
|
drain: self.drain(range),
|
||||||
|
@ -21,7 +21,8 @@ use core::cmp::Ordering;
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::iter::{repeat, FromIterator, FusedIterator};
|
use core::iter::{repeat, FromIterator, FusedIterator};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::ops::{Index, IndexMut, Place, Placer, InPlace};
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeBounds};
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
use core::slice;
|
use core::slice;
|
||||||
@ -32,8 +33,6 @@ use core::cmp;
|
|||||||
use raw_vec::RawVec;
|
use raw_vec::RawVec;
|
||||||
|
|
||||||
use super::allocator::CollectionAllocErr;
|
use super::allocator::CollectionAllocErr;
|
||||||
use super::range::RangeArgument;
|
|
||||||
use Bound::{Excluded, Included, Unbounded};
|
|
||||||
use super::vec::Vec;
|
use super::vec::Vec;
|
||||||
|
|
||||||
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
|
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
|
||||||
@ -969,7 +968,7 @@ impl<T> VecDeque<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "drain", since = "1.6.0")]
|
#[stable(feature = "drain", since = "1.6.0")]
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain<T>
|
pub fn drain<R>(&mut self, range: R) -> Drain<T>
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
// Memory safety
|
// Memory safety
|
||||||
//
|
//
|
||||||
|
@ -192,7 +192,7 @@ pub use self::index::{Index, IndexMut};
|
|||||||
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
|
pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
|
||||||
|
|
||||||
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
||||||
pub use self::range::{RangeInclusive, RangeToInclusive};
|
pub use self::range::{RangeInclusive, RangeToInclusive, RangeBounds, Bound};
|
||||||
|
|
||||||
#[unstable(feature = "try_trait", issue = "42327")]
|
#[unstable(feature = "try_trait", issue = "42327")]
|
||||||
pub use self::try::Try;
|
pub use self::try::Try;
|
||||||
|
@ -442,3 +442,267 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
|
|||||||
|
|
||||||
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
|
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
|
||||||
// because underflow would be possible with (..0).into()
|
// because underflow would be possible with (..0).into()
|
||||||
|
|
||||||
|
/// An endpoint of a range of keys.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// `Bound`s are range endpoints:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(collections_range)]
|
||||||
|
///
|
||||||
|
/// use std::ops::Bound::*;
|
||||||
|
/// use std::ops::RangeBounds;
|
||||||
|
///
|
||||||
|
/// assert_eq!((..100).start(), Unbounded);
|
||||||
|
/// assert_eq!((1..12).start(), Included(&1));
|
||||||
|
/// assert_eq!((1..12).end(), Excluded(&12));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
|
||||||
|
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::collections::BTreeMap;
|
||||||
|
/// use std::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
///
|
||||||
|
/// let mut map = BTreeMap::new();
|
||||||
|
/// map.insert(3, "a");
|
||||||
|
/// map.insert(5, "b");
|
||||||
|
/// map.insert(8, "c");
|
||||||
|
///
|
||||||
|
/// for (key, value) in map.range((Excluded(3), Included(8))) {
|
||||||
|
/// println!("{}: {}", key, value);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range
|
||||||
|
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||||
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||||
|
pub enum Bound<T> {
|
||||||
|
/// An inclusive bound.
|
||||||
|
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||||
|
Included(#[stable(feature = "collections_bound", since = "1.17.0")] T),
|
||||||
|
/// An exclusive bound.
|
||||||
|
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||||
|
Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T),
|
||||||
|
/// An infinite endpoint. Indicates that there is no bound in this direction.
|
||||||
|
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||||
|
Unbounded,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
/// `RangeBounds` is implemented by Rust's built-in range types, produced
|
||||||
|
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
|
||||||
|
pub trait RangeBounds<T: ?Sized> {
|
||||||
|
/// Start index bound.
|
||||||
|
///
|
||||||
|
/// Returns the start value as a `Bound`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(collections_range)]
|
||||||
|
///
|
||||||
|
/// # fn main() {
|
||||||
|
/// use std::ops::Bound::*;
|
||||||
|
/// use std::ops::RangeBounds;
|
||||||
|
///
|
||||||
|
/// assert_eq!((..10).start(), Unbounded);
|
||||||
|
/// assert_eq!((3..10).start(), Included(&3));
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
fn start(&self) -> Bound<&T>;
|
||||||
|
|
||||||
|
/// End index bound.
|
||||||
|
///
|
||||||
|
/// Returns the end value as a `Bound`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(collections_range)]
|
||||||
|
///
|
||||||
|
/// # fn main() {
|
||||||
|
/// use std::ops::Bound::*;
|
||||||
|
/// use std::ops::RangeBounds;
|
||||||
|
///
|
||||||
|
/// assert_eq!((3..).end(), Unbounded);
|
||||||
|
/// assert_eq!((3..10).end(), Excluded(&10));
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
fn end(&self) -> Bound<&T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
use self::Bound::{Excluded, Included, Unbounded};
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T: ?Sized> RangeBounds<T> for RangeFull {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for RangeFrom<T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(&self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for RangeTo<T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Excluded(&self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for Range<T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(&self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Excluded(&self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for RangeInclusive<T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(&self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Included(&self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for RangeToInclusive<T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Included(&self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
match *self {
|
||||||
|
(Included(ref start), _) => Included(start),
|
||||||
|
(Excluded(ref start), _) => Excluded(start),
|
||||||
|
(Unbounded, _) => Unbounded,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
match *self {
|
||||||
|
(_, Included(ref end)) => Included(end),
|
||||||
|
(_, Excluded(ref end)) => Excluded(end),
|
||||||
|
(_, Unbounded) => Unbounded,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T> RangeBounds<T> for RangeFrom<&'a T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T> RangeBounds<T> for RangeTo<&'a T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Excluded(self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T> RangeBounds<T> for Range<&'a T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Excluded(self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T> RangeBounds<T> for RangeInclusive<&'a T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Included(self.start)
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Included(self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "collections_range",
|
||||||
|
reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
|
||||||
|
issue = "30877")]
|
||||||
|
impl<'a, T> RangeBounds<T> for RangeToInclusive<&'a T> {
|
||||||
|
fn start(&self) -> Bound<&T> {
|
||||||
|
Unbounded
|
||||||
|
}
|
||||||
|
fn end(&self) -> Bound<&T> {
|
||||||
|
Included(self.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,11 +15,10 @@
|
|||||||
//!
|
//!
|
||||||
//! The N above is determined by Array's implementor, by way of an associated constant.
|
//! The N above is determined by Array's implementor, by way of an associated constant.
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut, RangeBounds};
|
||||||
use std::iter::{self, IntoIterator, FromIterator};
|
use std::iter::{self, IntoIterator, FromIterator};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::collections::range::RangeArgument;
|
|
||||||
|
|
||||||
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ impl<A: Array> AccumulateVec<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain<A>
|
pub fn drain<R>(&mut self, range: R) -> Drain<A>
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
AccumulateVec::Array(ref mut v) => {
|
AccumulateVec::Array(ref mut v) => {
|
||||||
|
@ -18,9 +18,9 @@ use std::hash::{Hash, Hasher};
|
|||||||
use std::slice;
|
use std::slice;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::collections::range::RangeArgument;
|
|
||||||
use std::collections::Bound::{Excluded, Included, Unbounded};
|
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
use std::ops::Bound::{Excluded, Included, Unbounded};
|
||||||
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
pub unsafe trait Array {
|
pub unsafe trait Array {
|
||||||
type Element;
|
type Element;
|
||||||
@ -106,7 +106,7 @@ impl<A: Array> ArrayVec<A> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn drain<R>(&mut self, range: R) -> Drain<A>
|
pub fn drain<R>(&mut self, range: R) -> Drain<A>
|
||||||
where R: RangeArgument<usize>
|
where R: RangeBounds<usize>
|
||||||
{
|
{
|
||||||
// Memory safety
|
// Memory safety
|
||||||
//
|
//
|
||||||
|
@ -8,12 +8,11 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use std::collections::range::RangeArgument;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::iter::{self, FromIterator};
|
use std::iter::{self, FromIterator};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::{Index, IndexMut, Range};
|
use std::ops::{Index, IndexMut, Range, RangeBounds};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@ -448,13 +447,13 @@ impl<I: Idx, T> IndexVec<I, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn drain<'a, R: RangeArgument<usize>>(
|
pub fn drain<'a, R: RangeBounds<usize>>(
|
||||||
&'a mut self, range: R) -> impl Iterator<Item=T> + 'a {
|
&'a mut self, range: R) -> impl Iterator<Item=T> + 'a {
|
||||||
self.raw.drain(range)
|
self.raw.drain(range)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn drain_enumerated<'a, R: RangeArgument<usize>>(
|
pub fn drain_enumerated<'a, R: RangeBounds<usize>>(
|
||||||
&'a mut self, range: R) -> impl Iterator<Item=(I, T)> + 'a {
|
&'a mut self, range: R) -> impl Iterator<Item=(I, T)> + 'a {
|
||||||
self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData })
|
self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData })
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,9 @@
|
|||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use alloc::Bound;
|
#[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.26.0")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use ops::Bound;
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet};
|
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet};
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
@ -435,8 +437,13 @@ pub use self::hash_map::HashMap;
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::hash_set::HashSet;
|
pub use self::hash_set::HashSet;
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[unstable(feature = "collections_range", issue = "30877")]
|
||||||
pub use alloc::range;
|
#[rustc_deprecated(reason = "renamed and moved to `std::ops::RangeBounds`", since = "1.26.0")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
/// Range syntax
|
||||||
|
pub mod range {
|
||||||
|
pub use ops::RangeBounds as RangeArgument;
|
||||||
|
}
|
||||||
|
|
||||||
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
|
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
|
||||||
pub use alloc::allocator::CollectionAllocErr;
|
pub use alloc::allocator::CollectionAllocErr;
|
||||||
|
@ -18,8 +18,8 @@ use std::collections::VecDeque;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use std::collections::Bound::Included;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ops::Bound::Included;
|
||||||
|
|
||||||
fn is_sync<T>(_: T) where T: Sync {}
|
fn is_sync<T>(_: T) where T: Sync {}
|
||||||
fn is_send<T>(_: T) where T: Send {}
|
fn is_send<T>(_: T) where T: Send {}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit eafd09010815da43302ac947afee45b0f5219e6b
|
Subproject commit b75618206cec71bd87ff7b07f0a8698ee854a2d1
|
Loading…
Reference in New Issue
Block a user