Skip to content

Commit 60482be

Browse files
authored
Rollup merge of #65277 - csmoe:fix-move, r=estebank
Query generator kind for error reporting Fixes #65166 (comment) r? @estebank cc @cramertj
2 parents 9917f06 + 9f69420 commit 60482be

File tree

4 files changed

+55
-26
lines changed

4 files changed

+55
-26
lines changed

src/librustc/hir/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,10 @@ impl Body {
13661366
hir_id: self.value.hir_id,
13671367
}
13681368
}
1369+
1370+
pub fn generator_kind(&self) -> Option<GeneratorKind> {
1371+
self.generator_kind
1372+
}
13691373
}
13701374

13711375
/// The type of source expression that caused this generator to be created.

src/librustc_mir/borrow_check/conflict_errors.rs

+22-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rustc::hir;
22
use rustc::hir::def_id::DefId;
3+
use rustc::hir::{AsyncGeneratorKind, GeneratorKind};
34
use rustc::mir::{
45
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
56
LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue,
@@ -788,7 +789,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
788789
..
789790
},
790791
) if borrow_spans.for_closure() => self.report_escaping_closure_capture(
791-
borrow_spans.args_or_use(),
792+
borrow_spans,
792793
borrow_span,
793794
region_name,
794795
category,
@@ -806,7 +807,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
806807
},
807808

808809
) if borrow_spans.for_generator() => self.report_escaping_closure_capture(
809-
borrow_spans.args_or_use(),
810+
borrow_spans,
810811
borrow_span,
811812
region_name,
812813
category,
@@ -1195,15 +1196,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11951196

11961197
fn report_escaping_closure_capture(
11971198
&mut self,
1198-
args_span: Span,
1199+
use_span: UseSpans,
11991200
var_span: Span,
12001201
fr_name: &RegionName,
12011202
category: ConstraintCategory,
12021203
constraint_span: Span,
12031204
captured_var: &str,
12041205
) -> DiagnosticBuilder<'cx> {
12051206
let tcx = self.infcx.tcx;
1206-
1207+
let args_span = use_span.args_or_use();
12071208
let mut err = self.cannot_capture_in_long_lived_closure(
12081209
args_span,
12091210
captured_var,
@@ -1223,12 +1224,25 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12231224
},
12241225
Err(_) => "move |<args>| <body>".to_string()
12251226
};
1226-
1227+
let kind = match use_span.generator_kind() {
1228+
Some(generator_kind) => match generator_kind {
1229+
GeneratorKind::Async(async_kind) => match async_kind {
1230+
AsyncGeneratorKind::Block => "async block",
1231+
AsyncGeneratorKind::Closure => "async closure",
1232+
_ => bug!("async block/closure expected, but async funtion found."),
1233+
},
1234+
GeneratorKind::Gen => "generator",
1235+
}
1236+
None => "closure",
1237+
};
12271238
err.span_suggestion(
12281239
args_span,
1229-
&format!("to force the closure to take ownership of {} (and any \
1230-
other referenced variables), use the `move` keyword",
1231-
captured_var),
1240+
&format!(
1241+
"to force the {} to take ownership of {} (and any \
1242+
other referenced variables), use the `move` keyword",
1243+
kind,
1244+
captured_var
1245+
),
12321246
suggestion,
12331247
Applicability::MachineApplicable,
12341248
);

src/librustc_mir/borrow_check/error_reporting.rs

+28-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc::hir;
22
use rustc::hir::def::Namespace;
33
use rustc::hir::def_id::DefId;
4+
use rustc::hir::GeneratorKind;
45
use 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;
1415
use syntax::symbol::sym;
1516

1617
use super::borrow_set::BorrowData;
17-
use super::{MirBorrowckCtxt};
18+
use super::MirBorrowckCtxt;
1819
use crate::dataflow::move_paths::{InitLocation, LookupResult};
1920

2021
pub(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
}

src/test/ui/async-await/async-borrowck-escaping-block-error.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ note: generator is returned here
1212
|
1313
LL | fn foo() -> Box<impl std::future::Future<Output = u32>> {
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
15+
help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword
1616
|
1717
LL | Box::new(async move { x } )
1818
| ^^^^^^^^^^

0 commit comments

Comments
 (0)