mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs
This commit is contained in:
parent
a20421734b
commit
c567eddec2
@ -1472,7 +1472,7 @@ fn suggest_ampmut<'tcx>(
|
||||
}
|
||||
|
||||
fn is_closure_or_coroutine(ty: Ty<'_>) -> bool {
|
||||
ty.is_closure() || ty.is_coroutine()
|
||||
ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure()
|
||||
}
|
||||
|
||||
/// Given a field that needs to be mutable, returns a span where the " mut " could go.
|
||||
|
@ -1303,7 +1303,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
// moved into the closure and subsequently used by the closure,
|
||||
// in order to populate our used_mut set.
|
||||
match **aggregate_kind {
|
||||
AggregateKind::Closure(def_id, _) | AggregateKind::Coroutine(def_id, _) => {
|
||||
AggregateKind::Closure(def_id, _)
|
||||
| AggregateKind::CoroutineClosure(def_id, _)
|
||||
| AggregateKind::Coroutine(def_id, _) => {
|
||||
let def_id = def_id.expect_local();
|
||||
let BorrowCheckResult { used_mut_upvars, .. } =
|
||||
self.infcx.tcx.mir_borrowck(def_id);
|
||||
@ -1609,6 +1611,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::CoroutineClosure(_, _)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -1633,7 +1636,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ty::Closure(_, _) | ty::Coroutine(_, _) | ty::Tuple(_) => (),
|
||||
ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::Tuple(_) => (),
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
@ -164,7 +164,7 @@ pub(crate) fn is_upvar_field_projection<'tcx>(
|
||||
match place_ref.last_projection() {
|
||||
Some((place_base, ProjectionElem::Field(field, _ty))) => {
|
||||
let base_ty = place_base.ty(body, tcx).ty;
|
||||
if (base_ty.is_closure() || base_ty.is_coroutine())
|
||||
if (base_ty.is_closure() || base_ty.is_coroutine() || base_ty.is_coroutine_closure())
|
||||
&& (!by_ref || upvars[field.index()].is_by_ref())
|
||||
{
|
||||
Some(field)
|
||||
|
@ -808,6 +808,14 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
||||
}),
|
||||
};
|
||||
}
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
return match args.as_coroutine_closure().upvar_tys().get(field.index()) {
|
||||
Some(&ty) => Ok(ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_coroutine_closure().upvar_tys().len(),
|
||||
}),
|
||||
};
|
||||
}
|
||||
ty::Coroutine(_, args) => {
|
||||
// Only prefix fields (upvars and current state) are
|
||||
// accessible without a variant index.
|
||||
@ -1875,6 +1883,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}),
|
||||
}
|
||||
}
|
||||
AggregateKind::CoroutineClosure(_, args) => {
|
||||
match args.as_coroutine_closure().upvar_tys().get(field_index.as_usize()) {
|
||||
Some(ty) => Ok(*ty),
|
||||
None => Err(FieldAccessError::OutOfRange {
|
||||
field_count: args.as_coroutine_closure().upvar_tys().len(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
AggregateKind::Array(ty) => Ok(ty),
|
||||
AggregateKind::Tuple => {
|
||||
unreachable!("This should have been covered in check_rvalues");
|
||||
@ -2478,6 +2494,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
AggregateKind::Tuple => None,
|
||||
AggregateKind::Closure(_, _) => None,
|
||||
AggregateKind::Coroutine(_, _) => None,
|
||||
AggregateKind::CoroutineClosure(_, _) => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -2705,7 +2722,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// desugaring. A closure gets desugared to a struct, and
|
||||
// these extra requirements are basically like where
|
||||
// clauses on the struct.
|
||||
AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args) => (
|
||||
AggregateKind::Closure(def_id, args)
|
||||
| AggregateKind::CoroutineClosure(def_id, args)
|
||||
| AggregateKind::Coroutine(def_id, args) => (
|
||||
def_id,
|
||||
self.prove_closure_bounds(
|
||||
tcx,
|
||||
@ -2754,10 +2773,16 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
let typeck_root_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
|
||||
let parent_args = match tcx.def_kind(def_id) {
|
||||
DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => {
|
||||
args.as_coroutine().parent_args()
|
||||
DefKind::Closure => {
|
||||
// FIXME(async_closures): It's kind of icky to access HIR here.
|
||||
match tcx.hir_node_by_def_id(def_id).expect_closure().kind {
|
||||
hir::ClosureKind::Closure => args.as_closure().parent_args(),
|
||||
hir::ClosureKind::Coroutine(_) => args.as_coroutine().parent_args(),
|
||||
hir::ClosureKind::CoroutineClosure(_) => {
|
||||
args.as_coroutine_closure().parent_args()
|
||||
}
|
||||
}
|
||||
}
|
||||
DefKind::Closure => args.as_closure().parent_args(),
|
||||
DefKind::InlineConst => args.as_inline_const().parent_args(),
|
||||
other => bug!("unexpected item {:?}", other),
|
||||
};
|
||||
|
@ -87,7 +87,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
||||
// FIXME(eddyb) producing readable type names for trait objects can result
|
||||
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
||||
// ty::Dynamic(..) |
|
||||
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||
ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||
if !cx.sess().fewer_names() =>
|
||||
{
|
||||
let mut name = with_no_trimmed_paths!(layout.ty.to_string());
|
||||
|
@ -33,7 +33,7 @@ fn uncached_llvm_type<'a, 'tcx>(
|
||||
// FIXME(eddyb) producing readable type names for trait objects can result
|
||||
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
||||
// ty::Dynamic(..) |
|
||||
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||
ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||
// For performance reasons we use names only when emitting LLVM IR.
|
||||
if !cx.sess().fewer_names() =>
|
||||
{
|
||||
|
@ -398,7 +398,9 @@ fn push_debuginfo_type_name<'tcx>(
|
||||
// processing
|
||||
visited.remove(&t);
|
||||
}
|
||||
ty::Closure(def_id, args) | ty::Coroutine(def_id, args, ..) => {
|
||||
ty::Closure(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args)
|
||||
| ty::Coroutine(def_id, args, ..) => {
|
||||
// Name will be "{closure_env#0}<T1, T2, ...>", "{coroutine_env#0}<T1, T2, ...>", or
|
||||
// "{async_fn_env#0}<T1, T2, ...>", etc.
|
||||
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
|
||||
@ -768,6 +770,8 @@ fn push_closure_or_coroutine_name<'tcx>(
|
||||
|
||||
// Truncate the args to the length of the above generics. This will cut off
|
||||
// anything closure- or coroutine-specific.
|
||||
// FIXME(async_closures): This is probably not going to be correct w.r.t.
|
||||
// multiple coroutine flavors. Maybe truncate to (parent + 1)?
|
||||
let args = args.truncate_to(tcx, generics);
|
||||
push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited);
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
|
||||
| ty::Infer(_)
|
||||
// FIXME(oli-obk): we can probably encode closures just like structs
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType),
|
||||
}
|
||||
@ -301,6 +302,7 @@ pub fn valtree_to_const_value<'tcx>(
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(_)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::FnPtr(_)
|
||||
|
@ -1007,6 +1007,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Error(_) => true,
|
||||
|
||||
|
@ -85,6 +85,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::CoroutineClosure(_, _)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -644,6 +644,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
||||
| ty::Str
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..) => Ok(false),
|
||||
// Some types only occur during typechecking, they have no layout.
|
||||
// We should not see them here and we could not check them anyway.
|
||||
|
@ -665,6 +665,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
};
|
||||
check_equal(self, location, f_ty);
|
||||
}
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
let args = args.as_coroutine_closure();
|
||||
let Some(&f_ty) = args.upvar_tys().get(f.as_usize()) else {
|
||||
fail_out_of_bounds(self, location);
|
||||
return;
|
||||
};
|
||||
check_equal(self, location, f_ty);
|
||||
}
|
||||
&ty::Coroutine(def_id, args) => {
|
||||
let f_ty = if let Some(var) = parent_ty.variant_index {
|
||||
let gen_body = if def_id == self.body.source.def_id() {
|
||||
@ -861,6 +869,20 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
AggregateKind::CoroutineClosure(_, args) => {
|
||||
let upvars = args.as_coroutine_closure().upvar_tys();
|
||||
if upvars.len() != fields.len() {
|
||||
self.fail(
|
||||
location,
|
||||
"coroutine-closure has the wrong number of initialized fields",
|
||||
);
|
||||
}
|
||||
for (src, dest) in std::iter::zip(fields, upvars) {
|
||||
if !self.mir_assign_valid_types(src.ty(self.body, self.tcx), dest) {
|
||||
self.fail(location, "coroutine-closure field has the wrong type");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Rvalue::Ref(_, BorrowKind::Fake, _) => {
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
|
||||
|
@ -51,6 +51,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
||||
| ty::FnDef(def_id, args)
|
||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||
| ty::Closure(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args)
|
||||
| ty::Coroutine(def_id, args) => self.print_def_path(def_id, args),
|
||||
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
||||
|
||||
|
@ -3703,6 +3703,7 @@ impl<'hir> Node<'hir> {
|
||||
expect_generic_param, &'hir GenericParam<'hir>, Node::GenericParam(n), n;
|
||||
expect_crate, &'hir Mod<'hir>, Node::Crate(n), n;
|
||||
expect_infer, &'hir InferArg, Node::Infer(n), n;
|
||||
expect_closure, &'hir Closure<'hir>, Node::Expr(Expr { kind: ExprKind::Closure(n), .. }), n;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,7 @@ impl<'tcx> InherentCollect<'tcx> {
|
||||
}
|
||||
ty::FnDef(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Bound(..)
|
||||
|
@ -244,6 +244,7 @@ fn do_orphan_check_impl<'tcx>(
|
||||
| ty::Tuple(..) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
|
||||
|
||||
ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Bound(..)
|
||||
|
@ -349,7 +349,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
ClosureKind::Coroutine(_) => {
|
||||
&["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
|
||||
}
|
||||
ClosureKind::CoroutineClosure(_) => todo!(),
|
||||
ClosureKind::CoroutineClosure(_) => &[
|
||||
"<closure_kind>",
|
||||
"<closure_signature_parts>",
|
||||
"<upvars>",
|
||||
"<bound_captures_by_ref>",
|
||||
"<witness>",
|
||||
][..],
|
||||
};
|
||||
|
||||
params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef {
|
||||
|
@ -235,8 +235,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
// leaf type -- noop
|
||||
}
|
||||
|
||||
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) => {
|
||||
bug!("Unexpected closure type in variance computation");
|
||||
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) | ty::CoroutineClosure(..) => {
|
||||
bug!("Unexpected coroutine/closure type in variance computation");
|
||||
}
|
||||
|
||||
ty::Ref(region, ty, mutbl) => {
|
||||
|
@ -147,7 +147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Check whether this is a call to a closure where we
|
||||
// haven't yet decided on whether the closure is fn vs
|
||||
// fnmut vs fnonce. If so, we have to defer further processing.
|
||||
if self.closure_kind(args).is_none() {
|
||||
if self.closure_kind(adjusted_ty).is_none() {
|
||||
let closure_sig = args.as_closure().sig();
|
||||
let closure_sig = self.instantiate_binder_with_fresh_vars(
|
||||
call_expr.span,
|
||||
@ -160,10 +160,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
DeferredCallResolution {
|
||||
call_expr,
|
||||
callee_expr,
|
||||
adjusted_ty,
|
||||
closure_ty: adjusted_ty,
|
||||
adjustments,
|
||||
fn_sig: closure_sig,
|
||||
closure_args: args,
|
||||
},
|
||||
);
|
||||
return Some(CallStep::DeferredClosure(def_id, closure_sig));
|
||||
@ -886,10 +885,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pub struct DeferredCallResolution<'tcx> {
|
||||
call_expr: &'tcx hir::Expr<'tcx>,
|
||||
callee_expr: &'tcx hir::Expr<'tcx>,
|
||||
adjusted_ty: Ty<'tcx>,
|
||||
closure_ty: Ty<'tcx>,
|
||||
adjustments: Vec<Adjustment<'tcx>>,
|
||||
fn_sig: ty::FnSig<'tcx>,
|
||||
closure_args: GenericArgsRef<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DeferredCallResolution<'tcx> {
|
||||
@ -898,10 +896,10 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> {
|
||||
|
||||
// we should not be invoked until the closure kind has been
|
||||
// determined by upvar inference
|
||||
assert!(fcx.closure_kind(self.closure_args).is_some());
|
||||
assert!(fcx.closure_kind(self.closure_ty).is_some());
|
||||
|
||||
// We may now know enough to figure out fn vs fnmut etc.
|
||||
match fcx.try_overloaded_call_traits(self.call_expr, self.adjusted_ty, None) {
|
||||
match fcx.try_overloaded_call_traits(self.call_expr, self.closure_ty, None) {
|
||||
Some((autoref, method_callee)) => {
|
||||
// One problem is that when we get here, we are going
|
||||
// to have a newly instantiated function signature
|
||||
|
@ -133,6 +133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Adt(..)
|
||||
| ty::Never
|
||||
|
@ -57,6 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match ty.kind() {
|
||||
// Not all of these (e.g., unsafe fns) implement `FnOnce`,
|
||||
// so we look for these beforehand.
|
||||
// FIXME(async_closures): These don't impl `FnOnce` by default.
|
||||
ty::Closure(..) | ty::FnDef(..) | ty::FnPtr(_) => true,
|
||||
// If it's not a simple function, look for things which implement `FnOnce`.
|
||||
_ => {
|
||||
|
@ -170,9 +170,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
) {
|
||||
// Extract the type of the closure.
|
||||
let ty = self.node_ty(closure_hir_id);
|
||||
let (closure_def_id, args) = match *ty.kind() {
|
||||
ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args)),
|
||||
ty::Coroutine(def_id, args) => (def_id, UpvarArgs::Coroutine(args)),
|
||||
let (closure_def_id, args, infer_kind) = match *ty.kind() {
|
||||
ty::Closure(def_id, args) => {
|
||||
(def_id, UpvarArgs::Closure(args), self.closure_kind(ty).is_none())
|
||||
}
|
||||
ty::Coroutine(def_id, args) => (def_id, UpvarArgs::Coroutine(args), false),
|
||||
ty::Error(_) => {
|
||||
// #51714: skip analysis when we have already encountered type errors
|
||||
return;
|
||||
@ -188,12 +190,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
let closure_def_id = closure_def_id.expect_local();
|
||||
|
||||
let infer_kind = if let UpvarArgs::Closure(closure_args) = args {
|
||||
self.closure_kind(closure_args).is_none().then_some(closure_args)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id);
|
||||
let mut delegate = InferBorrowKind {
|
||||
closure_def_id,
|
||||
@ -308,10 +304,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let before_feature_tys = self.final_upvar_tys(closure_def_id);
|
||||
|
||||
if let Some(closure_args) = infer_kind {
|
||||
if infer_kind {
|
||||
// Unify the (as yet unbound) type variable in the closure
|
||||
// args with the kind we inferred.
|
||||
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
||||
let closure_kind_ty = match args {
|
||||
UpvarArgs::Closure(args) => args.as_closure().kind_ty(),
|
||||
UpvarArgs::CoroutineClosure(args) => args.as_coroutine_closure().kind_ty(),
|
||||
UpvarArgs::Coroutine(_) => unreachable!("coroutines don't have an inferred kind"),
|
||||
};
|
||||
self.demand_eqtype(
|
||||
span,
|
||||
Ty::from_closure_kind(self.tcx, closure_kind),
|
||||
|
@ -414,6 +414,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Bool
|
||||
|
@ -2839,7 +2839,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||
// say, also take a look at the error code, maybe we can
|
||||
// tailor to that.
|
||||
_ => match terr {
|
||||
TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_coroutine() => Error0644,
|
||||
TypeError::CyclicTy(ty)
|
||||
if ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure() =>
|
||||
{
|
||||
Error0644
|
||||
}
|
||||
TypeError::IntrinsicCast => Error0308,
|
||||
_ => Error0308,
|
||||
},
|
||||
@ -2886,7 +2890,9 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||
// say, also take a look at the error code, maybe we can
|
||||
// tailor to that.
|
||||
_ => match terr {
|
||||
TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_coroutine() => {
|
||||
TypeError::CyclicTy(ty)
|
||||
if ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure() =>
|
||||
{
|
||||
ObligationCauseFailureCode::ClosureSelfref { span }
|
||||
}
|
||||
TypeError::IntrinsicCast => {
|
||||
|
@ -883,7 +883,10 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
||||
GenericArgKind::Type(ty) => {
|
||||
if matches!(
|
||||
ty.kind(),
|
||||
ty::Alias(ty::Opaque, ..) | ty::Closure(..) | ty::Coroutine(..)
|
||||
ty::Alias(ty::Opaque, ..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
) {
|
||||
// Opaque types can't be named by the user right now.
|
||||
//
|
||||
|
@ -228,7 +228,10 @@ impl<T> Trait<T> for X {
|
||||
#traits-as-parameters",
|
||||
);
|
||||
}
|
||||
(ty::Param(p), ty::Closure(..) | ty::Coroutine(..)) => {
|
||||
(
|
||||
ty::Param(p),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..),
|
||||
) => {
|
||||
let generics = tcx.generics_of(body_owner_def_id);
|
||||
if let Some(param) = generics.opt_type_param(p, tcx) {
|
||||
let p_span = tcx.def_span(param.def_id);
|
||||
@ -497,7 +500,7 @@ impl<T> Trait<T> for X {
|
||||
}
|
||||
CyclicTy(ty) => {
|
||||
// Watch out for various cases of cyclic types and try to explain.
|
||||
if ty.is_closure() || ty.is_coroutine() {
|
||||
if ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure() {
|
||||
diag.note(
|
||||
"closures cannot capture themselves or take themselves as argument;\n\
|
||||
this error may be the result of a recent compiler bug-fix,\n\
|
||||
|
@ -1538,9 +1538,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
/// Obtains the latest type of the given closure; this may be a
|
||||
/// closure in the current function, in which case its
|
||||
/// `ClosureKind` may not yet be known.
|
||||
pub fn closure_kind(&self, closure_args: GenericArgsRef<'tcx>) -> Option<ty::ClosureKind> {
|
||||
let closure_kind_ty = closure_args.as_closure().kind_ty();
|
||||
let closure_kind_ty = self.shallow_resolve(closure_kind_ty);
|
||||
pub fn closure_kind(&self, closure_ty: Ty<'tcx>) -> Option<ty::ClosureKind> {
|
||||
let unresolved_kind_ty = match *closure_ty.kind() {
|
||||
ty::Closure(_, args) => args.as_closure().kind_ty(),
|
||||
ty::CoroutineClosure(_, args) => args.as_coroutine_closure().kind_ty(),
|
||||
_ => bug!("unexpected type {closure_ty}"),
|
||||
};
|
||||
let closure_kind_ty = self.shallow_resolve(unresolved_kind_ty);
|
||||
closure_kind_ty.to_opt_closure_kind()
|
||||
}
|
||||
|
||||
|
@ -456,6 +456,17 @@ where
|
||||
args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
|
||||
for upvar in args.as_coroutine_closure().upvar_tys() {
|
||||
upvar.visit_with(self);
|
||||
}
|
||||
|
||||
// FIXME(async_closures): Is this the right signature to visit here?
|
||||
args.as_coroutine_closure().signature_parts_ty().visit_with(self);
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// Skip lifetime parameters of the enclosing item(s)
|
||||
// Also skip the witness type, because that has no free regions.
|
||||
|
@ -103,6 +103,11 @@ fn compute_components<'tcx>(
|
||||
compute_components(tcx, tupled_ty, out, visited);
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
let tupled_ty = args.as_coroutine_closure().tupled_upvars_ty();
|
||||
compute_components(tcx, tupled_ty, out, visited);
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// Same as the closure case
|
||||
let tupled_ty = args.as_coroutine().tupled_upvars_ty();
|
||||
|
@ -1435,6 +1435,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
| ty::Bound(..)
|
||||
| ty::Error(_)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Placeholder(..)
|
||||
|
@ -355,7 +355,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||
Some(len) => is_ty_must_use(cx, ty, expr, span)
|
||||
.map(|inner| MustUsePath::Array(Box::new(inner), len)),
|
||||
},
|
||||
ty::Closure(..) => Some(MustUsePath::Closure(span)),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) => Some(MustUsePath::Closure(span)),
|
||||
ty::Coroutine(def_id, ..) => {
|
||||
// async fn should be treated as "implementor of `Future`"
|
||||
let must_use = if cx.tcx.coroutine_is_async(def_id) {
|
||||
|
@ -990,7 +990,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
AggregateKind::Closure(def_id, args) => ty::tls::with(|tcx| {
|
||||
AggregateKind::Closure(def_id, args)
|
||||
| AggregateKind::CoroutineClosure(def_id, args) => ty::tls::with(|tcx| {
|
||||
let name = if tcx.sess.opts.unstable_opts.span_free_formats {
|
||||
let args = tcx.lift(args).unwrap();
|
||||
format!("{{closure@{}}}", tcx.def_path_str_with_args(def_id, args),)
|
||||
|
@ -1350,6 +1350,7 @@ pub enum AggregateKind<'tcx> {
|
||||
|
||||
Closure(DefId, GenericArgsRef<'tcx>),
|
||||
Coroutine(DefId, GenericArgsRef<'tcx>),
|
||||
CoroutineClosure(DefId, GenericArgsRef<'tcx>),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
|
@ -202,6 +202,9 @@ impl<'tcx> Rvalue<'tcx> {
|
||||
AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args),
|
||||
AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args),
|
||||
AggregateKind::Coroutine(did, args) => Ty::new_coroutine(tcx, did, args),
|
||||
AggregateKind::CoroutineClosure(did, args) => {
|
||||
Ty::new_coroutine_closure(tcx, did, args)
|
||||
}
|
||||
},
|
||||
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
|
||||
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
|
||||
|
@ -739,6 +739,12 @@ macro_rules! make_mir_visitor {
|
||||
) => {
|
||||
self.visit_args(coroutine_args, location);
|
||||
}
|
||||
AggregateKind::CoroutineClosure(
|
||||
_,
|
||||
coroutine_closure_args,
|
||||
) => {
|
||||
self.visit_args(coroutine_closure_args, location);
|
||||
}
|
||||
}
|
||||
|
||||
for operand in operands {
|
||||
|
@ -1544,6 +1544,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
CoroutineWitness,
|
||||
Dynamic,
|
||||
Closure,
|
||||
CoroutineClosure,
|
||||
Tuple,
|
||||
Bound,
|
||||
Param,
|
||||
|
@ -299,7 +299,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
},
|
||||
ty::FnPtr(_) => "fn pointer".into(),
|
||||
ty::Dynamic(..) => "trait object".into(),
|
||||
ty::Closure(..) => "closure".into(),
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) => "closure".into(),
|
||||
ty::Coroutine(def_id, ..) => {
|
||||
format!("{:#}", tcx.coroutine_kind(def_id).unwrap()).into()
|
||||
}
|
||||
|
@ -128,7 +128,9 @@ pub fn simplify_type<'tcx>(
|
||||
_ => Some(SimplifiedType::MarkerTraitObject),
|
||||
},
|
||||
ty::Ref(_, _, mutbl) => Some(SimplifiedType::Ref(mutbl)),
|
||||
ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(SimplifiedType::Closure(def_id)),
|
||||
ty::FnDef(def_id, _) | ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _) => {
|
||||
Some(SimplifiedType::Closure(def_id))
|
||||
}
|
||||
ty::Coroutine(def_id, _) => Some(SimplifiedType::Coroutine(def_id)),
|
||||
ty::CoroutineWitness(def_id, _) => Some(SimplifiedType::CoroutineWitness(def_id)),
|
||||
ty::Never => Some(SimplifiedType::Never),
|
||||
@ -236,6 +238,7 @@ impl DeepRejectCtxt {
|
||||
| ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()),
|
||||
ty::FnDef(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Placeholder(..)
|
||||
@ -312,7 +315,7 @@ impl DeepRejectCtxt {
|
||||
},
|
||||
|
||||
// Impls cannot contain these types as these cannot be named directly.
|
||||
ty::FnDef(..) | ty::Closure(..) | ty::Coroutine(..) => false,
|
||||
ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) => false,
|
||||
|
||||
// Placeholder types don't unify with anything on their own
|
||||
ty::Placeholder(..) | ty::Bound(..) => false,
|
||||
|
@ -136,6 +136,22 @@ impl FlagComputation {
|
||||
self.add_ty(args.tupled_upvars_ty());
|
||||
}
|
||||
|
||||
&ty::CoroutineClosure(_, args) => {
|
||||
let args = args.as_coroutine_closure();
|
||||
let should_remove_further_specializable =
|
||||
!self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
|
||||
self.add_args(args.parent_args());
|
||||
if should_remove_further_specializable {
|
||||
self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE;
|
||||
}
|
||||
|
||||
self.add_ty(args.signature_parts_ty());
|
||||
self.add_ty(args.coroutine_witness_ty());
|
||||
self.add_ty(args.coroutine_captures_by_ref_ty());
|
||||
self.add_ty(args.kind_ty());
|
||||
self.add_ty(args.tupled_upvars_ty());
|
||||
}
|
||||
|
||||
&ty::Bound(debruijn, _) => {
|
||||
self.add_bound_var(debruijn);
|
||||
self.add_flags(TypeFlags::HAS_TY_BOUND);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use crate::ty::sty::{ClosureArgs, CoroutineArgs, InlineConstArgs};
|
||||
use crate::ty::sty::{ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs};
|
||||
use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||
|
||||
@ -288,6 +288,14 @@ impl<'tcx> GenericArgs<'tcx> {
|
||||
ClosureArgs { args: self }
|
||||
}
|
||||
|
||||
/// Interpret these generic args as the args of a coroutine-closure type.
|
||||
/// Coroutine-closure args have a particular structure controlled by the
|
||||
/// compiler that encodes information like the signature and closure kind;
|
||||
/// see `ty::CoroutineClosureArgs` struct for more comments.
|
||||
pub fn as_coroutine_closure(&'tcx self) -> CoroutineClosureArgs<'tcx> {
|
||||
CoroutineClosureArgs { args: self }
|
||||
}
|
||||
|
||||
/// Interpret these generic args as the args of a coroutine type.
|
||||
/// Coroutine args have a particular structure controlled by the
|
||||
/// compiler that encodes information like the signature and coroutine kind;
|
||||
|
@ -906,6 +906,12 @@ where
|
||||
i,
|
||||
),
|
||||
|
||||
ty::CoroutineClosure(_, args) => field_ty_or_layout(
|
||||
TyAndLayout { ty: args.as_coroutine_closure().tupled_upvars_ty(), ..this },
|
||||
cx,
|
||||
i,
|
||||
),
|
||||
|
||||
ty::Coroutine(def_id, args) => match this.variants {
|
||||
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
||||
args.as_coroutine()
|
||||
|
@ -259,6 +259,7 @@ fn characteristic_def_id_of_type_cached<'a>(
|
||||
|
||||
ty::FnDef(def_id, _)
|
||||
| ty::Closure(def_id, _)
|
||||
| ty::CoroutineClosure(def_id, _)
|
||||
| ty::Coroutine(def_id, _)
|
||||
| ty::CoroutineWitness(def_id, _)
|
||||
| ty::Foreign(def_id) => Some(def_id),
|
||||
|
@ -874,6 +874,48 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||
}
|
||||
p!("}}");
|
||||
}
|
||||
ty::CoroutineClosure(did, args) => {
|
||||
p!(write("{{"));
|
||||
if !self.should_print_verbose() {
|
||||
p!(write("coroutine closure"));
|
||||
// FIXME(eddyb) should use `def_span`.
|
||||
if let Some(did) = did.as_local() {
|
||||
if self.tcx().sess.opts.unstable_opts.span_free_formats {
|
||||
p!("@", print_def_path(did.to_def_id(), args));
|
||||
} else {
|
||||
let span = self.tcx().def_span(did);
|
||||
let preference = if with_forced_trimmed_paths() {
|
||||
FileNameDisplayPreference::Short
|
||||
} else {
|
||||
FileNameDisplayPreference::Remapped
|
||||
};
|
||||
p!(write(
|
||||
"@{}",
|
||||
// This may end up in stderr diagnostics but it may also be emitted
|
||||
// into MIR. Hence we use the remapped path if available
|
||||
self.tcx().sess.source_map().span_to_string(span, preference)
|
||||
));
|
||||
}
|
||||
} else {
|
||||
p!(write("@"), print_def_path(did, args));
|
||||
}
|
||||
} else {
|
||||
p!(print_def_path(did, args));
|
||||
p!(
|
||||
" closure_kind_ty=",
|
||||
print(args.as_coroutine_closure().kind_ty()),
|
||||
" signature_parts_ty=",
|
||||
print(args.as_coroutine_closure().signature_parts_ty()),
|
||||
" upvar_tys=",
|
||||
print(args.as_coroutine_closure().tupled_upvars_ty()),
|
||||
" coroutine_captures_by_ref_ty=",
|
||||
print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
|
||||
" coroutine_witness_ty=",
|
||||
print(args.as_coroutine_closure().coroutine_witness_ty())
|
||||
);
|
||||
}
|
||||
p!("}}");
|
||||
}
|
||||
ty::Array(ty, sz) => p!("[", print(ty), "; ", print(sz), "]"),
|
||||
ty::Slice(ty) => p!("[", print(ty), "]"),
|
||||
}
|
||||
|
@ -481,6 +481,13 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
||||
Ok(Ty::new_closure(tcx, a_id, args))
|
||||
}
|
||||
|
||||
(&ty::CoroutineClosure(a_id, a_args), &ty::CoroutineClosure(b_id, b_args))
|
||||
if a_id == b_id =>
|
||||
{
|
||||
let args = relate_args_invariantly(relation, a_args, b_args)?;
|
||||
Ok(Ty::new_coroutine_closure(tcx, a_id, args))
|
||||
}
|
||||
|
||||
(&ty::RawPtr(a_mt), &ty::RawPtr(b_mt)) => {
|
||||
let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?;
|
||||
Ok(Ty::new_ptr(tcx, mt))
|
||||
|
@ -584,6 +584,9 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
ty::CoroutineWitness(did, args.try_fold_with(folder)?)
|
||||
}
|
||||
ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
|
||||
ty::CoroutineClosure(did, args) => {
|
||||
ty::CoroutineClosure(did, args.try_fold_with(folder)?)
|
||||
}
|
||||
ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
|
||||
|
||||
ty::Bool
|
||||
@ -632,6 +635,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||
ty::Coroutine(_did, ref args) => args.visit_with(visitor),
|
||||
ty::CoroutineWitness(_did, ref args) => args.visit_with(visitor),
|
||||
ty::Closure(_did, ref args) => args.visit_with(visitor),
|
||||
ty::CoroutineClosure(_did, ref args) => args.visit_with(visitor),
|
||||
ty::Alias(_, ref data) => data.visit_with(visitor),
|
||||
|
||||
ty::Bool
|
||||
|
@ -269,6 +269,97 @@ impl<'tcx> ClosureArgs<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct CoroutineClosureArgs<'tcx> {
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
}
|
||||
|
||||
pub struct CoroutineClosureArgsParts<'tcx> {
|
||||
pub parent_args: &'tcx [GenericArg<'tcx>],
|
||||
pub closure_kind_ty: Ty<'tcx>,
|
||||
pub signature_parts_ty: Ty<'tcx>,
|
||||
pub tupled_upvars_ty: Ty<'tcx>,
|
||||
pub coroutine_captures_by_ref_ty: Ty<'tcx>,
|
||||
pub coroutine_witness_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> CoroutineClosureArgs<'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
parts: CoroutineClosureArgsParts<'tcx>,
|
||||
) -> CoroutineClosureArgs<'tcx> {
|
||||
CoroutineClosureArgs {
|
||||
args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
|
||||
parts.closure_kind_ty.into(),
|
||||
parts.signature_parts_ty.into(),
|
||||
parts.tupled_upvars_ty.into(),
|
||||
parts.coroutine_captures_by_ref_ty.into(),
|
||||
parts.coroutine_witness_ty.into(),
|
||||
])),
|
||||
}
|
||||
}
|
||||
|
||||
fn split(self) -> CoroutineClosureArgsParts<'tcx> {
|
||||
match self.args[..] {
|
||||
[
|
||||
ref parent_args @ ..,
|
||||
closure_kind_ty,
|
||||
signature_parts_ty,
|
||||
tupled_upvars_ty,
|
||||
coroutine_captures_by_ref_ty,
|
||||
coroutine_witness_ty,
|
||||
] => CoroutineClosureArgsParts {
|
||||
parent_args,
|
||||
closure_kind_ty: closure_kind_ty.expect_ty(),
|
||||
signature_parts_ty: signature_parts_ty.expect_ty(),
|
||||
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
|
||||
coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
|
||||
coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
|
||||
},
|
||||
_ => bug!("closure args missing synthetics"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn upvar_tys(self) -> &'tcx List<Ty<'tcx>> {
|
||||
match self.tupled_upvars_ty().kind() {
|
||||
TyKind::Error(_) => ty::List::empty(),
|
||||
TyKind::Tuple(..) => self.tupled_upvars_ty().tuple_fields(),
|
||||
TyKind::Infer(_) => bug!("upvar_tys called before capture types are inferred"),
|
||||
ty => bug!("Unexpected representation of upvar types tuple {:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn tupled_upvars_ty(self) -> Ty<'tcx> {
|
||||
self.split().tupled_upvars_ty
|
||||
}
|
||||
|
||||
pub fn kind_ty(self) -> Ty<'tcx> {
|
||||
self.split().closure_kind_ty
|
||||
}
|
||||
|
||||
pub fn kind(self) -> ty::ClosureKind {
|
||||
self.kind_ty().to_opt_closure_kind().unwrap()
|
||||
}
|
||||
|
||||
pub fn signature_parts_ty(self) -> Ty<'tcx> {
|
||||
self.split().signature_parts_ty
|
||||
}
|
||||
|
||||
pub fn coroutine_captures_by_ref_ty(self) -> Ty<'tcx> {
|
||||
self.split().coroutine_captures_by_ref_ty
|
||||
}
|
||||
|
||||
pub fn coroutine_witness_ty(self) -> Ty<'tcx> {
|
||||
self.split().coroutine_witness_ty
|
||||
}
|
||||
}
|
||||
|
||||
/// Similar to `ClosureArgs`; see the above documentation for more.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
|
||||
pub struct CoroutineArgs<'tcx> {
|
||||
@ -479,6 +570,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
||||
pub enum UpvarArgs<'tcx> {
|
||||
Closure(GenericArgsRef<'tcx>),
|
||||
Coroutine(GenericArgsRef<'tcx>),
|
||||
CoroutineClosure(GenericArgsRef<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> UpvarArgs<'tcx> {
|
||||
@ -490,6 +582,7 @@ impl<'tcx> UpvarArgs<'tcx> {
|
||||
let tupled_tys = match self {
|
||||
UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
|
||||
UpvarArgs::Coroutine(args) => args.as_coroutine().tupled_upvars_ty(),
|
||||
UpvarArgs::CoroutineClosure(args) => args.as_coroutine_closure().tupled_upvars_ty(),
|
||||
};
|
||||
|
||||
match tupled_tys.kind() {
|
||||
@ -505,6 +598,7 @@ impl<'tcx> UpvarArgs<'tcx> {
|
||||
match self {
|
||||
UpvarArgs::Closure(args) => args.as_closure().tupled_upvars_ty(),
|
||||
UpvarArgs::Coroutine(args) => args.as_coroutine().tupled_upvars_ty(),
|
||||
UpvarArgs::CoroutineClosure(args) => args.as_coroutine_closure().tupled_upvars_ty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1393,6 +1487,20 @@ impl<'tcx> Ty<'tcx> {
|
||||
Ty::new(tcx, Closure(def_id, closure_args))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_coroutine_closure(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
closure_args: GenericArgsRef<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert_eq!(
|
||||
closure_args.len(),
|
||||
tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
|
||||
"closure constructed with incorrect substitutions"
|
||||
);
|
||||
Ty::new(tcx, CoroutineClosure(def_id, closure_args))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_coroutine(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -1795,7 +1903,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
type BreakTy = ();
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::Closure(_, _) = t.kind() {
|
||||
if let ty::Closure(..) = t.kind() {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
t.super_visit_with(self)
|
||||
@ -1942,6 +2050,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
@ -1980,6 +2089,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Error(_)
|
||||
// Extern types have metadata = ().
|
||||
@ -2077,6 +2187,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Error(_) => true,
|
||||
|
||||
@ -2140,7 +2251,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
ty::Coroutine(..) | ty::CoroutineWitness(..) => false,
|
||||
|
||||
// Might be, but not "trivial" so just giving the safe answer.
|
||||
ty::Adt(..) | ty::Closure(..) => false,
|
||||
ty::Adt(..) | ty::Closure(..) | ty::CoroutineClosure(..) => false,
|
||||
|
||||
// Needs normalization or revealing to determine, so no is the safe answer.
|
||||
ty::Alias(..) => false,
|
||||
@ -2212,6 +2323,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
| FnPtr(_)
|
||||
| Dynamic(_, _, _)
|
||||
| Closure(_, _)
|
||||
| CoroutineClosure(_, _)
|
||||
| Coroutine(_, _)
|
||||
| CoroutineWitness(..)
|
||||
| Never
|
||||
|
@ -1119,6 +1119,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
ty::Adt(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Foreign(_)
|
||||
| ty::Coroutine(..)
|
||||
@ -1158,6 +1159,7 @@ impl<'tcx> Ty<'tcx> {
|
||||
ty::Adt(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Foreign(_)
|
||||
| ty::Coroutine(..)
|
||||
@ -1280,7 +1282,11 @@ impl<'tcx> Ty<'tcx> {
|
||||
// Conservatively return `false` for all others...
|
||||
|
||||
// Anonymous function types
|
||||
ty::FnDef(..) | ty::Closure(..) | ty::Dynamic(..) | ty::Coroutine(..) => false,
|
||||
ty::FnDef(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Coroutine(..) => false,
|
||||
|
||||
// Generic or inferred types
|
||||
//
|
||||
@ -1424,6 +1430,7 @@ pub fn needs_drop_components<'tcx>(
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(_)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..) => Ok(smallvec![ty]),
|
||||
}
|
||||
@ -1456,7 +1463,11 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
|
||||
|
||||
// Not trivial because they have components, and instead of looking inside,
|
||||
// we'll just perform trait selection.
|
||||
ty::Closure(..) | ty::Coroutine(..) | ty::CoroutineWitness(..) | ty::Adt(..) => false,
|
||||
ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Adt(..) => false,
|
||||
|
||||
ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),
|
||||
|
||||
|
@ -189,6 +189,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
}
|
||||
ty::Adt(_, args)
|
||||
| ty::Closure(_, args)
|
||||
| ty::CoroutineClosure(_, args)
|
||||
| ty::Coroutine(_, args)
|
||||
| ty::CoroutineWitness(_, args)
|
||||
| ty::FnDef(_, args) => {
|
||||
|
@ -483,6 +483,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
UpvarArgs::Closure(args) => {
|
||||
Box::new(AggregateKind::Closure(closure_id.to_def_id(), args))
|
||||
}
|
||||
UpvarArgs::CoroutineClosure(args) => {
|
||||
Box::new(AggregateKind::CoroutineClosure(closure_id.to_def_id(), args))
|
||||
}
|
||||
};
|
||||
block.and(Rvalue::Aggregate(result, operands))
|
||||
}
|
||||
|
@ -495,7 +495,7 @@ fn construct_fn<'tcx>(
|
||||
args.as_coroutine().yield_ty(),
|
||||
args.as_coroutine().resume_ty(),
|
||||
))),
|
||||
ty::Closure(..) | ty::FnDef(..) => None,
|
||||
ty::Closure(..) | ty::CoroutineClosure(..) | ty::FnDef(..) => None,
|
||||
ty => span_bug!(span_with_body, "unexpected type of body: {ty:?}"),
|
||||
};
|
||||
|
||||
|
@ -861,6 +861,9 @@ where
|
||||
let ty = self.place_ty(self.place);
|
||||
match ty.kind() {
|
||||
ty::Closure(_, args) => self.open_drop_for_tuple(args.as_closure().upvar_tys()),
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
self.open_drop_for_tuple(args.as_coroutine_closure().upvar_tys())
|
||||
}
|
||||
// Note that `elaborate_drops` only drops the upvars of a coroutine,
|
||||
// and this is ok because `open_drop` here can only be reached
|
||||
// within that own coroutine's resume function.
|
||||
|
@ -154,7 +154,8 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -177,7 +178,10 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
union_path.get_or_insert(base);
|
||||
}
|
||||
}
|
||||
ty::Closure(_, _) | ty::Coroutine(_, _) | ty::Tuple(_) => (),
|
||||
ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::Tuple(_) => (),
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
@ -39,6 +39,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
|
||||
let body_abi = match body_ty.kind() {
|
||||
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
||||
ty::Closure(..) => Abi::RustCall,
|
||||
ty::CoroutineClosure(..) => Abi::RustCall,
|
||||
ty::Coroutine(..) => Abi::Rust,
|
||||
_ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
|
||||
};
|
||||
|
@ -128,7 +128,9 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
||||
),
|
||||
}
|
||||
}
|
||||
&AggregateKind::Closure(def_id, _) | &AggregateKind::Coroutine(def_id, _) => {
|
||||
&AggregateKind::Closure(def_id, _)
|
||||
| &AggregateKind::CoroutineClosure(def_id, _)
|
||||
| &AggregateKind::Coroutine(def_id, _) => {
|
||||
let def_id = def_id.expect_local();
|
||||
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
|
||||
self.tcx.mir_unsafety_check_result(def_id);
|
||||
|
@ -696,6 +696,7 @@ fn try_write_constant<'tcx>(
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Dynamic(..) => throw_machine_stop_str!("unsupported type"),
|
||||
|
||||
|
@ -57,6 +57,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
|
||||
let body_abi = match body_ty.kind() {
|
||||
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
||||
ty::Closure(..) => Abi::RustCall,
|
||||
ty::CoroutineClosure(..) => Abi::RustCall,
|
||||
ty::Coroutine(..) => Abi::Rust,
|
||||
_ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
|
||||
};
|
||||
|
@ -861,9 +861,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
if fields.is_empty() {
|
||||
let is_zst = match *kind {
|
||||
AggregateKind::Array(..) | AggregateKind::Tuple | AggregateKind::Closure(..) => {
|
||||
true
|
||||
}
|
||||
AggregateKind::Array(..)
|
||||
| AggregateKind::Tuple
|
||||
| AggregateKind::Closure(..)
|
||||
| AggregateKind::CoroutineClosure(..) => true,
|
||||
// Only enums can be non-ZST.
|
||||
AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
|
||||
// Coroutines are never ZST, as they at least contain the implicit states.
|
||||
@ -885,7 +886,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
||||
assert!(!fields.is_empty());
|
||||
(AggregateTy::Tuple, FIRST_VARIANT)
|
||||
}
|
||||
AggregateKind::Closure(did, substs) | AggregateKind::Coroutine(did, substs) => {
|
||||
AggregateKind::Closure(did, substs)
|
||||
| AggregateKind::CoroutineClosure(did, substs)
|
||||
| AggregateKind::Coroutine(did, substs) => {
|
||||
(AggregateTy::Def(did, substs), FIRST_VARIANT)
|
||||
}
|
||||
AggregateKind::Adt(did, variant_index, substs, _, None) => {
|
||||
|
@ -46,6 +46,7 @@ fn maybe_zst(ty: Ty<'_>) -> bool {
|
||||
ty::Adt(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Tuple(..)
|
||||
| ty::Alias(ty::Opaque, ..) => true,
|
||||
// definitely ZST
|
||||
|
@ -332,7 +332,8 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -719,6 +719,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
ty::ClosureKind::FnMut => {}
|
||||
ty::ClosureKind::FnOnce => return succ,
|
||||
},
|
||||
ty::CoroutineClosure(_def_id, args) => match args.as_coroutine_closure().kind() {
|
||||
ty::ClosureKind::Fn => {}
|
||||
ty::ClosureKind::FnMut => {}
|
||||
ty::ClosureKind::FnOnce => return succ,
|
||||
},
|
||||
ty::Coroutine(..) => return succ,
|
||||
_ => {
|
||||
span_bug!(
|
||||
|
@ -423,7 +423,8 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::Alias(_, _)
|
||||
| ty::Param(_)
|
||||
|
@ -182,6 +182,7 @@ where
|
||||
| ty::Foreign(def_id)
|
||||
| ty::FnDef(def_id, ..)
|
||||
| ty::Closure(def_id, ..)
|
||||
| ty::CoroutineClosure(def_id, ..)
|
||||
| ty::Coroutine(def_id, ..) => {
|
||||
self.def_id_visitor.visit_def_id(def_id, "type", &ty)?;
|
||||
if V::SHALLOW {
|
||||
|
@ -538,6 +538,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
|
||||
tables.tcx.coroutine_movability(*def_id).stable(tables),
|
||||
)
|
||||
}
|
||||
mir::AggregateKind::CoroutineClosure(..) => {
|
||||
todo!("FIXME(async_closure): Lower these to SMIR")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -383,6 +383,7 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
|
||||
tables.closure_def(*def_id),
|
||||
generic_args.stable(tables),
|
||||
)),
|
||||
ty::CoroutineClosure(..) => todo!("/* TODO */"),
|
||||
ty::Coroutine(def_id, generic_args) => TyKind::RigidTy(RigidTy::Coroutine(
|
||||
tables.coroutine_def(*def_id),
|
||||
generic_args.stable(tables),
|
||||
|
@ -211,6 +211,7 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||
ty::FnDef(def_id, args)
|
||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||
| ty::Closure(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args)
|
||||
| ty::Coroutine(def_id, args) => self.print_def_path(def_id, args),
|
||||
|
||||
// The `pretty_print_type` formatting of array size depends on
|
||||
@ -281,7 +282,11 @@ impl<'tcx> Printer<'tcx> for SymbolPrinter<'tcx> {
|
||||
// Similar to `pretty_path_qualified`, but for the other
|
||||
// types that are printed as paths (see `print_type` above).
|
||||
match self_ty.kind() {
|
||||
ty::FnDef(..) | ty::Alias(..) | ty::Closure(..) | ty::Coroutine(..)
|
||||
ty::FnDef(..)
|
||||
| ty::Alias(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
if trait_ref.is_none() =>
|
||||
{
|
||||
self.print_type(self_ty)
|
||||
|
@ -628,7 +628,9 @@ fn encode_ty<'tcx>(
|
||||
}
|
||||
|
||||
// Function types
|
||||
ty::FnDef(def_id, args) | ty::Closure(def_id, args) => {
|
||||
ty::FnDef(def_id, args)
|
||||
| ty::Closure(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args) => {
|
||||
// u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
|
||||
// as vendor extended type.
|
||||
let mut s = String::new();
|
||||
@ -895,6 +897,10 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, options));
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(def_id, args) => {
|
||||
ty = Ty::new_coroutine_closure(tcx, *def_id, transform_args(tcx, args, options));
|
||||
}
|
||||
|
||||
ty::Coroutine(def_id, args) => {
|
||||
ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, options));
|
||||
}
|
||||
|
@ -386,6 +386,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
| ty::FnDef(def_id, args)
|
||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||
| ty::Closure(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args)
|
||||
| ty::Coroutine(def_id, args) => {
|
||||
self.print_def_path(def_id, args)?;
|
||||
}
|
||||
|
@ -340,7 +340,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::Never
|
||||
| ty::Tuple(_) => {
|
||||
@ -538,6 +539,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -694,6 +696,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
| ty::FnPtr(_)
|
||||
| ty::Alias(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -57,6 +57,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
||||
|
||||
ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::CoroutineClosure(_, args) => Ok(vec![args.as_coroutine_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
let coroutine_args = args.as_coroutine();
|
||||
Ok(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()])
|
||||
@ -128,6 +130,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Dynamic(_, _, ty::DynStar)
|
||||
| ty::Error(_) => Ok(vec![]),
|
||||
@ -193,6 +196,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
||||
|
||||
ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::CoroutineClosure(..) => Err(NoSolution),
|
||||
|
||||
ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) {
|
||||
Movability::Static => Err(NoSolution),
|
||||
Movability::Movable => {
|
||||
@ -267,6 +272,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
|
||||
}
|
||||
Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output()))))
|
||||
}
|
||||
|
||||
// Coroutine closures don't implement `Fn` traits the normal way.
|
||||
ty::CoroutineClosure(..) => Err(NoSolution),
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
@ -391,6 +391,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
@ -627,6 +628,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
|
@ -950,7 +950,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -863,7 +863,7 @@ where
|
||||
}
|
||||
}
|
||||
ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
|
||||
ty::Closure(did, ..) | ty::Coroutine(did, ..) => {
|
||||
ty::Closure(did, ..) | ty::CoroutineClosure(did, ..) | ty::Coroutine(did, ..) => {
|
||||
if self.def_id_is_local(did) {
|
||||
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
|
||||
} else {
|
||||
|
@ -959,9 +959,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Option<ErrorGuaranteed> {
|
||||
if let ty::Closure(closure_def_id, closure_args) = *trait_ref.self_ty().skip_binder().kind()
|
||||
let self_ty = trait_ref.self_ty().skip_binder();
|
||||
if let ty::Closure(closure_def_id, closure_args) = *self_ty.kind()
|
||||
&& let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
|
||||
&& let Some(found_kind) = self.closure_kind(closure_args)
|
||||
&& let Some(found_kind) = self.closure_kind(self_ty)
|
||||
&& !found_kind.extends(expected_kind)
|
||||
&& let sig = closure_args.as_closure().sig()
|
||||
&& self.can_sub(
|
||||
@ -1875,6 +1876,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
ty::Coroutine(..) => Some(18),
|
||||
ty::Foreign(..) => Some(19),
|
||||
ty::CoroutineWitness(..) => Some(20),
|
||||
ty::CoroutineClosure(..) => Some(21),
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
|
||||
}
|
||||
}
|
||||
|
@ -1854,6 +1854,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -1903,6 +1904,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -48,7 +48,11 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
// (T1..Tn) and closures have same properties as T1..Tn --
|
||||
// check if *all* of them are trivial.
|
||||
ty::Tuple(tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
|
||||
ty::Closure(_, args) => trivial_dropck_outlives(tcx, args.as_closure().tupled_upvars_ty()),
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
trivial_dropck_outlives(tcx, args.as_coroutine_closure().tupled_upvars_ty())
|
||||
}
|
||||
|
||||
ty::Adt(def, _) => {
|
||||
if Some(def.did()) == tcx.lang_items().manually_drop() {
|
||||
@ -239,6 +243,22 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
||||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in args.as_coroutine_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty_inner(
|
||||
tcx,
|
||||
param_env,
|
||||
span,
|
||||
depth + 1,
|
||||
ty,
|
||||
constraints,
|
||||
)?;
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
// in the interior, and sit idle when coroutine yields
|
||||
|
@ -306,11 +306,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// Okay to skip binder because the args on closure types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
match *obligation.self_ty().skip_binder().kind() {
|
||||
ty::Closure(def_id, closure_args) => {
|
||||
let self_ty = obligation.self_ty().skip_binder();
|
||||
match *self_ty.kind() {
|
||||
ty::Closure(def_id, _) => {
|
||||
let is_const = self.tcx().is_const_fn_raw(def_id);
|
||||
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
|
||||
match self.infcx.closure_kind(closure_args) {
|
||||
match self.infcx.closure_kind(self_ty) {
|
||||
Some(closure_kind) => {
|
||||
debug!(?closure_kind, "assemble_unboxed_candidates");
|
||||
if closure_kind.extends(kind) {
|
||||
@ -488,7 +489,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(_)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -623,7 +625,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
@ -1000,6 +1003,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Tuple(_)
|
||||
| ty::CoroutineWitness(..) => {
|
||||
@ -1076,7 +1080,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
@ -1139,6 +1144,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
| ty::Placeholder(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -2106,6 +2106,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Dynamic(_, _, ty::DynStar)
|
||||
| ty::Error(_) => {
|
||||
@ -2227,6 +2228,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(async_closures): These are never clone, for now.
|
||||
ty::CoroutineClosure(_, _) => None,
|
||||
|
||||
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
|
||||
// Fallback to whatever user-defined impls exist in this case.
|
||||
None
|
||||
@ -2305,6 +2309,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
t.rebind(vec![ty])
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
let ty = self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty());
|
||||
t.rebind(vec![ty])
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
|
||||
let witness = args.as_coroutine().witness();
|
||||
|
@ -79,6 +79,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
||||
ty::Closure(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::CoroutineClosure(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::Coroutine(..) | ty::CoroutineWitness(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
|
@ -727,6 +727,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(did, args) => {
|
||||
// See the above comments.
|
||||
walker.skip_current_subtree();
|
||||
self.compute(args.as_coroutine_closure().tupled_upvars_ty().into());
|
||||
let obligations = self.nominal_obligations(did, args);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
// let the loop iterate into the argument/return
|
||||
// types appearing in the fn signature
|
||||
|
@ -215,6 +215,7 @@ fn resolve_associated_item<'tcx>(
|
||||
ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Tuple(..) => {}
|
||||
_ => return Ok(None),
|
||||
};
|
||||
|
@ -328,6 +328,17 @@ fn layout_of_uncached<'tcx>(
|
||||
)?
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
let tys = args.as_coroutine_closure().upvar_tys();
|
||||
univariant(
|
||||
&tys.iter()
|
||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
||||
.try_collect::<IndexVec<_, _>>()?,
|
||||
&ReprOptions::default(),
|
||||
StructKind::AlwaysSized,
|
||||
)?
|
||||
}
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
let kind =
|
||||
if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
|
||||
|
@ -172,6 +172,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
for upvar in args.as_coroutine_closure().upvar_tys() {
|
||||
queue_type(self, upvar);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a `Drop` impl and whether this is a union or
|
||||
// `ManuallyDrop`. If it's a struct or enum without a `Drop`
|
||||
// impl then check whether the field types need `Drop`.
|
||||
|
@ -18,7 +18,9 @@ fn sized_constraint_for_ty<'tcx>(
|
||||
|
||||
let result = match ty.kind() {
|
||||
Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
|
||||
| FnPtr(_) | Array(..) | Closure(..) | Coroutine(..) | Never => vec![],
|
||||
| FnPtr(_) | Array(..) | Closure(..) | CoroutineClosure(..) | Coroutine(..) | Never => {
|
||||
vec![]
|
||||
}
|
||||
|
||||
Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | CoroutineWitness(..) => {
|
||||
// these are never sized - return the target type
|
||||
|
@ -202,6 +202,9 @@ pub enum TyKind<I: Interner> {
|
||||
/// `ClosureArgs` for more details.
|
||||
Closure(I::DefId, I::GenericArgs),
|
||||
|
||||
/// TODO
|
||||
CoroutineClosure(I::DefId, I::GenericArgs),
|
||||
|
||||
/// The anonymous type of a coroutine. Used to represent the type of
|
||||
/// `|a| yield a`.
|
||||
///
|
||||
@ -317,16 +320,17 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
|
||||
FnPtr(_) => 13,
|
||||
Dynamic(..) => 14,
|
||||
Closure(_, _) => 15,
|
||||
Coroutine(_, _) => 16,
|
||||
CoroutineWitness(_, _) => 17,
|
||||
Never => 18,
|
||||
Tuple(_) => 19,
|
||||
Alias(_, _) => 20,
|
||||
Param(_) => 21,
|
||||
Bound(_, _) => 22,
|
||||
Placeholder(_) => 23,
|
||||
Infer(_) => 24,
|
||||
Error(_) => 25,
|
||||
CoroutineClosure(_, _) => 16,
|
||||
Coroutine(_, _) => 17,
|
||||
CoroutineWitness(_, _) => 18,
|
||||
Never => 19,
|
||||
Tuple(_) => 20,
|
||||
Alias(_, _) => 21,
|
||||
Param(_) => 22,
|
||||
Bound(_, _) => 23,
|
||||
Placeholder(_) => 24,
|
||||
Infer(_) => 25,
|
||||
Error(_) => 26,
|
||||
}
|
||||
}
|
||||
|
||||
@ -356,6 +360,7 @@ impl<I: Interner> PartialEq for TyKind<I> {
|
||||
a_p == b_p && a_r == b_r && a_repr == b_repr
|
||||
}
|
||||
(Closure(a_d, a_s), Closure(b_d, b_s)) => a_d == b_d && a_s == b_s,
|
||||
(CoroutineClosure(a_d, a_s), CoroutineClosure(b_d, b_s)) => a_d == b_d && a_s == b_s,
|
||||
(Coroutine(a_d, a_s), Coroutine(b_d, b_s)) => a_d == b_d && a_s == b_s,
|
||||
(CoroutineWitness(a_d, a_s), CoroutineWitness(b_d, b_s)) => a_d == b_d && a_s == b_s,
|
||||
(Tuple(a_t), Tuple(b_t)) => a_t == b_t,
|
||||
@ -430,6 +435,9 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
|
||||
}
|
||||
},
|
||||
Closure(d, s) => f.debug_tuple("Closure").field(d).field(&this.wrap(s)).finish(),
|
||||
CoroutineClosure(d, s) => {
|
||||
f.debug_tuple("CoroutineClosure").field(d).field(&this.wrap(s)).finish()
|
||||
}
|
||||
Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&this.wrap(s)).finish(),
|
||||
CoroutineWitness(d, s) => {
|
||||
f.debug_tuple("CoroutineWitness").field(d).field(&this.wrap(s)).finish()
|
||||
|
@ -2286,6 +2286,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
}
|
||||
|
||||
ty::Closure(..) => panic!("Closure"),
|
||||
ty::CoroutineClosure(..) => panic!("CoroutineClosure"),
|
||||
ty::Coroutine(..) => panic!("Coroutine"),
|
||||
ty::Placeholder(..) => panic!("Placeholder"),
|
||||
ty::CoroutineWitness(..) => panic!("CoroutineWitness"),
|
||||
|
@ -503,6 +503,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
}
|
||||
ty::Alias(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Dynamic(..)
|
||||
|
@ -881,6 +881,7 @@ impl TyCoercionStability {
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
| ty::Alias(ty::Projection, _) => Self::Deref,
|
||||
|
@ -490,6 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
||||
format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
|
||||
},
|
||||
},
|
||||
ClosureKind::CoroutineClosure(desugaring) => format!(
|
||||
"ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})"
|
||||
),
|
||||
};
|
||||
|
||||
let ret_ty = match fn_decl.output {
|
||||
|
@ -40,10 +40,10 @@ if let ExprKind::Block(block, None) = expr.kind
|
||||
{
|
||||
// report your lint here
|
||||
}
|
||||
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = expr.kind
|
||||
if let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind
|
||||
&& let FnRetTy::DefaultReturn(_) = fn_decl.output
|
||||
&& expr1 = &cx.tcx.hir().body(body_id).value
|
||||
&& let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
|
||||
&& let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind
|
||||
&& let FnRetTy::DefaultReturn(_) = fn_decl1.output
|
||||
&& expr2 = &cx.tcx.hir().body(body_id1).value
|
||||
&& let ExprKind::Block(block, None) = expr2.kind
|
||||
|
@ -29,6 +29,7 @@ fn main() {
|
||||
TyKind::FnPtr(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::Dynamic(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::Closure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::CoroutineClosure(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::Coroutine(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::CoroutineWitness(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
TyKind::Never => (), //~ ERROR usage of `ty::TyKind::<kind>`
|
||||
|
@ -109,71 +109,77 @@ LL | TyKind::Closure(..) => (),
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:32:9
|
||||
|
|
||||
LL | TyKind::Coroutine(..) => (),
|
||||
LL | TyKind::CoroutineClosure(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:33:9
|
||||
|
|
||||
LL | TyKind::CoroutineWitness(..) => (),
|
||||
LL | TyKind::Coroutine(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:34:9
|
||||
|
|
||||
LL | TyKind::Never => (),
|
||||
LL | TyKind::CoroutineWitness(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:35:9
|
||||
|
|
||||
LL | TyKind::Tuple(..) => (),
|
||||
LL | TyKind::Never => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:36:9
|
||||
|
|
||||
LL | TyKind::Alias(..) => (),
|
||||
LL | TyKind::Tuple(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:37:9
|
||||
|
|
||||
LL | TyKind::Param(..) => (),
|
||||
LL | TyKind::Alias(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:38:9
|
||||
|
|
||||
LL | TyKind::Bound(..) => (),
|
||||
LL | TyKind::Param(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:39:9
|
||||
|
|
||||
LL | TyKind::Placeholder(..) => (),
|
||||
LL | TyKind::Bound(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:40:9
|
||||
|
|
||||
LL | TyKind::Infer(..) => (),
|
||||
LL | TyKind::Placeholder(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:41:9
|
||||
|
|
||||
LL | TyKind::Infer(..) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:42:9
|
||||
|
|
||||
LL | TyKind::Error(_) => (),
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:46:12
|
||||
--> $DIR/ty_tykind_usage.rs:47:12
|
||||
|
|
||||
LL | if let TyKind::Int(int_ty) = kind {}
|
||||
| ^^^^^^ help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: usage of `ty::TyKind`
|
||||
--> $DIR/ty_tykind_usage.rs:48:24
|
||||
--> $DIR/ty_tykind_usage.rs:49:24
|
||||
|
|
||||
LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
|
||||
| ^^^^^^^^^^
|
||||
@ -181,7 +187,7 @@ LL | fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
|
||||
= help: try using `Ty` instead
|
||||
|
||||
error: usage of `ty::TyKind`
|
||||
--> $DIR/ty_tykind_usage.rs:50:37
|
||||
--> $DIR/ty_tykind_usage.rs:51:37
|
||||
|
|
||||
LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
|
||||
| ^^^^^^^^^^^
|
||||
@ -189,7 +195,7 @@ LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
|
||||
= help: try using `Ty` instead
|
||||
|
||||
error: usage of `ty::TyKind`
|
||||
--> $DIR/ty_tykind_usage.rs:50:53
|
||||
--> $DIR/ty_tykind_usage.rs:51:53
|
||||
|
|
||||
LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
|
||||
| ^^^^^^^^^^^
|
||||
@ -197,12 +203,12 @@ LL | fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
|
||||
= help: try using `Ty` instead
|
||||
|
||||
error: usage of `ty::TyKind::<kind>`
|
||||
--> $DIR/ty_tykind_usage.rs:53:9
|
||||
--> $DIR/ty_tykind_usage.rs:54:9
|
||||
|
|
||||
LL | IrTyKind::Bool
|
||||
| --------^^^^^^
|
||||
| |
|
||||
| help: try using `ty::<kind>` directly: `ty`
|
||||
|
||||
error: aborting due to 32 previous errors
|
||||
error: aborting due to 33 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user