From 12db2225b6e82b861597d1a98c018d56100a741c Mon Sep 17 00:00:00 2001 From: Eric Arellano Date: Mon, 7 Dec 2020 11:59:24 -0700 Subject: Dogfood 'str_split_once() with `compiler/` --- compiler/rustc_session/src/config.rs | 109 ++++++++++++++++------------------ compiler/rustc_session/src/lib.rs | 1 + compiler/rustc_session/src/options.rs | 7 ++- 3 files changed, 55 insertions(+), 62 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b648e14360c..54abb65dc38 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1296,8 +1296,10 @@ fn parse_output_types( if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { for output_type in list.split(',') { - let mut parts = output_type.splitn(2, '='); - let shorthand = parts.next().unwrap(); + let (shorthand, path) = match output_type.split_once('=') { + None => (output_type, None), + Some((shorthand, path)) => (shorthand, Some(PathBuf::from(path))), + }; let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| { early_error( error_format, @@ -1308,7 +1310,6 @@ fn parse_output_types( ), ) }); - let path = parts.next().map(PathBuf::from); output_types.insert(output_type, path); } } @@ -1452,11 +1453,10 @@ fn parse_opt_level( let max_c = matches .opt_strs_pos("C") .into_iter() - .flat_map( - |(i, s)| { - if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None } - }, - ) + .flat_map(|(i, s)| { + // NB: This can match a string without `=`. + if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None } + }) .max(); if max_o > max_c { OptLevel::Default @@ -1491,11 +1491,10 @@ fn select_debuginfo( let max_c = matches .opt_strs_pos("C") .into_iter() - .flat_map( - |(i, s)| { - if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None } - }, - ) + .flat_map(|(i, s)| { + // NB: This can match a string without `=`. + if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None } + }) .max(); if max_g > max_c { DebugInfo::Full @@ -1528,23 +1527,26 @@ fn parse_libs( .map(|s| { // Parse string of the form "[KIND=]lib[:new_name]", // where KIND is one of "dylib", "framework", "static". - let mut parts = s.splitn(2, '='); - let kind = parts.next().unwrap(); - let (name, kind) = match (parts.next(), kind) { - (None, name) => (name, NativeLibKind::Unspecified), - (Some(name), "dylib") => (name, NativeLibKind::Dylib), - (Some(name), "framework") => (name, NativeLibKind::Framework), - (Some(name), "static") => (name, NativeLibKind::StaticBundle), - (Some(name), "static-nobundle") => (name, NativeLibKind::StaticNoBundle), - (_, s) => { - early_error( - error_format, - &format!( - "unknown library kind `{}`, expected \ - one of dylib, framework, or static", - s - ), - ); + let (name, kind) = match s.split_once('=') { + None => (s, NativeLibKind::Unspecified), + Some((kind, name)) => { + let kind = match kind { + "dylib" => NativeLibKind::Dylib, + "framework" => NativeLibKind::Framework, + "static" => NativeLibKind::StaticBundle, + "static-nobundle" => NativeLibKind::StaticNoBundle, + s => { + early_error( + error_format, + &format!( + "unknown library kind `{}`, expected \ + one of dylib, framework, or static", + s + ), + ); + } + }; + (name.to_string(), kind) } }; if kind == NativeLibKind::StaticNoBundle @@ -1556,10 +1558,11 @@ fn parse_libs( accepted on the nightly compiler", ); } - let mut name_parts = name.splitn(2, ':'); - let name = name_parts.next().unwrap(); - let new_name = name_parts.next(); - (name.to_owned(), new_name.map(|n| n.to_owned()), kind) + let (name, new_name) = match name.split_once(':') { + None => (name, None), + Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())), + }; + (name, new_name, kind) }) .collect() } @@ -1580,20 +1583,13 @@ pub fn parse_externs( let is_unstable_enabled = debugging_opts.unstable_options; let mut externs: BTreeMap = BTreeMap::new(); for arg in matches.opt_strs("extern") { - let mut parts = arg.splitn(2, '='); - let name = parts - .next() - .unwrap_or_else(|| early_error(error_format, "--extern value must not be empty")); - let path = parts.next().map(|s| s.to_string()); - - let mut name_parts = name.splitn(2, ':'); - let first_part = name_parts.next(); - let second_part = name_parts.next(); - let (options, name) = match (first_part, second_part) { - (Some(opts), Some(name)) => (Some(opts), name), - (Some(name), None) => (None, name), - (None, None) => early_error(error_format, "--extern name must not be empty"), - _ => unreachable!(), + let (name, path) = match arg.split_once('=') { + None => (arg, None), + Some((name, path)) => (name.to_string(), Some(path.to_string())), + }; + let (options, name) = match name.split_once(':') { + None => (None, name), + Some((opts, name)) => (Some(opts), name.to_string()), }; let entry = externs.entry(name.to_owned()); @@ -1682,17 +1678,12 @@ fn parse_remap_path_prefix( matches .opt_strs("remap-path-prefix") .into_iter() - .map(|remap| { - let mut parts = remap.rsplitn(2, '='); // reverse iterator - let to = parts.next(); - let from = parts.next(); - match (from, to) { - (Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)), - _ => early_error( - error_format, - "--remap-path-prefix must contain '=' between FROM and TO", - ), - } + .map(|remap| match remap.rsplit_once('=') { + None => early_error( + error_format, + "--remap-path-prefix must contain '=' between FROM and TO", + ), + Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)), }) .collect() } diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index d002f597391..36bf8634c6e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,6 +1,7 @@ #![feature(crate_visibility_modifier)] #![feature(once_cell)] #![feature(or_patterns)] +#![feature(str_split_once)] #[macro_use] extern crate bitflags; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 91ebc9a7c82..74578f2dc17 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -179,9 +179,10 @@ macro_rules! options { { let mut op = $defaultfn(); for option in matches.opt_strs($prefix) { - let mut iter = option.splitn(2, '='); - let key = iter.next().unwrap(); - let value = iter.next(); + let (key, value) = match option.split_once('=') { + None => (option, None), + Some((k, v)) => (k.to_string(), Some(v)), + }; let option_to_lookup = key.replace("-", "_"); let mut found = false; for &(candidate, setter, type_desc, _) in $stat { -- cgit 1.4.1-3-g733a5 From b7795e135a642df024fc9bfee72abf7981c89ec8 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Fri, 11 Dec 2020 18:08:05 +0100 Subject: fix clippy::{needless_bool, manual_unwrap_or} --- .../src/transform/early_otherwise_branch.rs | 7 ++++--- compiler/rustc_session/src/session.rs | 5 +---- compiler/rustc_typeck/src/check/upvar.rs | 21 ++++++++++----------- compiler/rustc_typeck/src/collect.rs | 7 +------ src/bootstrap/sanity.rs | 6 +----- 5 files changed, 17 insertions(+), 29 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index 0460ebe0c0d..6fbcc140978 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -216,9 +216,10 @@ impl<'a, 'tcx> Helper<'a, 'tcx> { let discr = self.find_switch_discriminant_info(bb, switch)?; // go through each target, finding a discriminant read, and a switch - let results = discr.targets_with_values.iter().map(|(value, target)| { - self.find_discriminant_switch_pairing(&discr, *target, *value) - }); + let results = discr + .targets_with_values + .iter() + .map(|(value, target)| self.find_discriminant_switch_pairing(&discr, *target, *value)); // if the optimization did not apply for one of the targets, then abort if results.clone().any(|x| x.is_none()) || results.len() == 0 { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 4e269f3172c..75faab12e3e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1109,10 +1109,7 @@ impl Session { } pub fn link_dead_code(&self) -> bool { - match self.opts.cg.link_dead_code { - Some(explicitly_set) => explicitly_set, - None => false, - } + self.opts.cg.link_dead_code.unwrap_or(false) } pub fn mark_attr_known(&self, attr: &Attribute) { diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 373f2307019..1b04351018a 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -297,17 +297,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_captures.insert(*var_hir_id, upvar_id); - let new_capture_kind = if let Some(capture_kind) = - upvar_capture_map.get(&upvar_id) - { - // upvar_capture_map only stores the UpvarCapture (CaptureKind), - // so we create a fake capture info with no expression. - let fake_capture_info = - ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; - determine_capture_info(fake_capture_info, capture_info).capture_kind - } else { - capture_info.capture_kind - }; + let new_capture_kind = + if let Some(capture_kind) = upvar_capture_map.get(&upvar_id) { + // upvar_capture_map only stores the UpvarCapture (CaptureKind), + // so we create a fake capture info with no expression. + let fake_capture_info = + ty::CaptureInfo { expr_id: None, capture_kind: *capture_kind }; + determine_capture_info(fake_capture_info, capture_info).capture_kind + } else { + capture_info.capture_kind + }; upvar_capture_map.insert(upvar_id, new_capture_kind); } } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 38da1e5ea03..c70554cc627 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2141,13 +2141,8 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // * It must be an associated type for this trait (*not* a // supertrait). if let ty::Projection(projection) = ty.kind() { - if projection.substs == trait_identity_substs + projection.substs == trait_identity_substs && tcx.associated_item(projection.item_def_id).container.id() == def_id - { - true - } else { - false - } } else { false } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index aafb71629ad..85b4a73439d 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -159,11 +159,7 @@ pub fn check(build: &mut Build) { panic!("the iOS target is only supported on macOS"); } - build - .config - .target_config - .entry(*target) - .or_insert(Target::from_triple(&target.triple)); + build.config.target_config.entry(*target).or_insert(Target::from_triple(&target.triple)); if target.contains("-none-") || target.contains("nvptx") { if build.no_std(*target) == Some(false) { -- cgit 1.4.1-3-g733a5 From 4f550f1f930b9201bbeeb9fa10d42392a66cc9f2 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 14 Dec 2020 00:25:29 -0800 Subject: Improve warnings on incompatible options involving -Zinstrument-coverage Adds checks for: * `no_core` attribute * explicitly-enabled `legacy` symbol mangling * mir_opt_level > 1 (which enables inlining) I removed code from the `Inline` MIR pass that forcibly disabled inlining if `-Zinstrument-coverage` was set. The default `mir_opt_level` does not enable inlining anyway. But if the level is explicitly set and is greater than 1, I issue a warning. The new warnings show up in tests, which is much better for diagnosing potential option conflicts in these cases. --- compiler/rustc_interface/src/tests.rs | 4 +-- compiler/rustc_metadata/src/creader.rs | 11 +++++-- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +++- compiler/rustc_mir/src/transform/const_prop.rs | 8 +++-- compiler/rustc_mir/src/transform/dest_prop.rs | 3 +- .../src/transform/early_otherwise_branch.rs | 3 +- compiler/rustc_mir/src/transform/inline.rs | 11 ++----- compiler/rustc_mir/src/transform/match_branches.rs | 3 +- compiler/rustc_mir/src/transform/mod.rs | 3 +- .../src/transform/multiple_return_terminators.rs | 3 +- compiler/rustc_mir/src/transform/nrvo.rs | 3 +- .../rustc_mir/src/transform/unreachable_prop.rs | 3 +- compiler/rustc_session/src/config.rs | 38 ++++++++++++++++++++-- compiler/rustc_session/src/options.rs | 12 +++---- compiler/rustc_symbol_mangling/src/lib.rs | 6 +++- src/tools/clippy/src/driver.rs | 34 ++++++++++--------- 16 files changed, 103 insertions(+), 49 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2273266a3ff..7a7def0696d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -561,7 +561,7 @@ fn test_debugging_options_tracking_hash() { tracked!(link_only, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); - tracked!(mir_opt_level, 3); + tracked!(mir_opt_level, Some(3)); tracked!(mutable_noalias, true); tracked!(new_llvm_pass_manager, true); tracked!(no_codegen, true); @@ -587,7 +587,7 @@ fn test_debugging_options_tracking_hash() { tracked!(share_generics, Some(true)); tracked!(show_span, Some(String::from("abc"))); tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1)); - tracked!(symbol_mangling_version, SymbolManglingVersion::V0); + tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(teach, true); tracked!(thinlto, Some(true)); tracked!(tune_cpu, Some(String::from("abc"))); diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 33cbf0fb234..019ca5174a2 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -706,7 +706,7 @@ impl<'a> CrateLoader<'a> { self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } - fn inject_profiler_runtime(&mut self) { + fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if (self.sess.opts.debugging_opts.instrument_coverage || self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled()) @@ -714,6 +714,13 @@ impl<'a> CrateLoader<'a> { { info!("loading profiler"); + if self.sess.contains_name(&krate.attrs, sym::no_core) { + self.sess.err( + "`profiler_builtins` crate (required by compiler options) \ + is not compatible with crate attribute `#![no_core]`", + ); + } + let name = sym::profiler_builtins; let cnum = self.resolve_crate(name, DUMMY_SP, CrateDepKind::Implicit, None); let data = self.cstore.get_crate_data(cnum); @@ -879,7 +886,7 @@ impl<'a> CrateLoader<'a> { } pub fn postprocess(&mut self, krate: &ast::Crate) { - self.inject_profiler_runtime(); + self.inject_profiler_runtime(krate); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 46dd0df65e0..b0c75c1de9d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -663,7 +663,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), - symbol_mangling_version: tcx.sess.opts.debugging_opts.symbol_mangling_version, + symbol_mangling_version: tcx + .sess + .opts + .debugging_opts + .symbol_mangling_version + .unwrap_or(SymbolManglingVersion::default()), crate_deps, dylib_dependency_formats, diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 1d949e020ed..49b1cf92600 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -22,6 +22,7 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout}; @@ -708,7 +709,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 3 { self.eval_rvalue_with_identities(rvalue, place) } else { self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place)) @@ -886,7 +887,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns `true` if and only if this `op` should be const-propagated into. fn should_const_prop(&mut self, op: OpTy<'tcx>) -> bool { - let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level; + let mir_opt_level = + self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); if mir_opt_level == 0 { return false; @@ -1056,7 +1058,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // Only const prop copies and moves on `mir_opt_level=2` as doing so // currently slightly increases compile time in some cases. - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 2 { self.propagate_operand(operand) } } diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 46de5dba6e0..2363b6d58e1 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -115,6 +115,7 @@ use rustc_middle::mir::{ Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; // Empirical measurements have resulted in some observations: // - Running on a body with a single block and 500 locals takes barely any time @@ -129,7 +130,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove // storage statements at the moment). - if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index f91477911a4..023561923ee 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -1,6 +1,7 @@ use crate::{transform::MirPass, util::patch::MirPatch}; use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use std::fmt::Debug; use super::simplify::simplify_cfg; @@ -26,7 +27,7 @@ pub struct EarlyOtherwiseBranch; impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { return; } trace!("running EarlyOtherwiseBranch on {:?}", body.source); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 4eeb8969bb1..1a927f9bf50 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; @@ -37,15 +38,7 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { - return; - } - - if tcx.sess.opts.debugging_opts.instrument_coverage { - // The current implementation of source code coverage injects code region counters - // into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code- - // based function. - debug!("function inlining is disabled when compiling with `instrument_coverage`"); + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { return; } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index 53eeecc780f..e28e3f59a5e 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -1,6 +1,7 @@ use crate::transform::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MatchBranchSimplification; @@ -38,7 +39,7 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index e86d11e248f..039dfe2c0d5 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -10,6 +10,7 @@ use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{Span, Symbol}; use std::borrow::Cow; @@ -373,7 +374,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc } fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level; + let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); // Lowering generator control-flow and variables has to happen before we do anything else // to them. We run some optimizations before that, because they may be harder to do on the state diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs index 617086622cc..de4aee7ddbc 100644 --- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs +++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs @@ -5,12 +5,13 @@ use crate::transform::{simplify, MirPass}; use rustc_index::bit_set::BitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MultipleReturnTerminators; impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { return; } diff --git a/compiler/rustc_mir/src/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs index ce02fb261df..6e1dc03b9cb 100644 --- a/compiler/rustc_mir/src/transform/nrvo.rs +++ b/compiler/rustc_mir/src/transform/nrvo.rs @@ -5,6 +5,7 @@ use rustc_index::bit_set::HybridBitSet; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use crate::transform::MirPass; @@ -34,7 +35,7 @@ pub struct RenameReturnPlace; impl<'tcx> MirPass<'tcx> for RenameReturnPlace { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) == 0 { return; } diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index e39c8656021..c9053ce81cd 100644 --- a/compiler/rustc_mir/src/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs @@ -7,12 +7,13 @@ use crate::transform::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; +use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code. return; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 54abb65dc38..47e494b78c7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -174,6 +174,8 @@ pub enum MirSpanview { Block, } +pub const MIR_OPT_LEVEL_DEFAULT: usize = 1; + #[derive(Clone, PartialEq, Hash)] pub enum LinkerPluginLto { LinkerPlugin(PathBuf), @@ -212,6 +214,12 @@ pub enum SymbolManglingVersion { V0, } +impl SymbolManglingVersion { + pub fn default() -> Self { + SymbolManglingVersion::Legacy + } +} + impl_stable_hash_via_hash!(SymbolManglingVersion); #[derive(Clone, Copy, Debug, PartialEq, Hash)] @@ -1757,7 +1765,33 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over // multiple runs, including some changes to source code; so mangled names must be consistent // across compilations. - debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0; + match debugging_opts.symbol_mangling_version { + None => { + debugging_opts.symbol_mangling_version = Some(SymbolManglingVersion::V0); + } + Some(SymbolManglingVersion::Legacy) => { + early_warn( + error_format, + "-Z instrument-coverage requires symbol mangling version `v0`, \ + but `-Z symbol-mangling-version=legacy` was specified", + ); + } + Some(SymbolManglingVersion::V0) => {} + } + + match debugging_opts.mir_opt_level { + Some(level) if level > 1 => { + early_warn( + error_format, + &format!( + "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ + limits the effectiveness of `-Z instrument-coverage`.", + level, + ), + ); + } + _ => {} + } } if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") { @@ -2162,7 +2196,7 @@ crate mod dep_tracking { impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_via_hash!(LinkerPluginLto); impl_dep_tracking_hash_via_hash!(SwitchWithOptPath); - impl_dep_tracking_hash_via_hash!(SymbolManglingVersion); + impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(TrimmedDefPaths); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 74578f2dc17..1909550aca4 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -677,12 +677,12 @@ macro_rules! options { } fn parse_symbol_mangling_version( - slot: &mut SymbolManglingVersion, + slot: &mut Option, v: Option<&str>, ) -> bool { *slot = match v { - Some("legacy") => SymbolManglingVersion::Legacy, - Some("v0") => SymbolManglingVersion::V0, + Some("legacy") => Some(SymbolManglingVersion::Legacy), + Some("v0") => Some(SymbolManglingVersion::V0), _ => return false, }; true @@ -970,7 +970,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), - mir_opt_level: usize = (1, parse_uint, [TRACKED], + mir_opt_level: Option = (None, parse_opt_uint, [TRACKED], "MIR optimization level (0-3; default: 1)"), mutable_noalias: bool = (false, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: no)"), @@ -1088,9 +1088,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), - symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy, + symbol_mangling_version: Option = (None, parse_symbol_mangling_version, [TRACKED], - "which mangling version to use for symbol names"), + "which mangling version to use for symbol names ('legacy' (default) or 'v0')"), teach: bool = (false, parse_bool, [TRACKED], "show extended diagnostic help (default: no)"), terminal_width: Option = (None, parse_opt_uint, [UNTRACKED], diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 10245d21b63..945e788a146 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -245,7 +245,11 @@ fn compute_symbol_name( // 2. we favor `instantiating_crate` where possible (i.e. when `Some`) let mangling_version_crate = instantiating_crate.unwrap_or(def_id.krate); let mangling_version = if mangling_version_crate == LOCAL_CRATE { - tcx.sess.opts.debugging_opts.symbol_mangling_version + tcx.sess + .opts + .debugging_opts + .symbol_mangling_version + .unwrap_or(SymbolManglingVersion::default()) } else { tcx.symbol_mangling_version(mangling_version_crate) }; diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index ef31c72481a..9e5ae21f702 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -41,7 +41,7 @@ fn arg_value<'a, T: Deref>( match arg.next().or_else(|| args.next()) { Some(v) if pred(v) => return Some(v), - _ => {}, + _ => {} } } None @@ -85,7 +85,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // run on the unoptimized MIR. On the other hand this results in some false negatives. If // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. - config.opts.debugging_opts.mir_opt_level = 0; + config.opts.debugging_opts.mir_opt_level = Some(0); } } @@ -121,11 +121,12 @@ You can use tool lints to allow or deny lints from your code, eg.: const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new"; -static ICE_HOOK: SyncLazy) + Sync + Send + 'static>> = SyncLazy::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); - hook -}); +static ICE_HOOK: SyncLazy) + Sync + Send + 'static>> = + SyncLazy::new(|| { + let hook = panic::take_hook(); + panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL))); + hook + }); fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Invoke our ICE handler, which prints the actual panic message and optionally a backtrace @@ -257,14 +258,17 @@ pub fn main() { // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument. // We're invoking the compiler programmatically, so we ignore this/ - let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()); + let wrapper_mode = + orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some("rustc".as_ref()); if wrapper_mode { // we still want to be able to invoke it normally though orig_args.remove(1); } - if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) { + if !wrapper_mode + && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) + { display_help(); exit(0); } @@ -285,13 +289,11 @@ pub fn main() { if clippy_enabled { args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]); if let Ok(extra_args) = env::var("CLIPPY_ARGS") { - args.extend(extra_args.split("__CLIPPY_HACKERY__").filter_map(|s| { - if s.is_empty() { - None - } else { - Some(s.to_string()) - } - })); + args.extend( + extra_args + .split("__CLIPPY_HACKERY__") + .filter_map(|s| if s.is_empty() { None } else { Some(s.to_string()) }), + ); } } let mut clippy = ClippyCallbacks; -- cgit 1.4.1-3-g733a5 From 36c639a2ce2808c2c95cacf0856026235ad6350f Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Mon, 14 Dec 2020 13:12:15 -0800 Subject: Convenience funcs for `some_option.unwrap_or(...)` This ensures consistent handling of default values for options that are None if not specified on the command line. --- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +---- compiler/rustc_mir/src/transform/const_prop.rs | 8 ++---- compiler/rustc_mir/src/transform/dest_prop.rs | 3 +- .../src/transform/early_otherwise_branch.rs | 3 +- compiler/rustc_mir/src/transform/inline.rs | 3 +- compiler/rustc_mir/src/transform/match_branches.rs | 3 +- compiler/rustc_mir/src/transform/mod.rs | 3 +- .../src/transform/multiple_return_terminators.rs | 3 +- compiler/rustc_mir/src/transform/nrvo.rs | 3 +- .../rustc_mir/src/transform/unreachable_prop.rs | 3 +- compiler/rustc_session/src/config.rs | 33 +++++++++------------- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_symbol_mangling/src/lib.rs | 6 +--- src/tools/clippy/src/driver.rs | 2 +- 15 files changed, 29 insertions(+), 55 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 7a7def0696d..3e94f163773 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -561,7 +561,7 @@ fn test_debugging_options_tracking_hash() { tracked!(link_only, true); tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); - tracked!(mir_opt_level, Some(3)); + tracked!(mir_opt_level, 3); tracked!(mutable_noalias, true); tracked!(new_llvm_pass_manager, true); tracked!(no_codegen, true); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b0c75c1de9d..7b67d15f64a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -663,12 +663,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins), panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime), profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime), - symbol_mangling_version: tcx - .sess - .opts - .debugging_opts - .symbol_mangling_version - .unwrap_or(SymbolManglingVersion::default()), + symbol_mangling_version: tcx.sess.opts.debugging_opts.get_symbol_mangling_version(), crate_deps, dylib_dependency_formats, diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 49b1cf92600..1d949e020ed 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -22,7 +22,6 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, }; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_session::lint; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TargetDataLayout}; @@ -709,7 +708,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 3 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 { self.eval_rvalue_with_identities(rvalue, place) } else { self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place)) @@ -887,8 +886,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns `true` if and only if this `op` should be const-propagated into. fn should_const_prop(&mut self, op: OpTy<'tcx>) -> bool { - let mir_opt_level = - self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); + let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level; if mir_opt_level == 0 { return false; @@ -1058,7 +1056,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { // Only const prop copies and moves on `mir_opt_level=2` as doing so // currently slightly increases compile time in some cases. - if self.tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) >= 2 { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { self.propagate_operand(operand) } } diff --git a/compiler/rustc_mir/src/transform/dest_prop.rs b/compiler/rustc_mir/src/transform/dest_prop.rs index 2363b6d58e1..46de5dba6e0 100644 --- a/compiler/rustc_mir/src/transform/dest_prop.rs +++ b/compiler/rustc_mir/src/transform/dest_prop.rs @@ -115,7 +115,6 @@ use rustc_middle::mir::{ Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; // Empirical measurements have resulted in some observations: // - Running on a body with a single block and 500 locals takes barely any time @@ -130,7 +129,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove // storage statements at the moment). - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index 023561923ee..f91477911a4 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -1,7 +1,6 @@ use crate::{transform::MirPass, util::patch::MirPatch}; use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use std::fmt::Debug; use super::simplify::simplify_cfg; @@ -27,7 +26,7 @@ pub struct EarlyOtherwiseBranch; impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { return; } trace!("running EarlyOtherwiseBranch on {:?}", body.source); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 1a927f9bf50..6e7575c1d71 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -9,7 +9,6 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{hygiene::ExpnKind, ExpnData, Span}; use rustc_target::spec::abi::Abi; @@ -38,7 +37,7 @@ struct CallSite<'tcx> { impl<'tcx> MirPass<'tcx> for Inline { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 2 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { return; } diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index e28e3f59a5e..53eeecc780f 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -1,7 +1,6 @@ use crate::transform::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MatchBranchSimplification; @@ -39,7 +38,7 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) <= 1 { + if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs index 039dfe2c0d5..e86d11e248f 100644 --- a/compiler/rustc_mir/src/transform/mod.rs +++ b/compiler/rustc_mir/src/transform/mod.rs @@ -10,7 +10,6 @@ use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use rustc_span::{Span, Symbol}; use std::borrow::Cow; @@ -374,7 +373,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc } fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT); + let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level; // Lowering generator control-flow and variables has to happen before we do anything else // to them. We run some optimizations before that, because they may be harder to do on the state diff --git a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs index de4aee7ddbc..617086622cc 100644 --- a/compiler/rustc_mir/src/transform/multiple_return_terminators.rs +++ b/compiler/rustc_mir/src/transform/multiple_return_terminators.rs @@ -5,13 +5,12 @@ use crate::transform::{simplify, MirPass}; use rustc_index::bit_set::BitSet; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct MultipleReturnTerminators; impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { return; } diff --git a/compiler/rustc_mir/src/transform/nrvo.rs b/compiler/rustc_mir/src/transform/nrvo.rs index 6e1dc03b9cb..ce02fb261df 100644 --- a/compiler/rustc_mir/src/transform/nrvo.rs +++ b/compiler/rustc_mir/src/transform/nrvo.rs @@ -5,7 +5,6 @@ use rustc_index::bit_set::HybridBitSet; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; use crate::transform::MirPass; @@ -35,7 +34,7 @@ pub struct RenameReturnPlace; impl<'tcx> MirPass<'tcx> for RenameReturnPlace { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) == 0 { + if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { return; } diff --git a/compiler/rustc_mir/src/transform/unreachable_prop.rs b/compiler/rustc_mir/src/transform/unreachable_prop.rs index c9053ce81cd..e39c8656021 100644 --- a/compiler/rustc_mir/src/transform/unreachable_prop.rs +++ b/compiler/rustc_mir/src/transform/unreachable_prop.rs @@ -7,13 +7,12 @@ use crate::transform::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -use rustc_session::config::MIR_OPT_LEVEL_DEFAULT; pub struct UnreachablePropagation; impl MirPass<'_> for UnreachablePropagation { fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - if tcx.sess.opts.debugging_opts.mir_opt_level.unwrap_or(MIR_OPT_LEVEL_DEFAULT) < 3 { + if tcx.sess.opts.debugging_opts.mir_opt_level < 3 { // Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt // perf benchmark) LLVM may spend quite a lot of time optimizing the generated code. return; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 47e494b78c7..b77a8b631e0 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -174,8 +174,6 @@ pub enum MirSpanview { Block, } -pub const MIR_OPT_LEVEL_DEFAULT: usize = 1; - #[derive(Clone, PartialEq, Hash)] pub enum LinkerPluginLto { LinkerPlugin(PathBuf), @@ -214,12 +212,6 @@ pub enum SymbolManglingVersion { V0, } -impl SymbolManglingVersion { - pub fn default() -> Self { - SymbolManglingVersion::Legacy - } -} - impl_stable_hash_via_hash!(SymbolManglingVersion); #[derive(Clone, Copy, Debug, PartialEq, Hash)] @@ -700,6 +692,10 @@ impl DebuggingOptions { deduplicate_diagnostics: self.deduplicate_diagnostics, } } + + pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion { + self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy) + } } // The type of entry function, so users can have their own entry functions @@ -1779,18 +1775,15 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { Some(SymbolManglingVersion::V0) => {} } - match debugging_opts.mir_opt_level { - Some(level) if level > 1 => { - early_warn( - error_format, - &format!( - "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ - limits the effectiveness of `-Z instrument-coverage`.", - level, - ), - ); - } - _ => {} + if debugging_opts.mir_opt_level > 1 { + early_warn( + error_format, + &format!( + "`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \ + limits the effectiveness of `-Z instrument-coverage`.", + debugging_opts.mir_opt_level, + ), + ); } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 1909550aca4..49a7888fd6a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -970,7 +970,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, mir_emit_retag: bool = (false, parse_bool, [TRACKED], "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ (default: no)"), - mir_opt_level: Option = (None, parse_opt_uint, [TRACKED], + mir_opt_level: usize = (1, parse_uint, [TRACKED], "MIR optimization level (0-3; default: 1)"), mutable_noalias: bool = (false, parse_bool, [TRACKED], "emit noalias metadata for mutable references (default: no)"), diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 945e788a146..7f8cded0ac0 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -245,11 +245,7 @@ fn compute_symbol_name( // 2. we favor `instantiating_crate` where possible (i.e. when `Some`) let mangling_version_crate = instantiating_crate.unwrap_or(def_id.krate); let mangling_version = if mangling_version_crate == LOCAL_CRATE { - tcx.sess - .opts - .debugging_opts - .symbol_mangling_version - .unwrap_or(SymbolManglingVersion::default()) + tcx.sess.opts.debugging_opts.get_symbol_mangling_version() } else { tcx.symbol_mangling_version(mangling_version_crate) }; diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 9e5ae21f702..87dd19c5d4d 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -85,7 +85,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // run on the unoptimized MIR. On the other hand this results in some false negatives. If // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. - config.opts.debugging_opts.mir_opt_level = Some(0); + config.opts.debugging_opts.mir_opt_level = 0; } } -- cgit 1.4.1-3-g733a5 From acc63bc5baa1f5b51640e8f8ce7fd8b53d45c891 Mon Sep 17 00:00:00 2001 From: Jakub Kulik Date: Wed, 16 Dec 2020 10:41:07 +0100 Subject: Add support for target aliases --- compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 54abb65dc38..0e9cb7f325f 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1433,7 +1433,7 @@ fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType early_error(error_format, &format!("target file {:?} does not exist", path)) }) } - Some(target) => TargetTriple::TargetTriple(target), + Some(target) => TargetTriple::from_alias(target), _ => TargetTriple::from_triple(host_triple()), } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8d749493d0a..8d72df6850f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1800,6 +1800,24 @@ impl TargetTriple { Ok(TargetTriple::TargetPath(canonicalized_path)) } + /// Creates a target triple from its alias + pub fn from_alias(triple: String) -> Self { + macro_rules! target_aliases { + ( $(($alias:literal, $target:literal ),)+ ) => { + match triple.as_str() { + $( $alias => TargetTriple::from_triple($target), )+ + _ => TargetTriple::TargetTriple(triple), + } + } + } + + target_aliases! { + // `x86_64-pc-solaris` is an alias for `x86_64_sun_solaris` for backwards compatibility reasons. + // (See .) + ("x86_64-pc-solaris", "x86_64-sun-solaris"), + } + } + /// Returns a string triple for this target. /// /// If this target is a path, the file name (without extension) is returned. -- cgit 1.4.1-3-g733a5 From 57d05d35765a443fbb0b789a823e84ddff7c0cb1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 23 Sep 2020 16:50:58 +0100 Subject: session: add `split-dwarf` flag This commit adds a flag for Split DWARF, which enables debuginfo to be split into multiple files. Signed-off-by: David Wood --- compiler/rustc_session/src/config.rs | 17 +++++++++++++++++ compiler/rustc_session/src/options.rs | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b77a8b631e0..b5354513dc2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -221,6 +221,23 @@ pub enum DebugInfo { Full, } +/// Some debuginfo requires link-time relocation and some does not. LLVM can partition the debuginfo +/// into sections depending on whether or not it requires link-time relocation. Split DWARF +/// provides a mechanism which allows the linker to skip the sections which don't require link-time +/// relocation - either by putting those sections into DWARF object files, or keeping them in the +/// object file in such a way that the linker will skip them. +#[derive(Clone, Copy, Debug, PartialEq, Hash)] +pub enum SplitDwarfKind { + /// Disabled. + None, + /// Sections which do not require relocation are written into the object file but ignored + /// by the linker. + Single, + /// Sections which do not require relocation are written into a DWARF object (`.dwo`) file, + /// which is skipped by the linker by virtue of being a different file. + Split, +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] #[derive(Encodable, Decodable)] pub enum OutputType { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 49a7888fd6a..81f79f4b0e0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -269,6 +269,7 @@ macro_rules! options { pub const parse_switch_with_opt_path: &str = "an optional path to the profiling data output directory"; pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`"; + pub const parse_split_dwarf_kind: &str = "one of: `none`, `single` or `split`"; pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)"; pub const parse_src_file_hash: &str = "either `md5` or `sha1`"; pub const parse_relocation_model: &str = @@ -676,6 +677,19 @@ macro_rules! options { true } + fn parse_split_dwarf_kind( + slot: &mut SplitDwarfKind, + v: Option<&str>, + ) -> bool { + *slot = match v { + Some("none") => SplitDwarfKind::None, + Some("split") => SplitDwarfKind::Split, + Some("single") => SplitDwarfKind::Single, + _ => return false, + }; + true + } + fn parse_symbol_mangling_version( slot: &mut Option, v: Option<&str>, @@ -1088,6 +1102,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), strip: Strip = (Strip::None, parse_strip, [UNTRACKED], "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"), + split_dwarf: SplitDwarfKind = (SplitDwarfKind::None, parse_split_dwarf_kind, [UNTRACKED], + "enable generation of split dwarf"), + split_dwarf_inlining: bool = (true, parse_bool, [UNTRACKED], + "provide minimal debug info in the object/executable to facilitate online \ + symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"), symbol_mangling_version: Option = (None, parse_symbol_mangling_version, [TRACKED], "which mangling version to use for symbol names ('legacy' (default) or 'v0')"), -- cgit 1.4.1-3-g733a5 From e3fdae9d81052cf521298d19f8bb32ba0332b589 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 23 Sep 2020 17:33:54 +0100 Subject: cg_llvm: implement split dwarf support This commit implements Split DWARF support, wiring up the flag (added in earlier commits) to the modified FFI wrapper (also from earlier commits). Signed-off-by: David Wood --- compiler/rustc_codegen_llvm/src/back/lto.rs | 21 +++-- compiler/rustc_codegen_llvm/src/back/write.rs | 76 ++++++++++++---- .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 8 +- compiler/rustc_codegen_llvm/src/lib.rs | 12 ++- compiler/rustc_codegen_ssa/src/back/link.rs | 100 ++++++++++++++++++--- compiler/rustc_codegen_ssa/src/back/write.rs | 24 ++++- compiler/rustc_codegen_ssa/src/lib.rs | 5 +- compiler/rustc_session/src/config.rs | 28 +++++- 8 files changed, 228 insertions(+), 46 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 64ca7efb486..834fc02c48a 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -6,7 +6,9 @@ use crate::llvm::{self, build_string, False, True}; use crate::{LlvmCodegenBackend, ModuleLlvm}; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared}; use rustc_codegen_ssa::back::symbol_export; -use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; +use rustc_codegen_ssa::back::write::{ + CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryConfig, +}; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind}; use rustc_data_structures::fx::FxHashMap; @@ -728,7 +730,14 @@ pub unsafe fn optimize_thin_module( cgcx: &CodegenContext, ) -> Result, FatalError> { let diag_handler = cgcx.create_diag_handler(); - let tm = (cgcx.tm_factory)().map_err(|e| write::llvm_err(&diag_handler, &e))?; + + let module_name = &thin_module.shared.module_names[thin_module.idx]; + let split_dwarf_file = cgcx + .output_filenames + .split_dwarf_file(cgcx.split_dwarf_kind, Some(module_name.to_str().unwrap())); + let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file }; + let tm = + (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, &e))?; // Right now the implementation we've got only works over serialized // modules, so we create a fresh new LLVM context and parse the module @@ -736,12 +745,8 @@ pub unsafe fn optimize_thin_module( // crates but for locally codegened modules we may be able to reuse // that LLVM Context and Module. let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); - let llmod_raw = parse_module( - llcx, - &thin_module.shared.module_names[thin_module.idx], - thin_module.data(), - &diag_handler, - )? as *const _; + let llmod_raw = + parse_module(llcx, &module_name, thin_module.data(), &diag_handler)? as *const _; let module = ModuleCodegen { module_llvm: ModuleLlvm { llmod_raw, llcx, tm }, name: thin_module.name().to_string(), diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 612ed4405bb..ef99c87053c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -12,7 +12,8 @@ use crate::type_::Type; use crate::LlvmCodegenBackend; use crate::ModuleLlvm; use rustc_codegen_ssa::back::write::{ - BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryFn, + BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig, + TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; @@ -22,7 +23,9 @@ use rustc_fs_util::{link_or_copy, path_to_c_string}; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; -use rustc_session::config::{self, Lto, OutputType, Passes, SanitizerSet, SwitchWithOptPath}; +use rustc_session::config::{ + self, Lto, OutputType, Passes, SanitizerSet, SplitDwarfKind, SwitchWithOptPath, +}; use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::InnerSpan; @@ -51,18 +54,31 @@ pub fn write_output_file( pm: &llvm::PassManager<'ll>, m: &'ll llvm::Module, output: &Path, + dwo_output: Option<&Path>, file_type: llvm::FileType, ) -> Result<(), FatalError> { unsafe { let output_c = path_to_c_string(output); - let result = llvm::LLVMRustWriteOutputFile( - target, - pm, - m, - output_c.as_ptr(), - std::ptr::null(), - file_type, - ); + let result = if let Some(dwo_output) = dwo_output { + let dwo_output_c = path_to_c_string(dwo_output); + llvm::LLVMRustWriteOutputFile( + target, + pm, + m, + output_c.as_ptr(), + dwo_output_c.as_ptr(), + file_type, + ) + } else { + llvm::LLVMRustWriteOutputFile( + target, + pm, + m, + output_c.as_ptr(), + std::ptr::null(), + file_type, + ) + }; result.into_result().map_err(|()| { let msg = format!("could not write output to {}", output.display()); llvm_err(handler, &msg) @@ -71,12 +87,17 @@ pub fn write_output_file( } pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine { - target_machine_factory(sess, config::OptLevel::No)() + let config = TargetMachineFactoryConfig { split_dwarf_file: None }; + target_machine_factory(sess, config::OptLevel::No)(config) .unwrap_or_else(|err| llvm_err(sess.diagnostic(), &err).raise()) } -pub fn create_target_machine(tcx: TyCtxt<'_>) -> &'static mut llvm::TargetMachine { - target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))() +pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine { + let split_dwarf_file = tcx + .output_filenames(LOCAL_CRATE) + .split_dwarf_file(tcx.sess.opts.debugging_opts.split_dwarf, Some(mod_name)); + let config = TargetMachineFactoryConfig { split_dwarf_file }; + target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))(config) .unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise()) } @@ -172,8 +193,10 @@ pub fn target_machine_factory( let use_init_array = !sess.opts.debugging_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section); - Arc::new(move || { - let split_dwarf_file = std::ptr::null(); + Arc::new(move |config: TargetMachineFactoryConfig| { + let split_dwarf_file = config.split_dwarf_file.unwrap_or_default(); + let split_dwarf_file = CString::new(split_dwarf_file.to_str().unwrap()).unwrap(); + let tm = unsafe { llvm::LLVMRustCreateTargetMachine( triple.as_ptr(), @@ -192,7 +215,7 @@ pub fn target_machine_factory( emit_stack_size_section, relax_elf_relocations, use_init_array, - split_dwarf_file, + split_dwarf_file.as_ptr(), ) }; @@ -796,7 +819,15 @@ pub(crate) unsafe fn codegen( llmod }; with_codegen(tm, llmod, config.no_builtins, |cpm| { - write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) + write_output_file( + diag_handler, + tm, + cpm, + llmod, + &path, + None, + llvm::FileType::AssemblyFile, + ) })?; } @@ -805,6 +836,15 @@ pub(crate) unsafe fn codegen( let _timer = cgcx .prof .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); + + let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name); + let dwo_out = match cgcx.split_dwarf_kind { + // Don't change how DWARF is emitted in single mode (or when disabled). + SplitDwarfKind::None | SplitDwarfKind::Single => None, + // Emit (a subset of the) DWARF into a separate file in split mode. + SplitDwarfKind::Split => Some(dwo_out.as_path()), + }; + with_codegen(tm, llmod, config.no_builtins, |cpm| { write_output_file( diag_handler, @@ -812,6 +852,7 @@ pub(crate) unsafe fn codegen( cpm, llmod, &obj_out, + dwo_out, llvm::FileType::ObjectFile, ) })?; @@ -839,6 +880,7 @@ pub(crate) unsafe fn codegen( Ok(module.into_compiled_module( config.emit_obj != EmitObj::None, + cgcx.split_dwarf_kind == SplitDwarfKind::Split, config.emit_bc, &cgcx.output_filenames, )) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 41c8a5e5705..a9eff59b6af 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -995,7 +995,11 @@ pub fn compile_unit_metadata( let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); let work_dir = tcx.sess.working_dir.0.to_string_lossy(); let flags = "\0"; - let split_name = ""; + let split_name = tcx + .output_filenames(LOCAL_CRATE) + .split_dwarf_file(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name)) + .unwrap_or_default(); + let split_name = split_name.to_str().unwrap(); // FIXME(#60020): // @@ -1040,7 +1044,7 @@ pub fn compile_unit_metadata( split_name.len(), kind, 0, - true, + tcx.sess.opts.debugging_opts.split_dwarf_inlining, ); if tcx.sess.opts.debugging_opts.profile { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4fe0384b369..a5f125d114d 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -20,7 +20,7 @@ pub use llvm_util::target_features; use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ - CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryFn, + CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::ModuleCodegen; @@ -332,7 +332,7 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; - ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx) } + ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, mod_name) } } } @@ -353,7 +353,13 @@ impl ModuleLlvm { unsafe { let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); let llmod_raw = back::lto::parse_module(llcx, name, buffer, handler)?; - let tm = match (cgcx.tm_factory)() { + + let split_dwarf_file = cgcx + .output_filenames + .split_dwarf_file(cgcx.split_dwarf_kind, Some(name.to_str().unwrap())); + let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file }; + + let tm = match (cgcx.tm_factory)(tm_factory_config) { Ok(m) => m, Err(e) => { handler.struct_err(&e).emit(); diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 5001e97016c..123d1ae55fb 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -21,7 +21,9 @@ use super::archive::ArchiveBuilder; use super::command::Command; use super::linker::{self, Linker}; use super::rpath::{self, RPathConfig}; -use crate::{looks_like_rust_object_file, CodegenResults, CrateInfo, METADATA_FILENAME}; +use crate::{ + looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, METADATA_FILENAME, +}; use cc::windows_registry; use tempfile::Builder as TempFileBuilder; @@ -96,6 +98,9 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( path.as_ref(), target_cpu, ); + if sess.opts.debugging_opts.split_dwarf == config::SplitDwarfKind::Split { + link_dwarf_object(sess, &out_filename); + } } } if sess.opts.json_artifact_notifications { @@ -107,22 +112,30 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( // Remove the temporary object file and metadata if we aren't saving temps sess.time("link_binary_remove_temps", || { if !sess.opts.cg.save_temps { + let remove_temps_from_module = |module: &CompiledModule| { + if let Some(ref obj) = module.object { + remove(sess, obj); + } + + if let Some(ref obj) = module.dwarf_object { + remove(sess, obj); + } + }; + if sess.opts.output_types.should_codegen() && !preserve_objects_for_their_debuginfo(sess) { - for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { - remove(sess, obj); + for module in &codegen_results.modules { + remove_temps_from_module(module); } } + if let Some(ref metadata_module) = codegen_results.metadata_module { - if let Some(ref obj) = metadata_module.object { - remove(sess, obj); - } + remove_temps_from_module(metadata_module); } + if let Some(ref allocator_module) = codegen_results.allocator_module { - if let Some(ref obj) = allocator_module.object { - remove(sess, obj); - } + remove_temps_from_module(allocator_module); } } }); @@ -446,6 +459,69 @@ fn link_staticlib<'a, B: ArchiveBuilder<'a>>( } } +fn escape_stdout_stderr_string(s: &[u8]) -> String { + str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { + let mut x = "Non-UTF-8 output: ".to_string(); + x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); + x + }) +} + +const LLVM_DWP_EXECUTABLE: &'static str = "rust-llvm-dwp"; + +/// Invoke `llvm-dwp` (shipped alongside rustc) to link `dwo` files from Split DWARF into a `dwp` +/// file. +fn link_dwarf_object<'a>(sess: &'a Session, executable_out_filename: &Path) { + info!("preparing dwp to {}.dwp", executable_out_filename.to_str().unwrap()); + + let dwp_out_filename = executable_out_filename.with_extension("dwp"); + let mut cmd = Command::new(LLVM_DWP_EXECUTABLE); + cmd.arg("-e"); + cmd.arg(executable_out_filename); + cmd.arg("-o"); + cmd.arg(&dwp_out_filename); + + let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths(false); + if let Some(path) = env::var_os("PATH") { + new_path.extend(env::split_paths(&path)); + } + let new_path = env::join_paths(new_path).unwrap(); + cmd.env("PATH", new_path); + + info!("{:?}", &cmd); + match sess.time("run_dwp", || cmd.output()) { + Ok(prog) if !prog.status.success() => { + sess.struct_err(&format!( + "linking dwarf objects with `{}` failed: {}", + LLVM_DWP_EXECUTABLE, prog.status + )) + .note(&format!("{:?}", &cmd)) + .note(&escape_stdout_stderr_string(&prog.stdout)) + .note(&escape_stdout_stderr_string(&prog.stderr)) + .emit(); + info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr)); + info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout)); + } + Ok(_) => {} + Err(e) => { + let dwp_not_found = e.kind() == io::ErrorKind::NotFound; + let mut err = if dwp_not_found { + sess.struct_err(&format!("linker `{}` not found", LLVM_DWP_EXECUTABLE)) + } else { + sess.struct_err(&format!("could not exec the linker `{}`", LLVM_DWP_EXECUTABLE)) + }; + + err.note(&e.to_string()); + + if !dwp_not_found { + err.note(&format!("{:?}", &cmd)); + } + + err.emit(); + } + } +} + /// Create a dynamic library or executable. /// /// This will invoke the system linker/cc to create the resulting file. This links to all upstream @@ -661,7 +737,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( prog.status )) .note(&format!("{:?}", &cmd)) - .note(&escape_string(&output)) + .note(&escape_stdout_stderr_string(&output)) .emit(); // If MSVC's `link.exe` was expected but the return code @@ -714,8 +790,8 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( sess.abort_if_errors(); } - info!("linker stderr:\n{}", escape_string(&prog.stderr)); - info!("linker stdout:\n{}", escape_string(&prog.stdout)); + info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr)); + info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout)); } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 615eeecf54e..c84b87964b8 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -274,8 +274,19 @@ impl ModuleConfig { } } -pub type TargetMachineFactoryFn = - Arc Result<::TargetMachine, String> + Send + Sync>; +/// Configuration passed to the function returned by the `target_machine_factory`. +pub struct TargetMachineFactoryConfig { + /// Split DWARF is enabled in LLVM by checking that `TM.MCOptions.SplitDwarfFile` isn't empty, + /// so the path to the dwarf object has to be provided when we create the target machine. + /// This can be ignored by backends which do not need it for their Split DWARF support. + pub split_dwarf_file: Option, +} + +pub type TargetMachineFactoryFn = Arc< + dyn Fn(TargetMachineFactoryConfig) -> Result<::TargetMachine, String> + + Send + + Sync, +>; pub type ExportedSymbols = FxHashMap>>; @@ -303,6 +314,7 @@ pub struct CodegenContext { pub target_pointer_width: u32, pub target_arch: String, pub debuginfo: config::DebugInfo, + pub split_dwarf_kind: config::SplitDwarfKind, // Number of cgus excluding the allocator/metadata modules pub total_cgus: usize, @@ -619,6 +631,12 @@ fn produce_final_output_artifacts( } } + if let Some(ref path) = module.dwarf_object { + if !keep_numbered_objects { + remove(sess, path); + } + } + if let Some(ref path) = module.bytecode { if !keep_numbered_bitcode { remove(sess, path); @@ -841,6 +859,7 @@ fn execute_copy_from_cache_work_item( name: module.name, kind: ModuleKind::Regular, object, + dwarf_object: None, bytecode: None, })) } @@ -1019,6 +1038,7 @@ fn start_executing_work( target_pointer_width: tcx.sess.target.pointer_width, target_arch: tcx.sess.target.arch.clone(), debuginfo: tcx.sess.opts.debuginfo, + split_dwarf_kind: tcx.sess.opts.debugging_opts.split_dwarf, }; // This is the "main loop" of parallel work happening for parallel codegen. diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 8ec1eed4404..ee889d55241 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -64,13 +64,15 @@ impl ModuleCodegen { pub fn into_compiled_module( self, emit_obj: bool, + emit_dwarf_obj: bool, emit_bc: bool, outputs: &OutputFilenames, ) -> CompiledModule { let object = emit_obj.then(|| outputs.temp_path(OutputType::Object, Some(&self.name))); + let dwarf_object = emit_dwarf_obj.then(|| outputs.temp_path_dwo(Some(&self.name))); let bytecode = emit_bc.then(|| outputs.temp_path(OutputType::Bitcode, Some(&self.name))); - CompiledModule { name: self.name.clone(), kind: self.kind, object, bytecode } + CompiledModule { name: self.name.clone(), kind: self.kind, object, dwarf_object, bytecode } } } @@ -79,6 +81,7 @@ pub struct CompiledModule { pub name: String, pub kind: ModuleKind, pub object: Option, + pub dwarf_object: Option, pub bytecode: Option, } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b5354513dc2..b3d4c6e3ec7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -550,6 +550,7 @@ impl_stable_hash_via_hash!(OutputFilenames); pub const RLINK_EXT: &str = "rlink"; pub const RUST_CGU_EXT: &str = "rcgu"; +pub const DWARF_OBJECT_EXT: &str = "dwo"; impl OutputFilenames { pub fn new( @@ -583,7 +584,12 @@ impl OutputFilenames { self.temp_path_ext(extension, codegen_unit_name) } - /// Like temp_path, but also supports things where there is no corresponding + /// Like `temp_path`, but specifically for dwarf objects. + pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf { + self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name) + } + + /// Like `temp_path`, but also supports things where there is no corresponding /// OutputType, like noopt-bitcode or lto-bitcode. pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf { let mut extension = String::new(); @@ -610,6 +616,26 @@ impl OutputFilenames { path.set_extension(extension); path } + + /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF + /// mode is being used, which is the logic that this function is intended to encapsulate. + pub fn split_dwarf_file( + &self, + split_dwarf_kind: SplitDwarfKind, + cgu_name: Option<&str>, + ) -> Option { + let obj_out = self.temp_path(OutputType::Object, cgu_name); + let dwo_out = self.temp_path_dwo(cgu_name); + match split_dwarf_kind { + SplitDwarfKind::None => None, + // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes + // (pointing at the path which is being determined here). Use the path to the current + // object file. + SplitDwarfKind::Single => Some(obj_out), + // Split mode emits the DWARF into a different file, use that path. + SplitDwarfKind::Split => Some(dwo_out), + } + } } pub fn host_triple() -> &'static str { -- cgit 1.4.1-3-g733a5 From ee073b5ec54a13b393071298acc54e1fd28cfcdf Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 8 Nov 2020 17:17:37 +0000 Subject: cg_llvm: split dwarf filename and comp dir llvm-dwp concatenates `DW_AT_comp_dir` with `DW_AT_GNU_dwo_name` (only when `DW_AT_comp_dir` exists), which can result in it failing to find the DWARF object files. In earlier testing, `DW_AT_comp_dir` wasn't present in the final object and the current directory was the output directory. When running tests through compiletest, the working directory of the compilation is different from output directory and that resulted in `DW_AT_comp_dir` being in the object file (and set to the current working directory, rather than the output directory), and `DW_AT_GNU_dwo_name` being set to the full path (rather than just the filename), so llvm-dwp was failing. This commit changes the compilation directory provided to LLVM to match the output directory, where DWARF objects are output; and ensures that only the filename is used for `DW_AT_GNU_dwo_name`. Signed-off-by: David Wood --- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 2 +- compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 10 ++++++---- compiler/rustc_codegen_llvm/src/lib.rs | 2 +- compiler/rustc_session/src/config.rs | 13 ++++++++++++- 5 files changed, 21 insertions(+), 8 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 834fc02c48a..29415973ed0 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -734,7 +734,7 @@ pub unsafe fn optimize_thin_module( let module_name = &thin_module.shared.module_names[thin_module.idx]; let split_dwarf_file = cgcx .output_filenames - .split_dwarf_file(cgcx.split_dwarf_kind, Some(module_name.to_str().unwrap())); + .split_dwarf_filename(cgcx.split_dwarf_kind, Some(module_name.to_str().unwrap())); let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file }; let tm = (cgcx.tm_factory)(tm_factory_config).map_err(|e| write::llvm_err(&diag_handler, &e))?; diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index ef99c87053c..3fda1e26dae 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -95,7 +95,7 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm: pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine { let split_dwarf_file = tcx .output_filenames(LOCAL_CRATE) - .split_dwarf_file(tcx.sess.opts.debugging_opts.split_dwarf, Some(mod_name)); + .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(mod_name)); let config = TargetMachineFactoryConfig { split_dwarf_file }; target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))(config) .unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise()) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index a9eff59b6af..fa285f3488f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -993,12 +993,14 @@ pub fn compile_unit_metadata( let producer = format!("clang LLVM ({})", rustc_producer); let name_in_debuginfo = name_in_debuginfo.to_string_lossy(); - let work_dir = tcx.sess.working_dir.0.to_string_lossy(); let flags = "\0"; + + let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory; let split_name = tcx .output_filenames(LOCAL_CRATE) - .split_dwarf_file(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name)) + .split_dwarf_filename(tcx.sess.opts.debugging_opts.split_dwarf, Some(codegen_unit_name)) .unwrap_or_default(); + let out_dir = out_dir.to_str().unwrap(); let split_name = split_name.to_str().unwrap(); // FIXME(#60020): @@ -1024,8 +1026,8 @@ pub fn compile_unit_metadata( debug_context.builder, name_in_debuginfo.as_ptr().cast(), name_in_debuginfo.len(), - work_dir.as_ptr().cast(), - work_dir.len(), + out_dir.as_ptr().cast(), + out_dir.len(), llvm::ChecksumKind::None, ptr::null(), 0, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index a5f125d114d..a58c2fbd8ab 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -356,7 +356,7 @@ impl ModuleLlvm { let split_dwarf_file = cgcx .output_filenames - .split_dwarf_file(cgcx.split_dwarf_kind, Some(name.to_str().unwrap())); + .split_dwarf_filename(cgcx.split_dwarf_kind, Some(name.to_str().unwrap())); let tm_factory_config = TargetMachineFactoryConfig { split_dwarf_file }; let tm = match (cgcx.tm_factory)(tm_factory_config) { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b3d4c6e3ec7..c20b11656b2 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -617,9 +617,20 @@ impl OutputFilenames { path } + /// Returns the name of the Split DWARF file - this can differ depending on which Split DWARF + /// mode is being used, which is the logic that this function is intended to encapsulate. + pub fn split_dwarf_filename( + &self, + split_dwarf_kind: SplitDwarfKind, + cgu_name: Option<&str>, + ) -> Option { + self.split_dwarf_path(split_dwarf_kind, cgu_name) + .map(|path| path.strip_prefix(&self.out_directory).unwrap_or(&path).to_path_buf()) + } + /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF /// mode is being used, which is the logic that this function is intended to encapsulate. - pub fn split_dwarf_file( + pub fn split_dwarf_path( &self, split_dwarf_kind: SplitDwarfKind, cgu_name: Option<&str>, -- cgit 1.4.1-3-g733a5 From f1eb88b28a84b0533ddd036a60bb5b8acbffabb2 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 19 Dec 2020 16:30:56 -0500 Subject: Revert "Promote missing_fragment_specifier to hard error" This reverts commit 02eae432e7476a0686633a8c2b7cb1d5aab1bd2c. --- compiler/rustc_expand/src/mbe.rs | 2 +- compiler/rustc_expand/src/mbe/macro_parser.rs | 20 +++++++++++++++++--- compiler/rustc_expand/src/mbe/macro_rules.rs | 15 ++++++++------- compiler/rustc_expand/src/mbe/quoted.rs | 11 +++++++---- compiler/rustc_interface/src/passes.rs | 19 ++++++++++++++++++- compiler/rustc_session/src/parse.rs | 2 ++ src/test/ui/lint/expansion-time.rs | 4 ++++ src/test/ui/lint/expansion-time.stderr | 22 ++++++++++++++++++---- src/test/ui/macros/issue-39404.rs | 1 + src/test/ui/macros/issue-39404.stderr | 4 ++++ src/test/ui/macros/macro-match-nonterminal.rs | 1 + src/test/ui/macros/macro-match-nonterminal.stderr | 4 ++++ src/test/ui/parser/macro/issue-33569.rs | 1 - src/test/ui/parser/macro/issue-33569.stderr | 16 +++++----------- 14 files changed, 90 insertions(+), 32 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index eb4aab116f0..cbc4d14a65a 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -84,7 +84,7 @@ enum TokenTree { /// e.g., `$var` MetaVar(Span, Ident), /// e.g., `$var:expr`. This is only used in the left hand side of MBE macros. - MetaVarDecl(Span, Ident /* name to bind */, NonterminalKind), + MetaVarDecl(Span, Ident /* name to bind */, Option), } impl TokenTree { diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 3cf2d8f8ac1..0c44f5fe9e1 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -378,6 +378,11 @@ fn nameize>( n_rec(sess, next_m, res.by_ref(), ret_val)?; } } + TokenTree::MetaVarDecl(span, _, None) => { + if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { + return Err((span, "missing fragment specifier".to_string())); + } + } TokenTree::MetaVarDecl(sp, bind_name, _) => match ret_val .entry(MacroRulesNormalizedIdent::new(bind_name)) { @@ -446,6 +451,7 @@ fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode { /// /// A `ParseResult`. Note that matches are kept track of through the items generated. fn inner_parse_loop<'root, 'tt>( + sess: &ParseSess, cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, next_items: &mut Vec>, eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>, @@ -563,9 +569,16 @@ fn inner_parse_loop<'root, 'tt>( }))); } + // We need to match a metavar (but the identifier is invalid)... this is an error + TokenTree::MetaVarDecl(span, _, None) => { + if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() { + return Error(span, "missing fragment specifier".to_string()); + } + } + // We need to match a metavar with a valid ident... call out to the black-box // parser by adding an item to `bb_items`. - TokenTree::MetaVarDecl(span, _, kind) => { + TokenTree::MetaVarDecl(span, _, Some(kind)) => { // Built-in nonterminals never start with these tokens, so we can eliminate // them from consideration. // @@ -640,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na // parsing from the black-box parser done. The result is that `next_items` will contain a // bunch of possible next matcher positions in `next_items`. match inner_parse_loop( + parser.sess, &mut cur_items, &mut next_items, &mut eof_items, @@ -701,7 +715,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na let nts = bb_items .iter() .map(|item| match item.top_elts.get_tt(item.idx) { - TokenTree::MetaVarDecl(_, bind, kind) => format!("{} ('{}')", kind, bind), + TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind), _ => panic!(), }) .collect::>() @@ -731,7 +745,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na assert_eq!(bb_items.len(), 1); let mut item = bb_items.pop().unwrap(); - if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) { + if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) { let match_cur = item.match_cur; // We use the span of the metavariable declaration to determine any // edition-specific matching behavior for non-terminals. diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 66463eeb907..89d375b257d 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -401,7 +401,7 @@ pub fn compile_declarative_macro( let diag = &sess.parse_sess.span_diagnostic; let lhs_nm = Ident::new(sym::lhs, def.span); let rhs_nm = Ident::new(sym::rhs, def.span); - let tt_spec = NonterminalKind::TT; + let tt_spec = Some(NonterminalKind::TT); // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { @@ -578,7 +578,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { TokenTree::Sequence(span, ref seq) => { if seq.separator.is_none() && seq.tts.iter().all(|seq_tt| match *seq_tt { - TokenTree::MetaVarDecl(_, _, NonterminalKind::Vis) => true, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true, TokenTree::Sequence(_, ref sub_seq) => { sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore || sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne @@ -961,7 +961,7 @@ fn check_matcher_core( // Now `last` holds the complete set of NT tokens that could // end the sequence before SUFFIX. Check that every one works with `suffix`. for token in &last.tokens { - if let TokenTree::MetaVarDecl(_, name, kind) = *token { + if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token { for next_token in &suffix_first.tokens { match is_in_follow(next_token, kind) { IsInFollow::Yes => {} @@ -1019,7 +1019,7 @@ fn check_matcher_core( } fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool { - if let mbe::TokenTree::MetaVarDecl(_, _, kind) = *tok { + if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok { frag_can_be_followed_by_any(kind) } else { // (Non NT's can always be followed by anything in matchers.) @@ -1123,7 +1123,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { } _ => IsInFollow::No(TOKENS), }, - TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes, + TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } } @@ -1158,7 +1158,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { TokenTree::MetaVarDecl( _, _, - NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path, + Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path), ) => IsInFollow::Yes, _ => IsInFollow::No(TOKENS), } @@ -1171,7 +1171,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { match *tt { mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token), mbe::TokenTree::MetaVar(_, name) => format!("${}", name), - mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind), + mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name), _ => panic!( "{}", "unexpected mbe::TokenTree::{Sequence or Delimited} \ diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 48db532c78f..01b11bb979d 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -3,7 +3,7 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree use rustc_ast::token::{self, Token}; use rustc_ast::tokenstream; -use rustc_ast::NodeId; +use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, Ident}; @@ -73,7 +73,7 @@ pub(super) fn parse( .emit(); token::NonterminalKind::Ident }); - result.push(TokenTree::MetaVarDecl(span, ident, kind)); + result.push(TokenTree::MetaVarDecl(span, ident, Some(kind))); continue; } _ => token.span, @@ -83,8 +83,11 @@ pub(super) fn parse( } tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp), }; - sess.span_diagnostic.struct_span_err(span, "missing fragment specifier").emit(); - continue; + if node_id != DUMMY_NODE_ID { + // Macros loaded from other crates have dummy node ids. + sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id); + } + result.push(TokenTree::MetaVarDecl(span, ident, None)); } // Not a metavar or no matchers allowed, so just return the tree diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index c13d26c79d7..a8c8690b9e7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -29,6 +29,7 @@ use rustc_passes::{self, hir_stats, layout_test}; use rustc_plugin_impl as plugin; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode}; +use rustc_session::lint; use rustc_session::output::{filename_for_input, filename_for_metadata}; use rustc_session::search_paths::PathKind; use rustc_session::Session; @@ -306,11 +307,27 @@ fn configure_and_expand_inner<'a>( ecx.check_unused_macros(); }); + let mut missing_fragment_specifiers: Vec<_> = ecx + .sess + .parse_sess + .missing_fragment_specifiers + .borrow() + .iter() + .map(|(span, node_id)| (*span, *node_id)) + .collect(); + missing_fragment_specifiers.sort_unstable_by_key(|(span, _)| *span); + + let recursion_limit_hit = ecx.reduced_recursion_limit.is_some(); + + for (span, node_id) in missing_fragment_specifiers { + let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER; + let msg = "missing fragment specifier"; + resolver.lint_buffer().buffer_lint(lint, node_id, span, msg); + } if cfg!(windows) { env::set_var("PATH", &old_path); } - let recursion_limit_hit = ecx.reduced_recursion_limit.is_some(); if recursion_limit_hit { // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed // with a large AST diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 66c3738fb5b..b1a48342417 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -119,6 +119,7 @@ pub struct ParseSess { pub unstable_features: UnstableFeatures, pub config: CrateConfig, pub edition: Edition, + pub missing_fragment_specifiers: Lock>, /// Places where raw identifiers were used. This is used for feature-gating raw identifiers. pub raw_identifier_spans: Lock>, /// Used to determine and report recursive module inclusions. @@ -152,6 +153,7 @@ impl ParseSess { unstable_features: UnstableFeatures::from_environment(None), config: FxHashSet::default(), edition: ExpnId::root().expn_data().edition, + missing_fragment_specifiers: Default::default(), raw_identifier_spans: Lock::new(Vec::new()), included_mod_stack: Lock::new(vec![]), source_map, diff --git a/src/test/ui/lint/expansion-time.rs b/src/test/ui/lint/expansion-time.rs index a9c7ac363b0..f23c7cb0dca 100644 --- a/src/test/ui/lint/expansion-time.rs +++ b/src/test/ui/lint/expansion-time.rs @@ -5,6 +5,10 @@ macro_rules! foo { ( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator } +#[warn(missing_fragment_specifier)] +macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier + //~| WARN this was previously accepted + #[warn(soft_unstable)] mod benches { #[bench] //~ WARN use of unstable library feature 'test' diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr index 24e2733064e..b0fc1f8e5ee 100644 --- a/src/test/ui/lint/expansion-time.stderr +++ b/src/test/ui/lint/expansion-time.stderr @@ -12,14 +12,28 @@ note: the lint level is defined here LL | #[warn(meta_variable_misuse)] | ^^^^^^^^^^^^^^^^^^^^ +warning: missing fragment specifier + --> $DIR/expansion-time.rs:9:19 + | +LL | macro_rules! m { ($i) => {} } + | ^^ + | +note: the lint level is defined here + --> $DIR/expansion-time.rs:8:8 + | +LL | #[warn(missing_fragment_specifier)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 + warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable - --> $DIR/expansion-time.rs:10:7 + --> $DIR/expansion-time.rs:14:7 | LL | #[bench] | ^^^^^ | note: the lint level is defined here - --> $DIR/expansion-time.rs:8:8 + --> $DIR/expansion-time.rs:12:8 | LL | #[warn(soft_unstable)] | ^^^^^^^^^^^^^ @@ -33,10 +47,10 @@ LL | 2 | ^ | note: the lint level is defined here - --> $DIR/expansion-time.rs:25:8 + --> $DIR/expansion-time.rs:29:8 | LL | #[warn(incomplete_include)] | ^^^^^^^^^^^^^^^^^^ -warning: 3 warnings emitted +warning: 4 warnings emitted diff --git a/src/test/ui/macros/issue-39404.rs b/src/test/ui/macros/issue-39404.rs index 054958ba00b..2229f2c3900 100644 --- a/src/test/ui/macros/issue-39404.rs +++ b/src/test/ui/macros/issue-39404.rs @@ -2,5 +2,6 @@ macro_rules! m { ($i) => {} } //~^ ERROR missing fragment specifier +//~| WARN previously accepted fn main() {} diff --git a/src/test/ui/macros/issue-39404.stderr b/src/test/ui/macros/issue-39404.stderr index 645f06e59d8..d2f2a823c2a 100644 --- a/src/test/ui/macros/issue-39404.stderr +++ b/src/test/ui/macros/issue-39404.stderr @@ -3,6 +3,10 @@ error: missing fragment specifier | LL | macro_rules! m { ($i) => {} } | ^^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 error: aborting due to previous error diff --git a/src/test/ui/macros/macro-match-nonterminal.rs b/src/test/ui/macros/macro-match-nonterminal.rs index 6b023e41372..b23e5c71c03 100644 --- a/src/test/ui/macros/macro-match-nonterminal.rs +++ b/src/test/ui/macros/macro-match-nonterminal.rs @@ -2,6 +2,7 @@ macro_rules! test { ($a, $b) => { //~^ ERROR missing fragment //~| ERROR missing fragment + //~| WARN this was previously accepted () }; } diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr index 334d62812cd..674ce3434aa 100644 --- a/src/test/ui/macros/macro-match-nonterminal.stderr +++ b/src/test/ui/macros/macro-match-nonterminal.stderr @@ -9,6 +9,10 @@ error: missing fragment specifier | LL | ($a, $b) => { | ^^ + | + = note: `#[deny(missing_fragment_specifier)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs index cf81f0480a2..80e2d7c6545 100644 --- a/src/test/ui/parser/macro/issue-33569.rs +++ b/src/test/ui/parser/macro/issue-33569.rs @@ -2,7 +2,6 @@ macro_rules! foo { { $+ } => { //~ ERROR expected identifier, found `+` //~^ ERROR missing fragment specifier $(x)(y) //~ ERROR expected one of: `*`, `+`, or `?` - //~^ ERROR attempted to repeat an expression containing no syntax variables } } diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr index f54efaa6996..b4d38d3ce48 100644 --- a/src/test/ui/parser/macro/issue-33569.stderr +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -4,23 +4,17 @@ error: expected identifier, found `+` LL | { $+ } => { | ^ -error: missing fragment specifier - --> $DIR/issue-33569.rs:2:8 - | -LL | { $+ } => { - | ^ - error: expected one of: `*`, `+`, or `?` --> $DIR/issue-33569.rs:4:13 | LL | $(x)(y) | ^^^ -error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth - --> $DIR/issue-33569.rs:4:10 +error: missing fragment specifier + --> $DIR/issue-33569.rs:2:8 | -LL | $(x)(y) - | ^^^ +LL | { $+ } => { + | ^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -- cgit 1.4.1-3-g733a5 From bdc9291ed9dd0501a0d25a87463212ad5ec5d87a Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Wed, 30 Dec 2020 12:59:07 +0100 Subject: where possible, pass slices instead of &Vec or &String (clippy::ptr_arg) --- compiler/rustc_codegen_ssa/src/mir/block.rs | 2 +- compiler/rustc_driver/src/lib.rs | 2 +- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 4 ++-- compiler/rustc_macros/src/session_diagnostic.rs | 2 +- compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs | 2 +- .../src/borrow_check/type_check/liveness/local_use_map.rs | 6 +----- compiler/rustc_mir/src/interpret/validity.rs | 2 +- compiler/rustc_mir/src/transform/coverage/counters.rs | 6 +++--- compiler/rustc_mir/src/transform/function_item_references.rs | 4 ++-- compiler/rustc_mir_build/src/build/expr/as_place.rs | 6 +++--- compiler/rustc_resolve/src/late.rs | 8 +++----- compiler/rustc_session/src/filesearch.rs | 2 +- src/librustdoc/html/render/mod.rs | 2 +- 13 files changed, 21 insertions(+), 27 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index ce56f163549..ecac05fd955 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -522,7 +522,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mut bx: Bx, terminator: &mir::Terminator<'tcx>, func: &mir::Operand<'tcx>, - args: &Vec>, + args: &[mir::Operand<'tcx>], destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>, cleanup: Option, fn_span: Span, diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index b3466f49b9f..d57ab2433ad 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -603,7 +603,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { } } -fn show_content_with_pager(content: &String) { +fn show_content_with_pager(content: &str) { let pager_name = env::var_os("PAGER").unwrap_or_else(|| { if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") } }); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 6b7edde9a67..6d6bf4bf5f7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // obviously it never weeds out ALL errors. fn process_errors( &self, - errors: &Vec>, + errors: &[RegionResolutionError<'tcx>], ) -> Vec> { debug!("process_errors()"); @@ -442,7 +442,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; let mut errors = if errors.iter().all(|e| is_bound_failure(e)) { - errors.clone() + errors.to_owned() } else { errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect() }; diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs index 610b9155cfc..5c061a9d3c7 100644 --- a/compiler/rustc_macros/src/session_diagnostic.rs +++ b/compiler/rustc_macros/src/session_diagnostic.rs @@ -574,7 +574,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> { /// format!("Expected a point greater than ({x}, {y})", x = self.x, y = self.y) /// ``` /// This function builds the entire call to format!. - fn build_format(&self, input: &String, span: proc_macro2::Span) -> proc_macro2::TokenStream { + fn build_format(&self, input: &str, span: proc_macro2::Span) -> proc_macro2::TokenStream { // This set is used later to generate the final format string. To keep builds reproducible, // the iteration order needs to be deterministic, hence why we use a BTreeSet here instead // of a HashSet. diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs index 81571fd7300..4ebc1cdca60 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/mod.rs @@ -954,7 +954,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, def_id: DefId, target_place: PlaceRef<'tcx>, - places: &Vec>, + places: &[Operand<'tcx>], ) -> Option<(Span, Option, Span)> { debug!( "closure_span: def_id={:?} target_place={:?} places={:?}", diff --git a/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs index 995e3a60a0c..7e8a33efe11 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/liveness/local_use_map.rs @@ -58,11 +58,7 @@ impl vll::LinkElem for Appearance { } impl LocalUseMap { - crate fn build( - live_locals: &Vec, - elements: &RegionValueElements, - body: &Body<'_>, - ) -> Self { + crate fn build(live_locals: &[Local], elements: &RegionValueElements, body: &Body<'_>) -> Self { let nones = IndexVec::from_elem_n(None, body.local_decls.len()); let mut local_use_map = LocalUseMap { first_def_at: nones.clone(), diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index 57aec0953b8..a6ea039f278 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -153,7 +153,7 @@ impl RefTracking } /// Format a path -fn write_path(out: &mut String, path: &Vec) { +fn write_path(out: &mut String, path: &[PathElem]) { use self::PathElem::*; for elem in path.iter() { diff --git a/compiler/rustc_mir/src/transform/coverage/counters.rs b/compiler/rustc_mir/src/transform/coverage/counters.rs index 20f6a16e0f7..b5921aac561 100644 --- a/compiler/rustc_mir/src/transform/coverage/counters.rs +++ b/compiler/rustc_mir/src/transform/coverage/counters.rs @@ -140,7 +140,7 @@ impl<'a> BcbCounters<'a> { /// message for subsequent debugging. fn make_bcb_counters( &mut self, - coverage_spans: &Vec, + coverage_spans: &[CoverageSpan], ) -> Result, Error> { debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock"); let num_bcbs = self.basic_coverage_blocks.num_nodes(); @@ -465,7 +465,7 @@ impl<'a> BcbCounters<'a> { fn choose_preferred_expression_branch( &self, traversal: &TraverseCoverageGraphWithLoops, - branches: &Vec, + branches: &[BcbBranch], ) -> BcbBranch { let branch_needs_a_counter = |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none(); @@ -509,7 +509,7 @@ impl<'a> BcbCounters<'a> { fn find_some_reloop_branch( &self, traversal: &TraverseCoverageGraphWithLoops, - branches: &Vec, + branches: &[BcbBranch], ) -> Option { let branch_needs_a_counter = |branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none(); diff --git a/compiler/rustc_mir/src/transform/function_item_references.rs b/compiler/rustc_mir/src/transform/function_item_references.rs index d592580af9c..7c8c349da1d 100644 --- a/compiler/rustc_mir/src/transform/function_item_references.rs +++ b/compiler/rustc_mir/src/transform/function_item_references.rs @@ -99,7 +99,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { &self, def_id: DefId, substs_ref: SubstsRef<'tcx>, - args: &Vec>, + args: &[Operand<'tcx>], source_info: SourceInfo, ) { let param_env = self.tcx.param_env(def_id); @@ -162,7 +162,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> { .unwrap_or(None) } - fn nth_arg_span(&self, args: &Vec>, n: usize) -> Span { + fn nth_arg_span(&self, args: &[Operand<'tcx>], n: usize) -> Span { match &args[n] { Operand::Copy(place) | Operand::Move(place) => { self.body.local_decls[place.local].source_info.span diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index e1a3dc87c8c..cf2e4e8916d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -79,7 +79,7 @@ crate struct PlaceBuilder<'tcx> { /// part of a path that is captued by a closure. We stop applying projections once we see the first /// projection that isn't captured by a closure. fn convert_to_hir_projections_and_truncate_for_capture<'tcx>( - mir_projections: &Vec>, + mir_projections: &[PlaceElem<'tcx>], ) -> Vec { let mut hir_projections = Vec::new(); @@ -128,7 +128,7 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>( /// list are being applied to the same root variable. fn is_ancestor_or_same_capture( proj_possible_ancestor: &Vec, - proj_capture: &Vec, + proj_capture: &[HirProjectionKind], ) -> bool { // We want to make sure `is_ancestor_or_same_capture("x.0.0", "x.0")` to return false. // Therefore we can't just check if all projections are same in the zipped iterator below. @@ -171,7 +171,7 @@ fn find_capture_matching_projections<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, var_hir_id: HirId, closure_def_id: DefId, - projections: &Vec>, + projections: &[PlaceElem<'tcx>], ) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> { let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?; let root_variable_min_captures = closure_min_captures.get(&var_hir_id)?; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b13462587bc..21def3e1429 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1151,13 +1151,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { /// When evaluating a `trait` use its associated types' idents for suggestions in E0412. fn with_trait_items( &mut self, - trait_items: &'ast Vec>, + trait_items: &'ast [P], f: impl FnOnce(&mut Self) -> T, ) -> T { - let trait_assoc_items = replace( - &mut self.diagnostic_metadata.current_trait_assoc_items, - Some(&trait_items[..]), - ); + let trait_assoc_items = + replace(&mut self.diagnostic_metadata.current_trait_assoc_items, Some(&trait_items)); let result = f(self); self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items; result diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 55ee4e52082..3a757e5f007 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -76,7 +76,7 @@ impl<'a> FileSearch<'a> { pub fn new( sysroot: &'a Path, triple: &'a str, - search_paths: &'a Vec, + search_paths: &'a [SearchPath], tlib_path: &'a SearchPath, kind: PathKind, ) -> FileSearch<'a> { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 6f8a4d9513b..04876c1d3f0 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -3483,7 +3483,7 @@ enum AssocItemLink<'a> { } impl<'a> AssocItemLink<'a> { - fn anchor(&self, id: &'a String) -> Self { + fn anchor(&self, id: &'a str) -> Self { match *self { AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)), ref other => *other, -- cgit 1.4.1-3-g733a5