Skip to content

Commit ae1e75b

Browse files
authored
Rollup merge of #68212 - csmoe:temp, r=estebank
Suggest to shorten temporary lifetime during method call inside generator Closes #67376 ![image](https://user-images.githubusercontent.com/35686186/72364752-f6b1e400-3731-11ea-8ec9-8297ba4c6c77.png) r? @estebank cc @tmandry @nikomatsakis
2 parents 1b7b8cb + 4eb47de commit ae1e75b

File tree

7 files changed

+60
-16
lines changed

7 files changed

+60
-16
lines changed

src/librustc/traits/error_reporting.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -2479,19 +2479,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
24792479
);
24802480
eq
24812481
})
2482-
.map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| {
2483-
(span, source_map.span_to_snippet(*span), scope_span)
2482+
.map(|ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. }| {
2483+
(span, source_map.span_to_snippet(*span), scope_span, expr)
24842484
});
2485+
24852486
debug!(
24862487
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
24872488
generator_interior_types={:?} target_span={:?}",
24882489
target_ty, tables.generator_interior_types, target_span
24892490
);
2490-
if let Some((target_span, Ok(snippet), scope_span)) = target_span {
2491+
if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span {
24912492
self.note_obligation_cause_for_async_await(
24922493
err,
24932494
*target_span,
24942495
scope_span,
2496+
*expr,
24952497
snippet,
24962498
generator_did,
24972499
last_generator,
@@ -2514,6 +2516,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25142516
err: &mut DiagnosticBuilder<'_>,
25152517
target_span: Span,
25162518
scope_span: &Option<Span>,
2519+
expr: Option<hir::HirId>,
25172520
snippet: String,
25182521
first_generator: DefId,
25192522
last_generator: Option<DefId>,
@@ -2549,6 +2552,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25492552
// not implemented.
25502553
let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id);
25512554
let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id);
2555+
let hir = self.tcx.hir();
25522556
let trait_explanation = if is_send || is_sync {
25532557
let (trait_name, trait_verb) =
25542558
if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
@@ -2564,8 +2568,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25642568

25652569
let message = if let Some(name) = last_generator
25662570
.and_then(|generator_did| self.tcx.parent(generator_did))
2567-
.and_then(|parent_did| self.tcx.hir().as_local_hir_id(parent_did))
2568-
.and_then(|parent_hir_id| self.tcx.hir().opt_name(parent_hir_id))
2571+
.and_then(|parent_did| hir.as_local_hir_id(parent_did))
2572+
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
25692573
{
25702574
format!("future returned by `{}` is not {}", name, trait_name)
25712575
} else {
@@ -2581,7 +2585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25812585
};
25822586

25832587
// Look at the last interior type to get a span for the `.await`.
2584-
let await_span = tables.generator_interior_types.iter().map(|i| i.span).last().unwrap();
2588+
let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap();
25852589
let mut span = MultiSpan::from_span(await_span);
25862590
span.push_span_label(
25872591
await_span,
@@ -2606,6 +2610,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
26062610
),
26072611
);
26082612

2613+
if let Some(expr_id) = expr {
2614+
let expr = hir.expect_expr(expr_id);
2615+
let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
2616+
let parent = hir.get_parent_node(expr_id);
2617+
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
2618+
let method_span = hir.span(parent);
2619+
if tables.is_method_call(e) && is_ref {
2620+
err.span_help(
2621+
method_span,
2622+
"consider moving this method call into a `let` \
2623+
binding to create a shorter lived borrow",
2624+
);
2625+
}
2626+
}
2627+
}
2628+
26092629
// Add a note for the item obligation that remains - normally a note pointing to the
26102630
// bound that introduced the obligation (e.g. `T: Send`).
26112631
debug!("note_obligation_cause_for_async_await: next_code={:?}", next_code);

src/librustc/ty/adjustment.rs

+9
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ pub struct Adjustment<'tcx> {
8181
pub target: Ty<'tcx>,
8282
}
8383

84+
impl Adjustment<'tcx> {
85+
pub fn is_region_borrow(&self) -> bool {
86+
match self.kind {
87+
Adjust::Borrow(AutoBorrow::Ref(..)) => true,
88+
_ => false,
89+
}
90+
}
91+
}
92+
8493
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
8594
pub enum Adjust<'tcx> {
8695
/// Go from ! to any type.

