Skip to content

Commit f79be2c

Browse files
authored
Rollup merge of #81898 - nanguye2496:nanguye2496/fix_str_and_slice_visualization, r=varkor
Fix debug information for function arguments of type &str or slice. Issue details: When lowering MIR to LLVM IR, the compiler decomposes every &str and slice argument into a data pointer and a usize. Then, the original argument is reconstructed from the pointer and the usize arguments in the body of the function that owns it. Since the original argument is declared in the body of a function, it should be marked as a LocalVariable instead of an ArgumentVairable. This confusion causes MSVC debuggers unable to visualize &str and slice arguments correctly. (See #81894 for more details). Fix details: Making sure that the debug variable for every &str and slice argument is marked as LocalVariable instead of ArgumentVariable in computing_per_local_var_debug_info. This change has been verified on VS Code debugger, VS debugger, WinDbg and LLDB.
2 parents 91e5384 + 615fd14 commit f79be2c

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

Diff for: compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
320320
) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {
321321
let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full;
322322

323+
let target_is_msvc = self.cx.sess().target.is_like_msvc;
324+
323325
if !full_debug_info && self.cx.sess().fewer_names() {
324326
return None;
325327
}
@@ -341,11 +343,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
341343
&& var.source_info.scope == mir::OUTERMOST_SOURCE_SCOPE
342344
{
343345
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+
}
349369
} else {
350370
VariableKind::LocalVariable
351371
};

0 commit comments

Comments
 (0)