Skip to content

Commit 13e2840

Browse files
authored
Rollup merge of rust-lang#92444 - dtolnay:coremethods, r=joshtriplett
Consolidate Result's and Option's methods into fewer impl blocks `Result`'s and `Option`'s methods have historically been separated up into `impl` blocks based on their trait bounds, with the bounds specified on type parameters of the impl block. I find this unhelpful because closely related methods, like `unwrap_or` and `unwrap_or_default`, end up disproportionately far apart in source code and rustdocs: <pre> impl&lt;T&gt; Option&lt;T&gt; { pub fn unwrap_or(self, default: T) -&gt; T { ... } <img alt="one eternity later" src="https://user-images.githubusercontent.com/1940490/147780325-ad4e01a4-c971-436e-bdf4-e755f2d35f15.jpg" width="750"> } impl&lt;T: Default&gt; Option&lt;T&gt; { pub fn unwrap_or_default(self) -&gt; T { ... } } </pre> I'd prefer for method to be in as few impl blocks as possible, with the most logical grouping within each impl block. Any bounds needed can be written as `where` clauses on the method instead: ```rust impl<T> Option<T> { pub fn unwrap_or(self, default: T) -> T { ... } pub fn unwrap_or_default(self) -> T where T: Default, { ... } } ``` *Warning: the end-to-end diff of this PR is computed confusingly by git / rendered confusingly by GitHub; it's practically impossible to review that way. I've broken the PR into commits that move small groups of methods for which git behaves better &mdash; these each should be easily individually reviewable.*
2 parents df92119 + 5960f7a commit 13e2840

File tree

6 files changed

+529
-512
lines changed

6 files changed

+529
-512
lines changed

Diff for: library/core/src/option.rs

+118-122
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,45 @@ impl<T> Option<T> {
810810
}
811811
}
812812

813+
/// Returns the contained [`Some`] value or a default.
814+
///
815+
/// Consumes the `self` argument then, if [`Some`], returns the contained
816+
/// value, otherwise if [`None`], returns the [default value] for that
817+
/// type.
818+
///
819+
/// # Examples
820+
///
821+
/// Converts a string to an integer, turning poorly-formed strings
822+
/// into 0 (the default value for integers). [`parse`] converts
823+
/// a string to any other type that implements [`FromStr`], returning
824+
/// [`None`] on error.
825+
///
826+
/// ```
827+
/// let good_year_from_input = "1909";
828+
/// let bad_year_from_input = "190blarg";
829+
/// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
830+
/// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
831+
///
832+
/// assert_eq!(1909, good_year);
833+
/// assert_eq!(0, bad_year);
834+
/// ```
835+
///
836+
/// [default value]: Default::default
837+
/// [`parse`]: str::parse
838+
/// [`FromStr`]: crate::str::FromStr
839+
#[inline]
840+
#[stable(feature = "rust1", since = "1.0.0")]
841+
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
842+
pub const fn unwrap_or_default(self) -> T
843+
where
844+
T: ~const Default,
845+
{
846+
match self {
847+
Some(x) => x,
848+
None => Default::default(),
849+
}
850+
}
851+
813852
/// Returns the contained [`Some`] value, consuming the `self` value,
814853
/// without checking that the value is not [`None`].
815854
///
@@ -1033,6 +1072,58 @@ impl<T> Option<T> {
10331072
}
10341073
}
10351074

