@@ -4,6 +4,7 @@ use std::{cmp, collections::HashMap, convert::Infallible, mem};
44
55use chalk_ir:: { cast:: Cast , AliasEq , AliasTy , FnSubst , Mutability , TyKind , WhereClause } ;
66use hir_def:: {
7+ data:: adt:: VariantData ,
78 hir:: {
89 Array , BinaryOp , BindingAnnotation , BindingId , CaptureBy , Expr , ExprId , Pat , PatId ,
910 Statement , UnaryOp ,
@@ -18,6 +19,7 @@ use smallvec::SmallVec;
1819use stdx:: never;
1920
2021use crate :: {
22+ db:: HirDatabase ,
2123 mir:: { BorrowKind , MirSpan , ProjectionElem } ,
2224 static_lifetime, to_chalk_trait_id,
2325 traits:: FnTrait ,
@@ -146,13 +148,78 @@ pub(crate) enum CaptureKind {
146148}
147149
148150#[ derive( Debug , Clone , PartialEq , Eq ) ]
149- pub ( crate ) struct CapturedItem {
151+ pub struct CapturedItem {
150152 pub ( crate ) place : HirPlace ,
151153 pub ( crate ) kind : CaptureKind ,
152154 pub ( crate ) span : MirSpan ,
153155 pub ( crate ) ty : Ty ,
154156}
155157
158+ impl CapturedItem {
159+ pub fn display_kind ( & self ) -> & ' static str {
160+ match self . kind {
161+ CaptureKind :: ByRef ( k) => match k {
162+ BorrowKind :: Shared => "immutable borrow" ,
163+ BorrowKind :: Shallow => "shallow borrow" ,
164+ BorrowKind :: Unique => "unique immutable borrow" ,
165+ BorrowKind :: Mut { .. } => "mutable borrow" ,
166+ } ,
167+ CaptureKind :: ByValue => "move" ,
168+ }
169+ }
170+
171+ pub fn display_place ( & self , owner : ClosureId , db : & dyn HirDatabase ) -> String {
172+ let owner = db. lookup_intern_closure ( owner. into ( ) ) . 0 ;
173+ let body = db. body ( owner) ;
174+ let mut result = body[ self . place . local ] . name . to_string ( ) ;
175+ let mut field_need_paren = false ;
176+ for proj in & self . place . projections {
177+ match proj {
178+ ProjectionElem :: Deref => {
179+ result = format ! ( "*{result}" ) ;
180+ field_need_paren = true ;
181+ }
182+ ProjectionElem :: Field ( f) => {
183+ if field_need_paren {
184+ result = format ! ( "({result})" ) ;
185+ }
186+ let variant_data = f. parent . variant_data ( db. upcast ( ) ) ;
187+ let field = match & * variant_data {
188+ VariantData :: Record ( fields) => fields[ f. local_id ]
189+ . name
190+ . as_str ( )
191+ . unwrap_or ( "[missing field]" )
192+ . to_string ( ) ,
193+ VariantData :: Tuple ( fields) => fields
194+ . iter ( )
195+ . position ( |x| x. 0 == f. local_id )
196+ . unwrap_or_default ( )
197+ . to_string ( ) ,
198+ VariantData :: Unit => "[missing field]" . to_string ( ) ,
199+ } ;
200+ result = format ! ( "{result}.{field}" ) ;
201+ field_need_paren = false ;
202+ }
203+ & ProjectionElem :: TupleOrClosureField ( field) => {
204+ if field_need_paren {
205+ result = format ! ( "({result})" ) ;
206+ }
207+ result = format ! ( "{result}.{field}" ) ;
208+ field_need_paren = false ;
209+ }
210+ ProjectionElem :: Index ( _)
211+ | ProjectionElem :: ConstantIndex { .. }
212+ | ProjectionElem :: Subslice { .. }
213+ | ProjectionElem :: OpaqueCast ( _) => {
214+ never ! ( "Not happen in closure capture" ) ;
215+ continue ;
216+ }
217+ }
218+ }
219+ result
220+ }
221+ }
222+
156223#[ derive( Debug , Clone , PartialEq , Eq ) ]
157224pub ( crate ) struct CapturedItemWithoutTy {
158225 pub ( crate ) place : HirPlace ,
0 commit comments