Skip to content

Commit a5d103f

Browse files
committed
record upvar into GeneratorInteriorTypeCause
1 parent fb81c42 commit a5d103f

File tree

3 files changed

+54
-23
lines changed

3 files changed

+54
-23
lines changed

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+18-17
Original file line numberDiff line numberDiff line change
@@ -1454,26 +1454,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
14541454
format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet),
14551455
);
14561456

1457-
span.push_span_label(
1458-
target_span,
1459-
format!("has type `{}` which {}", target_ty, trait_explanation),
1460-
);
1461-
1462-
// If available, use the scope span to annotate the drop location.
1463-
if let Some(scope_span) = scope_span {
14641457
span.push_span_label(
1465-
source_map.end_point(*scope_span),
1466-
format!("`{}` is later dropped here", snippet),
1458+
target_span,
1459+
format!("has type `{}` which {}", target_ty, trait_explanation),
14671460
);
1468-
}
14691461

1470-
err.span_note(
1471-
span,
1472-
&format!(
1473-
"{} {} as this value is used across {}",
1474-
future_or_generator, trait_explanation, an_await_or_yield
1475-
),
1476-
);
1462+
// If available, use the scope span to annotate the drop location.
1463+
if let Some(scope_span) = scope_span {
1464+
span.push_span_label(
1465+
source_map.end_point(*scope_span),
1466+
format!("`{}` is later dropped here", snippet),
1467+
);
1468+
}
1469+
1470+
err.span_note(
1471+
span,
1472+
&format!(
1473+
"{} {} as this value is used across {}",
1474+
future_or_generator, trait_explanation, an_await_or_yield
1475+
),
1476+
);
1477+
}
14771478
}
14781479

14791480
if let Some(expr_id) = expr {

src/librustc_typeck/check/generator_interior.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_span::Span;
1616

1717
struct InteriorVisitor<'a, 'tcx> {
1818
fcx: &'a FnCtxt<'a, 'tcx>,
19+
closure_def_id: DefId,
1920
types: FxHashMap<ty::GeneratorInteriorTypeCause<'tcx>, usize>,
2021
region_scope_tree: &'tcx region::ScopeTree,
2122
expr_count: usize,
@@ -30,6 +31,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
3031
scope: Option<region::Scope>,
3132
expr: Option<&'tcx Expr<'tcx>>,
3233
source_span: Span,
34+
is_upvar: bool,
3335
) {
3436
use rustc_span::DUMMY_SP;
3537

@@ -96,7 +98,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
9698
span: source_span,
9799
ty: &ty,
98100
scope_span,
99-
yield_span: yield_data.span,
101+
yield_span: Some(yield_data.span),
100102
expr: expr.map(|e| e.hir_id),
101103
})
102104
.or_insert(entries);
@@ -117,6 +119,20 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
117119
unresolved_type, unresolved_type_span
118120
);
119121
self.prev_unresolved_span = unresolved_type_span;
122+
} else {
123+
if is_upvar {
124+
let entries = self.types.len();
125+
let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree));
126+
self.types
127+
.entry(ty::GeneratorInteriorTypeCause {
128+
span: source_span,
129+
ty: &ty,
130+
scope_span,
131+
yield_span: None,
132+
expr: expr.map(|e| e.hir_id),
133+
})
134+
.or_insert(entries);
135+
}
120136
}
121137
}
122138
}
@@ -130,8 +146,12 @@ pub fn resolve_interior<'a, 'tcx>(
130146
kind: hir::GeneratorKind,
131147
) {
132148
let body = fcx.tcx.hir().body(body_id);
149+
150+
let closure_def_id = fcx.tcx.hir().body_owner_def_id(body_id).to_def_id();
151+
133152
let mut visitor = InteriorVisitor {
134153
fcx,
154+
closure_def_id,
135155
types: FxHashMap::default(),
136156
region_scope_tree: fcx.tcx.region_scope_tree(def_id),
137157
expr_count: 0,
@@ -223,7 +243,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
223243
if let PatKind::Binding(..) = pat.kind {
224244
let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
225245
let ty = self.fcx.tables.borrow().pat_ty(pat);
226-
self.record(ty, Some(scope), None, pat.span);
246+
self.record(ty, Some(scope), None, pat.span, false);
227247
}
228248
}
229249

@@ -264,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
264284
// If there are adjustments, then record the final type --
265285
// this is the actual value that is being produced.
266286
if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
267-
self.record(adjusted_ty, scope, Some(expr), expr.span);
287+
self.record(adjusted_ty, scope, Some(expr), expr.span, false);
268288
}
269289

270290
// Also record the unadjusted type (which is the only type if
@@ -292,9 +312,17 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
292312
// The type table might not have information for this expression
293313
// if it is in a malformed scope. (#66387)
294314
if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
295-
self.record(ty, scope, Some(expr), expr.span);
315+
self.record(ty, scope, Some(expr), expr.span, false);
296316
} else {
297317
self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
298318
}
319+
320+
if let Some(upvars) = self.fcx.tcx.upvars(self.closure_def_id) {
321+
for (upvar_id, upvar) in upvars.iter() {
322+
let upvar_ty = self.fcx.tables.borrow().node_type(*upvar_id);
323+
debug!("type of upvar: {:?}", upvar_ty);
324+
self.record(upvar_ty, scope, Some(expr), upvar.span, true);
325+
}
326+
}
299327
}
300328
}
+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// edition 2018
22

3-
fn d<T: Sized>(t: T) -> impl std::future::Future<Output = T> + Send { //~ Error `T` cannot be sent between threads safely
4-
async { t }
3+
fn foo<T: Sized>(ty: T) -> impl std::future::Future<Output = T> + Send { //~ Error `T` cannot be sent between threads safely
4+
async { ty }
55
}
6+
7+
fn main() {}

0 commit comments

Comments
 (0)