@@ -8,7 +8,6 @@ use crate::Interner;
88use rustc_data_structures:: functor:: IdFunctor ;
99use rustc_index:: vec:: { Idx , IndexVec } ;
1010
11- use std:: mem:: ManuallyDrop ;
1211use std:: ops:: ControlFlow ;
1312use std:: rc:: Rc ;
1413use std:: sync:: Arc ;
@@ -98,39 +97,8 @@ EnumTypeTraversalImpl! {
9897}
9998
10099impl < 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) )
134102 }
135103}
136104
@@ -141,39 +109,8 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Rc<T> {
141109}
142110
143111impl < 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) )
177114 }
178115}
179116
0 commit comments