@@ -6,7 +6,7 @@ use rustc_errors::codes::*;
66use rustc_errors:: { Applicability , ErrorGuaranteed , MultiSpan , struct_span_code_err} ;
77use rustc_hir:: def:: * ;
88use rustc_hir:: def_id:: LocalDefId ;
9- use rustc_hir:: { self as hir, BindingMode , ByRef , HirId , MatchSource } ;
9+ use rustc_hir:: { self as hir, BindingMode , ByRef , HirId , LocalSource , MatchSource , Node } ;
1010use rustc_infer:: infer:: TyCtxtInferExt ;
1111use rustc_lint:: Level ;
1212use rustc_middle:: bug;
@@ -715,6 +715,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
715715 && self . tcx . sess . source_map ( ) . is_span_accessible ( span)
716716 && interpreted_as_const. is_none ( )
717717 && scrut. is_some ( )
718+ // we only suggest `let` when the pattern is not desugared from an assignment
719+ && !self . is_pat_from_assign_desugar ( pat)
718720 {
719721 let mut bindings = vec ! [ ] ;
720722 pat. each_binding ( |name, _, _, _| bindings. push ( name) ) ;
@@ -768,6 +770,32 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
768770 adt_defined_here,
769771 } ) ) ;
770772 }
773+
774+ /// Check if `pat` is desugared into a `let`, i.e., `LocalSource::AssignDesugar`
775+ /// rather than a real `let` the user wrote.
776+ /// This helps suppress suggestions for `let` statements when
777+ /// we're dealing with an assignment like `Some(x) = rhs`.
778+ fn is_pat_from_assign_desugar ( & self , pat : & Pat < ' tcx > ) -> bool {
779+ // Find a binding in the pattern
780+ let mut binding: Option < LocalVarId > = None ;
781+ pat. walk ( |p| {
782+ if let PatKind :: Binding { var, .. } = p. kind {
783+ binding = Some ( var) ;
784+ return false ;
785+ }
786+ true
787+ } ) ;
788+
789+ // Walk up the HIR parents to the enclosing `LetStmt`, then check its `source`.
790+ if let Some ( var) = binding {
791+ for ( _, node) in self . tcx . hir_parent_iter ( var. 0 ) {
792+ if let Node :: LetStmt ( let_stmt) = node {
793+ return matches ! ( let_stmt. source, LocalSource :: AssignDesugar ( _) ) ;
794+ }
795+ }
796+ }
797+ false
798+ }
771799}
772800
773801/// Check if a by-value binding is by-value. That is, check if the binding's type is not `Copy`.
0 commit comments