diff options
| author | kennytm <kennytm@gmail.com> | 2018-12-01 01:05:56 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2018-12-01 02:03:41 +0800 |
| commit | ce00a8dd4d795f47a38a207af861a2cffcee7256 (patch) | |
| tree | 2a6bc7612cd2b92a7766bc2d227617734106464b /src/libsyntax/ptr.rs | |
| parent | f7c407eb8bc9413d9d1449eeda9710715ad255a2 (diff) | |
| parent | 6674db48872c1b84fe3ac3feb94b8d3e0ee82b24 (diff) | |
| download | rust-ce00a8dd4d795f47a38a207af861a2cffcee7256.tar.gz rust-ce00a8dd4d795f47a38a207af861a2cffcee7256.zip | |
Rollup merge of #56268 - nnethercote:fold_opt_expr-recycle, r=petrochenkov
Reuse the `P` in `InvocationCollector::fold_{,opt_}expr`.
This requires adding a new method, `P::filter_map`.
This commit reduces instruction counts for various benchmarks by up to
0.7%.
Diffstat (limited to 'src/libsyntax/ptr.rs')
| -rw-r--r-- | src/libsyntax/ptr.rs | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index bb47d9b535b..9fbc64758da 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -72,7 +72,7 @@ impl<T: 'static> P<T> { *self.ptr } - /// Transform the inner value, consuming `self` and producing a new `P<T>`. + /// Produce a new `P<T>` from `self` without reallocating. pub fn map<F>(mut self, f: F) -> P<T> where F: FnOnce(T) -> T, { @@ -88,8 +88,30 @@ impl<T: 'static> P<T> { ptr::write(p, f(ptr::read(p))); // Recreate self from the raw pointer. - P { - ptr: Box::from_raw(p) + P { ptr: Box::from_raw(p) } + } + } + + /// Optionally produce a new `P<T>` from `self` without reallocating. + pub fn filter_map<F>(mut self, f: F) -> Option<P<T>> where + F: FnOnce(T) -> Option<T>, + { + let p: *mut T = &mut *self.ptr; + + // Leak self in case of panic. + // FIXME(eddyb) Use some sort of "free guard" that + // only deallocates, without dropping the pointee, + // in case the call the `f` below ends in a panic. + mem::forget(self); + + unsafe { + if let Some(v) = f(ptr::read(p)) { + ptr::write(p, v); + + // Recreate self from the raw pointer. + Some(P { ptr: Box::from_raw(p) }) + } else { + None } } } |
