Skip to content

Commit 92dcae4

Browse files
committed
Add internal impl_fn_for_zst macro for "named closure types"
1 parent 75f9159 commit 92dcae4

File tree

3 files changed

+75
-113
lines changed

3 files changed

+75
-113
lines changed

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
#![feature(simd_ffi)]
9696
#![feature(specialization)]
9797
#![feature(staged_api)]
98+
#![feature(std_internals)]
9899
#![feature(stmt_expr_attributes)]
99100
#![feature(unboxed_closures)]
100101
#![feature(unsized_locals)]

src/libcore/macros.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,49 @@ mod builtin {
749749
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
750750
}
751751
}
752+
753+
/// Create a named zero-size type similar to a closure.
754+
#[doc(hidden)]
755+
#[macro_export]
756+
#[unstable(feature = "std_internals", issue = "0")]
757+
macro_rules! impl_fn_for_zst {
758+
($(
759+
$( #[$attr: meta] )*
760+
// FIXME: when libcore is in the 2018 edition, use `?` repetition in
761+
// $( <$( $li : lifetime ),+> )?
762+
struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )* Fn =
763+
|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
764+
$body: block;
765+
)+) => {
766+
$(
767+
$( #[$attr] )*
768+
struct $Name;
769+
770+
impl $( <$( $lifetime ),+> )* Fn<($( $ArgTy, )*)> for $Name {
771+
#[inline]
772+
extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
773+
$body
774+
}
775+
}
776+
777+
impl $( <$( $lifetime ),+> )* FnMut<($( $ArgTy, )*)> for $Name {
778+
#[inline]
779+
extern "rust-call" fn call_mut(
780+
&mut self,
781+
($( $arg, )*): ($( $ArgTy, )*)
782+
) -> $ReturnTy {
783+
Fn::call(&*self, ($( $arg, )*))
784+
}
785+
}
786+
787+
impl $( <$( $lifetime ),+> )* FnOnce<($( $ArgTy, )*)> for $Name {
788+
type Output = $ReturnTy;
789+
790+
#[inline]
791+
extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
792+
Fn::call(&self, ($( $arg, )*))
793+
}
794+
}
795+
)+
796+
}
797+
}

src/libcore/str/mod.rs

Lines changed: 28 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,33 +1345,14 @@ impl FusedIterator for Lines<'_> {}
13451345
#[allow(deprecated)]
13461346
pub struct LinesAny<'a>(Lines<'a>);
13471347