1075+
/// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
1076+
///
1077+
/// Leaves the original Option in-place, creating a new one with a reference
1078+
/// to the original one, additionally coercing the contents via [`Deref`].
1079+
///
1080+
/// # Examples
1081+
///
1082+
/// ```
1083+
/// let x: Option<String> = Some("hey".to_owned());
1084+
/// assert_eq!(x.as_deref(), Some("hey"));
1085+
///
1086+
/// let x: Option<String> = None;
1087+
/// assert_eq!(x.as_deref(), None);
1088+
/// ```
1089+
#[stable(feature = "option_deref", since = "1.40.0")]
1090+
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1091+
pub const fn as_deref(&self) -> Option<&T::Target>
1092+
where
1093+
T: ~const Deref,
1094+
{
1095+
match self.as_ref() {
1096+
Some(t) => Some(t.deref()),
1097+
None => None,
1098+
}
1099+
}
1100+
1101+
/// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
1102+
///
1103+
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
1104+
/// the inner type's [`Deref::Target`] type.
1105+
///
1106+
/// # Examples
1107+
///
1108+
/// ```
1109+
/// let mut x: Option<String> = Some("hey".to_owned());
1110+
/// assert_eq!(x.as_deref_mut().map(|x| {
1111+
/// x.make_ascii_uppercase();
1112+
/// x
1113+
/// }), Some("HEY".to_owned().as_mut_str()));
1114+
/// ```
1115+
#[stable(feature = "option_deref", since = "1.40.0")]
1116+
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1117+
pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
1118+
where
1119+
T: ~const DerefMut,
1120+
{
1121+
match self.as_mut() {
1122+
Some(t) => Some(t.deref_mut()),
1123+
None => None,
1124+
}
1125+
}
1126+
10361127
/////////////////////////////////////////////////////////////////////////
10371128
// Iterator constructors
10381129
/////////////////////////////////////////////////////////////////////////
@@ -1581,7 +1672,7 @@ impl<T, U> Option<(T, U)> {
15811672
}
15821673
}
15831674

