@@ -85,15 +85,23 @@ fn make_mir_scope<'ll, 'tcx>(
8585 discriminators,
8686 parent,
8787 ) ;
88- debug_context. scopes [ parent]
88+ if let Some ( parent_scope) = debug_context. scopes [ parent] {
89+ parent_scope
90+ } else {
91+ // If the parent scope could not be represented then no children
92+ // can be either.
93+ debug_context. scopes [ scope] = None ;
94+ instantiated. insert ( scope) ;
95+ return ;
96+ }
8997 } else {
9098 // The root is the function itself.
9199 let file = cx. sess ( ) . source_map ( ) . lookup_source_file ( mir. span . lo ( ) ) ;
92- debug_context. scopes [ scope] = DebugScope {
100+ debug_context. scopes [ scope] = Some ( DebugScope {
93101 file_start_pos : file. start_pos ,
94102 file_end_pos : file. end_position ( ) ,
95- ..debug_context. scopes [ scope]
96- } ;
103+ ..debug_context. scopes [ scope] . unwrap ( )
104+ } ) ;
97105 instantiated. insert ( scope) ;
98106 return ;
99107 } ;
@@ -104,7 +112,7 @@ fn make_mir_scope<'ll, 'tcx>(
104112 {
105113 // Do not create a DIScope if there are no variables defined in this
106114 // MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
107- debug_context. scopes [ scope] = parent_scope;
115+ debug_context. scopes [ scope] = Some ( parent_scope) ;
108116 instantiated. insert ( scope) ;
109117 return ;
110118 }
@@ -137,21 +145,28 @@ fn make_mir_scope<'ll, 'tcx>(
137145 } ,
138146 } ;
139147
140- let inlined_at = scope_data. inlined . map ( |( _, callsite_span) | {
148+ let mut debug_scope = Some ( DebugScope {
149+ dbg_scope,
150+ inlined_at : parent_scope. inlined_at ,
151+ file_start_pos : loc. file . start_pos ,
152+ file_end_pos : loc. file . end_position ( ) ,
153+ } ) ;
154+
155+ if let Some ( ( _, callsite_span) ) = scope_data. inlined {
141156 let callsite_span = hygiene:: walk_chain_collapsed ( callsite_span, mir. span ) ;
142157 let callsite_scope = parent_scope. adjust_dbg_scope_for_span ( cx, callsite_span) ;
143158 let loc = cx. dbg_loc ( callsite_scope, parent_scope. inlined_at , callsite_span) ;
144159
145160 // NB: In order to produce proper debug info for variables (particularly
146- // arguments) in multiply-inline functions, LLVM expects to see a single
161+ // arguments) in multiply-inlined functions, LLVM expects to see a single
147162 // DILocalVariable with multiple different DILocations in the IR. While
148163 // the source information for each DILocation would be identical, their
149164 // inlinedAt attributes will be unique to the particular callsite.
150165 //
151166 // We generate DILocations here based on the callsite's location in the
152167 // source code. A single location in the source code usually can't
153168 // produce multiple distinct calls so this mostly works, until
154- // proc- macros get involved. A proc- macro can generate multiple calls
169+ // macros get involved. A macro can generate multiple calls
155170 // at the same span, which breaks the assumption that we're going to
156171 // produce a unique DILocation for every scope we process here. We
157172 // have to explicitly add discriminators if we see inlines into the
@@ -160,24 +175,29 @@ fn make_mir_scope<'ll, 'tcx>(
160175 // Note further that we can't key this hashtable on the span itself,
161176 // because these spans could have distinct SyntaxContexts. We have
162177 // to key on exactly what we're giving to LLVM.
163- match discriminators. entry ( callsite_span. lo ( ) ) {
178+ let inlined_at = match discriminators. entry ( callsite_span. lo ( ) ) {
164179 Entry :: Occupied ( mut o) => {
165180 * o. get_mut ( ) += 1 ;
166181 unsafe { llvm:: LLVMRustDILocationCloneWithBaseDiscriminator ( loc, * o. get ( ) ) }
167- . expect ( "Failed to encode discriminator in DILocation" )
168182 }
169183 Entry :: Vacant ( v) => {
170184 v. insert ( 0 ) ;
171- loc
185+ Some ( loc)
186+ }
187+ } ;
188+ match inlined_at {
189+ Some ( inlined_at) => {
190+ debug_scope. as_mut ( ) . unwrap ( ) . inlined_at = Some ( inlined_at) ;
191+ }
192+ None => {
193+ // LLVM has a maximum discriminator that it can encode (currently
194+ // it uses 12 bits for 4096 possible values). If we exceed that
195+ // there is little we can do but drop the debug info.
196+ debug_scope = None ;
172197 }
173198 }
174- } ) ;
199+ }
175200
176- debug_context. scopes [ scope] = DebugScope {
177- dbg_scope,
178- inlined_at : inlined_at. or ( parent_scope. inlined_at ) ,
179- file_start_pos : loc. file . start_pos ,
180- file_end_pos : loc. file . end_position ( ) ,
181- } ;
201+ debug_context. scopes [ scope] = debug_scope;
182202 instantiated. insert ( scope) ;
183203}
0 commit comments