1348-
/// A nameable, cloneable fn type
1349-
#[derive(Clone)]
1350-
struct LinesAnyMap;
1351-
1352-
impl<'a> Fn<(&'a str,)> for LinesAnyMap {
1353-
#[inline]
1354-
extern "rust-call" fn call(&self, (line,): (&'a str,)) -> &'a str {
1348+
impl_fn_for_zst! {
1349+
/// A nameable, cloneable fn type
1350+
#[derive(Clone)]
1351+
struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> &'a str {
13551352
let l = line.len();
13561353
if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
13571354
else { line }
1358-
}
1359-
}
1360-
1361-
impl<'a> FnMut<(&'a str,)> for LinesAnyMap {
1362-
#[inline]
1363-
extern "rust-call" fn call_mut(&mut self, (line,): (&'a str,)) -> &'a str {
1364-
Fn::call(&*self, (line,))
1365-
}
1366-
}
1367-
1368-
impl<'a> FnOnce<(&'a str,)> for LinesAnyMap {
1369-
type Output = &'a str;
1370-
1371-
#[inline]
1372-
extern "rust-call" fn call_once(self, (line,): (&'a str,)) -> &'a str {
1373-
Fn::call(&self, (line,))
1374-
}
1355+
};
13751356
}
13761357

13771358
#[stable(feature = "rust1", since = "1.0.0")]
@@ -2727,7 +2708,7 @@ impl str {
27272708
let inner = self
27282709
.as_bytes()
27292710
.split(IsAsciiWhitespace)
2730-
.filter(IsNotEmpty)
2711+
.filter(BytesIsNotEmpty)
27312712
.map(UnsafeBytesToStr);
27322713
SplitAsciiWhitespace { inner }
27332714
}
@@ -4011,102 +3992,36 @@ pub struct SplitWhitespace<'a> {
40113992
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
40123993
#[derive(Clone, Debug)]
40133994
pub struct SplitAsciiWhitespace<'a> {
4014-
inner: Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, IsNotEmpty>, UnsafeBytesToStr>,
4015-
}
4016-
4017-
#[derive(Clone)]
4018-
struct IsWhitespace;
4019-
4020-
impl FnOnce<(char, )> for IsWhitespace {
4021-
type Output = bool;
4022-
4023-
#[inline]
4024-
extern "rust-call" fn call_once(mut self, arg: (char, )) -> bool {
4025-
self.call_mut(arg)
4026-
}
3995+
inner: Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
40273996
}
40283997

4029-
impl FnMut<(char, )> for IsWhitespace {
4030-
#[inline]
4031-
extern "rust-call" fn call_mut(&mut self, arg: (char, )) -> bool {
4032-
arg.0.is_whitespace()
4033-
}
4034-
}
4035-
4036-
#[derive(Clone)]
4037-
struct IsAsciiWhitespace;
4038-
4039-
impl<'a> FnOnce<(&'a u8, )> for IsAsciiWhitespace {
4040-
type Output = bool;
4041-
4042-
#[inline]
4043-
extern "rust-call" fn call_once(mut self, arg: (&u8, )) -> bool {
4044-
self.call_mut(arg)
4045-
}
4046-
}
4047-
4048-
impl<'a> FnMut<(&'a u8, )> for IsAsciiWhitespace {
4049-
#[inline]
4050-
extern "rust-call" fn call_mut(&mut self, arg: (&u8, )) -> bool {
4051-
arg.0.is_ascii_whitespace()
4052-
}
4053-
}
4054-
4055-
#[derive(Clone)]
4056-
struct IsNotEmpty;
4057-
4058-
impl<'a, 'b> FnOnce<(&'a &'b str, )> for IsNotEmpty {
4059-
type Output = bool;
4060-
4061-
#[inline]
4062-
extern "rust-call" fn call_once(mut self, arg: (&'a &'b str, )) -> bool {
4063-
self.call_mut(arg)
4064-
}
4065-
}
4066-
4067-
impl<'a, 'b> FnMut<(&'a &'b str, )> for IsNotEmpty {
4068-
#[inline]
4069-
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b str, )) -> bool {
4070-
!arg.0.is_empty()
4071-
}
4072-
}
4073-
4074-
impl<'a, 'b> FnOnce<(&'a &'b [u8], )> for IsNotEmpty {
4075-
type Output = bool;
4076-
4077-
#[inline]
4078-
extern "rust-call" fn call_once(mut self, arg: (&'a &'b [u8], )) -> bool {
4079-
self.call_mut(arg)
4080-
}
4081-
}
4082-
4083-
impl<'a, 'b> FnMut<(&'a &'b [u8], )> for IsNotEmpty {
4084-
#[inline]
4085-
extern "rust-call" fn call_mut(&mut self, arg: (&'a &'b [u8], )) -> bool {
4086-
!arg.0.is_empty()
4087-
}
4088-
}
3998+
impl_fn_for_zst! {
3999+
#[derive(Clone)]
4000+
struct IsWhitespace impl Fn = |c: char| -> bool {
4001+
c.is_whitespace()
4002+
};
40894003

4090-
#[derive(Clone)]
4091-
struct UnsafeBytesToStr;
4004+
#[derive(Clone)]
4005+
struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool {
4006+
byte.is_ascii_whitespace()
4007+
};
40924008

4093-
impl<'a> FnOnce<(&'a [u8], )> for UnsafeBytesToStr {
4094-
type Output = &'a str;
4009+
#[derive(Clone)]
4010+
struct IsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b str| -> bool {
4011+
!s.is_empty()
4012+
};
40954013

4096-
#[inline]
4097-
extern "rust-call" fn call_once(mut self, arg: (&'a [u8], )) -> &'a str {
4098-
self.call_mut(arg)
4099-
}
4100-
}
4014+
#[derive(Clone)]
4015+
struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool {
4016+
!s.is_empty()
4017+
};
41014018

4102-
impl<'a> FnMut<(&'a [u8], )> for UnsafeBytesToStr {
4103-
#[inline]
4104-
extern "rust-call" fn call_mut(&mut self, arg: (&'a [u8], )) -> &'a str {
4105-
unsafe { from_utf8_unchecked(arg.0) }
4106-
}
4019+
#[derive(Clone)]
4020+
struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str {
4021+
unsafe { from_utf8_unchecked(bytes) }
4022+
};
41074023
}
41084024

4109-
41104025
#[stable(feature = "split_whitespace", since = "1.1.0")]
41114026
impl<'a> Iterator for SplitWhitespace<'a> {
41124027
type Item = &'a str;

0 commit comments

Comments
 (0)