1
1
mod for_loop_arg;
2
2
mod for_loop_over_map_kv;
3
+ mod for_mut_range_bound;
3
4
mod manual_flatten;
4
5
mod utils;
5
6
@@ -24,7 +25,6 @@ use rustc_hir::{
24
25
def_id, BinOpKind , BindingAnnotation , Block , BorrowKind , Expr , ExprKind , GenericArg , HirId , InlineAsmOperand ,
25
26
Local , LoopSource , MatchSource , Mutability , Node , Pat , PatKind , QPath , Stmt , StmtKind ,
26
27
} ;
27
- use rustc_infer:: infer:: TyCtxtInferExt ;
28
28
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
29
29
use rustc_middle:: hir:: map:: Map ;
30
30
use rustc_middle:: lint:: in_external_macro;
@@ -33,7 +33,6 @@ use rustc_middle::ty::{self, Ty};
33
33
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
34
34
use rustc_span:: source_map:: Span ;
35
35
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
36
- use rustc_typeck:: expr_use_visitor:: { ConsumeMode , Delegate , ExprUseVisitor , PlaceBase , PlaceWithHirId } ;
37
36
use std:: iter:: { once, Iterator } ;
38
37
use std:: mem;
39
38
use utils:: make_iterator_snippet;
@@ -865,7 +864,7 @@ fn check_for_loop<'tcx>(
865
864
}
866
865
for_loop_arg:: check_for_loop_arg ( cx, pat, arg, expr) ;
867
866
for_loop_over_map_kv:: check_for_loop_over_map_kv ( cx, pat, arg, body, expr) ;
868
- check_for_mut_range_bound ( cx, arg, body) ;
867
+ for_mut_range_bound :: check_for_mut_range_bound ( cx, arg, body) ;
869
868
check_for_single_element_loop ( cx, pat, arg, body, expr) ;
870
869
detect_same_item_push ( cx, pat, arg, body, expr) ;
871
870
manual_flatten:: check_manual_flatten ( cx, pat, arg, body, span) ;
@@ -1769,112 +1768,6 @@ fn check_for_single_element_loop<'tcx>(
1769
1768
}
1770
1769
}
1771
1770
1772
- struct MutatePairDelegate < ' a , ' tcx > {
1773
- cx : & ' a LateContext < ' tcx > ,
1774
- hir_id_low : Option < HirId > ,
1775
- hir_id_high : Option < HirId > ,
1776
- span_low : Option < Span > ,
1777
- span_high : Option < Span > ,
1778
- }
1779
-
1780
- impl < ' tcx > Delegate < ' tcx > for MutatePairDelegate < ' _ , ' tcx > {
1781
- fn consume ( & mut self , _: & PlaceWithHirId < ' tcx > , _: HirId , _: ConsumeMode ) { }
1782
-
1783
- fn borrow ( & mut self , cmt : & PlaceWithHirId < ' tcx > , diag_expr_id : HirId , bk : ty:: BorrowKind ) {
1784
- if let ty:: BorrowKind :: MutBorrow = bk {
1785
- if let PlaceBase :: Local ( id) = cmt. place . base {
1786
- if Some ( id) == self . hir_id_low {
1787
- self . span_low = Some ( self . cx . tcx . hir ( ) . span ( diag_expr_id) )
1788
- }
1789
- if Some ( id) == self . hir_id_high {
1790
- self . span_high = Some ( self . cx . tcx . hir ( ) . span ( diag_expr_id) )
1791
- }
1792
- }
1793
- }
1794
- }
1795
-
1796
- fn mutate ( & mut self , cmt : & PlaceWithHirId < ' tcx > , diag_expr_id : HirId ) {
1797
- if let PlaceBase :: Local ( id) = cmt. place . base {
1798
- if Some ( id) == self . hir_id_low {
1799
- self . span_low = Some ( self . cx . tcx . hir ( ) . span ( diag_expr_id) )
1800
- }
1801
- if Some ( id) == self . hir_id_high {
1802
- self . span_high = Some ( self . cx . tcx . hir ( ) . span ( diag_expr_id) )
1803
- }
1804
- }
1805
- }
1806
- }
1807
-
1808
- impl MutatePairDelegate < ' _ , ' _ > {
1809
- fn mutation_span ( & self ) -> ( Option < Span > , Option < Span > ) {
1810
- ( self . span_low , self . span_high )
1811
- }
1812
- }
1813
-
1814
- fn check_for_mut_range_bound ( cx : & LateContext < ' _ > , arg : & Expr < ' _ > , body : & Expr < ' _ > ) {
1815
- if let Some ( higher:: Range {
1816
- start : Some ( start) ,
1817
- end : Some ( end) ,
1818
- ..
1819
- } ) = higher:: range ( arg)
1820
- {
1821
- let mut_ids = vec ! [ check_for_mutability( cx, start) , check_for_mutability( cx, end) ] ;
1822
- if mut_ids[ 0 ] . is_some ( ) || mut_ids[ 1 ] . is_some ( ) {
1823
- let ( span_low, span_high) = check_for_mutation ( cx, body, & mut_ids) ;
1824
- mut_warn_with_span ( cx, span_low) ;
1825
- mut_warn_with_span ( cx, span_high) ;
1826
- }
1827
- }
1828
- }
1829
-
1830
- fn mut_warn_with_span ( cx : & LateContext < ' _ > , span : Option < Span > ) {
1831
- if let Some ( sp) = span {
1832
- span_lint (
1833
- cx,
1834
- MUT_RANGE_BOUND ,
1835
- sp,
1836
- "attempt to mutate range bound within loop; note that the range of the loop is unchanged" ,
1837
- ) ;
1838
- }
1839
- }
1840
-
1841
- fn check_for_mutability ( cx : & LateContext < ' _ > , bound : & Expr < ' _ > ) -> Option < HirId > {
1842
- if_chain ! {
1843
- if let Some ( hir_id) = path_to_local( bound) ;
1844
- if let Node :: Binding ( pat) = cx. tcx. hir( ) . get( hir_id) ;
1845
- if let PatKind :: Binding ( BindingAnnotation :: Mutable , ..) = pat. kind;
1846
- then {
1847
- return Some ( hir_id) ;
1848
- }
1849
- }
1850
- None
1851
- }
1852
-
1853
- fn check_for_mutation < ' tcx > (
1854
- cx : & LateContext < ' tcx > ,
1855
- body : & Expr < ' _ > ,
1856
- bound_ids : & [ Option < HirId > ] ,
1857
- ) -> ( Option < Span > , Option < Span > ) {
1858
- let mut delegate = MutatePairDelegate {
1859
- cx,
1860
- hir_id_low : bound_ids[ 0 ] ,
1861
- hir_id_high : bound_ids[ 1 ] ,
1862
- span_low : None ,
1863
- span_high : None ,
1864
- } ;
1865
- cx. tcx . infer_ctxt ( ) . enter ( |infcx| {
1866
- ExprUseVisitor :: new (
1867
- & mut delegate,
1868
- & infcx,
1869
- body. hir_id . owner ,
1870
- cx. param_env ,
1871
- cx. typeck_results ( ) ,
1872
- )
1873
- . walk_expr ( body) ;
1874
- } ) ;
1875
- delegate. mutation_span ( )
1876
- }
1877
-
1878
1771
struct VarVisitor < ' a , ' tcx > {
1879
1772
/// context reference
1880
1773
cx : & ' a LateContext < ' tcx > ,
0 commit comments