@@ -63,9 +63,9 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE};
6363use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
6464use rustc_hir:: LangItem :: { ResultErr , ResultOk } ;
6565use rustc_hir:: {
66- def, Arm , BindingAnnotation , Block , Body , Constness , Expr , ExprKind , FnDecl , GenericArgs , HirId , Impl , ImplItem ,
67- ImplItemKind , Item , ItemKind , LangItem , MatchSource , Node , Param , Pat , PatKind , Path , PathSegment , QPath ,
68- TraitItem , TraitItemKind , TraitRef , TyKind ,
66+ def, Arm , BindingAnnotation , Block , Body , Constness , Destination , Expr , ExprKind , FnDecl , GenericArgs , HirId , Impl ,
67+ ImplItem , ImplItemKind , Item , ItemKind , LangItem , MatchSource , Node , Param , Pat , PatKind , Path , PathSegment , QPath ,
68+ Stmt , StmtKind , TraitItem , TraitItemKind , TraitRef , TyKind ,
6969} ;
7070use rustc_lint:: { LateContext , Level , Lint , LintContext } ;
7171use rustc_middle:: hir:: exports:: Export ;
@@ -1245,6 +1245,82 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
12451245 did. map_or ( false , |did| must_use_attr ( & cx. tcx . get_attrs ( did) ) . is_some ( ) )
12461246}
12471247
1248+ pub fn get_expr_use_node ( tcx : TyCtxt < ' tcx > , expr : & Expr < ' _ > ) -> Option < Node < ' tcx > > {
1249+ let map = tcx. hir ( ) ;
1250+ let mut child_id = expr. hir_id ;
1251+ let mut iter = map. parent_iter ( child_id) ;
1252+ loop {
1253+ match iter. next ( ) {
1254+ None => break None ,
1255+ Some ( ( id, Node :: Block ( _) ) ) => child_id = id,
1256+ Some ( ( id, Node :: Arm ( arm) ) ) if arm. body . hir_id == child_id => child_id = id,
1257+ Some ( ( _, Node :: Expr ( expr) ) ) => match expr. kind {
1258+ ExprKind :: Break (
1259+ Destination {
1260+ target_id : Ok ( dest) , ..
1261+ } ,
1262+ _,
1263+ ) => {
1264+ iter = map. parent_iter ( dest) ;
1265+ child_id = dest;
1266+ } ,
1267+ ExprKind :: DropTemps ( _) | ExprKind :: Block ( ..) => child_id = expr. hir_id ,
1268+ ExprKind :: If ( control_expr, ..) | ExprKind :: Match ( control_expr, ..)
1269+ if control_expr. hir_id != child_id =>
1270+ {
1271+ child_id = expr. hir_id
1272+ } ,
1273+ _ => break Some ( Node :: Expr ( expr) ) ,
1274+ } ,
1275+ Some ( ( _, node) ) => break Some ( node) ,
1276+ }
1277+ }
1278+ }
1279+
1280+ pub fn is_expr_used ( tcx : TyCtxt < ' _ > , expr : & Expr < ' _ > ) -> bool {
1281+ !matches ! (
1282+ get_expr_use_node( tcx, expr) ,
1283+ Some ( Node :: Stmt ( Stmt {
1284+ kind: StmtKind :: Expr ( _) | StmtKind :: Semi ( _) ,
1285+ ..
1286+ } ) )
1287+ )
1288+ }
1289+
1290+ pub fn get_expr_use_or_unification_node ( tcx : TyCtxt < ' tcx > , expr : & Expr < ' _ > ) -> Option < Node < ' tcx > > {
1291+ let map = tcx. hir ( ) ;
1292+ let mut child_id = expr. hir_id ;
1293+ let mut iter = map. parent_iter ( child_id) ;
1294+ loop {
1295+ match iter. next ( ) {
1296+ None => break None ,
1297+ Some ( ( id, Node :: Block ( _) ) ) => child_id = id,
1298+ Some ( ( id, Node :: Arm ( arm) ) ) if arm. body . hir_id == child_id => child_id = id,
1299+ Some ( ( _, Node :: Expr ( expr) ) ) => match expr. kind {
1300+ ExprKind :: Match ( _, [ arm] , _) if arm. hir_id == child_id => child_id = expr. hir_id ,
1301+ ExprKind :: Block ( ..) | ExprKind :: DropTemps ( _) => child_id = expr. hir_id ,
1302+ ExprKind :: If ( _, then_expr, None ) if then_expr. hir_id == child_id => break None ,
1303+ _ => break Some ( Node :: Expr ( expr) ) ,
1304+ } ,
1305+ Some ( ( _, node) ) => break Some ( node) ,
1306+ }
1307+ }
1308+ }
1309+
1310+ pub fn is_expr_used_or_unified ( tcx : TyCtxt < ' _ > , expr : & Expr < ' _ > ) -> bool {
1311+ !matches ! (
1312+ get_expr_use_or_unification_node( tcx, expr) ,
1313+ None | Some ( Node :: Stmt ( Stmt {
1314+ kind: StmtKind :: Expr ( _) | StmtKind :: Semi ( _) ,
1315+ ..
1316+ } ) )
1317+ )
1318+ }
1319+
1320+ pub fn is_expr_final_block_expr ( tcx : TyCtxt < ' _ > , expr : & Expr < ' _ > ) -> bool {
1321+ matches ! ( get_parent_node( tcx, expr. hir_id) , Some ( Node :: Block ( ..) ) )
1322+ }
1323+
12481324pub fn is_no_std_crate ( cx : & LateContext < ' _ > ) -> bool {
12491325 cx. tcx . hir ( ) . attrs ( hir:: CRATE_HIR_ID ) . iter ( ) . any ( |attr| {
12501326 if let ast:: AttrKind :: Normal ( ref attr, _) = attr. kind {
@@ -1414,28 +1490,43 @@ pub fn peel_hir_pat_refs(pat: &'a Pat<'a>) -> (&'a Pat<'a>, usize) {
14141490 peel ( pat, 0 )
14151491}
14161492
1493+ /// Peels of expressions while the given closure returns `Some`.
1494+ pub fn peel_hir_expr_while < ' tcx > (
1495+ mut expr : & ' tcx Expr < ' tcx > ,
1496+ mut f : impl FnMut ( & ' tcx Expr < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > ,
1497+ ) -> & ' tcx Expr < ' tcx > {
1498+ while let Some ( e) = f ( expr) {
1499+ expr = e;
1500+ }
1501+ expr
1502+ }
1503+
14171504/// Peels off up to the given number of references on the expression. Returns the underlying
14181505/// expression and the number of references removed.
14191506pub fn peel_n_hir_expr_refs ( expr : & ' a Expr < ' a > , count : usize ) -> ( & ' a Expr < ' a > , usize ) {
1420- fn f ( expr : & ' a Expr < ' a > , count : usize , target : usize ) -> ( & ' a Expr < ' a > , usize ) {
1421- match expr. kind {
1422- ExprKind :: AddrOf ( _, _, expr) if count != target => f ( expr, count + 1 , target) ,
1423- _ => ( expr, count) ,
1424- }
1425- }
1426- f ( expr, 0 , count)
1507+ let mut remaining = count;
1508+ let e = peel_hir_expr_while ( expr, |e| match e. kind {
1509+ ExprKind :: AddrOf ( BorrowKind :: Ref , _, e) if remaining != 0 => {
1510+ remaining -= 1 ;
1511+ Some ( e)
1512+ } ,
1513+ _ => None ,
1514+ } ) ;
1515+ ( e, count - remaining)
14271516}
14281517
14291518/// Peels off all references on the expression. Returns the underlying expression and the number of
14301519/// references removed.
14311520pub fn peel_hir_expr_refs ( expr : & ' a Expr < ' a > ) -> ( & ' a Expr < ' a > , usize ) {
1432- fn f ( expr : & ' a Expr < ' a > , count : usize ) -> ( & ' a Expr < ' a > , usize ) {
1433- match expr. kind {
1434- ExprKind :: AddrOf ( BorrowKind :: Ref , _, expr) => f ( expr, count + 1 ) ,
1435- _ => ( expr, count) ,
1436- }
1437- }
1438- f ( expr, 0 )
1521+ let mut count = 0 ;
1522+ let e = peel_hir_expr_while ( expr, |e| match e. kind {
1523+ ExprKind :: AddrOf ( BorrowKind :: Ref , _, e) => {
1524+ count += 1 ;
1525+ Some ( e)
1526+ } ,
1527+ _ => None ,
1528+ } ) ;
1529+ ( e, count)
14391530}
14401531
14411532#[ macro_export]
0 commit comments