@@ -320,6 +320,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
320
320
) -> Option < IndexVec < mir:: Local , Vec < PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > > > > {
321
321
let full_debug_info = self . cx . sess ( ) . opts . debuginfo == DebugInfo :: Full ;
322
322
323
+ let target_is_msvc = self . cx . sess ( ) . target . is_like_msvc ;
324
+
323
325
if !full_debug_info && self . cx . sess ( ) . fewer_names ( ) {
324
326
return None ;
325
327
}
@@ -341,11 +343,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
341
343
&& var. source_info . scope == mir:: OUTERMOST_SOURCE_SCOPE
342
344
{
343
345
let arg_index = place. local . index ( ) - 1 ;
344
-
345
- // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
346
- // offset in closures to account for the hidden environment?
347
- // Also, is this `+ 1` needed at all?
348
- VariableKind :: ArgumentVariable ( arg_index + 1 )
346
+ if target_is_msvc {
347
+ // Rust compiler decomposes every &str or slice argument into two components:
348
+ // a pointer to the memory address where the data is stored and a usize representing
349
+ // the length of the str (or slice). These components will later be used to reconstruct
350
+ // the original argument inside the body of the function that owns it (see the
351
+ // definition of debug_introduce_local for more details).
352
+ //
353
+ // Since the original argument is declared inside a function rather than being passed
354
+ // in as an argument, it must be marked as a LocalVariable for MSVC debuggers to visualize
355
+ // its data correctly. (See issue #81894 for an in-depth description of the problem).
356
+ match * var_ty. kind ( ) {
357
+ ty:: Ref ( _, inner_type, _) => match * inner_type. kind ( ) {
358
+ ty:: Slice ( _) | ty:: Str => VariableKind :: LocalVariable ,
359
+ _ => VariableKind :: ArgumentVariable ( arg_index + 1 ) ,
360
+ } ,
361
+ _ => VariableKind :: ArgumentVariable ( arg_index + 1 ) ,
362
+ }
363
+ } else {
364
+ // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
365
+ // offset in closures to account for the hidden environment?
366
+ // Also, is this `+ 1` needed at all?
367
+ VariableKind :: ArgumentVariable ( arg_index + 1 )
368
+ }
349
369
} else {
350
370
VariableKind :: LocalVariable
351
371
} ;
0 commit comments