diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 2bb886ee167a3..82ac4f89faa09 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1256,13 +1256,11 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; let mut struct_fmt = fmt.debug_struct(&name); - // FIXME(project-rfc-2229#48): This should be a list of capture names/places - if let Some(def_id) = def_id.as_local() - && let Some(upvars) = tcx.upvars_mentioned(def_id) - { - for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir_name(var_id); - struct_fmt.field(var_name.as_str(), place); + if let Some(def_id) = def_id.as_local() { + let captures = tcx.closure_captures(def_id); + assert_eq!(captures.len(), places.len()); + for (&capture, place) in iter::zip(captures, places) { + struct_fmt.field(capture.to_symbol().as_str(), place); } } else { for (index, place) in places.iter().enumerate() { @@ -1277,13 +1275,11 @@ impl<'tcx> Debug for Rvalue<'tcx> { let name = format!("{{coroutine@{:?}}}", tcx.def_span(def_id)); let mut struct_fmt = fmt.debug_struct(&name); - // FIXME(project-rfc-2229#48): This should be a list of capture names/places - if let Some(def_id) = def_id.as_local() - && let Some(upvars) = tcx.upvars_mentioned(def_id) - { - for (&var_id, place) in iter::zip(upvars.keys(), places) { - let var_name = tcx.hir_name(var_id); - struct_fmt.field(var_name.as_str(), place); + if let Some(def_id) = def_id.as_local() { + let captures = tcx.closure_captures(def_id); + assert_eq!(captures.len(), places.len()); + for (&capture, place) in iter::zip(captures, places) { + struct_fmt.field(capture.to_symbol().as_str(), place); } } else { for (index, place) in places.iter().enumerate() { diff --git a/tests/mir-opt/issues/issue_154166.rs b/tests/mir-opt/issues/issue_154166.rs new file mode 100644 index 0000000000000..e65c59ea8fca4 --- /dev/null +++ b/tests/mir-opt/issues/issue_154166.rs @@ -0,0 +1,20 @@ +// Check that closure debug implementation correctly displays all captures precisely. + +//@ revisions: e2018 e2021 +//@[e2018] edition: 2018 +//@[e2021] edition: 2021 + +#![crate_type = "lib"] + +pub fn foo(x: (String, String)) { + // CHECK-LABEL: foo( + // e2018: {closure{{.*}}issue_154166{{.*}}} { x: {{.*}} }; + // e2021: {closure{{.*}}issue_154166{{.*}}} { x__0: {{.*}}, x__1: {{.*}} }; + let _closure = || { + if std::hint::black_box(true) { + let _a = &x.1; + } else { + let _b = x.0; + } + }; +}