@@ -8,7 +8,6 @@ use crate::Interner;
8
8
use rustc_data_structures:: functor:: IdFunctor ;
9
9
use rustc_index:: vec:: { Idx , IndexVec } ;
10
10
11
- use std:: mem:: ManuallyDrop ;
12
11
use std:: ops:: ControlFlow ;
13
12
use std:: rc:: Rc ;
14
13
use std:: sync:: Arc ;
@@ -98,39 +97,8 @@ EnumTypeTraversalImpl! {
98
97
}
99
98
100
99
impl < I : Interner , T : TypeFoldable < I > > TypeFoldable < I > for Rc < T > {
101
- fn try_fold_with < F : FallibleTypeFolder < I > > ( mut self , folder : & mut F ) -> Result < Self , F :: Error > {
102
- // We merely want to replace the contained `T`, if at all possible,
103
- // so that we don't needlessly allocate a new `Rc` or indeed clone
104
- // the contained type.
105
- unsafe {
106
- // First step is to ensure that we have a unique reference to
107
- // the contained type, which `Rc::make_mut` will accomplish (by
108
- // allocating a new `Rc` and cloning the `T` only if required).
109
- // This is done *before* casting to `Rc<ManuallyDrop<T>>` so that
110
- // panicking during `make_mut` does not leak the `T`.
111
- Rc :: make_mut ( & mut self ) ;
112
-
113
- // Casting to `Rc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
114
- // is `repr(transparent)`.
115
- let ptr = Rc :: into_raw ( self ) . cast :: < ManuallyDrop < T > > ( ) ;
116
- let mut unique = Rc :: from_raw ( ptr) ;
117
-
118
- // Call to `Rc::make_mut` above guarantees that `unique` is the
119
- // sole reference to the contained value, so we can avoid doing
120
- // a checked `get_mut` here.
121
- let slot = Rc :: get_mut_unchecked ( & mut unique) ;
122
-
123
- // Semantically move the contained type out from `unique`, fold
124
- // it, then move the folded value back into `unique`. Should
125
- // folding fail, `ManuallyDrop` ensures that the "moved-out"
126
- // value is not re-dropped.
127
- let owned = ManuallyDrop :: take ( slot) ;
128
- let folded = owned. try_fold_with ( folder) ?;
129
- * slot = ManuallyDrop :: new ( folded) ;
130
-
131
- // Cast back to `Rc<T>`.
132
- Ok ( Rc :: from_raw ( Rc :: into_raw ( unique) . cast ( ) ) )
133
- }
100
+ fn try_fold_with < F : FallibleTypeFolder < I > > ( self , folder : & mut F ) -> Result < Self , F :: Error > {
101
+ self . try_map_id ( |value| value. try_fold_with ( folder) )
134
102
}
135
103
}
136
104
@@ -141,39 +109,8 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Rc<T> {
141
109
}
142
110
143
111
impl < I : Interner , T : TypeFoldable < I > > TypeFoldable < I > for Arc < T > {
144
- fn try_fold_with < F : FallibleTypeFolder < I > > ( mut self , folder : & mut F ) -> Result < Self , F :: Error > {
145
- // We merely want to replace the contained `T`, if at all possible,
146
- // so that we don't needlessly allocate a new `Arc` or indeed clone
147
- // the contained type.
148
- unsafe {
149
- // First step is to ensure that we have a unique reference to
150
- // the contained type, which `Arc::make_mut` will accomplish (by
151
- // allocating a new `Arc` and cloning the `T` only if required).
152
- // This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
153
- // panicking during `make_mut` does not leak the `T`.
154
- Arc :: make_mut ( & mut self ) ;
155
-
156
- // Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
157
- // is `repr(transparent)`.
158
- let ptr = Arc :: into_raw ( self ) . cast :: < ManuallyDrop < T > > ( ) ;
159
- let mut unique = Arc :: from_raw ( ptr) ;
160
-
161
- // Call to `Arc::make_mut` above guarantees that `unique` is the
162
- // sole reference to the contained value, so we can avoid doing
163
- // a checked `get_mut` here.
164
- let slot = Arc :: get_mut_unchecked ( & mut unique) ;
165
-
166
- // Semantically move the contained type out from `unique`, fold
167
- // it, then move the folded value back into `unique`. Should
168
- // folding fail, `ManuallyDrop` ensures that the "moved-out"
169
- // value is not re-dropped.
170
- let owned = ManuallyDrop :: take ( slot) ;
171
- let folded = owned. try_fold_with ( folder) ?;
172
- * slot = ManuallyDrop :: new ( folded) ;
173
-
174
- // Cast back to `Arc<T>`.
175
- Ok ( Arc :: from_raw ( Arc :: into_raw ( unique) . cast ( ) ) )
176
- }
112
+ fn try_fold_with < F : FallibleTypeFolder < I > > ( self , folder : & mut F ) -> Result < Self , F :: Error > {
113
+ self . try_map_id ( |value| value. try_fold_with ( folder) )
177
114
}
178
115
}
179
116
0 commit comments