@@ -46,22 +46,6 @@ use rustc_span::{Span, Symbol};
46
46
47
47
use std:: env;
48
48
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
-
65
49
/// Describe the relationship between the paths of two places
66
50
/// eg:
67
51
/// - foo is ancestor of foo.bar.baz
@@ -144,9 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
144
128
145
129
let mut capture_information = FxIndexMap :: < Place < ' tcx > , ty:: CaptureInfo < ' tcx > > :: default ( ) ;
146
130
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" ) ;
148
131
} else {
149
- log_capture_analysis ! ( self , closure_def_id, "Using old-style capture analysis" ) ;
150
132
if let Some ( upvars) = self . tcx . upvars_mentioned ( closure_def_id) {
151
133
for ( & var_hir_id, _) in upvars. iter ( ) {
152
134
let place = self . place_for_root_variable ( local_def_id, var_hir_id) ;
@@ -182,12 +164,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
182
164
)
183
165
. consume_body ( body) ;
184
166
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
190
170
) ;
171
+ self . log_closure_capture_info ( closure_def_id, & delegate. capture_information , span) ;
191
172
192
173
if let Some ( closure_substs) = infer_kind {
193
174
// Unify the (as yet unbound) type variable in the closure
@@ -206,6 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
206
187
}
207
188
208
189
self . compute_min_captures ( closure_def_id, delegate) ;
190
+ self . log_closure_min_capture_info ( closure_def_id, span) ;
191
+
209
192
self . set_closure_captures ( closure_def_id) ;
210
193
211
194
// Now that we've analyzed the closure, we know how each
@@ -333,10 +316,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
333
316
}
334
317
}
335
318
}
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) ;
340
320
debug ! (
341
321
"For closure_def_id={:?}, upvar_capture_map={:#?}" ,
342
322
closure_def_id, upvar_capture_map
@@ -478,12 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
478
458
}
479
459
}
480
460
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) ;
487
462
488
463
if !root_var_min_capture_list. is_empty ( ) {
489
464
self . typeck_results
@@ -581,6 +556,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
581
556
}
582
557
}
583
558
}
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
+ }
584
599
}
585
600
586
601
struct InferBorrowKind < ' a , ' tcx > {
@@ -917,6 +932,37 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
917
932
}
918
933
}
919
934
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
+
920
966
fn var_name ( tcx : TyCtxt < ' _ > , var_hir_id : hir:: HirId ) -> Symbol {
921
967
tcx. hir ( ) . name ( var_hir_id)
922
968
}
0 commit comments