@@ -4304,7 +4304,52 @@ impl MutVisitor for CondChecker<'_> {
43044304 mut_visit:: walk_expr ( self , e) ;
43054305 self . forbid_let_reason = forbid_let_reason;
43064306 }
4307- ExprKind :: Assign ( ref lhs, _, span) => {
4307+ ExprKind :: Assign ( ref lhs, ref rhs, span) => {
4308+ if let ExprKind :: Call ( _, _) = & lhs. kind {
4309+ fn get_path_from_rhs ( e : & Expr ) -> Option < ( u32 , & Path ) > {
4310+ fn inner ( e : & Expr , depth : u32 ) -> Option < ( u32 , & Path ) > {
4311+ match & e. kind {
4312+ ExprKind :: Binary ( _, lhs, _) => inner ( lhs, depth + 1 ) ,
4313+ ExprKind :: Path ( _, path) => Some ( ( depth, path) ) ,
4314+ _ => None ,
4315+ }
4316+ }
4317+
4318+ inner ( e, 0 )
4319+ }
4320+
4321+ if let Some ( ( depth, path) ) = get_path_from_rhs ( rhs) {
4322+ // For cases like if Some(_) = x && let Some(_) = y && let Some(_) = z
4323+ // This return let Some(_) = y expression
4324+ fn find_let_some ( expr : & Expr ) -> Option < & Expr > {
4325+ match & expr. kind {
4326+ ExprKind :: Let ( ..) => Some ( expr) ,
4327+
4328+ ExprKind :: Binary ( op, lhs, rhs) if op. node == BinOpKind :: And => {
4329+ find_let_some ( lhs) . or_else ( || find_let_some ( rhs) )
4330+ }
4331+
4332+ _ => None ,
4333+ }
4334+ }
4335+
4336+ let expr_span = lhs. span . to ( path. span ) ;
4337+
4338+ if let Some ( later_rhs) = find_let_some ( rhs)
4339+ && depth > 0
4340+ {
4341+ let guar = self . parser . dcx ( ) . emit_err ( errors:: LetChainMissingLet {
4342+ span : lhs. span ,
4343+ label_span : expr_span,
4344+ rhs_span : later_rhs. span ,
4345+ sug_span : lhs. span . shrink_to_lo ( ) ,
4346+ } ) ;
4347+
4348+ self . found_incorrect_let_chain = Some ( guar) ;
4349+ }
4350+ }
4351+ }
4352+
43084353 let forbid_let_reason = self . forbid_let_reason ;
43094354 self . forbid_let_reason = Some ( OtherForbidden ) ;
43104355 let missing_let = self . missing_let ;
0 commit comments