@@ -15,6 +15,7 @@ use self::RootUnsafeContext::*;
1515use dep_graph:: DepNode ;
1616use ty:: { self , Ty , TyCtxt } ;
1717use ty:: MethodCall ;
18+ use lint;
1819
1920use syntax:: ast;
2021use syntax_pos:: Span ;
@@ -57,16 +58,25 @@ struct EffectCheckVisitor<'a, 'tcx: 'a> {
5758}
5859
5960impl < ' a , ' tcx > EffectCheckVisitor < ' a , ' tcx > {
60- fn require_unsafe ( & mut self , span : Span , description : & str ) {
61+ fn require_unsafe_ext ( & mut self , node_id : ast:: NodeId , span : Span ,
62+ description : & str , is_lint : bool ) {
6163 if self . unsafe_context . push_unsafe_count > 0 { return ; }
6264 match self . unsafe_context . root {
6365 SafeContext => {
64- // Report an error.
65- struct_span_err ! (
66- self . tcx. sess, span, E0133 ,
67- "{} requires unsafe function or block" , description)
68- . span_label ( span, & description)
69- . emit ( ) ;
66+ if is_lint {
67+ self . tcx . sess . add_lint ( lint:: builtin:: SAFE_EXTERN_STATICS ,
68+ node_id,
69+ span,
70+ format ! ( "{} requires unsafe function or \
71+ block (error E0133)", description) ) ;
72+ } else {
73+ // Report an error.
74+ struct_span_err ! (
75+ self . tcx. sess, span, E0133 ,
76+ "{} requires unsafe function or block" , description)
77+ . span_label ( span, & description)
78+ . emit ( ) ;
79+ }
7080 }
7181 UnsafeBlock ( block_id) => {
7282 // OK, but record this.
@@ -76,6 +86,10 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
7686 UnsafeFn => { }
7787 }
7888 }
89+
90+ fn require_unsafe ( & mut self , span : Span , description : & str ) {
91+ self . require_unsafe_ext ( ast:: DUMMY_NODE_ID , span, description, false )
92+ }
7993}
8094
8195impl < ' a , ' tcx , ' v > Visitor < ' v > for EffectCheckVisitor < ' a , ' tcx > {
@@ -173,8 +187,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
173187 self . require_unsafe ( expr. span , "use of inline assembly" ) ;
174188 }
175189 hir:: ExprPath ( ..) => {
176- if let Def :: Static ( _, true ) = self . tcx . expect_def ( expr. id ) {
177- self . require_unsafe ( expr. span , "use of mutable static" ) ;
190+ if let Def :: Static ( def_id, mutbl) = self . tcx . expect_def ( expr. id ) {
191+ if mutbl {
192+ self . require_unsafe ( expr. span , "use of mutable static" ) ;
193+ } else if match self . tcx . map . get_if_local ( def_id) {
194+ Some ( hir:: map:: NodeForeignItem ( ..) ) => true ,
195+ Some ( ..) => false ,
196+ None => self . tcx . sess . cstore . is_foreign_item ( def_id) ,
197+ } {
198+ self . require_unsafe_ext ( expr. id , expr. span , "use of extern static" , true ) ;
199+ }
178200 }
179201 }
180202 hir:: ExprField ( ref base_expr, field) => {
0 commit comments