1
1
use rustc:: hir;
2
2
use rustc:: hir:: def:: Namespace ;
3
3
use rustc:: hir:: def_id:: DefId ;
4
+ use rustc:: hir:: GeneratorKind ;
4
5
use rustc:: mir:: {
5
6
AggregateKind , Constant , Field , Local , LocalKind , Location , Operand ,
6
7
Place , PlaceBase , PlaceRef , ProjectionElem , Rvalue , Statement , StatementKind ,
@@ -14,7 +15,7 @@ use syntax_pos::Span;
14
15
use syntax:: symbol:: sym;
15
16
16
17
use super :: borrow_set:: BorrowData ;
17
- use super :: { MirBorrowckCtxt } ;
18
+ use super :: MirBorrowckCtxt ;
18
19
use crate :: dataflow:: move_paths:: { InitLocation , LookupResult } ;
19
20
20
21
pub ( super ) struct IncludingDowncast ( pub ( super ) bool ) ;
@@ -604,7 +605,7 @@ pub(super) enum UseSpans {
604
605
// The access is caused by capturing a variable for a closure.
605
606
ClosureUse {
606
607
// This is true if the captured variable was from a generator.
607
- is_generator : bool ,
608
+ generator_kind : Option < GeneratorKind > ,
608
609
// The span of the args of the closure, including the `move` keyword if
609
610
// it's present.
610
611
args_span : Span ,
@@ -631,6 +632,13 @@ impl UseSpans {
631
632
}
632
633
}
633
634
635
+ pub ( super ) fn generator_kind ( self ) -> Option < GeneratorKind > {
636
+ match self {
637
+ UseSpans :: ClosureUse { generator_kind, .. } => generator_kind,
638
+ _ => None ,
639
+ }
640
+ }
641
+
634
642
// Add a span label to the arguments of the closure, if it exists.
635
643
pub ( super ) fn args_span_label (
636
644
self ,
@@ -656,23 +664,23 @@ impl UseSpans {
656
664
/// Returns `false` if this place is not used in a closure.
657
665
pub ( super ) fn for_closure ( & self ) -> bool {
658
666
match * self {
659
- UseSpans :: ClosureUse { is_generator , .. } => !is_generator ,
667
+ UseSpans :: ClosureUse { generator_kind , .. } => generator_kind . is_none ( ) ,
660
668
_ => false ,
661
669
}
662
670
}
663
671
664
672
/// Returns `false` if this place is not used in a generator.
665
673
pub ( super ) fn for_generator ( & self ) -> bool {
666
674
match * self {
667
- UseSpans :: ClosureUse { is_generator , .. } => is_generator ,
675
+ UseSpans :: ClosureUse { generator_kind , .. } => generator_kind . is_some ( ) ,
668
676
_ => false ,
669
677
}
670
678
}
671
679
672
680
/// Describe the span associated with a use of a place.
673
681
pub ( super ) fn describe ( & self ) -> String {
674
682
match * self {
675
- UseSpans :: ClosureUse { is_generator , .. } => if is_generator {
683
+ UseSpans :: ClosureUse { generator_kind , .. } => if generator_kind . is_some ( ) {
676
684
" in generator" . to_string ( )
677
685
} else {
678
686
" in closure" . to_string ( )
@@ -794,19 +802,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
794
802
if let StatementKind :: Assign (
795
803
box( _, Rvalue :: Aggregate ( ref kind, ref places) )
796
804
) = 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,
800
808
_ => return OtherUse ( stmt. source_info . span ) ,
801
809
} ;
802
810
803
811
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
806
814
) ;
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) {
808
817
return ClosureUse {
809
- is_generator ,
818
+ generator_kind ,
810
819
args_span,
811
820
var_span,
812
821
} ;
@@ -857,11 +866,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
857
866
"borrow_spans: def_id={:?} is_generator={:?} places={:?}" ,
858
867
def_id, is_generator, places
859
868
) ;
860
- if let Some ( ( args_span, var_span) ) = self . closure_span (
869
+ if let Some ( ( args_span, generator_kind , var_span) ) = self . closure_span (
861
870
* def_id, Place :: from ( target) . as_ref ( ) , places
862
871
) {
863
872
return ClosureUse {
864
- is_generator ,
873
+ generator_kind ,
865
874
args_span,
866
875
var_span,
867
876
} ;
@@ -884,7 +893,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
884
893
def_id : DefId ,
885
894
target_place : PlaceRef < ' cx , ' tcx > ,
886
895
places : & Vec < Operand < ' tcx > > ,
887
- ) -> Option < ( Span , Span ) > {
896
+ ) -> Option < ( Span , Option < GeneratorKind > , Span ) > {
888
897
debug ! (
889
898
"closure_span: def_id={:?} target_place={:?} places={:?}" ,
890
899
def_id, target_place, places
@@ -893,14 +902,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
893
902
let expr = & self . infcx . tcx . hir ( ) . expect_expr ( hir_id) . kind ;
894
903
debug ! ( "closure_span: hir_id={:?} expr={:?}" , hir_id, expr) ;
895
904
if let hir:: ExprKind :: Closure (
896
- .., args_span, _
905
+ .., body_id , args_span, _
897
906
) = expr {
898
907
for ( upvar, place) in self . infcx . tcx . upvars ( def_id) ?. values ( ) . zip ( places) {
899
908
match place {
900
909
Operand :: Copy ( place) |
901
910
Operand :: Move ( place) if target_place == place. as_ref ( ) => {
902
911
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 ) ) ;
904
915
} ,
905
916
_ => { }
906
917
}
0 commit comments