1use std::fmt::Write;
2
3use rustc_data_structures::fx::FxIndexMap;
4use rustc_hir as hir;
5use rustc_hir::HirId;
6use rustc_hir::def_id::LocalDefId;
7use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
8use rustc_span::def_id::LocalDefIdMap;
9use rustc_span::{Ident, Span, Symbol};
10
11use super::TyCtxt;
12use crate::hir::place::{
13 Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
14};
15use crate::query::Providers;
16use crate::{mir, ty};
17
18pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::from_u32(1);
21
22#[derive(#[automatically_derived]
impl ::core::clone::Clone for UpvarPath {
#[inline]
fn clone(&self) -> UpvarPath {
let _: ::core::clone::AssertParamIsClone<HirId>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for UpvarPath { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for UpvarPath {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "UpvarPath",
"hir_id", &&self.hir_id)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for UpvarPath {
#[inline]
fn eq(&self, other: &UpvarPath) -> bool { self.hir_id == other.hir_id }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for UpvarPath {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<HirId>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for UpvarPath {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.hir_id, state)
}
}Hash, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for UpvarPath {
fn encode(&self, __encoder: &mut __E) {
match *self {
UpvarPath { hir_id: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for UpvarPath {
fn decode(__decoder: &mut __D) -> Self {
UpvarPath {
hir_id: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for UpvarPath {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
UpvarPath { hir_id: ref __binding_0 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
23#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarPath {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
UpvarPath { hir_id: __binding_0 } => {
UpvarPath {
hir_id: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?,
}
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
UpvarPath { hir_id: __binding_0 } => {
UpvarPath {
hir_id: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder),
}
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarPath {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
UpvarPath { hir_id: ref __binding_0 } => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
24pub struct UpvarPath {
25 pub hir_id: HirId,
26}
27
28#[derive(#[automatically_derived]
impl ::core::clone::Clone for UpvarId {
#[inline]
fn clone(&self) -> UpvarId {
let _: ::core::clone::AssertParamIsClone<UpvarPath>;
let _: ::core::clone::AssertParamIsClone<LocalDefId>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for UpvarId { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for UpvarId {
#[inline]
fn eq(&self, other: &UpvarId) -> bool {
self.var_path == other.var_path &&
self.closure_expr_id == other.closure_expr_id
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for UpvarId {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<UpvarPath>;
let _: ::core::cmp::AssertParamIsEq<LocalDefId>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for UpvarId {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.var_path, state);
::core::hash::Hash::hash(&self.closure_expr_id, state)
}
}Hash, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for UpvarId {
fn encode(&self, __encoder: &mut __E) {
match *self {
UpvarId {
var_path: ref __binding_0, closure_expr_id: ref __binding_1
} => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for UpvarId {
fn decode(__decoder: &mut __D) -> Self {
UpvarId {
var_path: ::rustc_serialize::Decodable::decode(__decoder),
closure_expr_id: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for UpvarId {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
UpvarId {
var_path: ref __binding_0, closure_expr_id: ref __binding_1
} => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
32#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarId {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
UpvarId {
var_path: __binding_0, closure_expr_id: __binding_1 } => {
UpvarId {
var_path: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?,
closure_expr_id: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
__folder)?,
}
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
UpvarId {
var_path: __binding_0, closure_expr_id: __binding_1 } => {
UpvarId {
var_path: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder),
closure_expr_id: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
__folder),
}
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarId {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
UpvarId {
var_path: ref __binding_0, closure_expr_id: ref __binding_1
} => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
33pub struct UpvarId {
34 pub var_path: UpvarPath,
35 pub closure_expr_id: LocalDefId,
36}
37
38impl UpvarId {
39 pub fn new(var_hir_id: HirId, closure_def_id: LocalDefId) -> UpvarId {
40 UpvarId { var_path: UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id }
41 }
42}
43
44#[derive(#[automatically_derived]
impl ::core::cmp::Eq for UpvarCapture {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<BorrowKind>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for UpvarCapture {
#[inline]
fn eq(&self, other: &UpvarCapture) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(UpvarCapture::ByRef(__self_0), UpvarCapture::ByRef(__arg1_0))
=> __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for UpvarCapture {
#[inline]
fn clone(&self) -> UpvarCapture {
let _: ::core::clone::AssertParamIsClone<BorrowKind>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for UpvarCapture {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
UpvarCapture::ByValue =>
::core::fmt::Formatter::write_str(f, "ByValue"),
UpvarCapture::ByUse =>
::core::fmt::Formatter::write_str(f, "ByUse"),
UpvarCapture::ByRef(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "ByRef",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for UpvarCapture { }Copy, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for UpvarCapture {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
UpvarCapture::ByValue => { 0usize }
UpvarCapture::ByUse => { 1usize }
UpvarCapture::ByRef(ref __binding_0) => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
UpvarCapture::ByValue => {}
UpvarCapture::ByUse => {}
UpvarCapture::ByRef(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for UpvarCapture {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { UpvarCapture::ByValue }
1usize => { UpvarCapture::ByUse }
2usize => {
UpvarCapture::ByRef(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `UpvarCapture`, expected 0..3, actual {0}",
n));
}
}
}
}
};TyDecodable, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for UpvarCapture {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
UpvarCapture::ByValue => {}
UpvarCapture::ByUse => {}
UpvarCapture::ByRef(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, #[automatically_derived]
impl ::core::hash::Hash for UpvarCapture {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
UpvarCapture::ByRef(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash)]
47#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarCapture {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
UpvarCapture::ByValue => { UpvarCapture::ByValue }
UpvarCapture::ByUse => { UpvarCapture::ByUse }
UpvarCapture::ByRef(__binding_0) => {
UpvarCapture::ByRef(::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?)
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
UpvarCapture::ByValue => { UpvarCapture::ByValue }
UpvarCapture::ByUse => { UpvarCapture::ByUse }
UpvarCapture::ByRef(__binding_0) => {
UpvarCapture::ByRef(::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder))
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for UpvarCapture {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
UpvarCapture::ByValue => {}
UpvarCapture::ByUse => {}
UpvarCapture::ByRef(ref __binding_0) => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
48pub enum UpvarCapture {
49 ByValue,
53
54 ByUse,
56
57 ByRef(BorrowKind),
59}
60
61pub type MinCaptureInformationMap<'tcx> = LocalDefIdMap<RootVariableMinCaptureList<'tcx>>;
64
65pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<HirId, MinCaptureList<'tcx>>;
72
73pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
75
76#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::Eq for CapturedPlace<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<Ident>;
let _: ::core::cmp::AssertParamIsEq<HirPlace<'tcx>>;
let _: ::core::cmp::AssertParamIsEq<CaptureInfo>;
let _: ::core::cmp::AssertParamIsEq<hir::Mutability>;
}
}Eq, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for CapturedPlace<'tcx> {
#[inline]
fn eq(&self, other: &CapturedPlace<'tcx>) -> bool {
self.var_ident == other.var_ident && self.place == other.place &&
self.info == other.info && self.mutability == other.mutability
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for CapturedPlace<'tcx> {
#[inline]
fn clone(&self) -> CapturedPlace<'tcx> {
CapturedPlace {
var_ident: ::core::clone::Clone::clone(&self.var_ident),
place: ::core::clone::Clone::clone(&self.place),
info: ::core::clone::Clone::clone(&self.info),
mutability: ::core::clone::Clone::clone(&self.mutability),
}
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CapturedPlace<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "CapturedPlace",
"var_ident", &self.var_ident, "place", &self.place, "info",
&self.info, "mutability", &&self.mutability)
}
}Debug, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for CapturedPlace<'tcx> {
fn encode(&self, __encoder: &mut __E) {
match *self {
CapturedPlace {
var_ident: ref __binding_0,
place: ref __binding_1,
info: ref __binding_2,
mutability: ref __binding_3 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for CapturedPlace<'tcx> {
fn decode(__decoder: &mut __D) -> Self {
CapturedPlace {
var_ident: ::rustc_serialize::Decodable::decode(__decoder),
place: ::rustc_serialize::Decodable::decode(__decoder),
info: ::rustc_serialize::Decodable::decode(__decoder),
mutability: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable, const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for CapturedPlace<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
CapturedPlace {
var_ident: ref __binding_0,
place: ref __binding_1,
info: ref __binding_2,
mutability: ref __binding_3 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
{ __binding_3.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, #[automatically_derived]
impl<'tcx> ::core::hash::Hash for CapturedPlace<'tcx> {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.var_ident, state);
::core::hash::Hash::hash(&self.place, state);
::core::hash::Hash::hash(&self.info, state);
::core::hash::Hash::hash(&self.mutability, state)
}
}Hash)]
78#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for CapturedPlace<'tcx> {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
CapturedPlace {
var_ident: __binding_0,
place: __binding_1,
info: __binding_2,
mutability: __binding_3 } => {
CapturedPlace {
var_ident: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?,
place: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
__folder)?,
info: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_2,
__folder)?,
mutability: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_3,
__folder)?,
}
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
CapturedPlace {
var_ident: __binding_0,
place: __binding_1,
info: __binding_2,
mutability: __binding_3 } => {
CapturedPlace {
var_ident: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder),
place: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
__folder),
info: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_2,
__folder),
mutability: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_3,
__folder),
}
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for CapturedPlace<'tcx> {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
CapturedPlace {
var_ident: ref __binding_0,
place: ref __binding_1,
info: ref __binding_2,
mutability: ref __binding_3 } => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_2,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_3,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
79pub struct CapturedPlace<'tcx> {
80 pub var_ident: Ident,
82
83 pub place: HirPlace<'tcx>,
85
86 pub info: CaptureInfo,
88
89 pub mutability: hir::Mutability,
91}
92
93impl<'tcx> CapturedPlace<'tcx> {
94 pub fn to_string(&self, tcx: TyCtxt<'tcx>) -> String {
95 place_to_string_for_capture(tcx, &self.place)
96 }
97
98 pub fn to_symbol(&self) -> Symbol {
100 let mut symbol = self.var_ident.to_string();
101
102 let mut ty = self.place.base_ty;
103 for proj in self.place.projections.iter() {
104 match proj.kind {
105 HirProjectionKind::Field(idx, variant) => match ty.kind() {
106 ty::Tuple(_) => (&mut symbol).write_fmt(format_args!("__{0}", idx.index()))write!(&mut symbol, "__{}", idx.index()).unwrap(),
107 ty::Adt(def, ..) => {
108 (&mut symbol).write_fmt(format_args!("__{0}",
def.variant(variant).fields[idx].name.as_str()))write!(
109 &mut symbol,
110 "__{}",
111 def.variant(variant).fields[idx].name.as_str(),
112 )
113 .unwrap();
114 }
115 ty => {
116 crate::util::bug::bug_fmt(format_args!("Unexpected type {0:?} for `Field` projection",
ty))bug!("Unexpected type {:?} for `Field` projection", ty)
117 }
118 },
119
120 HirProjectionKind::UnwrapUnsafeBinder => {
121 (&mut symbol).write_fmt(format_args!("__unwrap"))write!(&mut symbol, "__unwrap").unwrap();
122 }
123
124 HirProjectionKind::Deref => {}
127 HirProjectionKind::OpaqueCast => {}
129 proj => crate::util::bug::bug_fmt(format_args!("Unexpected projection {0:?} in captured place",
proj))bug!("Unexpected projection {:?} in captured place", proj),
130 }
131 ty = proj.ty;
132 }
133
134 Symbol::intern(&symbol)
135 }
136
137 pub fn get_root_variable(&self) -> HirId {
140 match self.place.base {
141 HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
142 base => crate::util::bug::bug_fmt(format_args!("Expected upvar, found={0:?}", base))bug!("Expected upvar, found={:?}", base),
143 }
144 }
145
146 pub fn get_closure_local_def_id(&self) -> LocalDefId {
148 match self.place.base {
149 HirPlaceBase::Upvar(upvar_id) => upvar_id.closure_expr_id,
150 base => crate::util::bug::bug_fmt(format_args!("expected upvar, found={0:?}", base))bug!("expected upvar, found={:?}", base),
151 }
152 }
153
154 pub fn get_path_span(&self, tcx: TyCtxt<'tcx>) -> Span {
156 if let Some(path_expr_id) = self.info.path_expr_id {
157 tcx.hir_span(path_expr_id)
158 } else if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
159 tcx.hir_span(capture_kind_expr_id)
160 } else {
161 tcx.upvars_mentioned(self.get_closure_local_def_id()).unwrap()
165 [&self.get_root_variable()]
166 .span
167 }
168 }
169
170 pub fn get_capture_kind_span(&self, tcx: TyCtxt<'tcx>) -> Span {
172 if let Some(capture_kind_expr_id) = self.info.capture_kind_expr_id {
173 tcx.hir_span(capture_kind_expr_id)
174 } else if let Some(path_expr_id) = self.info.path_expr_id {
175 tcx.hir_span(path_expr_id)
176 } else {
177 tcx.upvars_mentioned(self.get_closure_local_def_id()).unwrap()
181 [&self.get_root_variable()]
182 .span
183 }
184 }
185
186 pub fn is_by_ref(&self) -> bool {
187 match self.info.capture_kind {
188 ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse => false,
189 ty::UpvarCapture::ByRef(..) => true,
190 }
191 }
192}
193
194#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for ClosureTypeInfo<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ClosureTypeInfo<'tcx> {
#[inline]
fn clone(&self) -> ClosureTypeInfo<'tcx> {
let _:
::core::clone::AssertParamIsClone<ty::CanonicalPolyFnSig<'tcx>>;
let _:
::core::clone::AssertParamIsClone<&'tcx ty::List<&'tcx ty::CapturedPlace<'tcx>>>;
let _:
::core::clone::AssertParamIsClone<Option<&'tcx (Span,
HirPlace<'tcx>)>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ClosureTypeInfo<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClosureTypeInfo", "user_provided_sig", &self.user_provided_sig,
"captures", &self.captures, "kind_origin", &&self.kind_origin)
}
}Debug, const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for ClosureTypeInfo<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
ClosureTypeInfo {
user_provided_sig: ref __binding_0,
captures: ref __binding_1,
kind_origin: ref __binding_2 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable)]
195pub struct ClosureTypeInfo<'tcx> {
196 user_provided_sig: ty::CanonicalPolyFnSig<'tcx>,
197 captures: &'tcx ty::List<&'tcx ty::CapturedPlace<'tcx>>,
198 kind_origin: Option<&'tcx (Span, HirPlace<'tcx>)>,
199}
200
201fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo<'tcx> {
202 if true {
if !tcx.is_closure_like(def.to_def_id()) {
::core::panicking::panic("assertion failed: tcx.is_closure_like(def.to_def_id())")
};
};debug_assert!(tcx.is_closure_like(def.to_def_id()));
203 let typeck_results = tcx.typeck(def);
204 let user_provided_sig = typeck_results.user_provided_sigs[&def];
205 let captures = typeck_results.closure_min_captures_flattened(def);
206 let captures = tcx.mk_captures_from_iter(captures);
207 let hir_id = tcx.local_def_id_to_hir_id(def);
208 let kind_origin = typeck_results.closure_kind_origins().get(hir_id);
209 ClosureTypeInfo { user_provided_sig, captures, kind_origin }
210}
211
212impl<'tcx> TyCtxt<'tcx> {
213 pub fn closure_kind_origin(self, def_id: LocalDefId) -> Option<&'tcx (Span, HirPlace<'tcx>)> {
214 self.closure_typeinfo(def_id).kind_origin
215 }
216
217 pub fn closure_user_provided_sig(self, def_id: LocalDefId) -> ty::CanonicalPolyFnSig<'tcx> {
218 self.closure_typeinfo(def_id).user_provided_sig
219 }
220
221 pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
222 if !self.is_closure_like(def_id.to_def_id()) {
223 return &[];
224 }
225 self.closure_typeinfo(def_id).captures
226 }
227}
228
229pub fn is_ancestor_or_same_capture(
243 proj_possible_ancestor: &[HirProjectionKind],
244 proj_capture: &[HirProjectionKind],
245) -> bool {
246 if proj_possible_ancestor.len() > proj_capture.len() {
249 return false;
250 }
251
252 proj_possible_ancestor.iter().zip(proj_capture).all(|(a, b)| a == b)
253}
254
255#[derive(#[automatically_derived]
impl ::core::cmp::Eq for CaptureInfo {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<Option<HirId>>;
let _: ::core::cmp::AssertParamIsEq<Option<HirId>>;
let _: ::core::cmp::AssertParamIsEq<UpvarCapture>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialEq for CaptureInfo {
#[inline]
fn eq(&self, other: &CaptureInfo) -> bool {
self.capture_kind_expr_id == other.capture_kind_expr_id &&
self.path_expr_id == other.path_expr_id &&
self.capture_kind == other.capture_kind
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for CaptureInfo {
#[inline]
fn clone(&self) -> CaptureInfo {
let _: ::core::clone::AssertParamIsClone<Option<HirId>>;
let _: ::core::clone::AssertParamIsClone<Option<HirId>>;
let _: ::core::clone::AssertParamIsClone<UpvarCapture>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CaptureInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "CaptureInfo",
"capture_kind_expr_id", &self.capture_kind_expr_id,
"path_expr_id", &self.path_expr_id, "capture_kind",
&&self.capture_kind)
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for CaptureInfo { }Copy, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for CaptureInfo {
fn encode(&self, __encoder: &mut __E) {
match *self {
CaptureInfo {
capture_kind_expr_id: ref __binding_0,
path_expr_id: ref __binding_1,
capture_kind: ref __binding_2 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for CaptureInfo {
fn decode(__decoder: &mut __D) -> Self {
CaptureInfo {
capture_kind_expr_id: ::rustc_serialize::Decodable::decode(__decoder),
path_expr_id: ::rustc_serialize::Decodable::decode(__decoder),
capture_kind: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for CaptureInfo {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
CaptureInfo {
capture_kind_expr_id: ref __binding_0,
path_expr_id: ref __binding_1,
capture_kind: ref __binding_2 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, #[automatically_derived]
impl ::core::hash::Hash for CaptureInfo {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.capture_kind_expr_id, state);
::core::hash::Hash::hash(&self.path_expr_id, state);
::core::hash::Hash::hash(&self.capture_kind, state)
}
}Hash)]
259#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for CaptureInfo {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
CaptureInfo {
capture_kind_expr_id: __binding_0,
path_expr_id: __binding_1,
capture_kind: __binding_2 } => {
CaptureInfo {
capture_kind_expr_id: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_0,
__folder)?,
path_expr_id: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_1,
__folder)?,
capture_kind: ::rustc_middle::ty::TypeFoldable::try_fold_with(__binding_2,
__folder)?,
}
}
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
CaptureInfo {
capture_kind_expr_id: __binding_0,
path_expr_id: __binding_1,
capture_kind: __binding_2 } => {
CaptureInfo {
capture_kind_expr_id: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_0,
__folder),
path_expr_id: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_1,
__folder),
capture_kind: ::rustc_middle::ty::TypeFoldable::fold_with(__binding_2,
__folder),
}
}
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for CaptureInfo {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
CaptureInfo {
capture_kind_expr_id: ref __binding_0,
path_expr_id: ref __binding_1,
capture_kind: ref __binding_2 } => {
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_0,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_1,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
{
match ::rustc_middle::ty::VisitorResult::branch(::rustc_middle::ty::TypeVisitable::visit_with(__binding_2,
__visitor)) {
::core::ops::ControlFlow::Continue(()) => {}
::core::ops::ControlFlow::Break(r) => {
return ::rustc_middle::ty::VisitorResult::from_residual(r);
}
}
}
}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
260pub struct CaptureInfo {
261 pub capture_kind_expr_id: Option<HirId>,
291 pub path_expr_id: Option<HirId>,
296
297 pub capture_kind: UpvarCapture,
299}
300
301pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
302 let mut curr_string: String = match place.base {
303 HirPlaceBase::Upvar(upvar_id) => tcx.hir_name(upvar_id.var_path.hir_id).to_string(),
304 _ => crate::util::bug::bug_fmt(format_args!("Capture_information should only contain upvars"))bug!("Capture_information should only contain upvars"),
305 };
306
307 for (i, proj) in place.projections.iter().enumerate() {
308 match proj.kind {
309 HirProjectionKind::Deref => {
310 curr_string = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("*{0}", curr_string))
})format!("*{curr_string}");
311 }
312 HirProjectionKind::Field(idx, variant) => match place.ty_before_projection(i).kind() {
313 ty::Adt(def, ..) => {
314 curr_string = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}.{1}", curr_string,
def.variant(variant).fields[idx].name.as_str()))
})format!(
315 "{}.{}",
316 curr_string,
317 def.variant(variant).fields[idx].name.as_str()
318 );
319 }
320 ty::Tuple(_) => {
321 curr_string = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}.{1}", curr_string,
idx.index()))
})format!("{}.{}", curr_string, idx.index());
322 }
323 _ => {
324 crate::util::bug::bug_fmt(format_args!("Field projection applied to a type other than Adt or Tuple: {0:?}.",
place.ty_before_projection(i).kind()))bug!(
325 "Field projection applied to a type other than Adt or Tuple: {:?}.",
326 place.ty_before_projection(i).kind()
327 )
328 }
329 },
330 HirProjectionKind::UnwrapUnsafeBinder => {
331 curr_string = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unwrap_binder!({0})", curr_string))
})format!("unwrap_binder!({curr_string})");
332 }
333 HirProjectionKind::OpaqueCast => {}
335 proj => crate::util::bug::bug_fmt(format_args!("{0:?} unexpected because it isn\'t captured",
proj))bug!("{:?} unexpected because it isn't captured", proj),
336 }
337 }
338
339 curr_string
340}
341
342#[derive(#[automatically_derived]
impl ::core::cmp::Eq for BorrowKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::clone::Clone for BorrowKind {
#[inline]
fn clone(&self) -> BorrowKind { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BorrowKind {
#[inline]
fn eq(&self, other: &BorrowKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for BorrowKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
BorrowKind::Immutable => "Immutable",
BorrowKind::UniqueImmutable => "UniqueImmutable",
BorrowKind::Mutable => "Mutable",
})
}
}Debug, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for BorrowKind {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
BorrowKind::Immutable => { 0usize }
BorrowKind::UniqueImmutable => { 1usize }
BorrowKind::Mutable => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
BorrowKind::Immutable => {}
BorrowKind::UniqueImmutable => {}
BorrowKind::Mutable => {}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for BorrowKind {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { BorrowKind::Immutable }
1usize => { BorrowKind::UniqueImmutable }
2usize => { BorrowKind::Mutable }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `BorrowKind`, expected 0..3, actual {0}",
n));
}
}
}
}
};TyDecodable, #[automatically_derived]
impl ::core::marker::Copy for BorrowKind { }Copy, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_query_system::ich::StableHashingContext<'__ctx>>
for BorrowKind {
#[inline]
fn hash_stable(&self,
__hcx:
&mut ::rustc_query_system::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
BorrowKind::Immutable => {}
BorrowKind::UniqueImmutable => {}
BorrowKind::Mutable => {}
}
}
}
};HashStable, #[automatically_derived]
impl ::core::hash::Hash for BorrowKind {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
343#[derive(const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>
for BorrowKind {
fn try_fold_with<__F: ::rustc_middle::ty::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Result<Self, __F::Error> {
Ok(match self {
BorrowKind::Immutable => { BorrowKind::Immutable }
BorrowKind::UniqueImmutable => {
BorrowKind::UniqueImmutable
}
BorrowKind::Mutable => { BorrowKind::Mutable }
})
}
fn fold_with<__F: ::rustc_middle::ty::TypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>(self,
__folder: &mut __F) -> Self {
match self {
BorrowKind::Immutable => { BorrowKind::Immutable }
BorrowKind::UniqueImmutable => {
BorrowKind::UniqueImmutable
}
BorrowKind::Mutable => { BorrowKind::Mutable }
}
}
}
};TypeFoldable, const _: () =
{
impl<'tcx>
::rustc_middle::ty::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>
for BorrowKind {
fn visit_with<__V: ::rustc_middle::ty::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>(&self,
__visitor: &mut __V) -> __V::Result {
match *self {
BorrowKind::Immutable => {}
BorrowKind::UniqueImmutable => {}
BorrowKind::Mutable => {}
}
<__V::Result as ::rustc_middle::ty::VisitorResult>::output()
}
}
};TypeVisitable)]
344pub enum BorrowKind {
345 Immutable,
347
348 UniqueImmutable,
395
396 Mutable,
398}
399
400impl BorrowKind {
401 pub fn from_mutbl(m: hir::Mutability) -> BorrowKind {
402 match m {
403 hir::Mutability::Mut => BorrowKind::Mutable,
404 hir::Mutability::Not => BorrowKind::Immutable,
405 }
406 }
407
408 pub fn to_mutbl_lossy(self) -> hir::Mutability {
413 match self {
414 BorrowKind::Mutable => hir::Mutability::Mut,
415 BorrowKind::Immutable => hir::Mutability::Not,
416
417 BorrowKind::UniqueImmutable => hir::Mutability::Mut,
421 }
422 }
423}
424
425pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>(
426 parent_captures: impl IntoIterator<Item = &'a CapturedPlace<'tcx>>,
427 child_captures: impl IntoIterator<Item = &'a CapturedPlace<'tcx>>,
428 mut for_each: impl FnMut((usize, &'a CapturedPlace<'tcx>), (usize, &'a CapturedPlace<'tcx>)) -> T,
429) -> impl Iterator<Item = T> {
430 gen move {
431 let mut child_captures = child_captures.into_iter().enumerate().peekable();
432
433 for (parent_field_idx, parent_capture) in parent_captures.into_iter().enumerate() {
438 let mut field_used_at_least_once = false;
441
442 while child_captures.peek().is_some_and(|(_, child_capture)| {
446 child_prefix_matches_parent_projections(parent_capture, child_capture)
447 }) {
448 let (child_field_idx, child_capture) = child_captures.next().unwrap();
449 if !(child_capture.place.projections.len() >=
parent_capture.place.projections.len()) {
{
::core::panicking::panic_fmt(format_args!("parent capture ({0:#?}) expected to be prefix of child capture ({1:#?})",
parent_capture, child_capture));
}
};assert!(
452 child_capture.place.projections.len() >= parent_capture.place.projections.len(),
453 "parent capture ({parent_capture:#?}) expected to be prefix of \
454 child capture ({child_capture:#?})"
455 );
456
457 yield for_each(
458 (parent_field_idx, parent_capture),
459 (child_field_idx, child_capture),
460 );
461
462 field_used_at_least_once = true;
463 }
464
465 if !field_used_at_least_once {
{
::core::panicking::panic_fmt(format_args!("we captured {0:#?} but it was not used in the child coroutine?",
parent_capture));
}
};assert!(
467 field_used_at_least_once,
468 "we captured {parent_capture:#?} but it was not used in the child coroutine?"
469 );
470 }
471 match (&child_captures.next(), &None) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("leftover child captures?")));
}
}
};assert_eq!(child_captures.next(), None, "leftover child captures?");
472 }
473}
474
475fn child_prefix_matches_parent_projections(
476 parent_capture: &ty::CapturedPlace<'_>,
477 child_capture: &ty::CapturedPlace<'_>,
478) -> bool {
479 let HirPlaceBase::Upvar(parent_base) = parent_capture.place.base else {
480 crate::util::bug::bug_fmt(format_args!("expected capture to be an upvar"));bug!("expected capture to be an upvar");
481 };
482 let HirPlaceBase::Upvar(child_base) = child_capture.place.base else {
483 crate::util::bug::bug_fmt(format_args!("expected capture to be an upvar"));bug!("expected capture to be an upvar");
484 };
485
486 parent_base.var_path.hir_id == child_base.var_path.hir_id
487 && std::iter::zip(&child_capture.place.projections, &parent_capture.place.projections)
488 .all(|(child, parent)| child.kind == parent.kind)
489}
490
491pub fn provide(providers: &mut Providers) {
492 *providers = Providers { closure_typeinfo, ..*providers }
493}