@@ -86,6 +86,9 @@ impl<T> Clone for Iter<'_, T> {
8686/// [`LinkedList`]: struct.LinkedList.html
8787#[ stable( feature = "rust1" , since = "1.0.0" ) ]
8888pub struct IterMut < ' a , T : ' a > {
89+ // We do *not* exclusively own the entire list here, references to node's `element`
90+ // have been handed out by the iterator! So be careful when using this; the methods
91+ // called must be aware that there can be aliasing pointers to `element`.
8992 list : & ' a mut LinkedList < T > ,
9093 head : Option < NonNull < Node < T > > > ,
9194 tail : Option < NonNull < Node < T > > > ,
@@ -143,14 +146,17 @@ impl<T> LinkedList<T> {
143146 /// Adds the given node to the front of the list.
144147 #[ inline]
145148 fn push_front_node ( & mut self , mut node : Box < Node < T > > ) {
149+ // This method takes care not to create mutable references to whole nodes,
150+ // to maintain validity of aliasing pointers into `element`.
146151 unsafe {
147152 node. next = self . head ;
148153 node. prev = None ;
149154 let node = Some ( Box :: into_raw_non_null ( node) ) ;
150155
151156 match self . head {
152157 None => self . tail = node,
153- Some ( mut head) => head. as_mut ( ) . prev = node,
158+ // Not creating new mutable (unique!) references overlapping `element`.
159+ Some ( head) => ( * head. as_ptr ( ) ) . prev = node,
154160 }
155161
156162 self . head = node;
@@ -161,13 +167,16 @@ impl<T> LinkedList<T> {
161167 /// Removes and returns the node at the front of the list.
162168 #[ inline]
163169 fn pop_front_node ( & mut self ) -> Option < Box < Node < T > > > {
170+ // This method takes care not to create mutable references to whole nodes,
171+ // to maintain validity of aliasing pointers into `element`.
164172 self . head . map ( |node| unsafe {
165173 let node = Box :: from_raw ( node. as_ptr ( ) ) ;
166174 self . head = node. next ;
167175
168176 match self . head {
169177 None => self . tail = None ,
170- Some ( mut head) => head. as_mut ( ) . prev = None ,
178+ // Not creating new mutable (unique!) references overlapping `element`.
179+ Some ( head) => ( * head. as_ptr ( ) ) . prev = None ,
171180 }
172181
173182 self . len -= 1 ;
@@ -178,14 +187,17 @@ impl<T> LinkedList<T> {
178187 /// Adds the given node to the back of the list.
179188 #[ inline]
180189 fn push_back_node ( & mut self , mut node : Box < Node < T > > ) {
190+ // This method takes care not to create mutable references to whole nodes,
191+ // to maintain validity of aliasing pointers into `element`.
181192 unsafe {
182193 node. next = None ;
183194 node. prev = self . tail ;
184195 let node = Some ( Box :: into_raw_non_null ( node) ) ;
185196
186197 match self . tail {
187198 None => self . head = node,
188- Some ( mut tail) => tail. as_mut ( ) . next = node,
199+ // Not creating new mutable (unique!) references overlapping `element`.
200+ Some ( tail) => ( * tail. as_ptr ( ) ) . next = node,
189201 }
190202
191203 self . tail = node;
@@ -196,13 +208,16 @@ impl<T> LinkedList<T> {
196208 /// Removes and returns the node at the back of the list.
197209 #[ inline]
198210 fn pop_back_node ( & mut self ) -> Option < Box < Node < T > > > {
211+ // This method takes care not to create mutable references to whole nodes,
212+ // to maintain validity of aliasing pointers into `element`.
199213 self . tail . map ( |node| unsafe {
200214 let node = Box :: from_raw ( node. as_ptr ( ) ) ;
201215 self . tail = node. prev ;
202216
203217 match self . tail {
204218 None => self . head = None ,
205- Some ( mut tail) => tail. as_mut ( ) . next = None ,
219+ // Not creating new mutable (unique!) references overlapping `element`.
220+ Some ( tail) => ( * tail. as_ptr ( ) ) . next = None ,
206221 }
207222
208223 self . len -= 1 ;
@@ -213,18 +228,22 @@ impl<T> LinkedList<T> {
213228 /// Unlinks the specified node from the current list.
214229 ///
215230 /// Warning: this will not check that the provided node belongs to the current list.
231+ ///
232+ /// This method takes care not to create mutable references to `element`, to
233+ /// maintain validity of aliasing pointers.
216234 #[ inline]
217235 unsafe fn unlink_node ( & mut self , mut node : NonNull < Node < T > > ) {
218- let node = node. as_mut ( ) ;
236+ let node = node. as_mut ( ) ; // this one is ours now, we can create an &mut.
219237
238+ // Not creating new mutable (unique!) references overlapping `element`.
220239 match node. prev {
221- Some ( mut prev) => prev. as_mut ( ) . next = node. next . clone ( ) ,
240+ Some ( prev) => ( * prev. as_ptr ( ) ) . next = node. next . clone ( ) ,
222241 // this node is the head node
223242 None => self . head = node. next . clone ( ) ,
224243 } ;
225244
226245 match node. next {
227- Some ( mut next) => next. as_mut ( ) . prev = node. prev . clone ( ) ,
246+ Some ( next) => ( * next. as_ptr ( ) ) . prev = node. prev . clone ( ) ,
228247 // this node is the tail node
229248 None => self . tail = node. prev . clone ( ) ,
230249 } ;
@@ -297,6 +316,8 @@ impl<T> LinkedList<T> {
297316 match self . tail {
298317 None => mem:: swap ( self , other) ,
299318 Some ( mut tail) => {
319+ // `as_mut` is okay here because we have exclusive access to the entirety
320+ // of both lists.
300321 if let Some ( mut other_head) = other. head . take ( ) {
301322 unsafe {
302323 tail. as_mut ( ) . next = Some ( other_head) ;
@@ -916,9 +937,11 @@ impl<T> IterMut<'_, T> {
916937 issue = "27794" ) ]
917938 pub fn insert_next ( & mut self , element : T ) {
918939 match self . head {
940+ // `push_back` is okay with aliasing `element` references
919941 None => self . list . push_back ( element) ,
920- Some ( mut head) => unsafe {
921- let mut prev = match head. as_ref ( ) . prev {
942+ Some ( head) => unsafe {
943+ let prev = match head. as_ref ( ) . prev {
944+ // `push_front` is okay with aliasing nodes
922945 None => return self . list . push_front ( element) ,
923946 Some ( prev) => prev,
924947 } ;
@@ -929,8 +952,10 @@ impl<T> IterMut<'_, T> {
929952 element,
930953 } ) ) ;
931954
932- prev. as_mut ( ) . next = node;
933- head. as_mut ( ) . prev = node;
955+ // Not creating references to entire nodes to not invalidate the
956+ // reference to `element` we handed to the user.
957+ ( * prev. as_ptr ( ) ) . next = node;
958+ ( * head. as_ptr ( ) ) . prev = node;
934959
935960 self . list . len += 1 ;
936961 } ,
@@ -994,6 +1019,7 @@ impl<T, F> Iterator for DrainFilter<'_, T, F>
9941019 self . idx += 1 ;
9951020
9961021 if ( self . pred ) ( & mut node. as_mut ( ) . element ) {
1022+ // `unlink_node` is okay with aliasing `element` references.
9971023 self . list . unlink_node ( node) ;
9981024 return Some ( Box :: from_raw ( node. as_ptr ( ) ) . element ) ;
9991025 }
0 commit comments