Skip to content

Commit 1525dc2

Browse files
committed
rustc: dissuade compiler developers from misusing upvar debuginfo.
1 parent e6ec968 commit 1525dc2

File tree

4 files changed

+29
-24
lines changed

4 files changed

+29
-24
lines changed

src/librustc/mir/mod.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,11 @@ pub struct Mir<'tcx> {
146146

147147
/// Names and capture modes of all the closure upvars, assuming
148148
/// the first argument is either the closure or a reference to it.
149-
pub upvar_decls: Vec<UpvarDecl>,
149+
// NOTE(eddyb) This is *strictly* a temporary hack for codegen
150+
// debuginfo generation, and will be removed at some point.
151+
// Do **NOT** use it for anything else, upvar information should not be
152+
// in the MIR, please rely on local crate HIR or other side-channels.
153+
pub __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
150154

151155
/// Mark this MIR of a const context other than const functions as having converted a `&&` or
152156
/// `||` expression into `&` or `|` respectively. This is problematic because if we ever stop
@@ -173,7 +177,7 @@ impl<'tcx> Mir<'tcx> {
173177
local_decls: LocalDecls<'tcx>,
174178
user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
175179
arg_count: usize,
176-
upvar_decls: Vec<UpvarDecl>,
180+
__upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
177181
span: Span,
178182
control_flow_destroyed: Vec<(Span, String)>,
179183
) -> Self {
@@ -197,7 +201,7 @@ impl<'tcx> Mir<'tcx> {
197201
local_decls,
198202
user_type_annotations,
199203
arg_count,
200-
upvar_decls,
204+
__upvar_debuginfo_codegen_only_do_not_use,
201205
spread_arg: None,
202206
span,
203207
cache: cache::Cache::new(),
@@ -431,7 +435,7 @@ impl_stable_hash_for!(struct Mir<'tcx> {
431435
local_decls,
432436
user_type_annotations,
433437
arg_count,
434-
upvar_decls,
438+
__upvar_debuginfo_codegen_only_do_not_use,
435439
spread_arg,
436440
control_flow_destroyed,
437441
span,
@@ -983,7 +987,7 @@ impl<'tcx> LocalDecl<'tcx> {
983987

984988
/// A closure capture, with its name and mode.
985989
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
986-
pub struct UpvarDecl {
990+
pub struct UpvarDebuginfo {
987991
pub debug_name: Name,
988992

989993
/// If true, the capture is behind a reference.
@@ -3151,7 +3155,7 @@ CloneTypeFoldableAndLiftImpls! {
31513155
MirPhase,
31523156
Mutability,
31533157
SourceInfo,
3154-
UpvarDecl,
3158+
UpvarDebuginfo,
31553159
FakeReadCause,
31563160
RetagKind,
31573161
SourceScope,
@@ -3173,7 +3177,7 @@ BraceStructTypeFoldableImpl! {
31733177
local_decls,
31743178
user_type_annotations,
31753179
arg_count,
3176-
upvar_decls,
3180+
__upvar_debuginfo_codegen_only_do_not_use,
31773181
spread_arg,
31783182
control_flow_destroyed,
31793183
span,

src/librustc_codegen_ssa/mir/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,10 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
598598
tmp
599599
}
600600
};
601+
let upvar_debuginfo = &mir.__upvar_debuginfo_codegen_only_do_not_use;
601602
arg_scope.map(|scope| {
602603
// Is this a regular argument?
603-
if arg_index > 0 || mir.upvar_decls.is_empty() {
604+
if arg_index > 0 || upvar_debuginfo.is_empty() {
604605
// The Rust ABI passes indirect variables using a pointer and a manual copy, so we
605606
// need to insert a deref here, but the C ABI uses a pointer and a copy using the
606607
// byval attribute, for which LLVM always does the deref itself,
@@ -638,16 +639,16 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
638639
let (def_id, upvar_substs) = match closure_layout.ty.sty {
639640
ty::Closure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
640641
ty::Generator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
641-
_ => bug!("upvar_decls with non-closure arg0 type `{}`", closure_layout.ty)
642+
_ => bug!("upvar debuginfo with non-closure arg0 type `{}`", closure_layout.ty)
642643
};
643644
let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
644645

645646
let extra_locals = {
646-
let upvars = mir.upvar_decls
647+
let upvars = upvar_debuginfo
647648
.iter()
648649
.zip(upvar_tys)
649650
.enumerate()
650-
.map(|(i, (decl, ty))| (i, decl.debug_name, decl.by_ref, ty));
651+
.map(|(i, (upvar, ty))| (i, upvar.debug_name, upvar.by_ref, ty));
651652

652653
let generator_fields = mir.generator_layout.as_ref().map(|generator_layout| {
653654
let (def_id, gen_substs) = match closure_layout.ty.sty {
@@ -656,7 +657,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
656657
};
657658
let state_tys = gen_substs.state_tys(def_id, tcx);
658659

659-
let upvar_count = mir.upvar_decls.len();
660+
let upvar_count = upvar_debuginfo.len();
660661
generator_layout.fields
661662
.iter()
662663
.zip(state_tys)

src/librustc_mir/build/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
375375
var_indices: HirIdMap<LocalsForNode>,
376376
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
377377
canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
378-
upvar_decls: Vec<UpvarDecl>,
378+
__upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
379379
upvar_mutbls: Vec<Mutability>,
380380
unit_temp: Option<Place<'tcx>>,
381381

@@ -631,7 +631,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
631631
// closure and we stored in a map called upvar_list in TypeckTables indexed
632632
// with the closure's DefId. Here, we run through that vec of UpvarIds for
633633
// the given closure and use the necessary information to create UpvarDecl.
634-
let upvar_decls: Vec<_> = hir_tables
634+
let upvar_debuginfo: Vec<_> = hir_tables
635635
.upvar_list
636636
.get(&fn_def_id)
637637
.into_iter()
@@ -644,14 +644,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
644644
ty::UpvarCapture::ByValue => false,
645645
ty::UpvarCapture::ByRef(..) => true,
646646
};
647-
let mut decl = UpvarDecl {
647+
let mut debuginfo = UpvarDebuginfo {
648648
debug_name: keywords::Invalid.name(),
649649
by_ref,
650650
};
651651
let mut mutability = Mutability::Not;
652652
if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
653653
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
654-
decl.debug_name = ident.name;
654+
debuginfo.debug_name = ident.name;
655655
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
656656
if bm == ty::BindByValue(hir::MutMutable) {
657657
mutability = Mutability::Mut;
@@ -664,7 +664,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
664664
}
665665
}
666666
upvar_mutbls.push(mutability);
667-
decl
667+
debuginfo
668668
})
669669
.collect();
670670

@@ -674,7 +674,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
674674
safety,
675675
return_ty,
676676
return_ty_span,
677-
upvar_decls,
677+
upvar_debuginfo,
678678
upvar_mutbls);
679679

680680
let call_site_scope = region::Scope {
@@ -778,7 +778,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
778778
safety: Safety,
779779
return_ty: Ty<'tcx>,
780780
return_span: Span,
781-
upvar_decls: Vec<UpvarDecl>,
781+
__upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
782782
upvar_mutbls: Vec<Mutability>)
783783
-> Builder<'a, 'gcx, 'tcx> {
784784
let lint_level = LintLevel::Explicit(hir.root_lint_level);
@@ -801,7 +801,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
801801
1,
802802
),
803803
canonical_user_type_annotations: IndexVec::new(),
804-
upvar_decls,
804+
__upvar_debuginfo_codegen_only_do_not_use,
805805
upvar_mutbls,
806806
var_indices: Default::default(),
807807
unit_temp: None,
@@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
837837
self.local_decls,
838838
self.canonical_user_type_annotations,
839839
self.arg_count,
840-
self.upvar_decls,
840+
self.__upvar_debuginfo_codegen_only_do_not_use,
841841
self.fn_span,
842842
self.hir.control_flow_destroyed(),
843843
)

src/librustc_mir/transform/inline.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
222222
debug!("should_inline({:?})", callsite);
223223
let tcx = self.tcx;
224224

225-
// Don't inline closures that have captures
225+
// Don't inline closures that have capture debuginfo
226226
// FIXME: Handle closures better
227-
if callee_mir.upvar_decls.len() > 0 {
228-
debug!(" upvar decls present - not inlining");
227+
if callee_mir.__upvar_debuginfo_codegen_only_do_not_use.len() > 0 {
228+
debug!(" upvar debuginfo present - not inlining");
229229
return false;
230230
}
231231

0 commit comments

Comments
 (0)