From be53d619f874cbe8e4d87f900060561d16405d53 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sun, 7 Dec 2014 13:22:04 -0500 Subject: [PATCH] librustrt: use unboxed closures --- src/librustrt/args.rs | 2 +- src/librustrt/c_str.rs | 57 ++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/librustrt/args.rs b/src/librustrt/args.rs index 4632eca4d0f..c1b48e989a1 100644 --- a/src/librustrt/args.rs +++ b/src/librustrt/args.rs @@ -89,7 +89,7 @@ mod imp { }) } - fn with_lock(f: || -> T) -> T { + fn with_lock(f: F) -> T where F: FnOnce() -> T { unsafe { let _guard = LOCK.lock(); f() diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index 07094f08c5d..865c1af1d14 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -72,6 +72,7 @@ use collections::hash; use core::fmt; use core::kinds::{Sized, marker}; use core::mem; +use core::ops::{FnMut, FnOnce}; use core::prelude::{Clone, Drop, Eq, Iterator}; use core::prelude::{SlicePrelude, None, Option, Ordering, PartialEq}; use core::prelude::{PartialOrd, RawPtr, Some, StrPrelude, range}; @@ -319,14 +320,18 @@ pub trait ToCStr for Sized? { /// /// Panics the task if the receiver has an interior null. #[inline] - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { let c_str = self.to_c_str(); f(c_str.as_ptr()) } /// Unsafe variant of `with_c_str()` that doesn't check for nulls. #[inline] - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { let c_str = self.to_c_str_unchecked(); f(c_str.as_ptr()) } @@ -344,12 +349,16 @@ impl ToCStr for str { } #[inline] - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str_unchecked(f) } } @@ -366,12 +375,16 @@ impl ToCStr for String { } #[inline] - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { self.as_bytes().with_c_str_unchecked(f) } } @@ -397,11 +410,15 @@ impl ToCStr for [u8] { CString::new(buf as *const libc::c_char, true) } - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { unsafe { with_c_str(self, true, f) } } - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { with_c_str(self, false, f) } } @@ -418,19 +435,24 @@ impl<'a, Sized? T: ToCStr> ToCStr for &'a T { } #[inline] - fn with_c_str(&self, f: |*const libc::c_char| -> T) -> T { + fn with_c_str(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { (**self).with_c_str(f) } #[inline] - unsafe fn with_c_str_unchecked(&self, f: |*const libc::c_char| -> T) -> T { + unsafe fn with_c_str_unchecked(&self, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, + { (**self).with_c_str_unchecked(f) } } // Unsafe function that handles possibly copying the &[u8] into a stack array. -unsafe fn with_c_str(v: &[u8], checked: bool, - f: |*const libc::c_char| -> T) -> T { +unsafe fn with_c_str(v: &[u8], checked: bool, f: F) -> T where + F: FnOnce(*const libc::c_char) -> T, +{ let c_str = if v.len() < BUF_LEN { let mut buf: [u8, .. BUF_LEN] = mem::uninitialized(); slice::bytes::copy_memory(&mut buf, v); @@ -489,9 +511,12 @@ impl<'a> Iterator for CChars<'a> { /// /// The specified closure is invoked with each string that /// is found, and the number of strings found is returned. -pub unsafe fn from_c_multistring(buf: *const libc::c_char, - count: Option, - f: |&CString|) -> uint { +pub unsafe fn from_c_multistring(buf: *const libc::c_char, + count: Option, + mut f: F) + -> uint where + F: FnMut(&CString), +{ let mut curr_ptr: uint = buf as uint; let mut ctr = 0; @@ -678,7 +703,7 @@ mod tests { #[test] fn test_clone_noleak() { - fn foo(f: |c: &CString|) { + fn foo(f: F) where F: FnOnce(&CString) { let s = "test".to_string(); let c = s.to_c_str(); // give the closure a non-owned CString