1584-
impl<T: Copy> Option<&T> {
1675+
impl<T> Option<&T> {
15851676
/// Maps an `Option<&T>` to an `Option<T>` by copying the contents of the
15861677
/// option.
15871678
///
@@ -1597,41 +1688,18 @@ impl<T: Copy> Option<&T> {
15971688
#[must_use = "`self` will be dropped if the result is not used"]
15981689
#[stable(feature = "copied", since = "1.35.0")]
15991690
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
1600-
pub const fn copied(self) -> Option<T> {
1691+
pub const fn copied(self) -> Option<T>
1692+
where
1693+
T: Copy,
1694+
{
16011695
// FIXME: this implementation, which sidesteps using `Option::map` since it's not const
16021696
// ready yet, should be reverted when possible to avoid code repetition
16031697
match self {
16041698
Some(&v) => Some(v),
16051699
None => None,
16061700
}
16071701
}
1608-
}
16091702

1610-
impl<T: Copy> Option<&mut T> {
1611-
/// Maps an `Option<&mut T>` to an `Option<T>` by copying the contents of the
1612-
/// option.
1613-
///
1614-
/// # Examples
1615-
///
1616-
/// ```
1617-
/// let mut x = 12;
1618-
/// let opt_x = Some(&mut x);
1619-
/// assert_eq!(opt_x, Some(&mut 12));
1620-
/// let copied = opt_x.copied();
1621-
/// assert_eq!(copied, Some(12));
1622-
/// ```
1623-
#[must_use = "`self` will be dropped if the result is not used"]
1624-
#[stable(feature = "copied", since = "1.35.0")]
1625-
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1626-
pub const fn copied(self) -> Option<T> {
1627-
match self {
1628-
Some(&mut t) => Some(t),
1629-
None => None,
1630-
}
1631-
}
1632-
}
1633-
1634-
impl<T: Clone> Option<&T> {
16351703
/// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the
16361704
/// option.
16371705
///
@@ -1658,8 +1726,8 @@ impl<T: Clone> Option<&T> {
16581726
}
16591727
}
16601728

1661-
impl<T: Clone> Option<&mut T> {
1662-
/// Maps an `Option<&mut T>` to an `Option<T>` by cloning the contents of the
1729+
impl<T> Option<&mut T> {
1730+
/// Maps an `Option<&mut T>` to an `Option<T>` by copying the contents of the
16631731
/// option.
16641732
///
16651733
/// # Examples
@@ -1668,115 +1736,43 @@ impl<T: Clone> Option<&mut T> {
16681736
/// let mut x = 12;
16691737
/// let opt_x = Some(&mut x);
16701738
/// assert_eq!(opt_x, Some(&mut 12));
1671-
/// let cloned = opt_x.cloned();
1672-
/// assert_eq!(cloned, Some(12));
1739+
/// let copied = opt_x.copied();
1740+
/// assert_eq!(copied, Some(12));
16731741
/// ```
16741742
#[must_use = "`self` will be dropped if the result is not used"]
1675-
#[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
1676-
#[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")]
1677-
pub const fn cloned(self) -> Option<T>
1678-
where
1679-
T: ~const Clone,
1680-
{
1681-
match self {
1682-
Some(t) => Some(t.clone()),
1683-
None => None,
1684-
}
1685-
}
1686-
}
1687-
1688-
impl<T: Default> Option<T> {
1689-
/// Returns the contained [`Some`] value or a default.
1690-
///
1691-
/// Consumes the `self` argument then, if [`Some`], returns the contained
1692-
/// value, otherwise if [`None`], returns the [default value] for that
1693-
/// type.
1694-
///
1695-
/// # Examples
1696-
///
1697-
/// Converts a string to an integer, turning poorly-formed strings
1698-
/// into 0 (the default value for integers). [`parse`] converts
1699-
/// a string to any other type that implements [`FromStr`], returning
1700-
/// [`None`] on error.
1701-
///
1702-
/// ```
1703-
/// let good_year_from_input = "1909";
1704-
/// let bad_year_from_input = "190blarg";
1705-
/// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
1706-
/// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
1707-
///
1708-
/// assert_eq!(1909, good_year);
1709-
/// assert_eq!(0, bad_year);
1710-
/// ```
1711-
///
1712-
/// [default value]: Default::default
1713-
/// [`parse`]: str::parse
1714-
/// [`FromStr`]: crate::str::FromStr
1715-
#[inline]
1716-
#[stable(feature = "rust1", since = "1.0.0")]
1743+
#[stable(feature = "copied", since = "1.35.0")]
17171744
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1718-
pub const fn unwrap_or_default(self) -> T
1745+
pub const fn copied(self) -> Option<T>
17191746
where
1720-
T: ~const Default,
1747+
T: Copy,
17211748
{
17221749
match self {
1723-
Some(x) => x,
1724-
None => Default::default(),
1725-
}
1726-
}
1727-
}
1728-
1729-
impl<T: Deref> Option<T> {
1730-
/// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
1731-
///
1732-
/// Leaves the original Option in-place, creating a new one with a reference
1733-
/// to the original one, additionally coercing the contents via [`Deref`].
1734-
///
1735-
/// # Examples
1736-
///
1737-
/// ```
1738-
/// let x: Option<String> = Some("hey".to_owned());
1739-
/// assert_eq!(x.as_deref(), Some("hey"));
1740-
///
1741-
/// let x: Option<String> = None;
1742-
/// assert_eq!(x.as_deref(), None);
1743-
/// ```
1744-
#[stable(feature = "option_deref", since = "1.40.0")]
1745-
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1746-
pub const fn as_deref(&self) -> Option<&T::Target>
1747-
where
1748-
T: ~const Deref,
1749-
{
1750-
match self.as_ref() {
1751-
Some(t) => Some(t.deref()),
1750+
Some(&mut t) => Some(t),
17521751
None => None,
17531752
}
17541753
}
1755-
}
17561754

1757-
impl<T: DerefMut> Option<T> {
1758-
/// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
1759-
///
1760-
/// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
1761-
/// the inner type's [`Deref::Target`] type.
1755+
/// Maps an `Option<&mut T>` to an `Option<T>` by cloning the contents of the
1756+
/// option.
17621757
///
17631758
/// # Examples
17641759
///
17651760
/// ```
1766-
/// let mut x: Option<String> = Some("hey".to_owned());
1767-
/// assert_eq!(x.as_deref_mut().map(|x| {
1768-
/// x.make_ascii_uppercase();
1769-
/// x
1770-
/// }), Some("HEY".to_owned().as_mut_str()));
1761+
/// let mut x = 12;
1762+
/// let opt_x = Some(&mut x);
1763+
/// assert_eq!(opt_x, Some(&mut 12));
1764+
/// let cloned = opt_x.cloned();
1765+
/// assert_eq!(cloned, Some(12));
17711766
/// ```
1772-
#[stable(feature = "option_deref", since = "1.40.0")]
1773-
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
1774-
pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
1767+
#[must_use = "`self` will be dropped if the result is not used"]
1768+
#[stable(since = "1.26.0", feature = "option_ref_mut_cloned")]
1769+
#[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")]
1770+
pub const fn cloned(self) -> Option<T>
17751771
where
1776-
T: ~const DerefMut,
1772+
T: ~const Clone,
17771773
{
1778-
match self.as_mut() {
1779-
Some(t) => Some(t.deref_mut()),
1774+
match self {
1775+
Some(t) => Some(t.clone()),
17801776
None => None,
17811777
}
17821778
}

0 commit comments

Comments
 (0)