@@ -399,21 +399,31 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
399399 fake_reads : _,
400400 } => {
401401 let closure_id = closure_id. expect_local ( ) ;
402- let closure_def = if let Some ( ( did, const_param_id) ) =
403- ty:: WithOptConstParam :: try_lookup ( closure_id, self . tcx )
404- {
405- ty:: WithOptConstParam { did, const_param_did : Some ( const_param_id) }
406- } else {
407- ty:: WithOptConstParam :: unknown ( closure_id)
408- } ;
409- let ( closure_thir, expr) = self . tcx . thir_body ( closure_def) ;
410- let closure_thir = & closure_thir. borrow ( ) ;
411- let hir_context = self . tcx . hir ( ) . local_def_id_to_hir_id ( closure_id) ;
412- let mut closure_visitor =
413- UnsafetyVisitor { thir : closure_thir, hir_context, ..* self } ;
414- closure_visitor. visit_expr ( & closure_thir[ expr] ) ;
415- // Unsafe blocks can be used in closures, make sure to take it into account
416- self . safety_context = closure_visitor. safety_context ;
402+ let closure_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( closure_id) ;
403+
404+ // Closures in AnonConsts are handled separately to avoid cycles (issue #87414).
405+ if !matches ! (
406+ self . tcx. hir( ) . get( self . tcx. hir( ) . enclosing_body_owner( closure_hir_id) ) ,
407+ hir:: Node :: AnonConst ( _)
408+ ) {
409+ let closure_def = if let Some ( ( did, const_param_id) ) =
410+ ty:: WithOptConstParam :: try_lookup ( closure_id, self . tcx )
411+ {
412+ ty:: WithOptConstParam { did, const_param_did : Some ( const_param_id) }
413+ } else {
414+ ty:: WithOptConstParam :: unknown ( closure_id)
415+ } ;
416+ let ( closure_thir, expr) = self . tcx . thir_body ( closure_def) ;
417+ let closure_thir = & closure_thir. borrow ( ) ;
418+ let mut closure_visitor = UnsafetyVisitor {
419+ thir : closure_thir,
420+ hir_context : closure_hir_id,
421+ ..* self
422+ } ;
423+ closure_visitor. visit_expr ( & closure_thir[ expr] ) ;
424+ // Unsafe blocks can be used in closures, make sure to take it into account
425+ self . safety_context = closure_visitor. safety_context ;
426+ }
417427 }
418428 ExprKind :: Field { lhs, .. } => {
419429 let lhs = & self . thir [ lhs] ;
@@ -597,11 +607,19 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
597607 return ;
598608 }
599609
600- // Closures are handled by their owner, if it has a body
610+ let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ;
611+
612+ // Closures are handled by their owner, if it has a body, except if the
613+ // closure occurs in an AnonConst body to avoid a cycle (issue #87414)
601614 if tcx. is_closure ( def. did . to_def_id ( ) ) {
602- let owner = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) . owner ;
603- let owner_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( owner) ;
615+ let encl_body_owner = tcx. hir ( ) . enclosing_body_owner ( hir_id) ;
616+ if matches ! ( tcx. hir( ) . get( encl_body_owner) , hir:: Node :: AnonConst ( _) ) {
617+ tcx. ensure ( ) . thir_check_unsafety ( tcx. hir ( ) . local_def_id ( encl_body_owner) ) ;
618+ return ;
619+ }
604620
621+ let owner = hir_id. owner ;
622+ let owner_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( owner) ;
605623 if tcx. hir ( ) . maybe_body_owned_by ( owner_hir_id) . is_some ( ) {
606624 tcx. ensure ( ) . thir_check_unsafety ( owner) ;
607625 return ;
@@ -615,7 +633,6 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
615633 return ;
616634 }
617635
618- let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def. did ) ;
619636 let body_unsafety = tcx. hir ( ) . fn_sig_by_hir_id ( hir_id) . map_or ( BodyUnsafety :: Safe , |fn_sig| {
620637 if fn_sig. header . unsafety == hir:: Unsafety :: Unsafe {
621638 BodyUnsafety :: Unsafe ( fn_sig. span )
0 commit comments