@@ -18,7 +18,8 @@ use middle::trans::base;
18
18
use middle:: trans:: build;
19
19
use middle:: trans:: callee;
20
20
use middle:: trans:: common;
21
- use middle:: trans:: common:: { Block , FunctionContext , ExprId } ;
21
+ use middle:: trans:: common:: { Block , FunctionContext , ExprId , NodeInfo } ;
22
+ use middle:: trans:: debuginfo;
22
23
use middle:: trans:: glue;
23
24
use middle:: trans:: type_:: Type ;
24
25
use middle:: ty;
@@ -36,6 +37,10 @@ pub struct CleanupScope<'blk, 'tcx: 'blk> {
36
37
// Cleanups to run upon scope exit.
37
38
cleanups : Vec < CleanupObj > ,
38
39
40
+ // The debug location any drop calls generated for this scope will be
41
+ // associated with.
42
+ debug_loc : Option < NodeInfo > ,
43
+
39
44
cached_early_exits : Vec < CachedEarlyExit > ,
40
45
cached_landing_pad : Option < BasicBlockRef > ,
41
46
}
@@ -69,7 +74,10 @@ pub struct CachedEarlyExit {
69
74
pub trait Cleanup {
70
75
fn must_unwind ( & self ) -> bool ;
71
76
fn clean_on_unwind ( & self ) -> bool ;
72
- fn trans < ' blk , ' tcx > ( & self , bcx : Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx > ;
77
+ fn trans < ' blk , ' tcx > ( & self ,
78
+ bcx : Block < ' blk , ' tcx > ,
79
+ debug_loc : Option < NodeInfo > )
80
+ -> Block < ' blk , ' tcx > ;
73
81
}
74
82
75
83
pub type CleanupObj = Box < Cleanup +' static > ;
@@ -80,14 +88,14 @@ pub enum ScopeId {
80
88
}
81
89
82
90
impl < ' blk , ' tcx > CleanupMethods < ' blk , ' tcx > for FunctionContext < ' blk , ' tcx > {
83
- fn push_ast_cleanup_scope ( & self , id : ast :: NodeId ) {
91
+ fn push_ast_cleanup_scope ( & self , debug_loc : NodeInfo ) {
84
92
/*!
85
93
* Invoked when we start to trans the code contained
86
94
* within a new cleanup scope.
87
95
*/
88
96
89
97
debug ! ( "push_ast_cleanup_scope({})" ,
90
- self . ccx. tcx( ) . map. node_to_string( id) ) ;
98
+ self . ccx. tcx( ) . map. node_to_string( debug_loc . id) ) ;
91
99
92
100
// FIXME(#2202) -- currently closure bodies have a parent
93
101
// region, which messes up the assertion below, since there
@@ -101,10 +109,15 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
101
109
// this new AST scope had better be its immediate child.
102
110
let top_scope = self . top_ast_scope ( ) ;
103
111
if top_scope. is_some ( ) {
104
- assert_eq ! ( self . ccx. tcx( ) . region_maps. opt_encl_scope( id) , top_scope) ;
112
+ assert_eq ! ( self . ccx
113
+ . tcx( )
114
+ . region_maps
115
+ . opt_encl_scope( debug_loc. id) ,
116
+ top_scope) ;
105
117
}
106
118
107
- self . push_scope ( CleanupScope :: new ( AstScopeKind ( id) ) ) ;
119
+ self . push_scope ( CleanupScope :: new ( AstScopeKind ( debug_loc. id ) ,
120
+ Some ( debug_loc) ) ) ;
108
121
}
109
122
110
123
fn push_loop_cleanup_scope ( & self ,
@@ -114,13 +127,38 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
114
127
self . ccx. tcx( ) . map. node_to_string( id) ) ;
115
128
assert_eq ! ( Some ( id) , self . top_ast_scope( ) ) ;
116
129
117
- self . push_scope ( CleanupScope :: new ( LoopScopeKind ( id , exits ) ) ) ;
130
+ // Just copy the debuginfo source location from the enclosing scope
131
+ let debug_loc = self . scopes
132
+ . borrow ( )
133
+ . last ( )
134
+ . unwrap ( )
135
+ . debug_loc ;
136
+
137
+ self . push_scope( CleanupScope :: new( LoopScopeKind ( id, exits) , debug_loc) ) ;
118
138
}
119
139
120
140
fn push_custom_cleanup_scope ( & self ) -> CustomScopeIndex {
121
141
let index = self . scopes_len ( ) ;
122
142
debug ! ( "push_custom_cleanup_scope(): {}" , index) ;
123
- self . push_scope ( CleanupScope :: new ( CustomScopeKind ) ) ;
143
+
144
+ // Just copy the debuginfo source location from the enclosing scope
145
+ let debug_loc = self . scopes
146
+ . borrow ( )
147
+ . last ( )
148
+ . map ( |opt_scope| opt_scope. debug_loc )
149
+ . unwrap_or ( None ) ;
150
+
151
+ self . push_scope ( CleanupScope :: new ( CustomScopeKind , debug_loc) ) ;
152
+ CustomScopeIndex { index : index }
153
+ }
154
+
155
+ fn push_custom_cleanup_scope_with_debug_loc ( & self ,
156
+ debug_loc : NodeInfo )
157
+ -> CustomScopeIndex {
158
+ let index = self . scopes_len ( ) ;
159
+ debug ! ( "push_custom_cleanup_scope(): {}" , index) ;
160
+
161
+ self . push_scope ( CleanupScope :: new ( CustomScopeKind , Some ( debug_loc) ) ) ;
124
162
CustomScopeIndex { index : index }
125
163
}
126
164
@@ -141,7 +179,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
141
179
142
180
let scope = self . pop_scope ( ) ;
143
181
self . trans_scope_cleanups ( bcx, & scope)
144
-
145
182
}
146
183
147
184
fn pop_loop_cleanup_scope ( & self ,
@@ -175,9 +212,9 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
175
212
}
176
213
177
214
fn pop_and_trans_custom_cleanup_scope ( & self ,
178
- bcx : Block < ' blk , ' tcx > ,
179
- custom_scope : CustomScopeIndex )
180
- -> Block < ' blk , ' tcx > {
215
+ bcx : Block < ' blk , ' tcx > ,
216
+ custom_scope : CustomScopeIndex )
217
+ -> Block < ' blk , ' tcx > {
181
218
/*!
182
219
* Removes the top cleanup scope from the stack, which must be
183
220
* a temporary scope, and generates the code to do its
@@ -503,7 +540,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
503
540
let mut bcx = bcx;
504
541
if !bcx. unreachable . get ( ) {
505
542
for cleanup in scope. cleanups . iter ( ) . rev ( ) {
506
- bcx = cleanup. trans ( bcx) ;
543
+ bcx = cleanup. trans ( bcx, scope . debug_loc ) ;
507
544
}
508
545
}
509
546
bcx
@@ -671,7 +708,8 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
671
708
let mut bcx_out = bcx_in;
672
709
for cleanup in scope. cleanups . iter ( ) . rev ( ) {
673
710
if cleanup_is_suitable_for ( & * * cleanup, label) {
674
- bcx_out = cleanup. trans ( bcx_out) ;
711
+ bcx_out = cleanup. trans ( bcx_out,
712
+ scope. debug_loc ) ;
675
713
}
676
714
}
677
715
build:: Br ( bcx_out, prev_llbb) ;
@@ -785,9 +823,12 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
785
823
}
786
824
787
825
impl < ' blk , ' tcx > CleanupScope < ' blk , ' tcx > {
788
- fn new ( kind : CleanupScopeKind < ' blk , ' tcx > ) -> CleanupScope < ' blk , ' tcx > {
826
+ fn new ( kind : CleanupScopeKind < ' blk , ' tcx > ,
827
+ debug_loc : Option < NodeInfo > )
828
+ -> CleanupScope < ' blk , ' tcx > {
789
829
CleanupScope {
790
830
kind : kind,
831
+ debug_loc : debug_loc,
791
832
cleanups : vec ! ( ) ,
792
833
cached_early_exits : vec ! ( ) ,
793
834
cached_landing_pad : None ,
@@ -902,11 +943,14 @@ impl Cleanup for DropValue {
902
943
self . must_unwind
903
944
}
904
945
905
- fn trans < ' blk , ' tcx > ( & self , bcx : Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx > {
946
+ fn trans < ' blk , ' tcx > ( & self ,
947
+ bcx : Block < ' blk , ' tcx > ,
948
+ debug_loc : Option < NodeInfo > )
949
+ -> Block < ' blk , ' tcx > {
906
950
let bcx = if self . is_immediate {
907
- glue:: drop_ty_immediate ( bcx, self . val , self . ty )
951
+ glue:: drop_ty_immediate ( bcx, self . val , self . ty , debug_loc )
908
952
} else {
909
- glue:: drop_ty ( bcx, self . val , self . ty )
953
+ glue:: drop_ty ( bcx, self . val , self . ty , debug_loc )
910
954
} ;
911
955
if self . zero {
912
956
base:: zero_mem ( bcx, self . val , self . ty ) ;
@@ -935,7 +979,12 @@ impl Cleanup for FreeValue {
935
979
true
936
980
}
937
981
938
- fn trans < ' blk , ' tcx > ( & self , bcx : Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx > {
982
+ fn trans < ' blk , ' tcx > ( & self ,
983
+ bcx : Block < ' blk , ' tcx > ,
984
+ debug_loc : Option < NodeInfo > )
985
+ -> Block < ' blk , ' tcx > {
986
+ apply_debug_loc ( bcx. fcx , debug_loc) ;
987
+
939
988
match self . heap {
940
989
HeapManaged => {
941
990
glue:: trans_free ( bcx, self . ptr )
@@ -963,7 +1012,12 @@ impl Cleanup for FreeSlice {
963
1012
true
964
1013
}
965
1014
966
- fn trans < ' blk , ' tcx > ( & self , bcx : Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx > {
1015
+ fn trans < ' blk , ' tcx > ( & self ,
1016
+ bcx : Block < ' blk , ' tcx > ,
1017
+ debug_loc : Option < NodeInfo > )
1018
+ -> Block < ' blk , ' tcx > {
1019
+ apply_debug_loc ( bcx. fcx , debug_loc) ;
1020
+
967
1021
match self . heap {
968
1022
HeapManaged => {
969
1023
glue:: trans_free ( bcx, self . ptr )
@@ -988,7 +1042,11 @@ impl Cleanup for LifetimeEnd {
988
1042
true
989
1043
}
990
1044
991
- fn trans < ' blk , ' tcx > ( & self , bcx : Block < ' blk , ' tcx > ) -> Block < ' blk , ' tcx > {
1045
+ fn trans < ' blk , ' tcx > ( & self ,
1046
+ bcx : Block < ' blk , ' tcx > ,
1047
+ debug_loc : Option < NodeInfo > )
1048
+ -> Block < ' blk , ' tcx > {
1049
+ apply_debug_loc ( bcx. fcx , debug_loc) ;
992
1050
base:: call_lifetime_end ( bcx, self . ptr ) ;
993
1051
bcx
994
1052
}
@@ -1023,15 +1081,29 @@ fn cleanup_is_suitable_for(c: &Cleanup,
1023
1081
!label. is_unwind ( ) || c. clean_on_unwind ( )
1024
1082
}
1025
1083
1084
+ fn apply_debug_loc ( fcx : & FunctionContext , debug_loc : Option < NodeInfo > ) {
1085
+ match debug_loc {
1086
+ Some ( ref src_loc) => {
1087
+ debuginfo:: set_source_location ( fcx, src_loc. id , src_loc. span ) ;
1088
+ }
1089
+ None => {
1090
+ debuginfo:: clear_source_location ( fcx) ;
1091
+ }
1092
+ }
1093
+ }
1094
+
1026
1095
///////////////////////////////////////////////////////////////////////////
1027
1096
// These traits just exist to put the methods into this file.
1028
1097
1029
1098
pub trait CleanupMethods < ' blk , ' tcx > {
1030
- fn push_ast_cleanup_scope ( & self , id : ast :: NodeId ) ;
1099
+ fn push_ast_cleanup_scope ( & self , id : NodeInfo ) ;
1031
1100
fn push_loop_cleanup_scope ( & self ,
1032
- id : ast:: NodeId ,
1033
- exits : [ Block < ' blk , ' tcx > , ..EXIT_MAX ] ) ;
1101
+ id : ast:: NodeId ,
1102
+ exits : [ Block < ' blk , ' tcx > , ..EXIT_MAX ] ) ;
1034
1103
fn push_custom_cleanup_scope ( & self ) -> CustomScopeIndex ;
1104
+ fn push_custom_cleanup_scope_with_debug_loc ( & self ,
1105
+ debug_loc : NodeInfo )
1106
+ -> CustomScopeIndex ;
1035
1107
fn pop_and_trans_ast_cleanup_scope ( & self ,
1036
1108
bcx : Block < ' blk , ' tcx > ,
1037
1109
cleanup_scope : ast:: NodeId )
0 commit comments