11use rustc:: hir;
22use rustc:: hir:: def:: Namespace ;
33use rustc:: hir:: def_id:: DefId ;
4+ use rustc:: hir:: GeneratorKind ;
45use rustc:: mir:: {
56 AggregateKind , Constant , Field , Local , LocalKind , Location , Operand ,
67 Place , PlaceBase , PlaceRef , ProjectionElem , Rvalue , Statement , StatementKind ,
@@ -14,7 +15,7 @@ use syntax_pos::Span;
1415use syntax:: symbol:: sym;
1516
1617use super :: borrow_set:: BorrowData ;
17- use super :: { MirBorrowckCtxt } ;
18+ use super :: MirBorrowckCtxt ;
1819use crate :: dataflow:: move_paths:: { InitLocation , LookupResult } ;
1920
2021pub ( super ) struct IncludingDowncast ( pub ( super ) bool ) ;
@@ -604,7 +605,7 @@ pub(super) enum UseSpans {
604605 // The access is caused by capturing a variable for a closure.
605606 ClosureUse {
606607 // This is true if the captured variable was from a generator.
607- is_generator : bool ,
608+ generator_kind : Option < GeneratorKind > ,
608609 // The span of the args of the closure, including the `move` keyword if
609610 // it's present.
610611 args_span : Span ,
@@ -631,6 +632,13 @@ impl UseSpans {
631632 }
632633 }
633634
635+ pub ( super ) fn generator_kind ( self ) -> Option < GeneratorKind > {
636+ match self {
637+ UseSpans :: ClosureUse { generator_kind, .. } => generator_kind,
638+ _ => None ,
639+ }
640+ }
641+
634642 // Add a span label to the arguments of the closure, if it exists.
635643 pub ( super ) fn args_span_label (
636644 self ,
@@ -656,23 +664,23 @@ impl UseSpans {
656664 /// Returns `false` if this place is not used in a closure.
657665 pub ( super ) fn for_closure ( & self ) -> bool {
658666 match * self {
659- UseSpans :: ClosureUse { is_generator , .. } => !is_generator ,
667+ UseSpans :: ClosureUse { generator_kind , .. } => generator_kind . is_none ( ) ,
660668 _ => false ,
661669 }
662670 }
663671
664672 /// Returns `false` if this place is not used in a generator.
665673 pub ( super ) fn for_generator ( & self ) -> bool {
666674 match * self {
667- UseSpans :: ClosureUse { is_generator , .. } => is_generator ,
675+ UseSpans :: ClosureUse { generator_kind , .. } => generator_kind . is_some ( ) ,
668676 _ => false ,
669677 }
670678 }
671679
672680 /// Describe the span associated with a use of a place.
673681 pub ( super ) fn describe ( & self ) -> String {
674682 match * self {
675- UseSpans :: ClosureUse { is_generator , .. } => if is_generator {
683+ UseSpans :: ClosureUse { generator_kind , .. } => if generator_kind . is_some ( ) {
676684 " in generator" . to_string ( )
677685 } else {
678686 " in closure" . to_string ( )
@@ -794,19 +802,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
794802 if let StatementKind :: Assign (
795803 box( _, Rvalue :: Aggregate ( ref kind, ref places) )
796804 ) = stmt. kind {
797- let ( def_id, is_generator ) = match kind {
798- box AggregateKind :: Closure ( def_id, _) => ( def_id , false ) ,
799- box AggregateKind :: Generator ( def_id, _, _) => ( def_id, true ) ,
805+ let def_id = match kind {
806+ box AggregateKind :: Closure ( def_id, _)
807+ | box AggregateKind :: Generator ( def_id, _, _) => def_id,
800808 _ => return OtherUse ( stmt. source_info . span ) ,
801809 } ;
802810
803811 debug ! (
804- "move_spans: def_id={:?} is_generator={:?} places={:?}" ,
805- def_id, is_generator , places
812+ "move_spans: def_id={:?} places={:?}" ,
813+ def_id, places
806814 ) ;
807- if let Some ( ( args_span, var_span) ) = self . closure_span ( * def_id, moved_place, places) {
815+ if let Some ( ( args_span, generator_kind, var_span) )
816+ = self . closure_span ( * def_id, moved_place, places) {
808817 return ClosureUse {
809- is_generator ,
818+ generator_kind ,
810819 args_span,
811820 var_span,
812821 } ;
@@ -857,11 +866,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
857866 "borrow_spans: def_id={:?} is_generator={:?} places={:?}" ,
858867 def_id, is_generator, places
859868 ) ;
860- if let Some ( ( args_span, var_span) ) = self . closure_span (
869+ if let Some ( ( args_span, generator_kind , var_span) ) = self . closure_span (
861870 * def_id, Place :: from ( target) . as_ref ( ) , places
862871 ) {
863872 return ClosureUse {
864- is_generator ,
873+ generator_kind ,
865874 args_span,
866875 var_span,
867876 } ;
@@ -884,7 +893,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
884893 def_id : DefId ,
885894 target_place : PlaceRef < ' cx , ' tcx > ,
886895 places : & Vec < Operand < ' tcx > > ,
887- ) -> Option < ( Span , Span ) > {
896+ ) -> Option < ( Span , Option < GeneratorKind > , Span ) > {
888897 debug ! (
889898 "closure_span: def_id={:?} target_place={:?} places={:?}" ,
890899 def_id, target_place, places
@@ -893,14 +902,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
893902 let expr = & self . infcx . tcx . hir ( ) . expect_expr ( hir_id) . kind ;
894903 debug ! ( "closure_span: hir_id={:?} expr={:?}" , hir_id, expr) ;
895904 if let hir:: ExprKind :: Closure (
896- .., args_span, _
905+ .., body_id , args_span, _
897906 ) = expr {
898907 for ( upvar, place) in self . infcx . tcx . upvars ( def_id) ?. values ( ) . zip ( places) {
899908 match place {
900909 Operand :: Copy ( place) |
901910 Operand :: Move ( place) if target_place == place. as_ref ( ) => {
902911 debug ! ( "closure_span: found captured local {:?}" , place) ;
903- return Some ( ( * args_span, upvar. span ) ) ;
912+ let body = self . infcx . tcx . hir ( ) . body ( * body_id) ;
913+ let generator_kind = body. generator_kind ( ) ;
914+ return Some ( ( * args_span, generator_kind, upvar. span ) ) ;
904915 } ,
905916 _ => { }
906917 }
0 commit comments