Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8cab8e0

Browse files
committedMar 22, 2025
Don't produce debug information for compiler-introduced-vars when desugaring assignments.
An assignment such as (a, b) = (b, c); desugars to the HIR { let (lhs, lhs) = (b, c); a = lhs; b = lhs; }; The repeated `lhs` leads to multiple Locals assigned to the same DILocalVariable. Rather than attempting to fix that, get rid of the debug info for these bindings that don't even exist in the program to begin with. Fixes rust-lang#138198
1 parent 01dc45c commit 8cab8e0

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed
 

‎compiler/rustc_mir_build/src/builder/matches/mod.rs

+42-16
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use std::sync::Arc;
1313
use rustc_abi::VariantIdx;
1414
use rustc_data_structures::fx::FxIndexMap;
1515
use rustc_data_structures::stack::ensure_sufficient_stack;
16-
use rustc_hir::{BindingMode, ByRef};
16+
use rustc_hir::{BindingMode, ByRef, LetStmt, LocalSource, Node};
1717
use rustc_middle::bug;
1818
use rustc_middle::middle::region;
1919
use rustc_middle::mir::{self, *};
2020
use rustc_middle::thir::{self, *};
2121
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
22-
use rustc_span::{BytePos, Pos, Span, Symbol};
22+
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
2323
use tracing::{debug, instrument};
2424

2525
use crate::builder::ForGuard::{self, OutsideGuard, RefWithinGuard};
@@ -2796,13 +2796,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
27962796
)))),
27972797
};
27982798
let for_arm_body = self.local_decls.push(local);
2799-
self.var_debug_info.push(VarDebugInfo {
2800-
name,
2801-
source_info: debug_source_info,
2802-
value: VarDebugInfoContents::Place(for_arm_body.into()),
2803-
composite: None,
2804-
argument_index: None,
2805-
});
2799+
if self.should_emit_debug_info_for_binding(name, var_id) {
2800+
self.var_debug_info.push(VarDebugInfo {
2801+
name,
2802+
source_info: debug_source_info,
2803+
value: VarDebugInfoContents::Place(for_arm_body.into()),
2804+
composite: None,
2805+
argument_index: None,
2806+
});
2807+
}
28062808
let locals = if has_guard.0 {
28072809
let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
28082810
// This variable isn't mutated but has a name, so has to be
@@ -2815,18 +2817,42 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
28152817
BindingForm::RefForGuard,
28162818
))),
28172819
});
2818-
self.var_debug_info.push(VarDebugInfo {
2819-
name,
2820-
source_info: debug_source_info,
2821-
value: VarDebugInfoContents::Place(ref_for_guard.into()),
2822-
composite: None,
2823-
argument_index: None,
2824-
});
2820+
if self.should_emit_debug_info_for_binding(name, var_id) {
2821+
self.var_debug_info.push(VarDebugInfo {
2822+
name,
2823+
source_info: debug_source_info,
2824+
value: VarDebugInfoContents::Place(ref_for_guard.into()),
2825+
composite: None,
2826+
argument_index: None,
2827+
});
2828+
}
28252829
LocalsForNode::ForGuard { ref_for_guard, for_arm_body }
28262830
} else {
28272831
LocalsForNode::One(for_arm_body)
28282832
};
28292833
debug!(?locals);
28302834
self.var_indices.insert(var_id, locals);
28312835
}
2836+
2837+
/// Some bindings are introduced when producing HIR from the AST and don't
2838+
/// actually exist in the source. Skip producing debug info for those when
2839+
/// we can recognize them.
2840+
fn should_emit_debug_info_for_binding(&self, name: Symbol, var_id: LocalVarId) -> bool {
2841+
// For now we only recognize the output of desugaring assigns.
2842+
if name != sym::lhs {
2843+
return true;
2844+
}
2845+
2846+
let tcx = self.tcx;
2847+
for (_, node) in tcx.hir_parent_iter(var_id.0) {
2848+
// FIXME(khuey) at what point is it safe to bail on the iterator?
2849+
// Can we stop at the first non-Pat node?
2850+
if matches!(node, Node::LetStmt(&LetStmt { source: LocalSource::AssignDesugar(_), .. }))
2851+
{
2852+
return false;
2853+
}
2854+
}
2855+
2856+
true
2857+
}
28322858
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ compile-flags: -g -Zmir-opt-level=0
2+
3+
#![crate_type = "lib"]
4+
5+
#[inline(never)]
6+
fn swizzle(a: u32, b: u32, c: u32) -> (u32, (u32, u32)) {
7+
(b, (c, a))
8+
}
9+
10+
pub fn work() {
11+
let mut a = 1;
12+
let mut b = 2;
13+
let mut c = 3;
14+
(a, (b, c)) = swizzle(a, b, c);
15+
println!("{a} {b} {c}");
16+
}
17+
18+
// CHECK-NOT: !DILocalVariable(name: "lhs",

0 commit comments

Comments
 (0)
Failed to load comments.