@@ -22,7 +22,7 @@ use rustc_middle::ty::{
2222 UpvarArgs ,
2323} ;
2424use rustc_middle:: { bug, span_bug} ;
25- use rustc_span:: Span ;
25+ use rustc_span:: { DesugaringKind , Span } ;
2626use tracing:: { debug, info, instrument, trace} ;
2727
2828use crate :: diagnostics:: * ;
@@ -72,18 +72,24 @@ impl<'tcx> ThirBuildCx<'tcx> {
7272
7373 let mut attrs = ThinVec :: new ( ) ;
7474
75- if let ExprKind :: Loop { .. } = expr. kind {
76- // For loops defined with loop and while, the expr already has the attrs
77- if let hir:: Node :: Block ( _) = self . tcx . parent_hir_node ( hir_expr. hir_id ) {
78- attrs = parsed_attrs ( hir_expr. hir_id , self . tcx ) ;
79- }
80-
81- // For loop desugaring puts us pretty deep down the HIR tree
82- if let hir:: Node :: Arm ( arm) = self . tcx . parent_hir_node ( hir_expr. hir_id )
83- && let hir:: Node :: Expr ( expr) = self . tcx . parent_hir_node ( arm. hir_id )
84- && let hir:: Node :: Expr ( expr) = self . tcx . parent_hir_node ( expr. hir_id )
85- {
86- attrs = parsed_attrs ( expr. hir_id , self . tcx ) ;
75+ if let hir:: ExprKind :: Loop ( _, _, _, span) = hir_expr. kind {
76+ match span. desugaring_kind ( ) {
77+ // `for` loop desugaring puts us pretty deep down the HIR tree
78+ Some ( DesugaringKind :: ForLoop ) => {
79+ let arm = self . tcx . parent_hir_node ( hir_expr. hir_id ) . expect_arm ( ) ;
80+ let expr = self . tcx . parent_hir_node ( arm. hir_id ) . expect_expr ( ) ;
81+ std:: assert_matches!( expr. kind, hir:: ExprKind :: Match ( ..) ) ;
82+ // ignore async for loops
83+ if let hir:: Node :: Expr ( expr) = self . tcx . parent_hir_node ( expr. hir_id ) {
84+ std:: assert_matches!( expr. kind, hir:: ExprKind :: DropTemps ( ..) ) ;
85+ attrs = parsed_attrs ( expr. hir_id , self . tcx )
86+ }
87+ }
88+ // For loops defined with `loop` and `while`, the expr already has the attrs
89+ Some ( DesugaringKind :: WhileLoop ) | None => {
90+ attrs = parsed_attrs ( hir_expr. hir_id , self . tcx ) ;
91+ }
92+ _ => ( ) ,
8793 }
8894 }
8995
0 commit comments