@@ -46,22 +46,6 @@ use rustc_span::{Span, Symbol};
4646
4747use std:: env;
4848
49- macro_rules! log_capture_analysis {
50- ( $fcx: expr, $closure_def_id: expr, $fmt: literal) => {
51- if $fcx. should_log_capture_analysis( $closure_def_id) {
52- print!( "For closure={:?}: " , $closure_def_id) ;
53- println!( $fmt) ;
54- }
55- } ;
56-
57- ( $fcx: expr, $closure_def_id: expr, $fmt: literal, $( $args: expr) ,* ) => {
58- if $fcx. should_log_capture_analysis( $closure_def_id) {
59- print!( "For closure={:?}: " , $closure_def_id) ;
60- println!( $fmt, $( $args) ,* ) ;
61- }
62- } ;
63- }
64-
6549/// Describe the relationship between the paths of two places
6650/// eg:
6751/// - foo is ancestor of foo.bar.baz
@@ -144,9 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
144128
145129 let mut capture_information = FxIndexMap :: < Place < ' tcx > , ty:: CaptureInfo < ' tcx > > :: default ( ) ;
146130 if self . tcx . features ( ) . capture_disjoint_fields || matches ! ( env:: var( "SG_NEW" ) , Ok ( _) ) {
147- log_capture_analysis ! ( self , closure_def_id, "Using new-style capture analysis" ) ;
148131 } else {
149- log_capture_analysis ! ( self , closure_def_id, "Using old-style capture analysis" ) ;
150132 if let Some ( upvars) = self . tcx . upvars_mentioned ( closure_def_id) {
151133 for ( & var_hir_id, _) in upvars. iter ( ) {
152134 let place = self . place_for_root_variable ( local_def_id, var_hir_id) ;
@@ -182,12 +164,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
182164 )
183165 . consume_body ( body) ;
184166
185- log_capture_analysis ! (
186- self ,
187- closure_def_id,
188- "capture information: {:#?}" ,
189- delegate. capture_information
167+ debug ! (
168+ "For closure={:?}, capture_information={:#?}" ,
169+ closure_def_id, delegate. capture_information
190170 ) ;
171+ self . log_closure_capture_info ( closure_def_id, & delegate. capture_information , span) ;
191172
192173 if let Some ( closure_substs) = infer_kind {
193174 // Unify the (as yet unbound) type variable in the closure
@@ -206,6 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
206187 }
207188
208189 self . compute_min_captures ( closure_def_id, delegate) ;
190+ self . log_closure_min_capture_info ( closure_def_id, span) ;
191+
209192 self . set_closure_captures ( closure_def_id) ;
210193
211194 // Now that we've analyzed the closure, we know how each
@@ -333,10 +316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
333316 }
334317 }
335318 }
336- debug ! (
337- "For closure_def_id={:?}, set_closure_captures={:#?}" ,
338- closure_def_id, closure_captures
339- ) ;
319+ debug ! ( "For closure_def_id={:?}, closure_captures={:#?}" , closure_def_id, closure_captures) ;
340320 debug ! (
341321 "For closure_def_id={:?}, upvar_capture_map={:#?}" ,
342322 closure_def_id, upvar_capture_map
@@ -478,12 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478458 }
479459 }
480460
481- log_capture_analysis ! (
482- self ,
483- closure_def_id,
484- "min_captures={:#?}" ,
485- root_var_min_capture_list
486- ) ;
461+ debug ! ( "For closure={:?}, min_captures={:#?}" , closure_def_id, root_var_min_capture_list) ;
487462
488463 if !root_var_min_capture_list. is_empty ( ) {
489464 self . typeck_results
@@ -581,6 +556,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
581556 }
582557 }
583558 }
559+
560+ fn log_closure_capture_info (
561+ & self ,
562+ closure_def_id : rustc_hir:: def_id:: DefId ,
563+ capture_information : & FxIndexMap < Place < ' tcx > , ty:: CaptureInfo < ' tcx > > ,
564+ closure_span : Span ,
565+ ) {
566+ if self . should_log_capture_analysis ( closure_def_id) {
567+ for ( place, capture_info) in capture_information {
568+ let capture_str = construct_capture_info_string ( self . tcx , place, capture_info) ;
569+ let output_str = format ! ( "Capturing {}" , capture_str) ;
570+
571+ let span = capture_info. expr_id . map_or ( closure_span, |e| self . tcx . hir ( ) . span ( e) ) ;
572+ self . tcx . sess . span_err ( span, & output_str) ;
573+ }
574+ }
575+ }
576+
577+ fn log_closure_min_capture_info ( & self , closure_def_id : DefId , closure_span : Span ) {
578+ if self . should_log_capture_analysis ( closure_def_id) {
579+ if let Some ( min_captures) =
580+ self . typeck_results . borrow ( ) . closure_min_captures . get ( & closure_def_id)
581+ {
582+ for ( _, min_captures_for_var) in min_captures {
583+ for capture in min_captures_for_var {
584+ let place = & capture. place ;
585+ let capture_info = & capture. info ;
586+
587+ let capture_str =
588+ construct_capture_info_string ( self . tcx , place, capture_info) ;
589+ let output_str = format ! ( "Min Capture {}" , capture_str) ;
590+
591+ let span =
592+ capture_info. expr_id . map_or ( closure_span, |e| self . tcx . hir ( ) . span ( e) ) ;
593+ self . tcx . sess . span_err ( span, & output_str) ;
594+ }
595+ }
596+ }
597+ }
598+ }
584599}
585600
586601struct InferBorrowKind < ' a , ' tcx > {
@@ -917,6 +932,37 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
917932 }
918933}
919934
935+ fn construct_capture_info_string (
936+ tcx : TyCtxt < ' _ > ,
937+ place : & Place < ' tcx > ,
938+ capture_info : & ty:: CaptureInfo < ' tcx > ,
939+ ) -> String {
940+ let variable_name = match place. base {
941+ PlaceBase :: Upvar ( upvar_id) => var_name ( tcx, upvar_id. var_path . hir_id ) . to_string ( ) ,
942+ _ => bug ! ( "Capture_information should only contain upvars" ) ,
943+ } ;
944+
945+ let mut projections_str = String :: new ( ) ;
946+ for ( i, item) in place. projections . iter ( ) . enumerate ( ) {
947+ let proj = match item. kind {
948+ ProjectionKind :: Field ( a, b) => format ! ( "({:?}, {:?})" , a, b) ,
949+ ProjectionKind :: Deref => String :: from ( "Deref" ) ,
950+ ProjectionKind :: Index => String :: from ( "Index" ) ,
951+ ProjectionKind :: Subslice => String :: from ( "Subslice" ) ,
952+ } ;
953+ if i != 0 {
954+ projections_str. push_str ( "," ) ;
955+ }
956+ projections_str. push_str ( proj. as_str ( ) ) ;
957+ }
958+
959+ let capture_kind_str = match capture_info. capture_kind {
960+ ty:: UpvarCapture :: ByValue ( _) => "ByValue" . into ( ) ,
961+ ty:: UpvarCapture :: ByRef ( borrow) => format ! ( "{:?}" , borrow. kind) ,
962+ } ;
963+ format ! ( "{}[{}] -> {}" , variable_name, projections_str, capture_kind_str)
964+ }
965+
920966fn var_name ( tcx : TyCtxt < ' _ > , var_hir_id : hir:: HirId ) -> Symbol {
921967 tcx. hir ( ) . name ( var_hir_id)
922968}
0 commit comments