@@ -199,11 +199,39 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
199199    fn  visit_place ( & mut  self , 
200200                    place :  & Place < ' tcx > , 
201201                    context :  PlaceContext , 
202-                     location :  Location )  { 
203-         match  place { 
204-             & Place :: Projection ( box Projection  { 
205-                 ref  base,  ref  elem
206-             } )  => { 
202+                     _location :  Location )  { 
203+         place. iterate ( |place_base,  place_projections| { 
204+             match  place_base { 
205+                 PlaceBase :: Local ( ..)  => { 
206+                     // Locals are safe. 
207+                 } 
208+                 PlaceBase :: Static ( box Static  {  kind :  StaticKind :: Promoted ( _) ,  .. } )  => { 
209+                     bug ! ( "unsafety checking should happen before promotion" ) 
210+                 } 
211+                 PlaceBase :: Static ( box Static  {  kind :  StaticKind :: Static ( def_id) ,  .. } )  => { 
212+                     if  self . tcx . is_mutable_static ( * def_id)  { 
213+                         self . require_unsafe ( "use of mutable static" , 
214+                             "mutable statics can be mutated by multiple threads: aliasing \  
215+                               violations or data races will cause undefined behavior", 
216+                              UnsafetyViolationKind :: General ) ; 
217+                     }  else  if  self . tcx . is_foreign_item ( * def_id)  { 
218+                         let  source_info = self . source_info ; 
219+                         let  lint_root =
220+                             self . source_scope_local_data [ source_info. scope ] . lint_root ; 
221+                         self . register_violations ( & [ UnsafetyViolation  { 
222+                             source_info, 
223+                             description :  InternedString :: intern ( "use of extern static" ) , 
224+                             details :  InternedString :: intern ( 
225+                                 "extern statics are not controlled by the Rust type system: \  
226+                                  invalid data, aliasing violations or data races will cause \ 
227+                                  undefined behavior") , 
228+                             kind :  UnsafetyViolationKind :: ExternStatic ( lint_root) 
229+                         } ] ,  & [ ] ) ; 
230+                     } 
231+                 } 
232+             } 
233+ 
234+             for  proj in  place_projections { 
207235                if  context. is_borrow ( )  { 
208236                    if  util:: is_disaligned ( self . tcx ,  self . mir ,  self . param_env ,  place)  { 
209237                        let  source_info = self . source_info ; 
@@ -220,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
220248                        } ] ,  & [ ] ) ; 
221249                    } 
222250                } 
223-                 let  is_borrow_of_interior_mut = context. is_borrow ( )  && !base
251+                 let  is_borrow_of_interior_mut = context. is_borrow ( )  && !proj . base 
224252                    . ty ( self . mir ,  self . tcx ) 
225253                    . ty 
226254                    . is_freeze ( self . tcx ,  self . param_env ,  self . source_info . span ) ; 
@@ -236,15 +264,15 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
236264                    ) ; 
237265                } 
238266                let  old_source_info = self . source_info ; 
239-                 if  let  & Place :: Base ( PlaceBase :: Local ( local) )  = base { 
267+                 if  let  Place :: Base ( PlaceBase :: Local ( local) )  = proj . base  { 
240268                    if  self . mir . local_decls [ local] . internal  { 
241269                        // Internal locals are used in the `move_val_init` desugaring. 
242270                        // We want to check unsafety against the source info of the 
243271                        // desugaring, rather than the source info of the RHS. 
244272                        self . source_info  = self . mir . local_decls [ local] . source_info ; 
245273                    } 
246274                } 
247-                 let  base_ty = base. ty ( self . mir ,  self . tcx ) . ty ; 
275+                 let  base_ty = proj . base . ty ( self . mir ,  self . tcx ) . ty ; 
248276                match  base_ty. sty  { 
249277                    ty:: RawPtr ( ..)  => { 
250278                        self . require_unsafe ( "dereference of raw pointer" , 
@@ -260,8 +288,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
260288                                    MutatingUseContext :: AsmOutput 
261289                                ) 
262290                            { 
263-                                 let  elem_ty = match  elem { 
264-                                     & ProjectionElem :: Field ( _,  ty)  => ty, 
291+                                 let  elem_ty = match  proj . elem  { 
292+                                     ProjectionElem :: Field ( _,  ty)  => ty, 
265293                                    _ => span_bug ! ( 
266294                                        self . source_info. span, 
267295                                        "non-field projection {:?} from union?" , 
@@ -292,36 +320,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
292320                } 
293321                self . source_info  = old_source_info; 
294322            } 
295-             & Place :: Base ( PlaceBase :: Local ( ..) )  => { 
296-                 // locals are safe 
297-             } 
298-             & Place :: Base ( PlaceBase :: Static ( box Static  {  kind :  StaticKind :: Promoted ( _) ,  .. } ) )  => { 
299-                 bug ! ( "unsafety checking should happen before promotion" ) 
300-             } 
301-             & Place :: Base ( 
302-                 PlaceBase :: Static ( box Static  {  kind :  StaticKind :: Static ( def_id) ,  .. } ) 
303-             )  => { 
304-                 if  self . tcx . is_mutable_static ( def_id)  { 
305-                     self . require_unsafe ( "use of mutable static" , 
306-                         "mutable statics can be mutated by multiple threads: aliasing violations \  
307-                           or data races will cause undefined behavior", 
308-                          UnsafetyViolationKind :: General ) ; 
309-                 }  else  if  self . tcx . is_foreign_item ( def_id)  { 
310-                     let  source_info = self . source_info ; 
311-                     let  lint_root =
312-                         self . source_scope_local_data [ source_info. scope ] . lint_root ; 
313-                     self . register_violations ( & [ UnsafetyViolation  { 
314-                         source_info, 
315-                         description :  InternedString :: intern ( "use of extern static" ) , 
316-                         details :  InternedString :: intern ( 
317-                             "extern statics are not controlled by the Rust type system: invalid \  
318-                              data, aliasing violations or data races will cause undefined behavior") , 
319-                         kind :  UnsafetyViolationKind :: ExternStatic ( lint_root) 
320-                     } ] ,  & [ ] ) ; 
321-                 } 
322-             } 
323-         } ; 
324-         self . super_place ( place,  context,  location) ; 
323+         } ) ; 
325324    } 
326325} 
327326
0 commit comments