@@ -126,12 +126,13 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
126126 self . fcx , 
127127 ty, 
128128 hir_id, 
129-  expr, 
130-  source_span, 
131-  yield_data. span , 
132-  "" , 
133-  "" , 
134-  1 , 
129+  SuspendCheckData  { 
130+  expr, 
131+  source_span, 
132+  yield_span :  yield_data. span , 
133+  plural_len :  1 , 
134+  ..Default :: default ( ) 
135+  } , 
135136 ) ; 
136137
137138 self . types . insert ( ty:: GeneratorInteriorTypeCause  { 
@@ -448,56 +449,43 @@ impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> {
448449 } 
449450} 
450451
452+ #[ derive( Default ) ]  
453+ pub  struct  SuspendCheckData < ' a ,  ' tcx >  { 
454+  expr :  Option < & ' tcx  Expr < ' tcx > > , 
455+  source_span :  Span , 
456+  yield_span :  Span , 
457+  descr_pre :  & ' a  str , 
458+  descr_post :  & ' a  str , 
459+  plural_len :  usize , 
460+ } 
461+ 
451462// Returns whether it emitted a diagnostic or not 
452463// Note that this fn and the proceding one are based on the code 
453464// for creating must_use diagnostics 
454465pub  fn  check_must_not_suspend_ty < ' tcx > ( 
455466 fcx :  & FnCtxt < ' _ ,  ' tcx > , 
456467 ty :  Ty < ' tcx > , 
457468 hir_id :  HirId , 
458-  expr :  Option < & ' tcx  Expr < ' tcx > > , 
459-  source_span :  Span , 
460-  yield_span :  Span , 
461-  descr_pre :  & str , 
462-  descr_post :  & str , 
463-  plural_len :  usize , 
469+  data :  SuspendCheckData < ' _ ,  ' tcx > , 
464470)  -> bool  { 
465471 if  ty. is_unit ( ) 
466472 // FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage 
467473 // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in 
468474 // `must_use` 
469475 // || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env) 
470476 { 
471-  return  true ; 
477+  return  false ; 
472478 } 
473479
474-  let  plural_suffix = pluralize ! ( plural_len) ; 
480+  let  plural_suffix = pluralize ! ( data . plural_len) ; 
475481
476482 match  * ty. kind ( )  { 
477483 ty:: Adt ( ..)  if  ty. is_box ( )  => { 
478484 let  boxed_ty = ty. boxed_ty ( ) ; 
479-  let  descr_pre = & format ! ( "{}boxed " ,  descr_pre) ; 
480-  check_must_not_suspend_ty ( 
481-  fcx, 
482-  boxed_ty, 
483-  hir_id, 
484-  expr, 
485-  source_span, 
486-  yield_span, 
487-  descr_pre, 
488-  descr_post, 
489-  plural_len, 
490-  ) 
485+  let  descr_pre = & format ! ( "{}boxed " ,  data. descr_pre) ; 
486+  check_must_not_suspend_ty ( fcx,  boxed_ty,  hir_id,  SuspendCheckData  {  descr_pre,  ..data } ) 
491487 } 
492-  ty:: Adt ( def,  _)  => check_must_not_suspend_def ( 
493-  fcx. tcx , 
494-  def. did , 
495-  hir_id, 
496-  source_span, 
497-  yield_span, 
498-  descr_pre, 
499-  descr_post, 
500-  ) , 
488+  ty:: Adt ( def,  _)  => check_must_not_suspend_def ( fcx. tcx ,  def. did ,  hir_id,  data) , 
501489 // FIXME: support adding the attribute to TAITs 
502490 ty:: Opaque ( def,  _)  => { 
503491 let  mut  has_emitted = false ; 
@@ -507,15 +495,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
507495 predicate. kind ( ) . skip_binder ( ) 
508496 { 
509497 let  def_id = poly_trait_predicate. trait_ref . def_id ; 
510-  let  descr_pre = & format ! ( "{}implementer{} of " ,  descr_pre,  plural_suffix, ) ; 
498+  let  descr_pre = & format ! ( "{}implementer{} of " ,  data . descr_pre,  plural_suffix) ; 
511499 if  check_must_not_suspend_def ( 
512500 fcx. tcx , 
513501 def_id, 
514502 hir_id, 
515-  source_span, 
516-  yield_span, 
517-  descr_pre, 
518-  descr_post, 
503+  SuspendCheckData  {  descr_pre,  ..data } , 
519504 )  { 
520505 has_emitted = true ; 
521506 break ; 
@@ -529,15 +514,12 @@ pub fn check_must_not_suspend_ty<'tcx>(
529514 for  predicate in  binder. iter ( )  { 
530515 if  let  ty:: ExistentialPredicate :: Trait ( ref  trait_ref)  = predicate. skip_binder ( )  { 
531516 let  def_id = trait_ref. def_id ; 
532-  let  descr_post = & format ! ( " trait object{}{}" ,  plural_suffix,  descr_post, ) ; 
517+  let  descr_post = & format ! ( " trait object{}{}" ,  plural_suffix,  data . descr_post) ; 
533518 if  check_must_not_suspend_def ( 
534519 fcx. tcx , 
535520 def_id, 
536521 hir_id, 
537-  source_span, 
538-  yield_span, 
539-  descr_pre, 
540-  descr_post, 
522+  SuspendCheckData  {  descr_post,  ..data } , 
541523 )  { 
542524 has_emitted = true ; 
543525 break ; 
@@ -548,35 +530,38 @@ pub fn check_must_not_suspend_ty<'tcx>(
548530 } 
549531 ty:: Tuple ( ref  tys)  => { 
550532 let  mut  has_emitted = false ; 
551-  let  spans = if  let  Some ( hir:: ExprKind :: Tup ( comps) )  = expr. map ( |e| & e. kind )  { 
533+  let  spans = if  let  Some ( hir:: ExprKind :: Tup ( comps) )  = data . expr . map ( |e| & e. kind )  { 
552534 debug_assert_eq ! ( comps. len( ) ,  tys. len( ) ) ; 
553535 comps. iter ( ) . map ( |e| e. span ) . collect ( ) 
554536 }  else  { 
555537 vec ! [ ] 
556538 } ; 
557539 for  ( i,  ty)  in  tys. iter ( ) . map ( |k| k. expect_ty ( ) ) . enumerate ( )  { 
558540 let  descr_post = & format ! ( " in tuple element {}" ,  i) ; 
559-  let  span = * spans. get ( i) . unwrap_or ( & source_span) ; 
541+  let  span = * spans. get ( i) . unwrap_or ( & data . source_span ) ; 
560542 if  check_must_not_suspend_ty ( 
561-  fcx,  ty,  hir_id,  expr,  span,  yield_span,  descr_pre,  descr_post,  plural_len, 
543+  fcx, 
544+  ty, 
545+  hir_id, 
546+  SuspendCheckData  {  descr_post,  source_span :  span,  ..data } , 
562547 )  { 
563548 has_emitted = true ; 
564549 } 
565550 } 
566551 has_emitted
567552 } 
568553 ty:: Array ( ty,  len)  => { 
569-  let  descr_pre = & format ! ( "{}array{} of " ,  descr_pre,  plural_suffix, ) ; 
554+  let  descr_pre = & format ! ( "{}array{} of " ,  data . descr_pre,  plural_suffix) ; 
570555 check_must_not_suspend_ty ( 
571556 fcx, 
572557 ty, 
573558 hir_id, 
574-  expr , 
575-  source_span , 
576-  yield_span , 
577-  descr_pre , 
578-  descr_post , 
579-  len . try_eval_usize ( fcx . tcx ,  fcx . param_env ) . unwrap_or ( 0 )   as   usize  +  1 , 
559+  SuspendCheckData   { 
560+   descr_pre , 
561+    plural_len :  len . try_eval_usize ( fcx . tcx ,  fcx . param_env ) . unwrap_or ( 0 )   as   usize 
562+   +  1 , 
563+   ..data 
564+  } , 
580565 ) 
581566 } 
582567 _ => false , 
@@ -587,39 +572,38 @@ fn check_must_not_suspend_def(
587572 tcx :  TyCtxt < ' _ > , 
588573 def_id :  DefId , 
589574 hir_id :  HirId , 
590-  source_span :  Span , 
591-  yield_span :  Span , 
592-  descr_pre_path :  & str , 
593-  descr_post_path :  & str , 
575+  data :  SuspendCheckData < ' _ ,  ' _ > , 
594576)  -> bool  { 
595577 for  attr in  tcx. get_attrs ( def_id) . iter ( )  { 
596578 if  attr. has_name ( sym:: must_not_suspend)  { 
597579 tcx. struct_span_lint_hir ( 
598580 rustc_session:: lint:: builtin:: MUST_NOT_SUSPEND , 
599581 hir_id, 
600-  source_span, 
582+  data . source_span , 
601583 |lint| { 
602584 let  msg = format ! ( 
603-  "{}`{}`{} held across a yield  point, but should not be" , 
604-  descr_pre_path , 
585+  "{}`{}`{} held across a suspend  point, but should not be" , 
586+  data . descr_pre , 
605587 tcx. def_path_str( def_id) , 
606-  descr_post_path 
588+  data . descr_post , 
607589 ) ; 
608590 let  mut  err = lint. build ( & msg) ; 
609591
610592 // add span pointing to the offending yield/await 
611-  err. span_label ( yield_span,  "the value is held across this yield  point" ) ; 
593+  err. span_label ( data . yield_span ,  "the value is held across this suspend  point" ) ; 
612594
613595 // Add optional reason note 
614596 if  let  Some ( note)  = attr. value_str ( )  { 
615-  err. span_note ( source_span,  & note. as_str ( ) ) ; 
597+  // FIXME(guswynn): consider formatting this better 
598+  err. span_note ( data. source_span ,  & note. as_str ( ) ) ; 
616599 } 
617600
618601 // Add some quick suggestions on what to do 
602+  // FIXME: can `drop` work as a suggestion here as well? 
619603 err. span_help ( 
620-  source_span, 
621-  "`drop` this value before the yield point, or use  a block (`{ ... }`) \  
622-   to shrink its  scope", 
604+  data . source_span , 
605+  "consider using  a block (`{ ... }`) \  
606+   to shrink the value's  scope, ending before the suspend point ", 
623607 ) ; 
624608
625609 err. emit ( ) ; 
0 commit comments