Skip to content

Commit 8a1227a

Browse files
Infer type of yield to be resume type
1 parent 25af2f6 commit 8a1227a

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

src/librustc_typeck/check/closure.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9292
.into(),
9393
GenericParamDefKind::Const => span_bug!(expr.span, "closure has const param"),
9494
});
95-
if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
95+
if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
96+
{
9697
let generator_substs = substs.as_generator();
9798
self.demand_eqtype(
9899
expr.span,
99-
self.tcx.mk_unit(), // WIP
100+
resume_ty,
100101
generator_substs.resume_ty(expr_def_id, self.tcx),
101102
);
102103
self.demand_eqtype(

src/librustc_typeck/check/expr.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,16 +1796,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17961796
expr: &'tcx hir::Expr<'tcx>,
17971797
src: &'tcx hir::YieldSource,
17981798
) -> Ty<'tcx> {
1799-
match self.yield_ty {
1800-
Some(ty) => {
1801-
self.check_expr_coercable_to_type(&value, ty);
1799+
match self.resume_yield_tys {
1800+
Some((resume_ty, yield_ty)) => {
1801+
self.check_expr_coercable_to_type(&value, yield_ty);
1802+
1803+
resume_ty
18021804
}
18031805
// Given that this `yield` expression was generated as a result of lowering a `.await`,
18041806
// we know that the yield type must be `()`; however, the context won't contain this
18051807
// information. Hence, we check the source of the yield expression here and check its
18061808
// value's type against `()` (this check should always hold).
18071809
None if src == &hir::YieldSource::Await => {
18081810
self.check_expr_coercable_to_type(&value, self.tcx.mk_unit());
1811+
self.tcx.mk_unit()
18091812
}
18101813
_ => {
18111814
struct_span_err!(
@@ -1815,9 +1818,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18151818
"yield expression outside of generator literal"
18161819
)
18171820
.emit();
1821+
self.tcx.mk_unit()
18181822
}
18191823
}
1820-
self.tcx.mk_unit()
18211824
}
18221825
}
18231826

src/librustc_typeck/check/mod.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ pub struct FnCtxt<'a, 'tcx> {
573573
/// First span of a return site that we find. Used in error messages.
574574
ret_coercion_span: RefCell<Option<Span>>,
575575

576-
yield_ty: Option<Ty<'tcx>>,
576+
resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
577577

578578
ps: RefCell<UnsafetyState>,
579579

@@ -1248,6 +1248,9 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
12481248
/// includes yield), it returns back some information about the yield
12491249
/// points.
12501250
struct GeneratorTypes<'tcx> {
1251+
/// Type of generator argument / values returned by `yield`.
1252+
resume_ty: Ty<'tcx>,
1253+
12511254
/// Type of value that is yielded.
12521255
yield_ty: Ty<'tcx>,
12531256

@@ -1308,7 +1311,11 @@ fn check_fn<'a, 'tcx>(
13081311
let yield_ty = fcx
13091312
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
13101313
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
1311-
fcx.yield_ty = Some(yield_ty);
1314+
1315+
// Resume type defaults to `()` if the generator has no argument.
1316+
let resume_ty = fn_sig.inputs().get(0).map(|ty| *ty).unwrap_or_else(|| tcx.mk_unit());
1317+
1318+
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
13121319
}
13131320

13141321
let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id));
@@ -1361,8 +1368,11 @@ fn check_fn<'a, 'tcx>(
13611368
let interior = fcx
13621369
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
13631370
fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
1371+
1372+
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
13641373
Some(GeneratorTypes {
1365-
yield_ty: fcx.yield_ty.unwrap(),
1374+
resume_ty,
1375+
yield_ty,
13661376
interior,
13671377
movability: can_be_generator.unwrap(),
13681378
})
@@ -2764,7 +2774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27642774
err_count_on_creation: inh.tcx.sess.err_count(),
27652775
ret_coercion: None,
27662776
ret_coercion_span: RefCell::new(None),
2767-
yield_ty: None,
2777+
resume_yield_tys: None,
27682778
ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)),
27692779
diverges: Cell::new(Diverges::Maybe),
27702780
has_errors: Cell::new(false),

0 commit comments

Comments
 (0)