src/librustc/ty/context.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,16 @@ pub struct ResolvedOpaqueTy<'tcx> {
315315
///
316316
/// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for
317317
/// the scope that contains `x`.
318-
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq)]
319-
#[derive(HashStable, TypeFoldable)]
318+
#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
320319
pub struct GeneratorInteriorTypeCause<'tcx> {
321320
/// Type of the captured binding.
322321
pub ty: Ty<'tcx>,
323322
/// Span of the binding that was captured.
324323
pub span: Span,
325324
/// Span of the scope of the captured binding.
326325
pub scope_span: Option<Span>,
326+
/// Expr which the type evaluated from.
327+
pub expr: Option<hir::HirId>,
327328
}
328329

329330
#[derive(RustcEncodable, RustcDecodable, Debug)]
@@ -436,7 +437,7 @@ pub struct TypeckTables<'tcx> {
436437
/// entire variable.
437438
pub upvar_list: ty::UpvarListMap,
438439

439-
/// Stores the type, span and optional scope span of all types
440+
/// Stores the type, expression, span and optional scope span of all types
440441
/// that are live across the yield of this generator (if a generator).
441442
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
442443
}

src/librustc_typeck/check/generator_interior.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
9797
span: source_span,
9898
ty: &ty,
9999
scope_span,
100+
expr: expr.map(|e| e.hir_id),
100101
})
101102
.or_insert(entries);
102103
}
@@ -164,17 +165,25 @@ pub fn resolve_interior<'a, 'tcx>(
164165
// which means that none of the regions inside relate to any other, even if
165166
// typeck had previously found constraints that would cause them to be related.
166167
let mut counter = 0;
167-
let types = fcx.tcx.fold_regions(&types, &mut false, |_, current_depth| {
168+
let fold_types: Vec<_> = types.iter().map(|(t, _)| t.ty).collect();
169+
let folded_types = fcx.tcx.fold_regions(&fold_types, &mut false, |_, current_depth| {
168170
counter += 1;
169171
fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter)))
170172
});
171173

172174
// Store the generator types and spans into the tables for this generator.
173-
let interior_types = types.iter().map(|t| t.0.clone()).collect::<Vec<_>>();
174-
visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types;
175+
let types = types
176+
.into_iter()
177+
.zip(&folded_types)
178+
.map(|((mut interior_cause, _), ty)| {
179+
interior_cause.ty = ty;
180+
interior_cause
181+
})
182+
.collect();
183+
visitor.fcx.inh.tables.borrow_mut().generator_interior_types = types;
175184

176185
// Extract type components
177-
let type_list = fcx.tcx.mk_type_list(types.into_iter().map(|t| (t.0).ty));
186+
let type_list = fcx.tcx.mk_type_list(folded_types.iter());
178187

179188
let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list));
180189

src/test/ui/async-await/issue-64130-4-async-move.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ LL | let _x = get().await;
1616
...
1717
LL | }
1818
| - `client` is later dropped here
19+
help: consider moving this method call into a `let` binding to create a shorter lived borrow
20+
--> $DIR/issue-64130-4-async-move.rs:19:15
21+
|
22+
LL | match client.status() {
23+
| ^^^^^^^^^^^^^^^
1924
= note: the return type of a function must have a statically known size
2025

2126
error: aborting due to previous error

src/test/ui/generator/not-send-sync.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LL | fn assert_sync<T: Sync>(_: T) {}
2020
LL | assert_sync(|| {
2121
| ^^^^^^^^^^^ future returned by `main` is not `Sync`
2222
|
23-
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
23+
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, (), ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
2424
note: future is not `Sync` as this value is used across an yield
2525
--> $DIR/not-send-sync.rs:12:9
2626
|

src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ error[E0720]: opaque type expands to a recursive type
7676
LL | fn generator_capture() -> impl Sized {
7777
| ^^^^^^^^^^ expands to a recursive type
7878
|
79-
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {()}]`
79+
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {(), ()}]`
8080

8181
error[E0720]: opaque type expands to a recursive type
8282
--> $DIR/recursive-impl-trait-type-indirect.rs:53:26
@@ -92,7 +92,7 @@ error[E0720]: opaque type expands to a recursive type
9292
LL | fn generator_hold() -> impl Sized {
9393
| ^^^^^^^^^^ expands to a recursive type
9494
|
95-
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, ()}]`
95+
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, (), ()}]`
9696

9797
error[E0720]: opaque type expands to a recursive type
9898
--> $DIR/recursive-impl-trait-type-indirect.rs:69:26

0 commit comments

Comments
 (0)