@@ -246,6 +246,8 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
246246 ( None , kind) => {
247247 let expr_ty = typeck. expr_ty ( expr) ;
248248 let ( position, parent_ctxt) = get_expr_position ( cx, expr) ;
249+ let ( stability, adjustments) = walk_parents ( cx, expr) ;
250+
249251 match kind {
250252 RefOp :: Deref => {
251253 if let Position :: FieldAccess ( name) = position
@@ -255,6 +257,11 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
255257 State :: ExplicitDerefField { name } ,
256258 StateData { span : expr. span , hir_id : expr. hir_id } ,
257259 ) ) ;
260+ } else if stability. is_deref_stable ( ) {
261+ self . state = Some ( (
262+ State :: ExplicitDeref { deref_span : expr. span , deref_hir_id : expr. hir_id } ,
263+ StateData { span : expr. span , hir_id : expr. hir_id } ,
264+ ) ) ;
258265 }
259266 }
260267 RefOp :: Method ( target_mut)
@@ -278,7 +285,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
278285 ) ) ;
279286 } ,
280287 RefOp :: AddrOf => {
281- let ( stability, adjustments) = walk_parents ( cx, expr) ;
282288 // Find the number of times the borrow is auto-derefed.
283289 let mut iter = adjustments. iter ( ) ;
284290 let mut deref_count = 0usize ;
@@ -632,6 +638,7 @@ impl AutoDerefStability {
632638/// Walks up the parent expressions attempting to determine both how stable the auto-deref result
633639/// is, and which adjustments will be applied to it. Note this will not consider auto-borrow
634640/// locations as those follow different rules.
641+ #[ allow( clippy:: too_many_lines) ]
635642fn walk_parents < ' tcx > ( cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' _ > ) -> ( AutoDerefStability , & ' tcx [ Adjustment < ' tcx > ] ) {
636643 let mut adjustments = [ ] . as_slice ( ) ;
637644 let stability = walk_to_expr_usage ( cx, e, & mut |node, child_id| {
@@ -643,16 +650,26 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (AutoDerefSt
643650 Node :: Local ( Local { ty : Some ( ty) , .. } ) => Some ( binding_ty_auto_deref_stability ( ty) ) ,
644651 Node :: Item ( & Item {
645652 kind : ItemKind :: Static ( ..) | ItemKind :: Const ( ..) ,
653+ def_id,
646654 ..
647655 } )
648656 | Node :: TraitItem ( & TraitItem {
649657 kind : TraitItemKind :: Const ( ..) ,
658+ def_id,
650659 ..
651660 } )
652661 | Node :: ImplItem ( & ImplItem {
653662 kind : ImplItemKind :: Const ( ..) ,
663+ def_id,
654664 ..
655- } ) => Some ( AutoDerefStability :: Deref ) ,
665+ } ) => {
666+ let ty = cx. tcx . type_of ( def_id) ;
667+ Some ( if ty. is_ref ( ) {
668+ AutoDerefStability :: None
669+ } else {
670+ AutoDerefStability :: Deref
671+ } )
672+ } ,
656673
657674 Node :: Item ( & Item {
658675 kind : ItemKind :: Fn ( ..) ,
@@ -670,7 +687,9 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (AutoDerefSt
670687 ..
671688 } ) => {
672689 let output = cx. tcx . fn_sig ( def_id. to_def_id ( ) ) . skip_binder ( ) . output ( ) ;
673- Some ( if output. has_placeholders ( ) || output. has_opaque_types ( ) {
690+ Some ( if !output. is_ref ( ) {
691+ AutoDerefStability :: None
692+ } else if output. has_placeholders ( ) || output. has_opaque_types ( ) {
674693 AutoDerefStability :: Reborrow
675694 } else {
676695 AutoDerefStability :: Deref
@@ -684,7 +703,9 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (AutoDerefSt
684703 . fn_sig ( cx. tcx . hir ( ) . body_owner_def_id ( cx. enclosing_body . unwrap ( ) ) )
685704 . skip_binder ( )
686705 . output ( ) ;
687- Some ( if output. has_placeholders ( ) || output. has_opaque_types ( ) {
706+ Some ( if !output. is_ref ( ) {
707+ AutoDerefStability :: None
708+ } else if output. has_placeholders ( ) || output. has_opaque_types ( ) {
688709 AutoDerefStability :: Reborrow
689710 } else {
690711 AutoDerefStability :: Deref
0 commit comments