@@ -8,10 +8,10 @@ pub use self::ConsumeMode::*;
88pub use rustc_middle:: hir:: place:: { Place , PlaceBase , PlaceWithHirId , Projection } ;
99
1010use rustc_hir as hir;
11- use rustc_hir:: def:: { DefKind , Res } ;
11+ use rustc_hir:: def:: Res ;
1212use rustc_hir:: def_id:: LocalDefId ;
1313use rustc_hir:: PatKind ;
14- use rustc_hir:: QPath ;
14+ // use rustc_hir::QPath;
1515use rustc_index:: vec:: Idx ;
1616use rustc_infer:: infer:: InferCtxt ;
1717use rustc_middle:: hir:: place:: ProjectionKind ;
@@ -54,7 +54,6 @@ pub trait Delegate<'tcx> {
5454 // `diag_expr_id` is the id used for diagnostics (see `consume` for more details).
5555 fn mutate ( & mut self , assignee_place : & PlaceWithHirId < ' tcx > , diag_expr_id : hir:: HirId ) ;
5656
57- // [FIXME] RFC2229 This should also affect clippy ref: https://github.com/sexxi-goose/rust/pull/27
5857 fn fake_read ( & mut self , place : Place < ' tcx > , cause : FakeReadCause ) ;
5958}
6059
@@ -235,24 +234,30 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
235234 hir:: ExprKind :: Match ( ref discr, arms, _) => {
236235 let discr_place = return_if_err ! ( self . mc. cat_expr( & discr) ) ;
237236
237+ // Matching should not always be considered a use of the place, hence
238+ // discr does not necessarily need to be borrowed.
238239 // We only want to borrow discr if the pattern contain something other
239- // than wildcards
240+ // than wildcards.
240241 let ExprUseVisitor { ref mc, body_owner : _, delegate : _ } = * self ;
241242 let mut needs_to_be_read = false ;
242243 for arm in arms. iter ( ) {
243244 return_if_err ! ( mc. cat_pattern( discr_place. clone( ) , & arm. pat, |_place, pat| {
244- if let PatKind :: Binding ( _, _, _, opt_sub_pat) = pat. kind {
245- if let None = opt_sub_pat {
246- needs_to_be_read = true ;
247- }
248- } else if let PatKind :: TupleStruct ( qpath, _, _) = & pat. kind {
249- // If a TupleStruct has a Some PathSegment, we should read the discr_place
250- // regardless if it contains a Wild pattern later
251- if let QPath :: Resolved ( _, path) = qpath {
252- if let Res :: Def ( DefKind :: Ctor ( _, _) , _) = path. res {
245+ match & pat. kind {
246+ PatKind :: Binding ( _, _, _, opt_sub_pat) => {
247+ // If the opt_sub_pat is None, than the binding does not count as
248+ // a wildcard for the purpose of borrowing discr
249+ if let None = opt_sub_pat {
253250 needs_to_be_read = true ;
254251 }
255252 }
253+ PatKind :: TupleStruct ( _, _, _)
254+ | PatKind :: Struct ( _, _, _)
255+ | PatKind :: Lit ( _) => {
256+ // If the PatKind is a TupleStruct, Struct, or Lit then we want
257+ // to borrow discr
258+ needs_to_be_read = true ;
259+ }
260+ _ => { }
256261 }
257262 } ) ) ;
258263 }
@@ -629,6 +634,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
629634 /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing
630635 /// closure as the DefId.
631636 fn walk_captures ( & mut self , closure_expr : & hir:: Expr < ' _ > ) {
637+ debug ! ( "walk_captures({:?})" , closure_expr) ;
638+
632639 let closure_def_id = self . tcx ( ) . hir ( ) . local_def_id ( closure_expr. hir_id ) . to_def_id ( ) ;
633640 let upvars = self . tcx ( ) . upvars_mentioned ( self . body_owner ) ;
634641
@@ -645,10 +652,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
645652 if upvars. map_or ( body_owner_is_closure, |upvars| {
646653 !upvars. contains_key ( & upvar_id. var_path . hir_id )
647654 } ) {
648- // [FIXME] RFC2229 Update this comment
649- // The nested closure might be capturing the current (enclosing) closure's local variables.
655+ // The nested closure might be fake reading the current (enclosing) closure's local variables.
650656 // We check if the root variable is ever mentioned within the enclosing closure, if not
651- // then for the current body (if it's a closure) these aren't captures , we will ignore them.
657+ // then for the current body (if it's a closure) these do not require fake_read , we will ignore them.
652658 continue ;
653659 }
654660 }
0 commit comments