@@ -85,15 +85,23 @@ fn make_mir_scope<'ll, 'tcx>(
85
85
discriminators,
86
86
parent,
87
87
) ;
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
+ }
89
97
} else {
90
98
// The root is the function itself.
91
99
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 {
93
101
file_start_pos : file. start_pos ,
94
102
file_end_pos : file. end_position ( ) ,
95
- ..debug_context. scopes [ scope]
96
- } ;
103
+ ..debug_context. scopes [ scope] . unwrap ( )
104
+ } ) ;
97
105
instantiated. insert ( scope) ;
98
106
return ;
99
107
} ;
@@ -104,7 +112,7 @@ fn make_mir_scope<'ll, 'tcx>(
104
112
{
105
113
// Do not create a DIScope if there are no variables defined in this
106
114
// 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) ;
108
116
instantiated. insert ( scope) ;
109
117
return ;
110
118
}
@@ -137,21 +145,28 @@ fn make_mir_scope<'ll, 'tcx>(
137
145
} ,
138
146
} ;
139
147
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 {
141
156
let callsite_span = hygiene:: walk_chain_collapsed ( callsite_span, mir. span ) ;
142
157
let callsite_scope = parent_scope. adjust_dbg_scope_for_span ( cx, callsite_span) ;
143
158
let loc = cx. dbg_loc ( callsite_scope, parent_scope. inlined_at , callsite_span) ;
144
159
145
160
// 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
147
162
// DILocalVariable with multiple different DILocations in the IR. While
148
163
// the source information for each DILocation would be identical, their
149
164
// inlinedAt attributes will be unique to the particular callsite.
150
165
//
151
166
// We generate DILocations here based on the callsite's location in the
152
167
// source code. A single location in the source code usually can't
153
168
// 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
155
170
// at the same span, which breaks the assumption that we're going to
156
171
// produce a unique DILocation for every scope we process here. We
157
172
// have to explicitly add discriminators if we see inlines into the
@@ -160,24 +175,29 @@ fn make_mir_scope<'ll, 'tcx>(
160
175
// Note further that we can't key this hashtable on the span itself,
161
176
// because these spans could have distinct SyntaxContexts. We have
162
177
// 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 ( ) ) {
164
179
Entry :: Occupied ( mut o) => {
165
180
* o. get_mut ( ) += 1 ;
166
181
unsafe { llvm:: LLVMRustDILocationCloneWithBaseDiscriminator ( loc, * o. get ( ) ) }
167
- . expect ( "Failed to encode discriminator in DILocation" )
168
182
}
169
183
Entry :: Vacant ( v) => {
170
184
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 ;
172
197
}
173
198
}
174
- } ) ;
199
+ }
175
200
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;
182
202
instantiated. insert ( scope) ;
183
203
}
0 commit comments