105
105
106
106
use core:: prelude:: * ;
107
107
108
+ use middle:: lint:: { unused_variable, dead_assignment} ;
108
109
use middle:: pat_util;
109
110
use middle:: ty;
110
111
use middle:: typeck;
@@ -118,6 +119,7 @@ use core::ptr;
118
119
use core:: to_str;
119
120
use core:: uint;
120
121
use core:: vec;
122
+ use core:: util:: with;
121
123
use syntax:: ast:: * ;
122
124
use syntax:: codemap:: span;
123
125
use syntax:: parse:: token:: special_idents;
@@ -169,6 +171,7 @@ pub fn check_crate(tcx: ty::ctxt,
169
171
visit_local : visit_local,
170
172
visit_expr : visit_expr,
171
173
visit_arm : visit_arm,
174
+ visit_item : visit_item,
172
175
.. * visit:: default_visitor ( )
173
176
} ) ;
174
177
@@ -177,7 +180,8 @@ pub fn check_crate(tcx: ty::ctxt,
177
180
method_map,
178
181
variable_moves_map,
179
182
capture_map,
180
- last_use_map) ;
183
+ last_use_map,
184
+ 0 ) ;
181
185
visit:: visit_crate ( * crate , initial_maps, visitor) ;
182
186
tcx. sess . abort_if_errors ( ) ;
183
187
return last_use_map;
@@ -269,13 +273,16 @@ struct IrMaps {
269
273
capture_info_map : HashMap < node_id , @~[ CaptureInfo ] > ,
270
274
var_kinds : ~[ VarKind ] ,
271
275
lnks : ~[ LiveNodeKind ] ,
276
+
277
+ cur_item : node_id ,
272
278
}
273
279
274
280
fn IrMaps ( tcx : ty:: ctxt ,
275
281
method_map : typeck:: method_map ,
276
282
variable_moves_map : moves:: VariableMovesMap ,
277
283
capture_map : moves:: CaptureMap ,
278
- last_use_map : last_use_map )
284
+ last_use_map : last_use_map ,
285
+ cur_item : node_id )
279
286
-> IrMaps {
280
287
IrMaps {
281
288
tcx : tcx,
@@ -289,7 +296,8 @@ fn IrMaps(tcx: ty::ctxt,
289
296
variable_map : HashMap :: new ( ) ,
290
297
capture_info_map : HashMap :: new ( ) ,
291
298
var_kinds : ~[ ] ,
292
- lnks : ~[ ]
299
+ lnks : ~[ ] ,
300
+ cur_item : cur_item,
293
301
}
294
302
}
295
303
@@ -394,6 +402,12 @@ pub impl IrMaps {
394
402
}
395
403
}
396
404
405
+ fn visit_item ( item : @item, &&self : @mut IrMaps , v : vt < @mut IrMaps > ) {
406
+ do with ( & mut self . cur_item , item. id ) {
407
+ visit:: visit_item ( item, self , v)
408
+ }
409
+ }
410
+
397
411
fn visit_fn ( fk : & visit:: fn_kind ,
398
412
decl : & fn_decl ,
399
413
body : & blk ,
@@ -409,7 +423,8 @@ fn visit_fn(fk: &visit::fn_kind,
409
423
self . method_map ,
410
424
self . variable_moves_map ,
411
425
self . capture_map ,
412
- self . last_use_map ) ;
426
+ self . last_use_map ,
427
+ self . cur_item ) ;
413
428
414
429
debug ! ( "creating fn_maps: %x" , ptr:: addr_of( & ( * fn_maps) ) as uint) ;
415
430
@@ -692,17 +707,19 @@ pub impl Liveness {
692
707
}
693
708
}
694
709
695
- fn pat_bindings( & self , pat: @pat, f: & fn( LiveNode , Variable , span) ) {
710
+ fn pat_bindings( & self , pat: @pat,
711
+ f: & fn( LiveNode , Variable , span, node_id) ) {
696
712
let def_map = self . tcx. def_map;
697
713
do pat_util:: pat_bindings( def_map, pat) |_bm, p_id, sp, _n| {
698
714
let ln = self . live_node( p_id, sp) ;
699
715
let var = self . variable( p_id, sp) ;
700
- f( ln, var, sp) ;
716
+ f( ln, var, sp, p_id ) ;
701
717
}
702
718
}
703
719
704
720
fn arm_pats_bindings( & self ,
705
- pats: & [ @pat] , f: & fn( LiveNode , Variable , span) ) {
721
+ pats: & [ @pat] ,
722
+ f: & fn( LiveNode , Variable , span, node_id) ) {
706
723
// only consider the first pattern; any later patterns must have
707
724
// the same bindings, and we also consider the first pattern to be
708
725
// the "authoratative" set of ids
@@ -718,7 +735,7 @@ pub impl Liveness {
718
735
fn define_bindings_in_arm_pats( & self , pats: & [ @pat] ,
719
736
succ: LiveNode ) -> LiveNode {
720
737
let mut succ = succ;
721
- do self. arm_pats_bindings( pats) |ln, var, _sp| {
738
+ do self. arm_pats_bindings( pats) |ln, var, _sp, _id | {
722
739
self . init_from_succ( ln, succ) ;
723
740
self . define( ln, var) ;
724
741
succ = ln;
@@ -1509,8 +1526,8 @@ fn check_local(local: @local, &&self: @Liveness, vt: vt<@Liveness>) {
1509
1526
// should not be live at this point.
1510
1527
1511
1528
debug!( "check_local( ) with no initializer") ;
1512
- do self . pat_bindings( local. node. pat) |ln, var, sp| {
1513
- if !self . warn_about_unused( sp, ln, var) {
1529
+ do self . pat_bindings( local. node. pat) |ln, var, sp, id | {
1530
+ if !self . warn_about_unused( sp, id , ln, var) {
1514
1531
match self . live_on_exit( ln, var) {
1515
1532
None => { /* not live: good */ }
1516
1533
Some ( lnk) => {
@@ -1528,8 +1545,8 @@ fn check_local(local: @local, &&self: @Liveness, vt: vt<@Liveness>) {
1528
1545
}
1529
1546
1530
1547
fn check_arm( arm: & arm, &&self : @Liveness , vt: vt<@Liveness >) {
1531
- do self . arm_pats_bindings( arm. pats) |ln, var, sp| {
1532
- self . warn_about_unused( sp, ln, var) ;
1548
+ do self . arm_pats_bindings( arm. pats) |ln, var, sp, id | {
1549
+ self . warn_about_unused( sp, id , ln, var) ;
1533
1550
}
1534
1551
visit:: visit_arm( arm, self , vt) ;
1535
1552
}
@@ -1691,14 +1708,14 @@ pub impl Liveness {
1691
1708
let ln = self . live_node ( expr. id , expr. span ) ;
1692
1709
let var = self . variable ( nid, expr. span ) ;
1693
1710
self . check_for_reassignment ( ln, var, expr. span ) ;
1694
- self . warn_about_dead_assign ( expr. span , ln, var) ;
1711
+ self . warn_about_dead_assign ( expr. span , expr . id , ln, var) ;
1695
1712
}
1696
1713
def => {
1697
1714
match relevant_def ( def) {
1698
1715
Some ( nid) => {
1699
1716
let ln = self . live_node ( expr. id , expr. span ) ;
1700
1717
let var = self . variable ( nid, expr. span ) ;
1701
- self . warn_about_dead_assign ( expr. span , ln, var) ;
1718
+ self . warn_about_dead_assign ( expr. span , expr . id , ln, var) ;
1702
1719
}
1703
1720
None => { }
1704
1721
}
@@ -1715,7 +1732,7 @@ pub impl Liveness {
1715
1732
}
1716
1733
1717
1734
fn check_for_reassignments_in_pat ( @self , pat : @pat) {
1718
- do self. pat_bindings ( pat ) |ln , var , sp| {
1735
+ do self. pat_bindings ( pat ) |ln , var , sp , _id | {
1719
1736
self . check_for_reassignment( ln, var, sp) ;
1720
1737
}
1721
1738
}
@@ -1861,21 +1878,21 @@ pub impl Liveness {
1861
1878
do pat_util:: pat_bindings( self . tcx. def_map, arg. pat)
1862
1879
|_bm, p_id, sp, _n| {
1863
1880
let var = self . variable ( p_id, sp) ;
1864
- self . warn_about_unused ( sp, entry_ln, var) ;
1881
+ self . warn_about_unused ( sp, p_id , entry_ln, var) ;
1865
1882
}
1866
1883
}
1867
1884
}
1868
1885
1869
1886
fn warn_about_unused_or_dead_vars_in_pat ( @self , pat : @pat) {
1870
- do self. pat_bindings ( pat ) |ln , var , sp| {
1871
- if !self . warn_about_unused( sp, ln, var) {
1872
- self . warn_about_dead_assign( sp, ln, var) ;
1887
+ do self. pat_bindings ( pat ) |ln , var , sp , id | {
1888
+ if !self . warn_about_unused( sp, id , ln, var) {
1889
+ self . warn_about_dead_assign( sp, id , ln, var) ;
1873
1890
}
1874
1891
}
1875
1892
}
1876
1893
1877
- fn warn_about_unused( @self , sp : span , ln : LiveNode , var : Variable )
1878
- -> bool {
1894
+ fn warn_about_unused( @self , sp : span , id : node_id ,
1895
+ ln : LiveNode , var : Variable ) -> bool {
1879
1896
if !self . used_on_entry ( ln, var) {
1880
1897
for self . should_warn( var) . each |name| {
1881
1898
@@ -1889,27 +1906,27 @@ pub impl Liveness {
1889
1906
} ;
1890
1907
1891
1908
if is_assigned {
1892
- // FIXME(#3266)--make liveness warnings lintable
1893
- self . tcx . sess . span_warn (
1894
- sp , fmt ! ( "variable `%s` is assigned to, \
1909
+ self . tcx . sess . span_lint ( unused_variable , id ,
1910
+ self . ir . cur_item , sp ,
1911
+ fmt ! ( "variable `%s` is assigned to, \
1895
1912
but never used", * * name) ) ;
1896
1913
} else {
1897
- // FIXME(#3266)--make liveness warnings lintable
1898
- self . tcx . sess . span_warn (
1899
- sp , fmt ! ( "unused variable: `%s`" , * * name) ) ;
1914
+ self . tcx . sess . span_lint ( unused_variable , id ,
1915
+ self . ir . cur_item , sp ,
1916
+ fmt ! ( "unused variable: `%s`" , * * name) ) ;
1900
1917
}
1901
1918
}
1902
1919
return true ;
1903
1920
}
1904
1921
return false ;
1905
1922
}
1906
1923
1907
- fn warn_about_dead_assign ( @self , sp : span , ln : LiveNode , var : Variable ) {
1924
+ fn warn_about_dead_assign ( @self , sp : span , id : node_id ,
1925
+ ln : LiveNode , var : Variable ) {
1908
1926
if self . live_on_exit ( ln, var) . is_none ( ) {
1909
1927
for self . should_warn( var) . each |name| {
1910
- // FIXME(#3266)--make liveness warnings lintable
1911
- self . tcx . sess . span_warn (
1912
- sp,
1928
+ self . tcx . sess . span_lint ( dead_assignment, id,
1929
+ self . ir . cur_item , sp,
1913
1930
fmt ! ( "value assigned to `%s` is never read" , * * name) ) ;
1914
1931
}
1915
1932
}
0 commit comments