From dc87ad23904803914603af7c1a5447f469113267 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 12 May 2022 00:34:45 +0900 Subject: [PATCH 01/10] Add regression test for #96395 --- src/test/ui/associated-types/issue-82079.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/ui/associated-types/issue-82079.rs b/src/test/ui/associated-types/issue-82079.rs index 590c799c2d71c..8b3bad707d3f2 100644 --- a/src/test/ui/associated-types/issue-82079.rs +++ b/src/test/ui/associated-types/issue-82079.rs @@ -1,4 +1,7 @@ +// revisions: default miropt // check-pass +//[miropt]compile-flags: -Z mir-opt-level=3 +// -^ This flag is for #96395 as a regression test. mod convenience_operators { use crate::{Op, Relation}; From 60458b97e750452409aa7e7e2307be6205512167 Mon Sep 17 00:00:00 2001 From: ridwanabdillahi <91507758+ridwanabdillahi@users.noreply.github.com> Date: Tue, 24 May 2022 11:14:48 -0700 Subject: [PATCH 02/10] Add support for embedding pretty printers via the `#[debugger_visualizer]` attribute. Add tests for embedding pretty printers and update documentation. Ensure all error checking for `#[debugger_visualizer]` is done up front and not when the `debugger_visualizer` query is run. Clean up potential ODR violations when embedding pretty printers into the `__rustc_debug_gdb_scripts_section__` section. Respond to PR comments and update documentation. --- .../rustc_codegen_llvm/src/debuginfo/gdb.rs | 56 ++++++++- compiler/rustc_codegen_ssa/src/back/link.rs | 74 ++++++------ compiler/rustc_codegen_ssa/src/back/linker.rs | 6 +- compiler/rustc_codegen_ssa/src/base.rs | 61 ++++++++-- compiler/rustc_codegen_ssa/src/lib.rs | 3 +- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 56 +++++---- .../rustc_passes/src/debugger_visualizer.rs | 54 +++------ compiler/rustc_span/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + .../language-features/debugger-visualizer.md | 4 +- ...ependency-with-embedded-visualizers.natvis | 10 ++ .../dependency-with-embedded-visualizers.py | 23 ++++ .../dependency-with-embedded-visualizers.rs | 19 +++ ...atvis => embedded-visualizer-point.natvis} | 10 +- .../debuginfo/embedded-visualizer-point.py | 23 ++++ src/test/debuginfo/embedded-visualizer.natvis | 10 ++ src/test/debuginfo/embedded-visualizer.py | 23 ++++ src/test/debuginfo/embedded-visualizer.rs | 112 ++++++++++++++++++ src/test/debuginfo/msvc-embedded-natvis.rs | 64 ---------- .../auxiliary/debugger-visualizer.natvis | 3 + .../feature-gate-debugger-visualizer.rs | 2 +- .../feature-gate-debugger-visualizer.stderr | 4 +- .../invalid-debugger-visualizer-option.rs | 5 +- .../invalid-debugger-visualizer-option.stderr | 14 ++- .../invalid-debugger-visualizer-target.rs | 1 - src/tools/compiletest/src/runtest.rs | 10 ++ 27 files changed, 453 insertions(+), 198 deletions(-) create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.natvis create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.py create mode 100644 src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs rename src/test/debuginfo/{msvc-embedded-natvis.natvis => embedded-visualizer-point.natvis} (54%) create mode 100644 src/test/debuginfo/embedded-visualizer-point.py create mode 100644 src/test/debuginfo/embedded-visualizer.natvis create mode 100644 src/test/debuginfo/embedded-visualizer.py create mode 100644 src/test/debuginfo/embedded-visualizer.rs delete mode 100644 src/test/debuginfo/msvc-embedded-natvis.rs create mode 100644 src/test/ui/feature-gates/auxiliary/debugger-visualizer.natvis diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 31a09242c5ada..355ef88382d24 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -5,11 +5,14 @@ use crate::llvm; use crate::builder::Builder; use crate::common::CodegenCx; use crate::value::Value; +use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; use rustc_codegen_ssa::traits::*; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; -use rustc_session::config::DebugInfo; +use rustc_session::config::{CrateType, DebugInfo}; use rustc_span::symbol::sym; +use rustc_span::DebuggerVisualizerType; /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. @@ -37,9 +40,33 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' section_var.unwrap_or_else(|| { let section_name = b".debug_gdb_scripts\0"; - let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; + let mut section_contents = Vec::new(); + + // Add the pretty printers for the standard library first. + section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0"); + + // Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute. + let visualizers = collect_debugger_visualizers_transitive( + cx.tcx, + DebuggerVisualizerType::GdbPrettyPrinter, + ); + let crate_name = cx.tcx.crate_name(LOCAL_CRATE); + for (index, visualizer) in visualizers.iter().enumerate() { + // The initial byte `4` instructs GDB that the following pretty printer + // is defined inline as opposed to in a file standalone file. + section_contents.extend_from_slice(b"\x04"); + let vis_name = format!("pretty-printer-{}-{}\n", crate_name.as_str(), index); + section_contents.extend_from_slice(vis_name.as_bytes()); + section_contents.extend_from_slice(&visualizer.src); + + // The final byte `0` tells GDB that the pretty printer has been + // fully defined and can continue searching for additional + // pretty printers. + section_contents.extend_from_slice(b"\0"); + } unsafe { + let section_contents = section_contents.as_slice(); let llvm_type = cx.type_array(cx.type_i8(), section_contents.len() as u64); let section_var = cx @@ -62,7 +89,32 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { let omit_gdb_pretty_printer_section = cx.tcx.sess.contains_name(cx.tcx.hir().krate_attrs(), sym::omit_gdb_pretty_printer_section); + // To ensure the section `__rustc_debug_gdb_scripts_section__` will not create + // ODR violations at link time, this section will not be emitted for rlibs since + // each rlib could produce a different set of visualizers that would be embedded + // in the `.debug_gdb_scripts` section. For that reason, we make sure that the + // section is only emitted for leaf crates. + let embed_visualizers = cx.sess().crate_types().iter().any(|&crate_type| match crate_type { + CrateType::Executable | CrateType::Dylib | CrateType::Cdylib | CrateType::Staticlib => { + // These are crate types for which we will embed pretty printers since they + // are treated as leaf crates. + true + } + CrateType::ProcMacro => { + // We could embed pretty printers for proc macro crates too but it does not + // seem like a good default, since this is a rare use case and we don't + // want to slow down the common case. + false + } + CrateType::Rlib => { + // As per the above description, embedding visualizers for rlibs could + // lead to ODR violations so we skip this crate type as well. + false + } + }); + !omit_gdb_pretty_printer_section && cx.sess().opts.debuginfo != DebugInfo::None && cx.sess().target.emit_debug_gdb_scripts + && embed_visualizers } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 04ec1e7f3c1af..aecbdffe499b1 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -5,7 +5,7 @@ use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_fs_util::fix_windows_verbatim_for_gcc; -use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::def_id::CrateNum; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::SymbolExportKind; use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip}; @@ -18,6 +18,7 @@ use rustc_session::utils::NativeLibKind; /// need out of the shared crate context before we get rid of it. use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; +use rustc_span::DebuggerVisualizerFile; use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback}; use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; @@ -37,6 +38,7 @@ use regex::Regex; use tempfile::Builder as TempFileBuilder; use std::borrow::Borrow; +use std::collections::BTreeSet; use std::ffi::OsString; use std::fs::{File, OpenOptions}; use std::io::{BufWriter, Write}; @@ -2099,14 +2101,16 @@ fn add_order_independent_options( // Pass optimization flags down to the linker. cmd.optimize(); - let debugger_visualizer_paths = if sess.target.is_like_msvc { - collect_debugger_visualizers(tmpdir, sess, &codegen_results.crate_info) - } else { - Vec::new() - }; + // Gather the set of NatVis files, if any, and write them out to a temp directory. + let natvis_visualizers = collect_natvis_visualizers( + tmpdir, + sess, + &codegen_results.crate_info.local_crate_name, + &codegen_results.crate_info.natvis_debugger_visualizers, + ); - // Pass debuginfo and strip flags down to the linker. - cmd.debuginfo(strip_value(sess), &debugger_visualizer_paths); + // Pass debuginfo, NatVis debugger visualizers and strip flags down to the linker. + cmd.debuginfo(strip_value(sess), &natvis_visualizers); // We want to prevent the compiler from accidentally leaking in any system libraries, // so by default we tell linkers not to link to any default libraries. @@ -2125,43 +2129,33 @@ fn add_order_independent_options( add_rpath_args(cmd, sess, codegen_results, out_filename); } -// Write the debugger visualizer files for each crate to the temp directory and gather the file paths. -fn collect_debugger_visualizers( +// Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths. +fn collect_natvis_visualizers( tmpdir: &Path, sess: &Session, - crate_info: &CrateInfo, + crate_name: &Symbol, + natvis_debugger_visualizers: &BTreeSet, ) -> Vec { - let mut visualizer_paths = Vec::new(); - let debugger_visualizers = &crate_info.debugger_visualizers; - let mut index = 0; + let mut visualizer_paths = Vec::with_capacity(natvis_debugger_visualizers.len()); - for (&cnum, visualizers) in debugger_visualizers { - let crate_name = if cnum == LOCAL_CRATE { - crate_info.local_crate_name.as_str() - } else { - crate_info.crate_name[&cnum].as_str() - }; + for (index, visualizer) in natvis_debugger_visualizers.iter().enumerate() { + let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name.as_str(), index)); - for visualizer in visualizers { - let visualizer_out_file = tmpdir.join(format!("{}-{}.natvis", crate_name, index)); - - match fs::write(&visualizer_out_file, &visualizer.src) { - Ok(()) => { - visualizer_paths.push(visualizer_out_file.clone()); - index += 1; - } - Err(error) => { - sess.warn( - format!( - "Unable to write debugger visualizer file `{}`: {} ", - visualizer_out_file.display(), - error - ) - .as_str(), - ); - } - }; - } + match fs::write(&visualizer_out_file, &visualizer.src) { + Ok(()) => { + visualizer_paths.push(visualizer_out_file); + } + Err(error) => { + sess.warn( + format!( + "Unable to write debugger visualizer file `{}`: {} ", + visualizer_out_file.display(), + error + ) + .as_str(), + ); + } + }; } visualizer_paths } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 2a71377d2f15b..e4236876463fc 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -183,7 +183,7 @@ pub trait Linker { fn optimize(&mut self); fn pgo_gen(&mut self); fn control_flow_guard(&mut self); - fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]); + fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]); fn no_crt_objects(&mut self); fn no_default_libraries(&mut self); fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]); @@ -915,7 +915,7 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg("/guard:cf"); } - fn debuginfo(&mut self, strip: Strip, debugger_visualizers: &[PathBuf]) { + fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) { match strip { Strip::None => { // This will cause the Microsoft linker to generate a PDB file @@ -944,7 +944,7 @@ impl<'a> Linker for MsvcLinker<'a> { } // This will cause the Microsoft linker to embed .natvis info for all crates into the PDB file - for path in debugger_visualizers { + for path in natvis_debugger_visualizers { let mut arg = OsString::from("/NATVIS:"); arg.push(path); self.cmd.arg(arg); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index d11f1534153ad..420adec456f61 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -31,11 +31,13 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::cgu_reuse_tracker::CguReuse; -use rustc_session::config::{self, EntryFnType, OutputType}; +use rustc_session::config::{self, CrateType, EntryFnType, OutputType}; use rustc_session::Session; use rustc_span::symbol::sym; +use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType}; use rustc_target::abi::{Align, VariantIdx}; +use std::collections::BTreeSet; use std::convert::TryFrom; use std::ops::{Deref, DerefMut}; use std::time::{Duration, Instant}; @@ -487,6 +489,29 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } +/// This function returns all of the debugger visualizers specified for the +/// current crate as well as all upstream crates transitively that match the +/// `visualizer_type` specified. +pub fn collect_debugger_visualizers_transitive( + tcx: TyCtxt<'_>, + visualizer_type: DebuggerVisualizerType, +) -> BTreeSet { + tcx.debugger_visualizers(LOCAL_CRATE) + .iter() + .chain( + tcx.crates(()) + .iter() + .filter(|&cnum| { + let used_crate_source = tcx.used_crate_source(*cnum); + used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some() + }) + .flat_map(|&cnum| tcx.debugger_visualizers(cnum)), + ) + .filter(|visualizer| visualizer.visualizer_type == visualizer_type) + .cloned() + .collect::>() +} + pub fn codegen_crate( backend: B, tcx: TyCtxt<'_>, @@ -838,13 +863,8 @@ impl CrateInfo { missing_lang_items: Default::default(), dependency_formats: tcx.dependency_formats(()).clone(), windows_subsystem, - debugger_visualizers: Default::default(), + natvis_debugger_visualizers: Default::default(), }; - let debugger_visualizers = tcx.debugger_visualizers(LOCAL_CRATE).clone(); - if !debugger_visualizers.is_empty() { - info.debugger_visualizers.insert(LOCAL_CRATE, debugger_visualizers); - } - let lang_items = tcx.lang_items(); let crates = tcx.crates(()); @@ -882,14 +902,29 @@ impl CrateInfo { let missing = missing.iter().cloned().filter(|&l| lang_items::required(tcx, l)).collect(); info.missing_lang_items.insert(cnum, missing); + } - // Only include debugger visualizer files from crates that will be statically linked. - if used_crate_source.rlib.is_some() || used_crate_source.rmeta.is_some() { - let debugger_visualizers = tcx.debugger_visualizers(cnum).clone(); - if !debugger_visualizers.is_empty() { - info.debugger_visualizers.insert(cnum, debugger_visualizers); - } + let embed_visualizers = tcx.sess.crate_types().iter().any(|&crate_type| match crate_type { + CrateType::Executable | CrateType::Dylib | CrateType::Cdylib => { + // These are crate types for which we invoke the linker and can embed + // NatVis visualizers. + true + } + CrateType::ProcMacro => { + // We could embed NatVis for proc macro crates too (to improve the debugging + // experience for them) but it does not seem like a good default, since + // this is a rare use case and we don't want to slow down the common case. + false } + CrateType::Staticlib | CrateType::Rlib => { + // We don't invoke the linker for these, so we don't need to collect the NatVis for them. + false + } + }); + + if tcx.sess.target.is_like_msvc && embed_visualizers { + info.natvis_debugger_visualizers = + collect_debugger_visualizers_transitive(tcx, DebuggerVisualizerType::Natvis); } info diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 9e1fe588c5379..7fde700be393d 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -36,6 +36,7 @@ use rustc_session::cstore::{self, CrateSource}; use rustc_session::utils::NativeLibKind; use rustc_span::symbol::Symbol; use rustc_span::DebuggerVisualizerFile; +use std::collections::BTreeSet; use std::path::{Path, PathBuf}; pub mod back; @@ -157,7 +158,7 @@ pub struct CrateInfo { pub missing_lang_items: FxHashMap>, pub dependency_formats: Lrc, pub windows_subsystem: Option, - pub debugger_visualizers: FxHashMap>, + pub natvis_debugger_visualizers: BTreeSet, } #[derive(Encodable, Decodable)] diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 097493e8985fb..e021e9603f321 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -399,7 +399,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // RFC #3191: #[debugger_visualizer] support gated!( - debugger_visualizer, Normal, template!(List: r#"natvis_file = "...""#), + debugger_visualizer, Normal, template!(List: r#"natvis_file = "...", gdb_script_file = "...""#), DuplicatesOk, experimental!(debugger_visualizer) ), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3d5da114ecfde..3d38ff00eaba7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -8,6 +8,7 @@ use rustc_ast::tokenstream::DelimSpan; use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MacArgs, MetaItemKind, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; +use rustc_expand::base::resolve_path; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -1982,49 +1983,64 @@ impl CheckAttrVisitor<'_> { } } - let hints = match attr.meta_item_list() { - Some(meta_item_list) => meta_item_list, - None => { - self.emit_debugger_visualizer_err(attr); - return false; - } + let Some(hints) = attr.meta_item_list() else { + self.emit_debugger_visualizer_err(attr.span); + return false; }; let hint = match hints.len() { 1 => &hints[0], _ => { - self.emit_debugger_visualizer_err(attr); + self.emit_debugger_visualizer_err(attr.span); return false; } }; - if !hint.has_name(sym::natvis_file) { - self.emit_debugger_visualizer_err(attr); + let Some(meta_item) = hint.meta_item() else { + self.emit_debugger_visualizer_err(attr.span); return false; - } + }; - let meta_item = match hint.meta_item() { - Some(meta_item) => meta_item, - None => { - self.emit_debugger_visualizer_err(attr); + let visualizer_path = match (meta_item.name_or_empty(), meta_item.value_str()) { + (sym::natvis_file, Some(value)) => value, + (sym::gdb_script_file, Some(value)) => value, + (_, _) => { + self.emit_debugger_visualizer_err(meta_item.span); return false; } }; - match (meta_item.name_or_empty(), meta_item.value_str()) { - (sym::natvis_file, Some(_)) => true, - (_, _) => { - self.emit_debugger_visualizer_err(attr); + let file = + match resolve_path(&self.tcx.sess.parse_sess, visualizer_path.as_str(), attr.span) { + Ok(file) => file, + Err(mut err) => { + err.emit(); + return false; + } + }; + + match std::fs::File::open(&file) { + Ok(_) => true, + Err(err) => { + self.tcx + .sess + .struct_span_err( + meta_item.span, + &format!("couldn't read {}: {}", file.display(), err), + ) + .emit(); false } } } - fn emit_debugger_visualizer_err(&self, attr: &Attribute) { + fn emit_debugger_visualizer_err(&self, span: Span) { self.tcx .sess - .struct_span_err(attr.span, "invalid argument") + .struct_span_err(span, "invalid argument") .note(r#"expected: `natvis_file = "..."`"#) + .note(r#"OR"#) + .note(r#"expected: `gdb_script_file = "..."`"#) .emit(); } diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 8305830bc988f..9b9ee93f63d99 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -21,9 +21,8 @@ fn check_for_debugger_visualizer<'tcx>( let attrs = tcx.hir().attrs(hir_id); for attr in attrs { if attr.has_name(sym::debugger_visualizer) { - let list = match attr.meta_item_list() { - Some(list) => list, - _ => continue, + let Some(list) = attr.meta_item_list() else { + continue }; let meta_item = match list.len() { @@ -34,45 +33,28 @@ fn check_for_debugger_visualizer<'tcx>( _ => continue, }; - let file = match (meta_item.name_or_empty(), meta_item.value_str()) { - (sym::natvis_file, Some(value)) => { + let visualizer_type = match meta_item.name_or_empty() { + sym::natvis_file => DebuggerVisualizerType::Natvis, + sym::gdb_script_file => DebuggerVisualizerType::GdbPrettyPrinter, + _ => continue, + }; + + let file = match meta_item.value_str() { + Some(value) => { match resolve_path(&tcx.sess.parse_sess, value.as_str(), attr.span) { Ok(file) => file, - Err(mut err) => { - err.emit(); - continue; - } + _ => continue, } } - (_, _) => continue, + None => continue, }; - if file.is_file() { - let contents = match std::fs::read(&file) { - Ok(contents) => contents, - Err(err) => { - tcx.sess - .struct_span_err( - attr.span, - &format!( - "Unable to read contents of file `{}`. {}", - file.display(), - err - ), - ) - .emit(); - continue; - } - }; - - debugger_visualizers.insert(DebuggerVisualizerFile::new( - Arc::from(contents), - DebuggerVisualizerType::Natvis, - )); - } else { - tcx.sess - .struct_span_err(attr.span, &format!("{} is not a valid file", file.display())) - .emit(); + match std::fs::read(&file) { + Ok(contents) => { + debugger_visualizers + .insert(DebuggerVisualizerFile::new(Arc::from(contents), visualizer_type)); + } + _ => {} } } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 8737e45487e90..4827eb0eaebca 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1203,6 +1203,7 @@ impl SourceFileHash { #[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)] pub enum DebuggerVisualizerType { Natvis, + GdbPrettyPrinter, } /// A single debugger visualizer file. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 5c9c16350e469..e2a7ff3f92eff 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -721,6 +721,7 @@ symbols! { fundamental, future, future_trait, + gdb_script_file, ge, gen_future, gen_kill, diff --git a/src/doc/unstable-book/src/language-features/debugger-visualizer.md b/src/doc/unstable-book/src/language-features/debugger-visualizer.md index 4ab482fffb97c..c7a0414b67602 100644 --- a/src/doc/unstable-book/src/language-features/debugger-visualizer.md +++ b/src/doc/unstable-book/src/language-features/debugger-visualizer.md @@ -14,6 +14,7 @@ to embed a debugger visualizer file into the PDB/ELF generated by `rustc`. ``` rust,ignore (partial-example) #![feature(debugger_visualizer)] #![debugger_visualizer(natvis_file = "foo.natvis")] +#![debugger_visualizer(gdb_script_file = "foo.py")] struct Foo { } @@ -22,4 +23,5 @@ struct Foo { ## Limitations Currently, this feature only supports embedding Natvis files on `-windows-msvc` -targets when using the MSVC linker via the `natvis_file` meta item. +targets via the `natvis_file` meta item. `-windows-gnu` targets are not currently +supported. diff --git a/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.natvis b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.natvis new file mode 100644 index 0000000000000..5900fcc01a6fe --- /dev/null +++ b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.natvis @@ -0,0 +1,10 @@ + + + + {name} is {age} years old. + + name + age + + + diff --git a/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.py b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.py new file mode 100644 index 0000000000000..2635ed487c803 --- /dev/null +++ b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.py @@ -0,0 +1,23 @@ +import gdb + +class PersonPrinter: + "Print a Person" + + def __init__(self, val): + self.val = val + self.name = val["name"] + self.age = int(val["age"]) + + def to_string(self): + return "{} is {} years old.".format(self.name, self.age) + +def lookup(val): + lookup_tag = val.type.tag + if lookup_tag is None: + return None + if "dependency_with_embedded_visualizers::Person" == lookup_tag: + return PersonPrinter(val) + + return None + +gdb.current_objfile().pretty_printers.append(lookup) diff --git a/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs new file mode 100644 index 0000000000000..327515b10afd1 --- /dev/null +++ b/src/test/debuginfo/auxiliary/dependency-with-embedded-visualizers.rs @@ -0,0 +1,19 @@ +// compile-flags:-g +// ignore-lldb +// no-prefer-dynamic + +#![feature(debugger_visualizer)] +#![debugger_visualizer(natvis_file = "dependency-with-embedded-visualizers.natvis")] +#![debugger_visualizer(gdb_script_file = "dependency-with-embedded-visualizers.py")] +#![crate_type = "rlib"] + +pub struct Person { + name: String, + age: i32, +} + +impl Person { + pub fn new(name: String, age: i32) -> Person { + Person { name: name, age: age } + } +} diff --git a/src/test/debuginfo/msvc-embedded-natvis.natvis b/src/test/debuginfo/embedded-visualizer-point.natvis similarity index 54% rename from src/test/debuginfo/msvc-embedded-natvis.natvis rename to src/test/debuginfo/embedded-visualizer-point.natvis index 201d014b5201d..d7bf6885dd40a 100644 --- a/src/test/debuginfo/msvc-embedded-natvis.natvis +++ b/src/test/debuginfo/embedded-visualizer-point.natvis @@ -1,18 +1,10 @@ - + ({x}, {y}) x y - - - ({a}, {b}) - - a - b - - diff --git a/src/test/debuginfo/embedded-visualizer-point.py b/src/test/debuginfo/embedded-visualizer-point.py new file mode 100644 index 0000000000000..d6b1af007855a --- /dev/null +++ b/src/test/debuginfo/embedded-visualizer-point.py @@ -0,0 +1,23 @@ +import gdb + +class PointPrinter: + "Print a Point" + + def __init__(self, val): + self.val = val + self.x = int(val["x"]) + self.y = int(val["y"]) + + def to_string(self): + return "({}, {})".format(self.x, self.y) + +def lookup(val): + lookup_tag = val.type.tag + if lookup_tag is None: + return None + if "embedded_visualizer::point::Point" == lookup_tag: + return PointPrinter(val) + + return None + +gdb.current_objfile().pretty_printers.append(lookup) diff --git a/src/test/debuginfo/embedded-visualizer.natvis b/src/test/debuginfo/embedded-visualizer.natvis new file mode 100644 index 0000000000000..100437f90e5d6 --- /dev/null +++ b/src/test/debuginfo/embedded-visualizer.natvis @@ -0,0 +1,10 @@ + + + + ({a}, {b}) + + a + b + + + diff --git a/src/test/debuginfo/embedded-visualizer.py b/src/test/debuginfo/embedded-visualizer.py new file mode 100644 index 0000000000000..8e4fab61614e2 --- /dev/null +++ b/src/test/debuginfo/embedded-visualizer.py @@ -0,0 +1,23 @@ +import gdb + +class LinePrinter: + "Print a Line" + + def __init__(self, val): + self.val = val + self.a = val["a"] + self.b = val["b"] + + def to_string(self): + return "({}, {})".format(self.a, self.b) + +def lookup(val): + lookup_tag = val.type.tag + if lookup_tag is None: + return None + if "embedded_visualizer::Line" == lookup_tag: + return LinePrinter(val) + + return None + +gdb.current_objfile().pretty_printers.append(lookup) diff --git a/src/test/debuginfo/embedded-visualizer.rs b/src/test/debuginfo/embedded-visualizer.rs new file mode 100644 index 0000000000000..0269015b46617 --- /dev/null +++ b/src/test/debuginfo/embedded-visualizer.rs @@ -0,0 +1,112 @@ +// compile-flags:-g +// min-gdb-version: 8.1 +// ignore-lldb + +// === CDB TESTS ================================================================================== + +// cdb-command: g + +// The .nvlist command in cdb does not always have a deterministic output +// for the order that NatVis files are displayed. + +// cdb-command: .nvlist +// cdb-check: [...].exe (embedded NatVis "[...]embedded_visualizer-0.natvis") + +// cdb-command: .nvlist +// cdb-check: [...].exe (embedded NatVis "[...]embedded_visualizer-1.natvis") + +// cdb-command: .nvlist +// cdb-check: [...].exe (embedded NatVis "[...]embedded_visualizer-2.natvis") + +// cdb-command: dx point_a +// cdb-check:point_a : (0, 0) [Type: embedded_visualizer::point::Point] +// cdb-check: [] [Type: embedded_visualizer::point::Point] +// cdb-check: [x] : 0 [Type: int] +// cdb-check: [y] : 0 [Type: int] + +// cdb-command: dx point_b +// cdb-check:point_b : (5, 8) [Type: embedded_visualizer::point::Point] +// cdb-check: [] [Type: embedded_visualizer::point::Point] +// cdb-check: [x] : 5 [Type: int] +// cdb-check: [y] : 8 [Type: int] + +// cdb-command: dx line +// cdb-check:line : ((0, 0), (5, 8)) [Type: embedded_visualizer::Line] +// cdb-check: [] [Type: embedded_visualizer::Line] +// cdb-check: [a] : (0, 0) [Type: embedded_visualizer::point::Point] +// cdb-check: [b] : (5, 8) [Type: embedded_visualizer::point::Point] + +// cdb-command: dx person +// cdb-check:person : "Person A" is 10 years old. [Type: dependency_with_embedded_visualizers::Person] +// cdb-check: [] [Type: dependency_with_embedded_visualizers::Person] +// cdb-check: [name] : "Person A" [Type: alloc::string::String] +// cdb-check: [age] : 10 [Type: int] + +// === GDB TESTS =================================================================================== + +// gdb-command: run + +// gdb-command: info auto-load python-scripts +// gdb-check:Yes pretty-printer-embedded_visualizer-0 +// gdb-check:Yes pretty-printer-embedded_visualizer-1 +// gdb-command: print point_a +// gdb-check:$1 = (0, 0) +// gdb-command: print point_b +// gdb-check:$2 = (5, 8) +// gdb-command: print line +// gdb-check:$3 = ((0, 0), (5, 8)) +// gdb-command: print person +// gdb-check:$4 = "Person A" is 10 years old. + +#![allow(unused_variables)] +#![feature(debugger_visualizer)] +#![debugger_visualizer(natvis_file = "embedded-visualizer.natvis")] +#![debugger_visualizer(gdb_script_file = "embedded-visualizer.py")] + +// aux-build: dependency-with-embedded-visualizers.rs +extern crate dependency_with_embedded_visualizers; + +use dependency_with_embedded_visualizers::Person; + +#[debugger_visualizer(natvis_file = "embedded-visualizer-point.natvis")] +#[debugger_visualizer(gdb_script_file = "embedded-visualizer-point.py")] +mod point { + pub struct Point { + x: i32, + y: i32, + } + + impl Point { + pub fn new(x: i32, y: i32) -> Point { + Point { x: x, y: y } + } + } +} + +use point::Point; + +pub struct Line { + a: Point, + b: Point, +} + +impl Line { + pub fn new(a: Point, b: Point) -> Line { + Line { a: a, b: b } + } +} + +fn main() { + let point_a = Point::new(0, 0); + let point_b = Point::new(5, 8); + let line = Line::new(point_a, point_b); + + let name = String::from("Person A"); + let person = Person::new(name, 10); + + zzz(); // #break +} + +fn zzz() { + () +} diff --git a/src/test/debuginfo/msvc-embedded-natvis.rs b/src/test/debuginfo/msvc-embedded-natvis.rs deleted file mode 100644 index f714fb2ad174d..0000000000000 --- a/src/test/debuginfo/msvc-embedded-natvis.rs +++ /dev/null @@ -1,64 +0,0 @@ -// only-cdb -// compile-flags:-g - -// === CDB TESTS ================================================================================== - -// cdb-command: g - -// cdb-command: .nvlist -// cdb-check: [...].exe (embedded NatVis "[...]msvc_embedded_natvis-0.natvis") - -// cdb-command: dx point_a -// cdb-check:point_a : (0, 0) [Type: msvc_embedded_natvis::Point] -// cdb-check: [] [Type: msvc_embedded_natvis::Point] -// cdb-check: [x] : 0 [Type: int] -// cdb-check: [y] : 0 [Type: int] - -// cdb-command: dx point_b -// cdb-check:point_b : (5, 8) [Type: msvc_embedded_natvis::Point] -// cdb-check: [] [Type: msvc_embedded_natvis::Point] -// cdb-check: [x] : 5 [Type: int] -// cdb-check: [y] : 8 [Type: int] - -// cdb-command: dx line -// cdb-check:line : ((0, 0), (5, 8)) [Type: msvc_embedded_natvis::Line] -// cdb-check: [] [Type: msvc_embedded_natvis::Line] -// cdb-check: [a] : (0, 0) [Type: msvc_embedded_natvis::Point] -// cdb-check: [b] : (5, 8) [Type: msvc_embedded_natvis::Point] - -#![feature(debugger_visualizer)] -#![debugger_visualizer(natvis_file = "msvc-embedded-natvis.natvis")] - -pub struct Point { - x: i32, - y: i32, -} - -impl Point { - pub fn new(x: i32, y: i32) -> Point { - Point { x: x, y: y } - } -} - -pub struct Line { - a: Point, - b: Point, -} - -impl Line { - pub fn new(a: Point, b: Point) -> Line { - Line { a: a, b: b } - } -} - -fn main() { - let point_a = Point::new(0, 0); - let point_b = Point::new(5, 8); - let line = Line::new(point_a, point_b); - - zzz(); // #break -} - -fn zzz() { - () -} diff --git a/src/test/ui/feature-gates/auxiliary/debugger-visualizer.natvis b/src/test/ui/feature-gates/auxiliary/debugger-visualizer.natvis new file mode 100644 index 0000000000000..6eb47e3d85be4 --- /dev/null +++ b/src/test/ui/feature-gates/auxiliary/debugger-visualizer.natvis @@ -0,0 +1,3 @@ + + + diff --git a/src/test/ui/feature-gates/feature-gate-debugger-visualizer.rs b/src/test/ui/feature-gates/feature-gate-debugger-visualizer.rs index 3f9eb27a0d654..4c4dc450d18bc 100644 --- a/src/test/ui/feature-gates/feature-gate-debugger-visualizer.rs +++ b/src/test/ui/feature-gates/feature-gate-debugger-visualizer.rs @@ -1,3 +1,3 @@ -#![debugger_visualizer(natvis_file = "../foo.natvis")] //~ ERROR the `#[debugger_visualizer]` attribute is an experimental feature +#![debugger_visualizer(natvis_file = "auxiliary/debugger-visualizer.natvis")] //~ ERROR the `#[debugger_visualizer]` attribute is an experimental feature fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-debugger-visualizer.stderr b/src/test/ui/feature-gates/feature-gate-debugger-visualizer.stderr index 721b2b185dad0..e9367fbc6c96c 100644 --- a/src/test/ui/feature-gates/feature-gate-debugger-visualizer.stderr +++ b/src/test/ui/feature-gates/feature-gate-debugger-visualizer.stderr @@ -1,8 +1,8 @@ error[E0658]: the `#[debugger_visualizer]` attribute is an experimental feature --> $DIR/feature-gate-debugger-visualizer.rs:1:1 | -LL | #![debugger_visualizer(natvis_file = "../foo.natvis")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #![debugger_visualizer(natvis_file = "auxiliary/debugger-visualizer.natvis")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #95939 for more information = help: add `#![feature(debugger_visualizer)]` to the crate attributes to enable diff --git a/src/test/ui/invalid/invalid-debugger-visualizer-option.rs b/src/test/ui/invalid/invalid-debugger-visualizer-option.rs index 5332298f0ef90..5645a30ccee7d 100644 --- a/src/test/ui/invalid/invalid-debugger-visualizer-option.rs +++ b/src/test/ui/invalid/invalid-debugger-visualizer-option.rs @@ -1,4 +1,7 @@ +// normalize-stderr-test: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" +// normalize-stderr-test: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" + #![feature(debugger_visualizer)] #![debugger_visualizer(random_file = "../foo.random")] //~ ERROR invalid argument - +#![debugger_visualizer(natvis_file = "../foo.random")] //~ ERROR fn main() {} diff --git a/src/test/ui/invalid/invalid-debugger-visualizer-option.stderr b/src/test/ui/invalid/invalid-debugger-visualizer-option.stderr index 24ad9361fe3a3..afb8d16ee960a 100644 --- a/src/test/ui/invalid/invalid-debugger-visualizer-option.stderr +++ b/src/test/ui/invalid/invalid-debugger-visualizer-option.stderr @@ -1,10 +1,18 @@ error: invalid argument - --> $DIR/invalid-debugger-visualizer-option.rs:2:1 + --> $DIR/invalid-debugger-visualizer-option.rs:5:24 | LL | #![debugger_visualizer(random_file = "../foo.random")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected: `natvis_file = "..."` + = note: OR + = note: expected: `gdb_script_file = "..."` -error: aborting due to previous error +error: couldn't read $DIR/../foo.random: $FILE_NOT_FOUND_MSG (os error $FILE_NOT_FOUND_CODE) + --> $DIR/invalid-debugger-visualizer-option.rs:6:24 + | +LL | #![debugger_visualizer(natvis_file = "../foo.random")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors diff --git a/src/test/ui/invalid/invalid-debugger-visualizer-target.rs b/src/test/ui/invalid/invalid-debugger-visualizer-target.rs index 7668d092e614b..f0aba6a75c4cb 100644 --- a/src/test/ui/invalid/invalid-debugger-visualizer-target.rs +++ b/src/test/ui/invalid/invalid-debugger-visualizer-target.rs @@ -1,5 +1,4 @@ #![feature(debugger_visualizer)] #[debugger_visualizer(natvis_file = "../foo.natvis")] //~ ERROR attribute should be applied to a module - fn main() {} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 64b6df3567a4a..494c8d771b07b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -929,6 +929,16 @@ impl<'test> TestCx<'test> { "add-auto-load-safe-path {}\n", rust_pp_module_abs_path.replace(r"\", r"\\") )); + + let output_base_dir = self.output_base_dir().to_str().unwrap().to_owned(); + + // Add the directory containing the output binary to + // include embedded pretty printers to GDB's script + // auto loading safe path + script_str.push_str(&format!( + "add-auto-load-safe-path {}\n", + output_base_dir.replace(r"\", r"\\") + )); } } _ => { From ab1f8ed2d912cfdefb5d6d734456732d5bb064e7 Mon Sep 17 00:00:00 2001 From: ridwanabdillahi <91507758+ridwanabdillahi@users.noreply.github.com> Date: Tue, 24 May 2022 11:22:14 -0700 Subject: [PATCH 03/10] Update documentation. --- compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 355ef88382d24..5186aee57fb12 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -53,7 +53,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global<'ll>(cx: &CodegenCx<'ll, ' let crate_name = cx.tcx.crate_name(LOCAL_CRATE); for (index, visualizer) in visualizers.iter().enumerate() { // The initial byte `4` instructs GDB that the following pretty printer - // is defined inline as opposed to in a file standalone file. + // is defined inline as opposed to in a standalone file. section_contents.extend_from_slice(b"\x04"); let vis_name = format!("pretty-printer-{}-{}\n", crate_name.as_str(), index); section_contents.extend_from_slice(vis_name.as_bytes()); @@ -107,7 +107,7 @@ pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { false } CrateType::Rlib => { - // As per the above description, embedding visualizers for rlibs could + // As per the above description, embedding pretty printers for rlibs could // lead to ODR violations so we skip this crate type as well. false } From 7ac62ce75cef963017245287f0a7b140e09589d7 Mon Sep 17 00:00:00 2001 From: ridwanabdillahi <91507758+ridwanabdillahi@users.noreply.github.com> Date: Wed, 25 May 2022 10:44:56 -0700 Subject: [PATCH 04/10] Respond to PR comments. --- compiler/rustc_passes/src/debugger_visualizer.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs index 9b9ee93f63d99..e08683fe23b20 100644 --- a/compiler/rustc_passes/src/debugger_visualizer.rs +++ b/compiler/rustc_passes/src/debugger_visualizer.rs @@ -54,7 +54,14 @@ fn check_for_debugger_visualizer<'tcx>( debugger_visualizers .insert(DebuggerVisualizerFile::new(Arc::from(contents), visualizer_type)); } - _ => {} + Err(err) => { + tcx.sess + .struct_span_err( + meta_item.span, + &format!("couldn't read {}: {}", file.display(), err), + ) + .emit(); + } } } } From 7005f24d17e6194e401a62d5fe4d13ef2a8370ef Mon Sep 17 00:00:00 2001 From: Patryk Wychowaniec Date: Thu, 26 May 2022 21:11:16 +0200 Subject: [PATCH 05/10] library/std: Bump compiler_builtins --- Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7154061f4b8d1..069f355e51387 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -746,9 +746,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.71" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "163437f05ca8f29d7e9128ea728dedf5eb620e445fbca273641d3a3050305f23" +checksum = "71b72fde1d7792ca3bd654f7c3ea4508f9e4d0c826e24179eabb7fcc97a90bc3" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 95506fc1eb9c8..229e546e08549 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.126", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.71" } +compiler_builtins = { version = "0.1.73" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } From 1c048eb5c01040feae731560f3c95f8647beb218 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Thu, 12 May 2022 00:27:06 +0300 Subject: [PATCH 06/10] validate derefer, run derefer inside generator --- .../src/transform/validate.rs | 11 +- compiler/rustc_middle/src/mir/mod.rs | 8 +- .../src/deref_separator.rs | 110 ++++++++++-------- compiler/rustc_mir_transform/src/generator.rs | 4 + compiler/rustc_mir_transform/src/inline.rs | 3 +- .../derefer_inline_test.main.Derefer.diff | 69 +++++++++++ src/test/mir-opt/derefer_inline_test.rs | 9 ++ .../inline/dyn_trait.get_query.Inline.diff | 4 + .../dyn_trait.try_execute_query.Inline.diff | 4 + .../inline_any_operand.bar.Inline.after.mir | 4 + .../inline_closure.foo.Inline.after.mir | 4 + ...e_closure_borrows_arg.foo.Inline.after.mir | 4 + ...line_closure_captures.foo.Inline.after.mir | 4 + ...patibility.inlined_no_sanitize.Inline.diff | 4 + ...ibility.inlined_target_feature.Inline.diff | 4 + .../inline/inline_cycle.one.Inline.diff | 4 + .../inline/inline_cycle.two.Inline.diff | 4 + .../inline/inline_diverging.f.Inline.diff | 4 + .../inline/inline_diverging.g.Inline.diff | 4 + .../inline/inline_diverging.h.Inline.diff | 4 + .../inline/inline_generator.main.Inline.diff | 18 ++- ...inline_instruction_set.default.Inline.diff | 4 + .../inline_instruction_set.t32.Inline.diff | 4 + .../inline_options.main.Inline.after.mir | 4 + .../inline/inline_retag.bar.Inline.after.mir | 4 + .../inline/inline_shims.clone.Inline.diff | 4 + .../inline/inline_shims.drop.Inline.diff | 4 + .../inline_specialization.main.Inline.diff | 4 + ...line_trait_method_2.test2.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.a.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.b.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.c.Inline.after.mir | 4 + ...67_inline_as_ref_as_mut.d.Inline.after.mir | 4 + ...ine_scopes_parenting.main.Inline.after.mir | 4 + ...age_markers.main.RemoveStorageMarkers.diff | 4 + ...nneeded_drops.opt.RemoveUnneededDrops.diff | 4 + ....opt_generic_copy.RemoveUnneededDrops.diff | 4 + ...mplify_arm.id_try.SimplifyArmIdentity.diff | 4 + ...implify_arm.id_try.SimplifyBranchSame.diff | 4 + 39 files changed, 297 insertions(+), 59 deletions(-) create mode 100644 src/test/mir-opt/derefer_inline_test.main.Derefer.diff create mode 100644 src/test/mir-opt/derefer_inline_test.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 54c2daf9ac20e..665b07c9f89ce 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::Scalar; +use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, Local, Location, MirPass, @@ -302,9 +303,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_projection_elem(local, proj_base, elem, context, location); } - fn visit_place(&mut self, place: &Place<'tcx>, _: PlaceContext, _: Location) { + fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) { // Set off any `bug!`s in the type computation code let _ = place.ty(&self.body.local_decls, self.tcx); + + if self.mir_phase >= MirPhase::Derefered + && place.projection.len() > 1 + && cntxt != PlaceContext::NonUse(VarDebugInfo) + && place.projection[1..].contains(&ProjectionElem::Deref) + { + self.fail(location, format!("{:?}, has deref at the wrong place", place)); + } } fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9f8b22c8afc47..84fb817418eae 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -172,12 +172,14 @@ pub enum MirPhase { /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands /// are allowed for non-`Copy` types. DropsLowered = 3, + /// After this projections may only contain deref projections as the first element. + Derefered = 4, /// Beginning with this phase, the following variant is disallowed: /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` /// /// And the following variant is allowed: /// * [`StatementKind::SetDiscriminant`] - Deaggregated = 4, + Deaggregated = 5, /// Before this phase, generators are in the "source code" form, featuring `yield` statements /// and such. With this phase change, they are transformed into a proper state machine. Running /// optimizations before this change can be potentially dangerous because the source code is to @@ -191,8 +193,8 @@ pub enum MirPhase { /// Beginning with this phase, the following variants are disallowed: /// * [`TerminatorKind::Yield`](terminator::TerminatorKind::Yield) /// * [`TerminatorKind::GeneratorDrop`](terminator::TerminatorKind::GeneratorDrop) - GeneratorsLowered = 5, - Optimized = 6, + GeneratorsLowered = 6, + Optimized = 7, } impl MirPhase { diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index 57a95a67df70c..bfb3ad1be2734 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -1,9 +1,11 @@ use crate::MirPass; use rustc_index::vec::IndexVec; use rustc_middle::mir::patch::MirPatch; +use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{MutVisitor, PlaceContext}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; + pub struct Derefer; pub struct DerefChecker<'tcx> { @@ -17,63 +19,68 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> { self.tcx } - fn visit_place(&mut self, place: &mut Place<'tcx>, _: PlaceContext, loc: Location) { - let mut place_local = place.local; - let mut last_len = 0; - let mut last_deref_idx = 0; + fn visit_place(&mut self, place: &mut Place<'tcx>, cntxt: PlaceContext, loc: Location) { + if !place.projection.is_empty() + && cntxt != PlaceContext::NonUse(VarDebugInfo) + && place.projection[1..].contains(&ProjectionElem::Deref) + { + let mut place_local = place.local; + let mut last_len = 0; + let mut last_deref_idx = 0; - let mut prev_temp: Option = None; + let mut prev_temp: Option = None; - for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { - if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() { - last_deref_idx = idx; - } - } - - for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { - if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() { - let ty = p_ref.ty(&self.local_decls, self.tcx).ty; - let temp = self.patcher.new_local_with_info( - ty, - self.local_decls[p_ref.local].source_info.span, - Some(Box::new(LocalInfo::DerefTemp)), - ); - - self.patcher.add_statement(loc, StatementKind::StorageLive(temp)); - - // We are adding current p_ref's projections to our - // temp value, excluding projections we already covered. - let deref_place = Place::from(place_local) - .project_deeper(&p_ref.projection[last_len..], self.tcx); - - self.patcher.add_assign( - loc, - Place::from(temp), - Rvalue::Use(Operand::Move(deref_place)), - ); - place_local = temp; - last_len = p_ref.projection.len(); - - // Change `Place` only if we are actually at the Place's last deref - if idx == last_deref_idx { - let temp_place = - Place::from(temp).project_deeper(&place.projection[idx..], self.tcx); - *place = temp_place; + for (idx, elem) in place.projection[0..].iter().enumerate() { + if *elem == ProjectionElem::Deref { + last_deref_idx = idx; } - - // We are destroying the previous temp since it's no longer used. - if let Some(prev_temp) = prev_temp { - self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp)); + } + for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { + if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref { + let ty = p_ref.ty(&self.local_decls, self.tcx).ty; + let temp = self.patcher.new_local_with_info( + ty, + self.local_decls[p_ref.local].source_info.span, + Some(Box::new(LocalInfo::DerefTemp)), + ); + + self.patcher.add_statement(loc, StatementKind::StorageLive(temp)); + + // We are adding current p_ref's projections to our + // temp value, excluding projections we already covered. + let deref_place = Place::from(place_local) + .project_deeper(&p_ref.projection[last_len..], self.tcx); + + self.patcher.add_assign( + loc, + Place::from(temp), + Rvalue::Use(Operand::Move(deref_place)), + ); + place_local = temp; + last_len = p_ref.projection.len(); + + // Change `Place` only if we are actually at the Place's last deref + if idx == last_deref_idx { + let temp_place = + Place::from(temp).project_deeper(&place.projection[idx..], self.tcx); + *place = temp_place; + } + + // We are destroying the previous temp since it's no longer used. + if let Some(prev_temp) = prev_temp { + self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp)); + } + + prev_temp = Some(temp); } - - prev_temp = Some(temp); } - } - // Since we won't be able to reach final temp, we destroy it outside the loop. - if let Some(prev_temp) = prev_temp { - let last_loc = Location { block: loc.block, statement_index: loc.statement_index + 1 }; - self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp)); + // Since we won't be able to reach final temp, we destroy it outside the loop. + if let Some(prev_temp) = prev_temp { + let last_loc = + Location { block: loc.block, statement_index: loc.statement_index + 1 }; + self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp)); + } } } } @@ -92,5 +99,6 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { impl<'tcx> MirPass<'tcx> for Derefer { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { deref_finder(tcx, body); + body.phase = MirPhase::Derefered; } } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 4a3505ca3ffcf..9eb77f6021373 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -49,6 +49,7 @@ //! For generators with state 1 (returned) and state 2 (poisoned) it does nothing. //! Otherwise it drops all the values in scope at the last suspension point. +use crate::deref_separator::deref_finder; use crate::simplify; use crate::util::expand_aggregate; use crate::MirPass; @@ -1368,6 +1369,9 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // Create the Generator::resume function create_generator_resume_function(tcx, transform, body, can_return); + + // Run derefer to fix Derefs that are not in the first place + deref_finder(tcx, body); } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 66fb01bd4646d..9526c0acc66d6 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1,5 +1,5 @@ //! Inlining pass for MIR functions - +use crate::deref_separator::deref_finder; use rustc_attr::InlineAttr; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; @@ -53,6 +53,7 @@ impl<'tcx> MirPass<'tcx> for Inline { debug!("running simplify cfg on {:?}", body.source); CfgSimplifier::new(body).simplify(); remove_dead_blocks(tcx, body); + deref_finder(tcx, body); } } } diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff new file mode 100644 index 0000000000000..e5e049df1db60 --- /dev/null +++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff @@ -0,0 +1,69 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_inline_test.rs:7:11: 7:11 + let _1: std::boxed::Box>; // in scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + let mut _2: usize; // in scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + let mut _3: usize; // in scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + let mut _4: *mut u8; // in scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + let mut _5: std::boxed::Box>; // in scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + let mut _6: (); // in scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + _2 = SizeOf(std::boxed::Box); // scope 1 at $DIR/derefer_inline_test.rs:8:5: 8:12 + _3 = AlignOf(std::boxed::Box); // scope 1 at $DIR/derefer_inline_test.rs:8:5: 8:12 + _4 = alloc::alloc::exchange_malloc(move _2, move _3) -> bb1; // scope 1 at $DIR/derefer_inline_test.rs:8:5: 8:12 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:8:5: 8:12 + // + literal: Const { ty: unsafe fn(usize, usize) -> *mut u8 {alloc::alloc::exchange_malloc}, val: Value(Scalar()) } + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + _5 = ShallowInitBox(move _4, std::boxed::Box); // scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + (*_5) = f() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:8:9: 8:12 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:8:9: 8:10 + // + literal: Const { ty: fn() -> Box {f}, val: Value(Scalar()) } + } + + bb2: { + _1 = move _5; // scope 0 at $DIR/derefer_inline_test.rs:8:5: 8:12 + goto -> bb3; // scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + } + + bb3: { + StorageDead(_5); // scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:8:12: 8:13 + } + + bb4: { + StorageDead(_1); // scope 0 at $DIR/derefer_inline_test.rs:8:12: 8:13 + _0 = const (); // scope 0 at $DIR/derefer_inline_test.rs:7:11: 9:2 + return; // scope 0 at $DIR/derefer_inline_test.rs:9:2: 9:2 + } + + bb5 (cleanup): { + goto -> bb8; // scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/derefer_inline_test.rs:7:1: 9:2 + } + + bb7 (cleanup): { + _6 = alloc::alloc::box_free::, std::alloc::Global>(move (_5.0: std::ptr::Unique>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + // mir::Constant + // + span: $DIR/derefer_inline_test.rs:8:11: 8:12 + // + literal: Const { ty: unsafe fn(Unique>, std::alloc::Global) {alloc::alloc::box_free::, std::alloc::Global>}, val: Value(Scalar()) } + } + + bb8 (cleanup): { + goto -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:8:11: 8:12 + } + } + diff --git a/src/test/mir-opt/derefer_inline_test.rs b/src/test/mir-opt/derefer_inline_test.rs new file mode 100644 index 0000000000000..5f5a06881caf0 --- /dev/null +++ b/src/test/mir-opt/derefer_inline_test.rs @@ -0,0 +1,9 @@ +// EMIT_MIR derefer_inline_test.main.Derefer.diff +#![feature(box_syntax)] +#[inline] +fn f() -> Box { + box 0 +} +fn main() { + box f(); +} diff --git a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff index 953d7b85c5ba7..d1ab29b8a21ab 100644 --- a/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff +++ b/src/test/mir-opt/inline/dyn_trait.get_query.Inline.diff @@ -57,6 +57,10 @@ StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:34:24: 34:25 StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:35:1: 35:2 return; // scope 0 at $DIR/dyn-trait.rs:35:2: 35:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 0 at $DIR/dyn-trait.rs:32:1: 35:2 } } diff --git a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff index 93bba58825d20..0c44c3ada0f8c 100644 --- a/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff +++ b/src/test/mir-opt/inline/dyn_trait.try_execute_query.Inline.diff @@ -32,6 +32,10 @@ + StorageDead(_4); // scope 1 at $DIR/dyn-trait.rs:21:21: 21:22 StorageDead(_2); // scope 0 at $DIR/dyn-trait.rs:27:15: 27:16 return; // scope 0 at $DIR/dyn-trait.rs:28:2: 28:2 ++ } ++ ++ bb2 (cleanup): { ++ resume; // scope 0 at $DIR/dyn-trait.rs:26:1: 28:2 } } diff --git a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir index b2745a17e9717..ade6ccfc7f144 100644 --- a/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_any_operand.bar.Inline.after.mir @@ -41,4 +41,8 @@ fn bar() -> bool { StorageDead(_1); // scope 0 at $DIR/inline-any-operand.rs:13:1: 13:2 return; // scope 0 at $DIR/inline-any-operand.rs:13:2: 13:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/inline-any-operand.rs:10:1: 13:2 + } } diff --git a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir index 4d6cdafd12dea..66fc5fa80ea26 100644 --- a/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure.foo.Inline.after.mir @@ -46,4 +46,8 @@ fn foo(_1: T, _2: i32) -> i32 { StorageDead(_3); // scope 0 at $DIR/inline-closure.rs:13:1: 13:2 return; // scope 0 at $DIR/inline-closure.rs:13:2: 13:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/inline-closure.rs:10:1: 13:2 + } } diff --git a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir index 45281302f9291..7bb17dab061ad 100644 --- a/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_borrows_arg.foo.Inline.after.mir @@ -53,4 +53,8 @@ fn foo(_1: T, _2: &i32) -> i32 { StorageDead(_3); // scope 0 at $DIR/inline-closure-borrows-arg.rs:17:1: 17:2 return; // scope 0 at $DIR/inline-closure-borrows-arg.rs:17:2: 17:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/inline-closure-borrows-arg.rs:11:1: 17:2 + } } diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index 75e37092ff3c3..c6b49b66dc5c0 100644 --- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -66,4 +66,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) { StorageDead(_3); // scope 0 at $DIR/inline-closure-captures.rs:13:1: 13:2 return; // scope 0 at $DIR/inline-closure-captures.rs:13:2: 13:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/inline-closure-captures.rs:10:1: 13:2 + } } diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff index 77eb326cd8263..fd9a540ca16e2 100644 --- a/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_no_sanitize.Inline.diff @@ -19,6 +19,10 @@ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:24:18: 24:19 _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:23:37: 25:2 return; // scope 0 at $DIR/inline-compatibility.rs:25:2: 25:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/inline-compatibility.rs:23:1: 25:2 } } diff --git a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff index a32db48715c23..e7db7aa382fae 100644 --- a/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff +++ b/src/test/mir-opt/inline/inline_compatibility.inlined_target_feature.Inline.diff @@ -19,6 +19,10 @@ StorageDead(_1); // scope 0 at $DIR/inline-compatibility.rs:13:21: 13:22 _0 = const (); // scope 0 at $DIR/inline-compatibility.rs:12:40: 14:2 return; // scope 0 at $DIR/inline-compatibility.rs:14:2: 14:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/inline-compatibility.rs:12:1: 14:2 } } diff --git a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff index b6615739a2150..b732e7cdb9bf8 100644 --- a/src/test/mir-opt/inline/inline_cycle.one.Inline.diff +++ b/src/test/mir-opt/inline/inline_cycle.one.Inline.diff @@ -22,6 +22,10 @@ StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:14:24: 14:25 _0 = const (); // scope 0 at $DIR/inline-cycle.rs:13:10: 15:2 return; // scope 0 at $DIR/inline-cycle.rs:15:2: 15:2 ++ } ++ ++ bb2 (cleanup): { ++ resume; // scope 0 at $DIR/inline-cycle.rs:13:1: 15:2 } } diff --git a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff index 4e46156200443..eac5bf8edec4b 100644 --- a/src/test/mir-opt/inline/inline_cycle.two.Inline.diff +++ b/src/test/mir-opt/inline/inline_cycle.two.Inline.diff @@ -41,6 +41,10 @@ StorageDead(_1); // scope 0 at $DIR/inline-cycle.rs:49:12: 49:13 _0 = const (); // scope 0 at $DIR/inline-cycle.rs:48:10: 50:2 return; // scope 0 at $DIR/inline-cycle.rs:50:2: 50:2 ++ } ++ ++ bb2 (cleanup): { ++ resume; // scope 0 at $DIR/inline-cycle.rs:48:1: 50:2 } } diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff index eb579b53b6c91..ff25c5b4bc337 100644 --- a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff @@ -19,6 +19,10 @@ + + bb1: { + goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:39:5: 39:12 ++ } ++ ++ bb2 (cleanup): { ++ resume; // scope 0 at $DIR/inline-diverging.rs:7:1: 9:2 } } diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff index 3ce823a0e33ec..da55260e284ea 100644 --- a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -44,6 +44,10 @@ + // mir::Constant + // + span: $SRC_DIR/std/src/panic.rs:LL:COL + // + literal: Const { ty: &str, val: Value(Slice(..)) } ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 0 at $DIR/inline-diverging.rs:12:1: 18:2 } } diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff index 647c27d11e58e..0a19daa5045c9 100644 --- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -52,6 +52,10 @@ + + bb1: { + goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 ++ } ++ ++ bb2 (cleanup): { ++ resume; // scope 0 at $DIR/inline-diverging.rs:21:1: 23:2 } } diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff index 48432c1ddd8a3..3e1c4a4670143 100644 --- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -30,6 +30,9 @@ + let mut _10: bool; // in scope 6 at $DIR/inline-generator.rs:15:9: 15:9 + let _11: bool; // in scope 6 at $DIR/inline-generator.rs:15:6: 15:7 + let mut _12: u32; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ let mut _13: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ let mut _14: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ let mut _15: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]; // in scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + } bb0: { @@ -73,7 +76,10 @@ + StorageLive(_10); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46 + StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46 + StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46 -+ _12 = discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ _13 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 } @@ -118,7 +124,10 @@ + Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 ++ StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 ++ _14 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 ++ discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 ++ StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39 + } + @@ -129,7 +138,10 @@ + Deinit(_1); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ discriminant((*(_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]))) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 ++ StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 ++ _15 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 ++ discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 ++ StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41 + } + diff --git a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff index 916244f1f6afb..65891cbb660e1 100644 --- a/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff +++ b/src/test/mir-opt/inline/inline_instruction_set.default.Inline.diff @@ -39,6 +39,10 @@ StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:53:30: 53:31 _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:50:18: 54:2 return; // scope 0 at $DIR/inline-instruction-set.rs:54:2: 54:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 0 at $DIR/inline-instruction-set.rs:50:1: 54:2 } } diff --git a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff index 8907bae9177aa..20e1d0ae4d5da 100644 --- a/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff +++ b/src/test/mir-opt/inline/inline_instruction_set.t32.Inline.diff @@ -41,6 +41,10 @@ StorageDead(_3); // scope 0 at $DIR/inline-instruction-set.rs:46:30: 46:31 _0 = const (); // scope 0 at $DIR/inline-instruction-set.rs:41:14: 47:2 return; // scope 0 at $DIR/inline-instruction-set.rs:47:2: 47:2 ++ } ++ ++ bb3 (cleanup): { ++ resume; // scope 0 at $DIR/inline-instruction-set.rs:41:1: 47:2 } } diff --git a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir index 9fd08f141dc76..eca76df576bf6 100644 --- a/src/test/mir-opt/inline/inline_options.main.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_options.main.Inline.after.mir @@ -52,4 +52,8 @@ fn main() -> () { _0 = const (); // scope 0 at $DIR/inline-options.rs:8:11: 11:2 return; // scope 0 at $DIR/inline-options.rs:11:2: 11:2 } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/inline-options.rs:8:1: 11:2 + } } diff --git a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir index 1aa859484f6f9..2d85ff9a0cbc2 100644 --- a/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_retag.bar.Inline.after.mir @@ -69,4 +69,8 @@ fn bar() -> bool { StorageDead(_4); // scope 0 at $DIR/inline-retag.rs:13:1: 13:2 return; // scope 0 at $DIR/inline-retag.rs:13:2: 13:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/inline-retag.rs:10:1: 13:2 + } } diff --git a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff index a7e0a52f7438e..7170cd4057200 100644 --- a/src/test/mir-opt/inline/inline_shims.clone.Inline.diff +++ b/src/test/mir-opt/inline/inline_shims.clone.Inline.diff @@ -21,6 +21,10 @@ + _0 = (*_2); // scope 1 at $SRC_DIR/core/src/clone.rs:LL:COL StorageDead(_2); // scope 0 at $DIR/inline-shims.rs:6:13: 6:14 return; // scope 0 at $DIR/inline-shims.rs:7:2: 7:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/inline-shims.rs:5:1: 7:2 } } diff --git a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff index b6d5f51c17306..aa55c90fcfb55 100644 --- a/src/test/mir-opt/inline/inline_shims.drop.Inline.diff +++ b/src/test/mir-opt/inline/inline_shims.drop.Inline.diff @@ -51,6 +51,10 @@ + + bb3: { + drop((((*_5) as Some).0: B)) -> bb2; // scope 3 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL ++ } ++ ++ bb4 (cleanup): { ++ resume; // scope 0 at $DIR/inline-shims.rs:10:1: 13:2 } } diff --git a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff index 97ff6f75f24bd..8e93baf6a7050 100644 --- a/src/test/mir-opt/inline/inline_specialization.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_specialization.main.Inline.diff @@ -23,6 +23,10 @@ _0 = const (); // scope 0 at $DIR/inline-specialization.rs:4:11: 6:2 StorageDead(_1); // scope 0 at $DIR/inline-specialization.rs:6:1: 6:2 return; // scope 0 at $DIR/inline-specialization.rs:6:2: 6:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/inline-specialization.rs:4:1: 6:2 } } diff --git a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir index 9d8818e657ebd..64375b6edc93e 100644 --- a/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_trait_method_2.test2.Inline.after.mir @@ -29,4 +29,8 @@ fn test2(_1: &dyn X) -> bool { StorageDead(_2); // scope 0 at $DIR/inline-trait-method_2.rs:5:11: 5:12 return; // scope 0 at $DIR/inline-trait-method_2.rs:6:2: 6:2 } + + bb2 (cleanup): { + resume; // scope 0 at $DIR/inline-trait-method_2.rs:4:1: 6:2 + } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir index e9c02cf2c6767..56a23cde0c7e1 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.a.Inline.after.mir @@ -27,4 +27,8 @@ fn a(_1: &mut [T]) -> &mut [T] { StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:1: 4:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:4:2: 4:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:2:1: 4:2 + } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index a18ff0e35fe9a..0bb3445a2d0d2 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -35,4 +35,8 @@ fn b(_1: &mut Box) -> &mut T { StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:1: 9:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:9:2: 9:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:7:1: 9:2 + } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir index 23f33daaa57f2..326b2ad71c0e5 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.c.Inline.after.mir @@ -19,4 +19,8 @@ fn c(_1: &[T]) -> &[T] { StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:1: 14:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:14:2: 14:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:12:1: 14:2 + } } diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index d079ba59ffc3d..c22852b99f4e9 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -23,4 +23,8 @@ fn d(_1: &Box) -> &T { StorageDead(_2); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:1: 19:2 return; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:19:2: 19:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:17:1: 19:2 + } } diff --git a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir index b9ddbacc0e75b..7c3048a69af61 100644 --- a/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_76997_inline_scopes_parenting.main.Inline.after.mir @@ -39,4 +39,8 @@ fn main() -> () { StorageDead(_1); // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:7:1: 7:2 return; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:7:2: 7:2 } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/issue-76997-inline-scopes-parenting.rs:4:1: 7:2 + } } diff --git a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff index 5131e2f088d3d..447fe654c0cca 100644 --- a/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff +++ b/src/test/mir-opt/remove_storage_markers.main.RemoveStorageMarkers.diff @@ -96,5 +96,9 @@ _10 = discriminant(_7); // scope 2 at $DIR/remove_storage_markers.rs:8:14: 8:19 switchInt(move _10) -> [0_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/remove_storage_markers.rs:8:14: 8:19 } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/remove_storage_markers.rs:6:1: 11:2 + } } diff --git a/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff index 714136a9e245e..44eda308bdf90 100644 --- a/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff +++ b/src/test/mir-opt/remove_unneeded_drops.opt.RemoveUnneededDrops.diff @@ -22,6 +22,10 @@ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:4:12: 4:13 - nop; // scope 0 at $DIR/remove_unneeded_drops.rs:3:17: 5:2 return; // scope 0 at $DIR/remove_unneeded_drops.rs:5:2: 5:2 +- } +- +- bb2 (cleanup): { +- resume; // scope 0 at $DIR/remove_unneeded_drops.rs:3:1: 5:2 } } diff --git a/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff index 3dca9f3e1b162..85de00e7001a7 100644 --- a/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff +++ b/src/test/mir-opt/remove_unneeded_drops.opt_generic_copy.RemoveUnneededDrops.diff @@ -22,6 +22,10 @@ StorageDead(_2); // scope 0 at $DIR/remove_unneeded_drops.rs:14:12: 14:13 - nop; // scope 0 at $DIR/remove_unneeded_drops.rs:13:36: 15:2 return; // scope 0 at $DIR/remove_unneeded_drops.rs:15:2: 15:2 +- } +- +- bb2 (cleanup): { +- resume; // scope 0 at $DIR/remove_unneeded_drops.rs:13:1: 15:2 } } diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff index 5da2ad1a27dc9..d2dbfbe1093a8 100644 --- a/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyArmIdentity.diff @@ -85,5 +85,9 @@ bb4: { return; // scope 0 at $DIR/simplify-arm.rs:41:2: 41:2 } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/simplify-arm.rs:35:1: 41:2 + } } diff --git a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff index 528828ad075ad..a993ea73665c4 100644 --- a/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff +++ b/src/test/mir-opt/simplify_arm.id_try.SimplifyBranchSame.diff @@ -85,5 +85,9 @@ bb4: { return; // scope 0 at $DIR/simplify-arm.rs:41:2: 41:2 } + + bb5 (cleanup): { + resume; // scope 0 at $DIR/simplify-arm.rs:35:1: 41:2 + } } From 643c508e869c1bed9ebd694ad4d2eb0cdf6baf24 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 28 May 2022 18:12:34 +0900 Subject: [PATCH 07/10] Remove FIXME on `ExtCtxt::fn_decl()` --- compiler/rustc_expand/src/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 301c67f702645..56d0263269b53 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -514,7 +514,7 @@ impl<'a> ExtCtxt<'a> { } } - // FIXME: unused `self` + // `self` is unused but keep it as method for the convenience use. pub fn fn_decl(&self, inputs: Vec, output: ast::FnRetTy) -> P { P(ast::FnDecl { inputs, output }) } From 4444defc1b4fbf66d234b0b68a43eb95be86e27f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 28 May 2022 18:57:02 +0900 Subject: [PATCH 08/10] Make some tests check-pass --- src/test/ui/lint/lint-unknown-feature-default.rs | 7 +++---- src/test/ui/lint/lint-unknown-feature.rs | 5 ++--- src/test/ui/parser/bounds-obj-parens.rs | 2 +- src/test/ui/parser/impl-qpath.rs | 2 +- src/test/ui/parser/trailing-plus-in-bounds.rs | 2 +- src/test/ui/parser/trait-plusequal-splitting.rs | 2 +- src/test/ui/underscore-imports/duplicate.rs | 2 +- src/test/ui/underscore-imports/intercrate.rs | 2 +- 8 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/test/ui/lint/lint-unknown-feature-default.rs b/src/test/ui/lint/lint-unknown-feature-default.rs index aebc4f1808573..84a2e5a4b3549 100644 --- a/src/test/ui/lint/lint-unknown-feature-default.rs +++ b/src/test/ui/lint/lint-unknown-feature-default.rs @@ -1,10 +1,9 @@ +// check-pass + // Tests the default for the unused_features lint #![allow(stable_features)] // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// build-pass (FIXME(62277): could be check-pass?) - - -fn main() { } +fn main() {} diff --git a/src/test/ui/lint/lint-unknown-feature.rs b/src/test/ui/lint/lint-unknown-feature.rs index 93fa7a6e96e37..1af8d4ff8420f 100644 --- a/src/test/ui/lint/lint-unknown-feature.rs +++ b/src/test/ui/lint/lint-unknown-feature.rs @@ -1,10 +1,9 @@ +// check-pass + #![warn(unused_features)] #![allow(stable_features)] // FIXME(#44232) we should warn that this isn't used. #![feature(rust1)] -// build-pass (FIXME(62277): could be check-pass?) - - fn main() {} diff --git a/src/test/ui/parser/bounds-obj-parens.rs b/src/test/ui/parser/bounds-obj-parens.rs index ae8112b61c66f..8c446d27d0a94 100644 --- a/src/test/ui/parser/bounds-obj-parens.rs +++ b/src/test/ui/parser/bounds-obj-parens.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/impl-qpath.rs b/src/test/ui/parser/impl-qpath.rs index ab45649f4de49..d1f0a02041bee 100644 --- a/src/test/ui/parser/impl-qpath.rs +++ b/src/test/ui/parser/impl-qpath.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // compile-flags: -Z parse-only impl <*const u8>::AssocTy {} // OK diff --git a/src/test/ui/parser/trailing-plus-in-bounds.rs b/src/test/ui/parser/trailing-plus-in-bounds.rs index 61819cabdf178..400649bcf752f 100644 --- a/src/test/ui/parser/trailing-plus-in-bounds.rs +++ b/src/test/ui/parser/trailing-plus-in-bounds.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![allow(bare_trait_objects)] diff --git a/src/test/ui/parser/trait-plusequal-splitting.rs b/src/test/ui/parser/trait-plusequal-splitting.rs index 26ac3ead6a5a6..6ca6774507b88 100644 --- a/src/test/ui/parser/trait-plusequal-splitting.rs +++ b/src/test/ui/parser/trait-plusequal-splitting.rs @@ -1,6 +1,6 @@ // Fixes issue where `+` in generics weren't parsed if they were part of a `+=`. -// build-pass (FIXME(62277): could be check-pass?) +// check-pass struct Whitespace { t: T } struct TokenSplit { t: T } diff --git a/src/test/ui/underscore-imports/duplicate.rs b/src/test/ui/underscore-imports/duplicate.rs index 3662a466ded14..20bc7848acd66 100644 --- a/src/test/ui/underscore-imports/duplicate.rs +++ b/src/test/ui/underscore-imports/duplicate.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // aux-build:duplicate.rs extern crate duplicate; diff --git a/src/test/ui/underscore-imports/intercrate.rs b/src/test/ui/underscore-imports/intercrate.rs index 1cccc67e9ab63..144f95bace1c0 100644 --- a/src/test/ui/underscore-imports/intercrate.rs +++ b/src/test/ui/underscore-imports/intercrate.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // aux-build:underscore-imports.rs extern crate underscore_imports; From ad33519455c7f10bc5e7fdb7cc45ef6f1ccc51c4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 28 May 2022 12:39:36 +0200 Subject: [PATCH 09/10] ptr::invalid is not equivalent to a int2ptr cast --- library/core/src/ptr/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index d2e680ecd20b5..93728f844ddba 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -557,8 +557,8 @@ pub const fn null_mut() -> *mut T { /// Creates an invalid pointer with the given address. /// -/// This is *currently* equivalent to `addr as *const T` but it expresses the intended semantic -/// more clearly, and may become important under future memory models. +/// This is different from `addr as *const T`, which creates a pointer that picks up a previously +/// exposed provenance. See [`from_exposed_addr`] for more details on that operation. /// /// The module's top-level documentation discusses the precise meaning of an "invalid" /// pointer but essentially this expresses that the pointer is not associated @@ -566,7 +566,7 @@ pub const fn null_mut() -> *mut T { /// /// This pointer will have no provenance associated with it and is therefore /// UB to read/write/offset. This mostly exists to facilitate things -/// like ptr::null and NonNull::dangling which make invalid pointers. +/// like `ptr::null` and `NonNull::dangling` which make invalid pointers. /// /// (Standard "Zero-Sized-Types get to cheat and lie" caveats apply, although it /// may be desirable to give them their own API just to make that 100% clear.) @@ -588,8 +588,8 @@ pub const fn invalid(addr: usize) -> *const T { /// Creates an invalid mutable pointer with the given address. /// -/// This is *currently* equivalent to `addr as *mut T` but it expresses the intended semantic -/// more clearly, and may become important under future memory models. +/// This is different from `addr as *mut T`, which creates a pointer that picks up a previously +/// exposed provenance. See [`from_exposed_addr_mut`] for more details on that operation. /// /// The module's top-level documentation discusses the precise meaning of an "invalid" /// pointer but essentially this expresses that the pointer is not associated @@ -597,7 +597,7 @@ pub const fn invalid(addr: usize) -> *const T { /// /// This pointer will have no provenance associated with it and is therefore /// UB to read/write/offset. This mostly exists to facilitate things -/// like ptr::null and NonNull::dangling which make invalid pointers. +/// like `ptr::null` and `NonNull::dangling` which make invalid pointers. /// /// (Standard "Zero-Sized-Types get to cheat and lie" caveats apply, although it /// may be desirable to give them their own API just to make that 100% clear.) From 852777eff12bfc99b355e7c9ddd803d11cd795aa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 28 May 2022 18:15:04 +0200 Subject: [PATCH 10/10] note to future self --- library/core/src/ptr/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 93728f844ddba..6b1e63e0cfaae 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -26,6 +26,7 @@ //! some memory happens to exist at that address and gets deallocated. This corresponds to writing //! your own allocator: allocating zero-sized objects is not very hard. The canonical way to //! obtain a pointer that is valid for zero-sized accesses is [`NonNull::dangling`]. +//FIXME: mention `ptr::invalid` above, once it is stable. //! * All accesses performed by functions in this module are *non-atomic* in the sense //! of [atomic operations] used to synchronize between threads. This means it is //! undefined behavior to perform two concurrent accesses to the same location from different