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