Skip to content

Commit 148c1bc

Browse files
committed
record generoator interior exprs in typecktable
1 parent 0b6c116 commit 148c1bc

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
24562456
let target_span = tables
24572457
.generator_interior_types
24582458
.iter()
2459-
.find(|ty::GeneratorInteriorTypeCause { ty, .. }| {
2459+
.zip(tables.generator_interior_exprs.iter())
2460+
.find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| {
24602461
// Careful: the regions for types that appear in the
24612462
// generator interior are not generally known, so we
24622463
// want to erase them when comparing (and anyway,
@@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
24792480
);
24802481
eq
24812482
})
2482-
.map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| {
2483-
(span, source_map.span_to_snippet(*span), scope_span)
2483+
.map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| {
2484+
(span, source_map.span_to_snippet(*span), scope_span, expr)
24842485
});
2486+
24852487
debug!(
24862488
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
24872489
generator_interior_types={:?} target_span={:?}",
24882490
target_ty, tables.generator_interior_types, target_span
24892491
);
2490-
if let Some((target_span, Ok(snippet), scope_span)) = target_span {
2492+
if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span {
24912493
self.note_obligation_cause_for_async_await(
24922494
err,
24932495
*target_span,
24942496
scope_span,
2497+
*expr,
24952498
snippet,
24962499
generator_did,
24972500
last_generator,
@@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25142517
err: &mut DiagnosticBuilder<'_>,
25152518
target_span: Span,
25162519
scope_span: &Option<Span>,
2520+
expr: Option<hir::HirId>,
25172521
snippet: String,
25182522
first_generator: DefId,
25192523
last_generator: Option<DefId>,
@@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25492553
// not implemented.
25502554
let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id);
25512555
let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id);
2556+
let hir = self.tcx.hir();
25522557
let trait_explanation = if is_send || is_sync {
25532558
let (trait_name, trait_verb) =
25542559
if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
@@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25642569

25652570
let message = if let Some(name) = last_generator
25662571
.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))
2572+
.and_then(|parent_did| hir.as_local_hir_id(parent_did))
2573+
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
25692574
{
25702575
format!("future returned by `{}` is not {}", name, trait_name)
25712576
} else {
@@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
25882593
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
25892594
);
25902595

2596+
if let Some(expr_id) = expr {
2597+
let expr = hir.expect_expr(expr_id);
2598+
let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
2599+
let parent = hir.get_parent_node(expr_id);
2600+
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
2601+
let method_span = hir.span(parent);
2602+
if tables.is_method_call(e) && is_ref {
2603+
err.span_help(
2604+
method_span,
2605+
"consider moving this method call into a `let` \
2606+
binding to create a shorter lived borrow"
2607+
);
2608+
}
2609+
}
2610+
}
2611+
25912612
span.push_span_label(target_span, format!("has type `{}`", target_ty));
25922613

25932614
// If available, use the scope span to annotate the drop location.

src/librustc/ty/adjustment.rs

Lines changed: 9 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ pub struct TypeckTables<'tcx> {
439439
/// Stores the type, span and optional scope span of all types
440440
/// that are live across the yield of this generator (if a generator).
441441
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
442+
443+
pub generator_interior_exprs: Vec<Option<hir::HirId>>,
442444
}
443445

444446
impl<'tcx> TypeckTables<'tcx> {
@@ -465,6 +467,7 @@ impl<'tcx> TypeckTables<'tcx> {
465467
concrete_opaque_types: Default::default(),
466468
upvar_list: Default::default(),
467469
generator_interior_types: Default::default(),
470+
generator_interior_exprs: Default::default(),
468471
}
469472
}
470473

@@ -728,6 +731,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
728731
ref concrete_opaque_types,
729732
ref upvar_list,
730733
ref generator_interior_types,
734+
ref generator_interior_exprs,
731735
} = *self;
732736

733737
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
@@ -766,6 +770,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
766770
concrete_opaque_types.hash_stable(hcx, hasher);
767771
upvar_list.hash_stable(hcx, hasher);
768772
generator_interior_types.hash_stable(hcx, hasher);
773+
generator_interior_exprs.hash_stable(hcx, hasher);
769774
})
770775
}
771776
}

0 commit comments

Comments
 (0)