diff options
Diffstat (limited to 'compiler/rustc_borrowck/src')
| -rw-r--r-- | compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/lib.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/path_utils.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/mod.rs | 33 | 
4 files changed, 39 insertions, 8 deletions
| diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 3fddf67f55b..55649ec2f16 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -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. diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8b5e548345c..eaf9fc45837 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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(_) diff --git a/compiler/rustc_borrowck/src/path_utils.rs b/compiler/rustc_borrowck/src/path_utils.rs index 2d997dfadf0..4cfde47664e 100644 --- a/compiler/rustc_borrowck/src/path_utils.rs +++ b/compiler/rustc_borrowck/src/path_utils.rs @@ -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) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 59c4d9a6c78..90a9844fda9 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -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), }; | 
