@@ -18,7 +18,8 @@ use middle::trans::base;
1818use middle:: trans:: build;
1919use middle:: trans:: callee;
2020use 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;
2223use middle:: trans:: glue;
2324use middle:: trans:: type_:: Type ;
2425use middle:: ty;
@@ -36,6 +37,10 @@ pub struct CleanupScope<'blk, 'tcx: 'blk> {
3637 // Cleanups to run upon scope exit.
3738 cleanups : Vec < CleanupObj > ,
3839
40+ // The debug location any drop calls generated for this scope will be
41+ // associated with.
42+ debug_loc : Option < NodeInfo > ,
43+
3944 cached_early_exits : Vec < CachedEarlyExit > ,
4045 cached_landing_pad : Option < BasicBlockRef > ,
4146}
@@ -69,7 +74,10 @@ pub struct CachedEarlyExit {
6974pub trait Cleanup {
7075 fn must_unwind ( & self ) -> bool ;
7176 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 > ;
7381}
7482
7583pub type CleanupObj = Box < Cleanup +' static > ;
@@ -80,14 +88,14 @@ pub enum ScopeId {
8088}
8189
8290impl < ' 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 ) {
8492 /*!
8593 * Invoked when we start to trans the code contained
8694 * within a new cleanup scope.
8795 */
8896
8997 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) ) ;
9199
92100 // FIXME(#2202) -- currently closure bodies have a parent
93101 // region, which messes up the assertion below, since there
@@ -101,10 +109,15 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
101109 // this new AST scope had better be its immediate child.
102110 let top_scope = self . top_ast_scope ( ) ;
103111 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) ;
105117 }
106118
107- self . push_scope ( CleanupScope :: new ( AstScopeKind ( id) ) ) ;
119+ self . push_scope ( CleanupScope :: new ( AstScopeKind ( debug_loc. id ) ,
120+ Some ( debug_loc) ) ) ;
108121 }
109122
110123 fn push_loop_cleanup_scope ( & self ,
@@ -114,13 +127,38 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
114127 self . ccx. tcx( ) . map. node_to_string( id) ) ;
115128 assert_eq ! ( Some ( id) , self . top_ast_scope( ) ) ;
116129
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) ) ;
118138 }
119139
120140 fn push_custom_cleanup_scope ( & self ) -> CustomScopeIndex {
121141 let index = self . scopes_len ( ) ;
122142 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) ) ) ;
124162 CustomScopeIndex { index : index }
125163 }
126164
@@ -141,7 +179,6 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
141179
142180 let scope = self . pop_scope ( ) ;
143181 self . trans_scope_cleanups ( bcx, & scope)
144-
145182 }
146183
147184 fn pop_loop_cleanup_scope ( & self ,
@@ -175,9 +212,9 @@ impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
175212 }
176213
177214 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 > {
181218 /*!
182219 * Removes the top cleanup scope from the stack, which must be
183220 * a temporary scope, and generates the code to do its
@@ -503,7 +540,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
503540 let mut bcx = bcx;
504541 if !bcx. unreachable . get ( ) {
505542 for cleanup in scope. cleanups . iter ( ) . rev ( ) {
506- bcx = cleanup. trans ( bcx) ;
543+ bcx = cleanup. trans ( bcx, scope . debug_loc ) ;
507544 }
508545 }
509546 bcx
@@ -671,7 +708,8 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
671708 let mut bcx_out = bcx_in;
672709 for cleanup in scope. cleanups . iter ( ) . rev ( ) {
673710 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 ) ;
675713 }
676714 }
677715 build:: Br ( bcx_out, prev_llbb) ;
@@ -785,9 +823,12 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
785823}
786824
787825impl < ' 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 > {
789829 CleanupScope {
790830 kind : kind,
831+ debug_loc : debug_loc,
791832 cleanups : vec ! ( ) ,
792833 cached_early_exits : vec ! ( ) ,
793834 cached_landing_pad : None ,
@@ -902,11 +943,14 @@ impl Cleanup for DropValue {
902943 self . must_unwind
903944 }
904945
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 > {
906950 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 )
908952 } else {
909- glue:: drop_ty ( bcx, self . val , self . ty )
953+ glue:: drop_ty ( bcx, self . val , self . ty , debug_loc )
910954 } ;
911955 if self . zero {
912956 base:: zero_mem ( bcx, self . val , self . ty ) ;
@@ -935,7 +979,12 @@ impl Cleanup for FreeValue {
935979 true
936980 }
937981
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+
939988 match self . heap {
940989 HeapManaged => {
941990 glue:: trans_free ( bcx, self . ptr )
@@ -963,7 +1012,12 @@ impl Cleanup for FreeSlice {
9631012 true
9641013 }
9651014
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+
9671021 match self . heap {
9681022 HeapManaged => {
9691023 glue:: trans_free ( bcx, self . ptr )
@@ -988,7 +1042,11 @@ impl Cleanup for LifetimeEnd {
9881042 true
9891043 }
9901044
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) ;
9921050 base:: call_lifetime_end ( bcx, self . ptr ) ;
9931051 bcx
9941052 }
@@ -1023,15 +1081,29 @@ fn cleanup_is_suitable_for(c: &Cleanup,
10231081 !label. is_unwind ( ) || c. clean_on_unwind ( )
10241082}
10251083
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+
10261095///////////////////////////////////////////////////////////////////////////
10271096// These traits just exist to put the methods into this file.
10281097
10291098pub trait CleanupMethods < ' blk , ' tcx > {
1030- fn push_ast_cleanup_scope ( & self , id : ast :: NodeId ) ;
1099+ fn push_ast_cleanup_scope ( & self , id : NodeInfo ) ;
10311100 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 ] ) ;
10341103 fn push_custom_cleanup_scope ( & self ) -> CustomScopeIndex ;
1104+ fn push_custom_cleanup_scope_with_debug_loc ( & self ,
1105+ debug_loc : NodeInfo )
1106+ -> CustomScopeIndex ;
10351107 fn pop_and_trans_ast_cleanup_scope ( & self ,
10361108 bcx : Block < ' blk , ' tcx > ,
10371109 cleanup_scope : ast:: NodeId )
0 commit comments