record generoator interior exprs in typecktable
This commit is contained in:
parent
0b6c116a84
commit
148c1bca0f
3 changed files with 41 additions and 6 deletions
|
@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let target_span = tables
|
let target_span = tables
|
||||||
.generator_interior_types
|
.generator_interior_types
|
||||||
.iter()
|
.iter()
|
||||||
.find(|ty::GeneratorInteriorTypeCause { ty, .. }| {
|
.zip(tables.generator_interior_exprs.iter())
|
||||||
|
.find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| {
|
||||||
// Careful: the regions for types that appear in the
|
// Careful: the regions for types that appear in the
|
||||||
// generator interior are not generally known, so we
|
// generator interior are not generally known, so we
|
||||||
// want to erase them when comparing (and anyway,
|
// want to erase them when comparing (and anyway,
|
||||||
|
@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
eq
|
eq
|
||||||
})
|
})
|
||||||
.map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| {
|
.map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| {
|
||||||
(span, source_map.span_to_snippet(*span), scope_span)
|
(span, source_map.span_to_snippet(*span), scope_span, expr)
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
|
"maybe_note_obligation_cause_for_async_await: target_ty={:?} \
|
||||||
generator_interior_types={:?} target_span={:?}",
|
generator_interior_types={:?} target_span={:?}",
|
||||||
target_ty, tables.generator_interior_types, target_span
|
target_ty, tables.generator_interior_types, target_span
|
||||||
);
|
);
|
||||||
if let Some((target_span, Ok(snippet), scope_span)) = target_span {
|
if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span {
|
||||||
self.note_obligation_cause_for_async_await(
|
self.note_obligation_cause_for_async_await(
|
||||||
err,
|
err,
|
||||||
*target_span,
|
*target_span,
|
||||||
scope_span,
|
scope_span,
|
||||||
|
*expr,
|
||||||
snippet,
|
snippet,
|
||||||
generator_did,
|
generator_did,
|
||||||
last_generator,
|
last_generator,
|
||||||
|
@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
err: &mut DiagnosticBuilder<'_>,
|
err: &mut DiagnosticBuilder<'_>,
|
||||||
target_span: Span,
|
target_span: Span,
|
||||||
scope_span: &Option<Span>,
|
scope_span: &Option<Span>,
|
||||||
|
expr: Option<hir::HirId>,
|
||||||
snippet: String,
|
snippet: String,
|
||||||
first_generator: DefId,
|
first_generator: DefId,
|
||||||
last_generator: Option<DefId>,
|
last_generator: Option<DefId>,
|
||||||
|
@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
// not implemented.
|
// not implemented.
|
||||||
let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id);
|
let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id);
|
||||||
let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id);
|
let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id);
|
||||||
|
let hir = self.tcx.hir();
|
||||||
let trait_explanation = if is_send || is_sync {
|
let trait_explanation = if is_send || is_sync {
|
||||||
let (trait_name, trait_verb) =
|
let (trait_name, trait_verb) =
|
||||||
if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
|
if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
|
||||||
|
@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
let message = if let Some(name) = last_generator
|
let message = if let Some(name) = last_generator
|
||||||
.and_then(|generator_did| self.tcx.parent(generator_did))
|
.and_then(|generator_did| self.tcx.parent(generator_did))
|
||||||
.and_then(|parent_did| self.tcx.hir().as_local_hir_id(parent_did))
|
.and_then(|parent_did| hir.as_local_hir_id(parent_did))
|
||||||
.and_then(|parent_hir_id| self.tcx.hir().opt_name(parent_hir_id))
|
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
|
||||||
{
|
{
|
||||||
format!("future returned by `{}` is not {}", name, trait_name)
|
format!("future returned by `{}` is not {}", name, trait_name)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
|
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let Some(expr_id) = expr {
|
||||||
|
let expr = hir.expect_expr(expr_id);
|
||||||
|
let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow());
|
||||||
|
let parent = hir.get_parent_node(expr_id);
|
||||||
|
if let Some(hir::Node::Expr(e)) = hir.find(parent) {
|
||||||
|
let method_span = hir.span(parent);
|
||||||
|
if tables.is_method_call(e) && is_ref {
|
||||||
|
err.span_help(
|
||||||
|
method_span,
|
||||||
|
"consider moving this method call into a `let` \
|
||||||
|
binding to create a shorter lived borrow"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
span.push_span_label(target_span, format!("has type `{}`", target_ty));
|
span.push_span_label(target_span, format!("has type `{}`", target_ty));
|
||||||
|
|
||||||
// If available, use the scope span to annotate the drop location.
|
// If available, use the scope span to annotate the drop location.
|
||||||
|
|
|
@ -81,6 +81,15 @@ pub struct Adjustment<'tcx> {
|
||||||
pub target: Ty<'tcx>,
|
pub target: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Adjustment<'tcx> {
|
||||||
|
pub fn is_region_borrow(&self) -> bool {
|
||||||
|
match self.kind {
|
||||||
|
Adjust::Borrow(AutoBorrow::Ref(..)) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||||
pub enum Adjust<'tcx> {
|
pub enum Adjust<'tcx> {
|
||||||
/// Go from ! to any type.
|
/// Go from ! to any type.
|
||||||
|
|
|
@ -439,6 +439,8 @@ pub struct TypeckTables<'tcx> {
|
||||||
/// Stores the type, span and optional scope span of all types
|
/// Stores the type, span and optional scope span of all types
|
||||||
/// that are live across the yield of this generator (if a generator).
|
/// that are live across the yield of this generator (if a generator).
|
||||||
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
|
pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
|
||||||
|
|
||||||
|
pub generator_interior_exprs: Vec<Option<hir::HirId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeckTables<'tcx> {
|
impl<'tcx> TypeckTables<'tcx> {
|
||||||
|
@ -465,6 +467,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
||||||
concrete_opaque_types: Default::default(),
|
concrete_opaque_types: Default::default(),
|
||||||
upvar_list: Default::default(),
|
upvar_list: Default::default(),
|
||||||
generator_interior_types: Default::default(),
|
generator_interior_types: Default::default(),
|
||||||
|
generator_interior_exprs: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,6 +731,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||||
ref concrete_opaque_types,
|
ref concrete_opaque_types,
|
||||||
ref upvar_list,
|
ref upvar_list,
|
||||||
ref generator_interior_types,
|
ref generator_interior_types,
|
||||||
|
ref generator_interior_exprs,
|
||||||
} = *self;
|
} = *self;
|
||||||
|
|
||||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||||
|
@ -766,6 +770,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
|
||||||
concrete_opaque_types.hash_stable(hcx, hasher);
|
concrete_opaque_types.hash_stable(hcx, hasher);
|
||||||
upvar_list.hash_stable(hcx, hasher);
|
upvar_list.hash_stable(hcx, hasher);
|
||||||
generator_interior_types.hash_stable(hcx, hasher);
|
generator_interior_types.hash_stable(hcx, hasher);
|
||||||
|
generator_interior_exprs.hash_stable(hcx, hasher);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue