Skip to content

Commit 71dacdf

Browse files
Don't create interior type variable in check_closure
1 parent 5a08ba6 commit 71dacdf

File tree

5 files changed

+76
-74
lines changed

5 files changed

+76
-74
lines changed

compiler/rustc_hir_typeck/src/check.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub(super) fn check_fn<'a, 'tcx>(
9494
// Resume type defaults to `()` if the coroutine has no argument.
9595
let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| Ty::new_unit(tcx));
9696

97-
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
97+
fcx.coroutine_types = Some(CoroutineTypes { resume_ty, yield_ty });
9898
}
9999

100100
GatherLocalsVisitor::new(fcx).visit_body(body);
@@ -146,20 +146,6 @@ pub(super) fn check_fn<'a, 'tcx>(
146146
fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType);
147147
fcx.check_return_expr(body.value, false);
148148

149-
// We insert the deferred_coroutine_interiors entry after visiting the body.
150-
// This ensures that all nested coroutines appear before the entry of this coroutine.
151-
// resolve_coroutine_interiors relies on this property.
152-
let coroutine_ty = if let Some(hir::ClosureKind::Coroutine(_)) = closure_kind {
153-
let interior = fcx
154-
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
155-
fcx.deferred_coroutine_interiors.borrow_mut().push((fn_def_id, body.id(), interior));
156-
157-
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
158-
Some(CoroutineTypes { resume_ty, yield_ty, interior })
159-
} else {
160-
None
161-
};
162-
163149
// Finalize the return check by taking the LUB of the return types
164150
// we saw and assigning it to the expected return type. This isn't
165151
// really expected to fail, since the coercions would have failed
@@ -195,7 +181,7 @@ pub(super) fn check_fn<'a, 'tcx>(
195181
check_lang_start_fn(tcx, fn_sig, fn_def_id);
196182
}
197183

198-
coroutine_ty
184+
fcx.coroutine_types
199185
}
200186

201187
fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>) {

compiler/rustc_hir_typeck/src/closure.rs

+67-50
Original file line numberDiff line numberDiff line change
@@ -105,59 +105,76 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
105105
span: self.tcx.def_span(expr_def_id),
106106
});
107107

108-
if let Some(CoroutineTypes { resume_ty, yield_ty, interior }) = coroutine_types {
109-
let coroutine_args = ty::CoroutineArgs::new(
110-
self.tcx,
111-
ty::CoroutineArgsParts {
112-
parent_args,
113-
resume_ty,
114-
yield_ty,
115-
return_ty: liberated_sig.output(),
116-
witness: interior,
117-
tupled_upvars_ty,
118-
},
119-
);
120-
121-
return Ty::new_coroutine(self.tcx, expr_def_id.to_def_id(), coroutine_args.args);
122-
}
123-
124-
// Tuple up the arguments and insert the resulting function type into
125-
// the `closures` table.
126-
let sig = bound_sig.map_bound(|sig| {
127-
self.tcx.mk_fn_sig(
128-
[Ty::new_tup(self.tcx, sig.inputs())],
129-
sig.output(),
130-
sig.c_variadic,
131-
sig.unsafety,
132-
sig.abi,
133-
)
134-
});
135-
136-
debug!(?sig, ?opt_kind);
137-
138-
let closure_kind_ty = match opt_kind {
139-
Some(kind) => Ty::from_closure_kind(self.tcx, kind),
108+
match closure.kind {
109+
hir::ClosureKind::Closure => {
110+
assert_eq!(coroutine_types, None);
111+
// Tuple up the arguments and insert the resulting function type into
112+
// the `closures` table.
113+
let sig = bound_sig.map_bound(|sig| {
114+
self.tcx.mk_fn_sig(
115+
[Ty::new_tup(self.tcx, sig.inputs())],
116+
sig.output(),
117+
sig.c_variadic,
118+
sig.unsafety,
119+
sig.abi,
120+
)
121+
});
140122

141-
// Create a type variable (for now) to represent the closure kind.
142-
// It will be unified during the upvar inference phase (`upvar.rs`)
143-
None => self.next_root_ty_var(TypeVariableOrigin {
144-
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
145-
kind: TypeVariableOriginKind::ClosureSynthetic,
146-
span: expr_span,
147-
}),
148-
};
123+
debug!(?sig, ?opt_kind);
124+
125+
let closure_kind_ty = match opt_kind {
126+
Some(kind) => Ty::from_closure_kind(self.tcx, kind),
127+
128+
// Create a type variable (for now) to represent the closure kind.
129+
// It will be unified during the upvar inference phase (`upvar.rs`)
130+
None => self.next_root_ty_var(TypeVariableOrigin {
131+
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
132+
kind: TypeVariableOriginKind::ClosureSynthetic,
133+
span: expr_span,
134+
}),
135+
};
136+
137+
let closure_args = ty::ClosureArgs::new(
138+
self.tcx,
139+
ty::ClosureArgsParts {
140+
parent_args,
141+
closure_kind_ty,
142+
closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(self.tcx, sig),
143+
tupled_upvars_ty,
144+
},
145+
);
149146

150-
let closure_args = ty::ClosureArgs::new(
151-
self.tcx,
152-
ty::ClosureArgsParts {
153-
parent_args,
154-
closure_kind_ty,
155-
closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(self.tcx, sig),
156-
tupled_upvars_ty,
157-
},
158-
);
147+
Ty::new_closure(self.tcx, expr_def_id.to_def_id(), closure_args.args)
148+
}
149+
hir::ClosureKind::Coroutine(_) => {
150+
let Some(CoroutineTypes { resume_ty, yield_ty }) = coroutine_types else {
151+
bug!("expected coroutine to have yield/resume types");
152+
};
153+
let interior = fcx.next_ty_var(TypeVariableOrigin {
154+
kind: TypeVariableOriginKind::MiscVariable,
155+
span: body.value.span,
156+
});
157+
fcx.deferred_coroutine_interiors.borrow_mut().push((
158+
expr_def_id,
159+
body.id(),
160+
interior,
161+
));
162+
163+
let coroutine_args = ty::CoroutineArgs::new(
164+
self.tcx,
165+
ty::CoroutineArgsParts {
166+
parent_args,
167+
resume_ty,
168+
yield_ty,
169+
return_ty: liberated_sig.output(),
170+
witness: interior,
171+
tupled_upvars_ty,
172+
},
173+
);
159174

160-
Ty::new_closure(self.tcx, expr_def_id.to_def_id(), closure_args.args)
175+
Ty::new_coroutine(self.tcx, expr_def_id.to_def_id(), coroutine_args.args)
176+
}
177+
}
161178
}
162179

163180
/// Given the expected type, figures out what it can about this closure we

compiler/rustc_hir_typeck/src/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::errors::{
1515
use crate::fatally_break_rust;
1616
use crate::method::SelfSource;
1717
use crate::type_error_struct;
18+
use crate::CoroutineTypes;
1819
use crate::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
1920
use crate::{
2021
report_unexpected_variant_res, BreakableCtxt, Diverges, FnCtxt, Needs,
@@ -3164,8 +3165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
31643165
expr: &'tcx hir::Expr<'tcx>,
31653166
src: &'tcx hir::YieldSource,
31663167
) -> Ty<'tcx> {
3167-
match self.resume_yield_tys {
3168-
Some((resume_ty, yield_ty)) => {
3168+
match self.coroutine_types {
3169+
Some(CoroutineTypes { resume_ty, yield_ty }) => {
31693170
self.check_expr_coercible_to_type(value, yield_ty, None);
31703171

31713172
resume_ty

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod checks;
55
mod suggestions;
66

77
use crate::coercion::DynamicCoerceMany;
8-
use crate::{Diverges, EnclosingBreakables, Inherited};
8+
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, Inherited};
99
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
1010
use rustc_hir as hir;
1111
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -68,7 +68,7 @@ pub struct FnCtxt<'a, 'tcx> {
6868
/// First span of a return site that we find. Used in error messages.
6969
pub(super) ret_coercion_span: Cell<Option<Span>>,
7070

71-
pub(super) resume_yield_tys: Option<(Ty<'tcx>, Ty<'tcx>)>,
71+
pub(super) coroutine_types: Option<CoroutineTypes<'tcx>>,
7272

7373
/// Whether the last checked node generates a divergence (e.g.,
7474
/// `return` will set this to `Always`). In general, when entering
@@ -122,7 +122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
122122
err_count_on_creation: inh.tcx.dcx().err_count(),
123123
ret_coercion: None,
124124
ret_coercion_span: Cell::new(None),
125-
resume_yield_tys: None,
125+
coroutine_types: None,
126126
diverges: Cell::new(Diverges::Maybe),
127127
enclosing_breakables: RefCell::new(EnclosingBreakables {
128128
stack: Vec::new(),

compiler/rustc_hir_typeck/src/lib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -295,15 +295,13 @@ fn typeck_with_fallback<'tcx>(
295295
/// When `check_fn` is invoked on a coroutine (i.e., a body that
296296
/// includes yield), it returns back some information about the yield
297297
/// points.
298+
#[derive(Debug, PartialEq, Copy, Clone)]
298299
struct CoroutineTypes<'tcx> {
299300
/// Type of coroutine argument / values returned by `yield`.
300301
resume_ty: Ty<'tcx>,
301302

302303
/// Type of value that is yielded.
303304
yield_ty: Ty<'tcx>,
304-
305-
/// Types that are captured (see `CoroutineInterior` for more).
306-
interior: Ty<'tcx>,
307305
}
308306

309307
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

0 commit comments

Comments
 (0)