From 47a443c50dbeee88cadc78e5c938f3e6d04d6f6b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:13:02 -0400 Subject: [PATCH 01/35] Duplicate lint specifications are always bug! Replace early_error and sess.err with bug!, in all cases. If the compiler we're running with, including plugins, is registering something twice, that's a (compiler/plugin) programmer error -- we should not try to be nice at the cost of developer ergononomics (hiding the stacktrace of the second registration is bad). This also is basically a static bug in ~all cases so it should not be a detriment to users, including with plugins. --- src/librustc/lint/context.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index fa73a3c6c4628..002c3f6623514 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -218,16 +218,7 @@ impl LintStore { let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { - let msg = format!("duplicate specification of lint {}", lint.name_lower()); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint {}", lint.name_lower()) } } } @@ -300,16 +291,7 @@ impl LintStore { } if !new { - let msg = format!("duplicate specification of lint group {}", name); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint group {}", name); } } From 577d442fe8337338b873d3df1ab5132de6a1af83 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:26:11 -0400 Subject: [PATCH 02/35] De-propagate optional session from lint registration This is straight up removing dead code, but is a separate commit from the previous to avoid conflating clean up and important changes. --- src/librustc/lint/context.rs | 17 ++++--------- src/librustc_interface/passes.rs | 6 ++--- src/librustc_interface/util.rs | 5 ++-- src/librustc_lint/lib.rs | 42 +++++++++++++------------------- 4 files changed, 28 insertions(+), 42 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 002c3f6623514..dc16de822ebcd 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -26,7 +26,7 @@ use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; -use crate::session::{config, early_error, Session}; +use crate::session::Session; use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::util::nodemap::FxHashMap; @@ -169,11 +169,10 @@ impl LintStore { } pub fn register_early_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -181,24 +180,22 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -210,7 +207,6 @@ impl LintStore { // Helper method for register_early/late_pass fn push_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, pass: &Box

) { for lint in pass.get_lints() { @@ -224,14 +220,13 @@ impl LintStore { } pub fn register_future_incompatible(&mut self, - sess: Option<&Session>, lints: Vec) { for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, edition.lint_name(), None, lints) + self.register_group(false, edition.lint_name(), None, lints) } } @@ -242,7 +237,6 @@ impl LintStore { } self.register_group( - sess, false, "future_incompatible", None, @@ -268,7 +262,6 @@ impl LintStore { pub fn register_group( &mut self, - sess: Option<&Session>, from_plugin: bool, name: &'static str, deprecated_name: Option<&'static str>, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 89de5714695de..280ac45803b7e 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,14 +299,14 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, false, pass); + ls.register_early_pass(true, false, pass); } for pass in late_lint_passes { - ls.register_late_pass(Some(sess), true, false, false, pass); + ls.register_late_pass(true, false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(Some(sess), true, name, deprecated_name, to); + ls.register_group(true, name, deprecated_name, to); } *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 0c272f0c4563b..005f1a44acd6a 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -108,9 +108,10 @@ pub fn create_session( let codegen_backend = get_codegen_backend(&sess); - rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); + rustc_lint::register_builtins(&mut sess.lint_store.get_mut(), + sess.opts.debugging_opts.no_interleave_lints); if sess.unstable_options() { - rustc_lint::register_internals(&mut sess.lint_store.borrow_mut(), Some(&sess)); + rustc_lint::register_internals(&mut sess.lint_store.get_mut()); } let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0e054013cd779..5c70e9f8a1a30 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,7 +41,6 @@ use rustc::lint::builtin::{ PRIVATE_DOC_TESTS, parser::ILL_FORMED_ATTRIBUTE_INPUT, }; -use rustc::session; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::ty::query::Providers; @@ -51,7 +50,6 @@ use syntax::ast; use syntax::edition::Edition; use syntax_pos::Span; -use session::Session; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -198,16 +196,16 @@ late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLint /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { +pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { - ($sess:ident, $name:expr, $($lint:ident),*) => ( - store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]); + ($name:expr, $($lint:ident),*) => ( + store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); ) } macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(sess, false, false, $($args,)* box $constructor); + store.$method(false, false, $($args,)* box $constructor); ) } @@ -219,35 +217,32 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { ) } - if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) { + if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); late_lint_passes!(register_passes, [register_late_pass, [false]]); late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - sess, false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - sess, false, true, true, box BuiltinCombinedModuleLateLintPass::new() + false, true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - sess, false, true, false, box BuiltinCombinedLateLintPass::new() + false, true, false, box BuiltinCombinedLateLintPass::new() ); } - add_lint_group!(sess, - "nonstandard_style", + add_lint_group!("nonstandard_style", NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS); - add_lint_group!(sess, - "unused", + add_lint_group!("unused", UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, @@ -267,8 +262,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_LABELS, UNUSED_PARENS); - add_lint_group!(sess, - "rust_2018_idioms", + add_lint_group!("rust_2018_idioms", BARE_TRAIT_OBJECTS, UNUSED_EXTERN_CRATES, ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, @@ -284,8 +278,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // MACRO_USE_EXTERN_CRATE, ); - add_lint_group!(sess, - "rustdoc", + add_lint_group!("rustdoc", INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); @@ -298,7 +291,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // and include the full URL, sort items in ascending order of issue numbers. // - Later, change lint to error // - Eventually, remove lint - store.register_future_incompatible(sess, vec![ + store.register_future_incompatible(vec![ FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", @@ -498,12 +491,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } -pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { - store.register_early_pass(sess, false, false, box DefaultHashTypes::new()); - store.register_early_pass(sess, false, false, box LintPassImpl); - store.register_late_pass(sess, false, false, false, box TyTyKind); +pub fn register_internals(store: &mut lint::LintStore) { + store.register_early_pass(false, false, box DefaultHashTypes::new()); + store.register_early_pass(false, false, box LintPassImpl); + store.register_late_pass(false, false, false, box TyTyKind); store.register_group( - sess, false, "rustc::internal", None, From 2121b04751702359f3bf03847040a9907ec2f66f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 24 Sep 2019 18:24:45 -0400 Subject: [PATCH 03/35] Handle lints, not passes in push_lints This extracts the call to get_lints() to callers. --- src/librustc/lint/context.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index dc16de822ebcd..c21c45b759c63 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -172,7 +172,7 @@ impl LintStore { from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -184,7 +184,7 @@ impl LintStore { register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } @@ -195,7 +195,7 @@ impl LintStore { register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,10 +206,8 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_pass(&mut self, - from_plugin: bool, - pass: &Box

) { - for lint in pass.get_lints() { + fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + for lint in lints { self.lints.push((lint, from_plugin)); let id = LintId::of(lint); From 748eccd48828e430b906ffa6bd3f6abdcc766dc9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:52:53 -0400 Subject: [PATCH 04/35] Lints being from a plugin is dependent on the lint, not the registration --- src/librustc/lint/context.rs | 17 +++++++---------- src/librustc/lint/mod.rs | 5 +++++ src/librustc_driver/lib.rs | 5 ++--- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 15 +++++++-------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c21c45b759c63..37f577da8bba2 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -50,7 +50,7 @@ use syntax_pos::{MultiSpan, Span, symbol::Symbol}; pub struct LintStore { /// Registered lints. The bool is true if the lint was /// added by a plugin. - lints: Vec<(&'static Lint, bool)>, + lints: Vec<&'static Lint>, /// Trait objects for each lint pass. /// This is only `None` while performing a lint pass. @@ -152,7 +152,7 @@ impl LintStore { } } - pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] { + pub fn get_lints<'t>(&'t self) -> &'t [&'static Lint] { &self.lints } @@ -169,10 +169,9 @@ impl LintStore { } pub fn register_early_pass(&mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -180,22 +179,20 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,9 +203,9 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + fn push_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { - self.lints.push((lint, from_plugin)); + self.lints.push(lint); let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7443cca822a99..455dc06a1efbd 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -76,6 +76,8 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + + pub is_plugin: bool, } impl Lint { @@ -117,6 +119,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: false, }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, @@ -128,6 +131,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)), report_in_external_macro: false, + is_plugin: false, }; ); } @@ -156,6 +160,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: true, }; ); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f33cb4e215d33..5af1e8faccc8f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -835,8 +835,7 @@ Available lint options: "); - fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { - let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); + fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> { // The sort doesn't case-fold but it's doubtful we care. lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name)); lints @@ -852,7 +851,7 @@ Available lint options: let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints() .iter() .cloned() - .partition(|&(_, p)| p); + .partition(|&lint| lint.is_plugin); let plugin = sort_lints(sess, plugin); let builtin = sort_lints(sess, builtin); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 280ac45803b7e..2684650c3a970 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(true, false, pass); + ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(true, false, false, pass); + ls.register_late_pass(false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5c70e9f8a1a30..2c39ba024513e 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, false, $($args,)* box $constructor); + store.$method(false, $($args,)* box $constructor); ) } @@ -224,16 +224,15 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - false, true, true, box BuiltinCombinedModuleLateLintPass::new() + true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - false, true, false, box BuiltinCombinedLateLintPass::new() + true, false, box BuiltinCombinedLateLintPass::new() ); } @@ -492,9 +491,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, false, box DefaultHashTypes::new()); - store.register_early_pass(false, false, box LintPassImpl); - store.register_late_pass(false, false, false, box TyTyKind); + store.register_early_pass(false, box DefaultHashTypes::new()); + store.register_early_pass(false, box LintPassImpl); + store.register_late_pass(false, false, box TyTyKind); store.register_group( false, "rustc::internal", From b060f3b84d98a0288cf51a6ab82be61e8f047c31 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:59:12 -0400 Subject: [PATCH 05/35] Split module and crate late pass registration --- src/librustc/lint/context.rs | 18 +++++++++--------- src/librustc_interface/passes.rs | 2 +- src/librustc_lint/lib.rs | 19 ++++++------------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 37f577da8bba2..c65acd98385fa 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -188,17 +188,17 @@ impl LintStore { } } - pub fn register_late_pass(&mut self, - register_only: bool, - per_module: bool, - pass: LateLintPassObject) { + pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { self.push_lints(&pass.get_lints()); if !register_only { - if per_module { - self.late_module_passes.push(pass); - } else { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + self.late_passes.lock().as_mut().unwrap().push(pass); + } + } + + pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { + self.push_lints(&pass.get_lints()); + if !register_only { + self.late_module_passes.push(pass); } } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2684650c3a970..544dd26d01528 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -302,7 +302,7 @@ pub fn register_plugins<'a>( ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(false, false, pass); + ls.register_late_pass(false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2c39ba024513e..5b190740c101a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -220,20 +220,13 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, [false]]); - late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); + late_lint_passes!(register_passes, [register_late_pass, []]); + late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); } else { - store.register_pre_expansion_pass( - true, - box BuiltinCombinedPreExpansionLintPass::new() - ); + store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_pass( - true, true, box BuiltinCombinedModuleLateLintPass::new() - ); - store.register_late_pass( - true, false, box BuiltinCombinedLateLintPass::new() - ); + store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); + store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); } add_lint_group!("nonstandard_style", @@ -493,7 +486,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_early_pass(false, box DefaultHashTypes::new()); store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, false, box TyTyKind); + store.register_late_pass(false, box TyTyKind); store.register_group( false, "rustc::internal", From e1079c82be514c6a9423acefd4457a7a08c0091c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:21:50 -0400 Subject: [PATCH 06/35] Split out just registration to separate function --- src/librustc/lint/context.rs | 40 +++++++++++--------------------- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 30 ++++++++++++------------ 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c65acd98385fa..ff0b5a9e25b79 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,42 +168,28 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - register_only: bool, - pass: EarlyLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.early_passes.as_mut().unwrap().push(pass); - } + pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.early_passes.as_mut().unwrap().push(pass); } - pub fn register_pre_expansion_pass( - &mut self, - register_only: bool, - pass: EarlyLintPassObject, - ) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.pre_expansion_passes.as_mut().unwrap().push(pass); - } + pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.pre_expansion_passes.as_mut().unwrap().push(pass); } - pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + pub fn register_late_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_passes.lock().as_mut().unwrap().push(pass); } - pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_module_passes.push(pass); - } + pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass - fn push_lints(&mut self, lints: &[&'static Lint]) { + pub fn register_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { self.lints.push(lint); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 544dd26d01528..4e879e508ab49 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(false, pass); + ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_late_pass(false, pass); + ls.register_late_pass(pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5b190740c101a..49ab34b830a9b 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,29 +204,29 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, $($args,)* box $constructor); + ($method:ident, $constructor:expr) => ( + store.$method(box $constructor); ) } macro_rules! register_passes { - ([$method:ident, $args:tt], [$($passes:ident: $constructor:expr,)*]) => ( + ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor, $args); + register_pass!($method, $constructor); )* ) } if no_interleave_lints { - pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); - early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, []]); - late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); + pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass); + early_lint_passes!(register_passes, register_early_pass); + late_lint_passes!(register_passes, register_late_pass); + late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); - store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); - store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); } add_lint_group!("nonstandard_style", @@ -484,9 +484,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, box DefaultHashTypes::new()); - store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, box TyTyKind); + store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(box LintPassImpl); + store.register_late_pass(box TyTyKind); store.register_group( false, "rustc::internal", From 68c07db80a90fd0fc3be03474555dc685864bcb6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:36:44 -0400 Subject: [PATCH 07/35] No longer implicitly register lints when registering passes This is in preparation for on-demand constructing passes --- src/librustc/lint/context.rs | 4 ---- src/librustc_interface/passes.rs | 2 ++ src/librustc_lint/lib.rs | 7 ++++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ff0b5a9e25b79..e04845d278a54 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -169,22 +169,18 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.early_passes.as_mut().unwrap().push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.pre_expansion_passes.as_mut().unwrap().push(pass); } pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_passes.lock().as_mut().unwrap().push(pass); } pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_module_passes.push(pass); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 4e879e508ab49..951b0970754a2 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,9 +299,11 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 49ab34b830a9b..3bb7de8b7f61c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr) => ( - store.$method(box $constructor); + let obj = box $constructor; + store.register_lints(&obj.get_lints()); + store.$method(obj); ) } @@ -484,8 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { + store.register_lints(&DefaultHashTypes::new().get_lints()); store.register_early_pass(box DefaultHashTypes::new()); + store.register_lints(&LintPassImpl.get_lints()); store.register_early_pass(box LintPassImpl); + store.register_lints(&TyTyKind.get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, From 7fef39791a093681c59f08181f96a0a2d63ab981 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:04:05 -0400 Subject: [PATCH 08/35] Make get_lints be a static function This moves from calling get_lints on instantiated pass objects to the raw object --- src/librustc/lint/context.rs | 10 +----- src/librustc/lint/mod.rs | 36 ++++++++----------- src/librustc_interface/passes.rs | 4 +-- src/librustc_lint/lib.rs | 20 +++++------ src/librustc_plugin/registry.rs | 9 +++++ src/librustdoc/core.rs | 7 ++-- .../lint_pass_impl_without_macro.rs | 10 +----- .../lint_pass_impl_without_macro.stderr | 3 +- 8 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e04845d278a54..373ee2568a47c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -1307,10 +1307,6 @@ impl LintPass for LateLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_late_lint_pass_impl_methods { @@ -1477,10 +1473,6 @@ impl LintPass for EarlyLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_early_lint_pass_impl_methods { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 455dc06a1efbd..1b34808ef30ac 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -178,14 +178,6 @@ pub type LintArray = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; - - /// Gets descriptions of the lints this `LintPass` object can emit. - /// - /// N.B., there is no enforcement that the object only emits lints it registered. - /// And some `rustc` internal `LintPass`es register lints to be emitted by other - /// parts of the compiler. If you want enforced access restrictions for your - /// `Lint`, make it a private `static` item in its own module. - fn get_lints(&self) -> LintArray; } /// Implements `LintPass for $name` with the given list of `Lint` statics. @@ -194,7 +186,9 @@ macro_rules! impl_lint_pass { ($name:ident => [$($lint:expr),* $(,)?]) => { impl LintPass for $name { fn name(&self) -> &'static str { stringify!($name) } - fn get_lints(&self) -> LintArray { $crate::lint_array!($($lint),*) } + } + impl $name { + pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) } } }; } @@ -332,6 +326,12 @@ macro_rules! declare_combined_late_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name { @@ -342,12 +342,6 @@ macro_rules! declare_combined_late_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } @@ -459,6 +453,12 @@ macro_rules! declare_combined_early_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl EarlyLintPass for $name { @@ -469,12 +469,6 @@ macro_rules! declare_combined_early_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 951b0970754a2..fdea437d37fbc 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -291,6 +291,7 @@ pub fn register_plugins<'a>( syntax_exts, early_lint_passes, late_lint_passes, + lints, lint_groups, llvm_passes, attributes, @@ -298,12 +299,11 @@ pub fn register_plugins<'a>( } = registry; let mut ls = sess.lint_store.borrow_mut(); + ls.register_lints(&lints); for pass in early_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3bb7de8b7f61c..752396188afd1 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,9 +204,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr) => ( + ($method:ident, $ty:ident, $constructor:expr) => ( let obj = box $constructor; - store.register_lints(&obj.get_lints()); + store.register_lints(&$ty::get_lints()); store.$method(obj); ) } @@ -214,7 +214,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_passes { ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor); + register_pass!($method, $passes, $constructor); )* ) } @@ -225,10 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_passes!(register_passes, register_late_pass); late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::get_lints()); } add_lint_group!("nonstandard_style", @@ -486,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_lints(&DefaultHashTypes::new().get_lints()); + store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(box DefaultHashTypes::new()); - store.register_lints(&LintPassImpl.get_lints()); + store.register_lints(&LintPassImpl::get_lints()); store.register_early_pass(box LintPassImpl); - store.register_lints(&TyTyKind.get_lints()); + store.register_lints(&TyTyKind::get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index b826dd9119838..a8076b57c86ac 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -41,6 +41,9 @@ pub struct Registry<'a> { #[doc(hidden)] pub late_lint_passes: Vec, + #[doc(hidden)] + pub lints: Vec<&'static Lint>, + #[doc(hidden)] pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, @@ -59,6 +62,7 @@ impl<'a> Registry<'a> { args_hidden: None, krate_span, syntax_exts: vec![], + lints: vec![], early_lint_passes: vec![], late_lint_passes: vec![], lint_groups: FxHashMap::default(), @@ -99,6 +103,11 @@ impl<'a> Registry<'a> { self.register_syntax_extension(Symbol::intern(name), ext); } + /// Register a compiler lint pass. + pub fn register_lints(&mut self, lints: &[&'static Lint]) { + self.lints.extend(lints); + } + /// Register a compiler lint pass. pub fn register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject) { self.early_lint_passes.push(lint_pass); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 00265caa965ea..2a468d679a887 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,7 +5,7 @@ use rustc::hir::HirId; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{Ty, TyCtxt}; -use rustc::lint::{self, LintPass}; +use rustc::lint; use rustc::session::config::ErrorOutputType; use rustc::session::DiagnosticOutput; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -273,10 +273,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints - .get_lints() + lint::builtin::HardwiredLints::get_lints() .into_iter() - .chain(rustc_lint::SoftLints.get_lints().into_iter()) + .chain(rustc_lint::SoftLints::get_lints().into_iter()) }; let lint_opts = lints().filter_map(|lint| { diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index 48dd5b122b5ac..0bfb32c6dc43b 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc; use rustc::lint::{LintArray, LintPass}; -use rustc::{declare_lint, declare_lint_pass, impl_lint_pass, lint_array}; +use rustc::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { pub TEST_LINT, @@ -17,10 +17,6 @@ declare_lint! { struct Foo; impl LintPass for Foo { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Foo" } @@ -31,10 +27,6 @@ macro_rules! custom_lint_pass_macro { struct Custom; impl LintPass for Custom { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Custom" } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b439ae2cd148d..b7cff343395e9 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)] = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:33:14 + --> $DIR/lint_pass_impl_without_macro.rs:29:14 | LL | impl LintPass for Custom { | ^^^^^^^^ @@ -23,4 +23,3 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors - From 24545128ebf7e19536e1384f64b89a18742471b0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:10:41 -0400 Subject: [PATCH 09/35] Take lint passes as constructor functions --- src/librustc/lint/context.rs | 16 ++++++++-------- src/librustc_lint/lib.rs | 9 ++++----- src/librustc_plugin/registry.rs | 8 ++++---- src/test/ui-fulldeps/auxiliary/lint-for-crate.rs | 3 ++- .../lint_pass_impl_without_macro.stderr | 1 + 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 373ee2568a47c..73d8bb11b719c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,20 +168,20 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push(pass); + pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.early_passes.as_mut().unwrap().push((pass)()); } - pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push(pass); + pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.pre_expansion_passes.as_mut().unwrap().push((pass)()); } - pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push(pass); + pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_passes.lock().as_mut().unwrap().push((pass)()); } - pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_module_passes.push((pass)()); } // Helper method for register_early/late_pass diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 752396188afd1..0026c2317d156 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,9 +205,8 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $ty:ident, $constructor:expr) => ( - let obj = box $constructor; store.register_lints(&$ty::get_lints()); - store.$method(obj); + store.$method(|| box $constructor); ) } @@ -487,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); - store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); - store.register_early_pass(box LintPassImpl); + store.register_early_pass(|| box LintPassImpl); store.register_lints(&TyTyKind::get_lints()); - store.register_late_pass(box TyTyKind); + store.register_late_pass(|| box TyTyKind); store.register_group( false, "rustc::internal", diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index a8076b57c86ac..44318bf06aaaf 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -36,10 +36,10 @@ pub struct Registry<'a> { pub syntax_exts: Vec, #[doc(hidden)] - pub early_lint_passes: Vec, + pub early_lint_passes: Vec EarlyLintPassObject>, #[doc(hidden)] - pub late_lint_passes: Vec, + pub late_lint_passes: Vec LateLintPassObject>, #[doc(hidden)] pub lints: Vec<&'static Lint>, @@ -109,12 +109,12 @@ impl<'a> Registry<'a> { } /// Register a compiler lint pass. - pub fn register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject) { + pub fn register_early_lint_pass(&mut self, lint_pass: fn() -> EarlyLintPassObject) { self.early_lint_passes.push(lint_pass); } /// Register a compiler lint pass. - pub fn register_late_lint_pass(&mut self, lint_pass: LateLintPassObject) { + pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) { self.late_lint_passes.push(lint_pass); } /// Register a lint group. diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 000e10392e827..ba5b5d1906aea 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -32,5 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); + reg.register_lint(&[&CRATE_NOT_OKAY]); + reg.register_late_lint_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b7cff343395e9..0dbdf4f5aa9e2 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -23,3 +23,4 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors + From aa4ee2cc0f722467da4c4b0d19ad365a4be1e5d5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:23:16 -0400 Subject: [PATCH 10/35] Move to storing constructor functions inside LintStore This stops storing the pass objects and instead stores constructor functions. The primary effect is that LintStore no longer has any interior mutability. --- src/librustc/lint/context.rs | 56 +++++++++++++++++------------------- src/librustc/lint/mod.rs | 3 -- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 73d8bb11b719c..6e67c0315cf23 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::edition; @@ -52,12 +52,17 @@ pub struct LintStore { /// added by a plugin. lints: Vec<&'static Lint>, - /// Trait objects for each lint pass. - /// This is only `None` while performing a lint pass. - pre_expansion_passes: Option>, - early_passes: Option>, - late_passes: Lock>>, - late_module_passes: Vec, + /// Constructor functions for each variety of lint pass. + /// + /// These should only be called once, but since we want to avoid locks or + /// interior mutability, we don't enforce this (and lints should, in theory, + /// be compatible with being constructed more than once, though not + /// necessarily in a sane manner. This is safe though.) + pre_expansion_passes: Vec EarlyLintPassObject>, + early_passes: Vec EarlyLintPassObject>, + late_passes: Vec LateLintPassObject>, + /// This is unique in that we construct them per-module, so not once. + late_module_passes: Vec LateLintPassObject>, /// Lints indexed by name. by_name: FxHashMap, @@ -142,9 +147,9 @@ impl LintStore { pub fn new() -> LintStore { LintStore { lints: vec![], - pre_expansion_passes: Some(vec![]), - early_passes: Some(vec![]), - late_passes: Lock::new(Some(vec![])), + pre_expansion_passes: vec![], + early_passes: vec![], + late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), future_incompatible: Default::default(), @@ -169,19 +174,19 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push((pass)()); + self.early_passes.push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push((pass)()); + self.pre_expansion_passes.push(pass); } pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push((pass)()); + self.late_passes.push(pass); } pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push((pass)()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass @@ -1374,7 +1379,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] }); @@ -1415,7 +1420,8 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap(); + let mut passes = tcx.sess.lint_store.borrow() + .late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { if !passes.is_empty() { @@ -1431,7 +1437,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b } let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); for pass in &mut passes { time(tcx.sess, &format!("running late module lint: {}", pass.name()), || { @@ -1439,9 +1445,6 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } } - - // Put the passes back in the session. - *tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes); } /// Performs lint checking on a crate. @@ -1525,14 +1528,14 @@ pub fn check_ast_crate( pre_expansion: bool, builtin_lints: T, ) { - let (mut passes, mut buffered) = if pre_expansion { + let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(), + sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow_mut().early_passes.take().unwrap(), + sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; @@ -1561,13 +1564,6 @@ pub fn check_ast_crate( } } - // Put the lint store levels and passes back in the session. - if pre_expansion { - sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes); - } else { - sess.lint_store.borrow_mut().early_passes = Some(passes); - } - // All of the buffered lints should have been emitted at this point. // If not, that means that we somehow buffered a lint for a node id // that was not lint-checked (perhaps it doesn't exist?). This is a bug. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 1b34808ef30ac..63c4013e1d317 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -286,9 +286,6 @@ macro_rules! expand_lint_pass_methods { macro_rules! declare_late_lint_pass { ([], [$hir:tt], [$($methods:tt)*]) => ( pub trait LateLintPass<'a, $hir>: LintPass { - fn fresh_late_pass(&self) -> LateLintPassObject { - panic!() - } expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]); } ) From c1abc30660c0c0b081a42d0a476d81ba04e6d16b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 18:47:08 -0400 Subject: [PATCH 11/35] Make declare_lint take any amount of boolean fields --- src/librustc/lint/builtin.rs | 8 ++++---- src/librustc/lint/mod.rs | 23 +++++++++++++++++------ src/librustc_lint/builtin.rs | 4 ++-- src/librustc_lint/unused.rs | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 983e3a9922ec2..29cc326fab64d 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -22,7 +22,7 @@ declare_lint! { pub CONST_ERR, Deny, "constant evaluation detected erroneous expression", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -71,7 +71,7 @@ declare_lint! { pub UNREACHABLE_CODE, Warn, "detects unreachable code paths", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -211,7 +211,7 @@ declare_lint! { pub DEPRECATED, Warn, "detects use of deprecated items", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -381,7 +381,7 @@ declare_lint! { pub DEPRECATED_IN_FUTURE, Allow, "detects use of items that will be deprecated in a future version", - report_in_external_macro: true + report_in_external_macro } declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 63c4013e1d317..76e6a28008a37 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -81,6 +81,17 @@ pub struct Lint { } impl Lint { + pub const fn default_fields_for_macro() -> Self { + Lint { + name: "", + default_level: Level::Forbid, + desc: "", + edition_lint_opts: None, + is_plugin: false, + report_in_external_macro: false, + } + } + /// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`. pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self { match lint_id { @@ -107,19 +118,19 @@ impl Lint { #[macro_export] macro_rules! declare_lint { ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, false} + declare_lint!( + $vis $NAME, $Level, $desc, + ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, report_in_external_macro: $rep: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, $rep} - ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $external: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, edition_lint_opts: None, - report_in_external_macro: $external, is_plugin: false, + $($v: true,)* + ..$crate::lint::Lint::default_fields_for_macro() }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 9a16d0a0715f7..2997e1d2ca942 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -280,7 +280,7 @@ declare_lint! { pub MISSING_DOCS, Allow, "detects missing documentation for public members", - report_in_external_macro: true + report_in_external_macro } pub struct MissingDoc { @@ -1374,7 +1374,7 @@ declare_lint! { UNNAMEABLE_TEST_ITEMS, Warn, "detects an item that cannot be named being marked as `#[test_case]`", - report_in_external_macro: true + report_in_external_macro } pub struct UnnameableTestItems { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 3b3995832cb4c..2ff8147149bb8 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -25,7 +25,7 @@ declare_lint! { pub UNUSED_MUST_USE, Warn, "unused result of a type flagged as `#[must_use]`", - report_in_external_macro: true + report_in_external_macro } declare_lint! { From 7abb1fafcec155c4b596147fda4aff5a5cda62f3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:49:21 -0400 Subject: [PATCH 12/35] Remove side table of future incompatibility info Moves this information to a direct field of Lint, which is where it belongs. --- src/librustc/lint/builtin.rs | 161 +++++++++++++++++++++++++++++------ src/librustc/lint/context.rs | 63 +++++--------- src/librustc/lint/mod.rs | 20 ++++- src/librustc_lint/builtin.rs | 13 ++- src/librustc_lint/lib.rs | 157 ---------------------------------- 5 files changed, 183 insertions(+), 231 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 29cc326fab64d..4c1093e00ceed 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,11 +4,12 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo}; use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; +use syntax::edition::Edition; use syntax::source_map::Span; use syntax::symbol::Symbol; @@ -125,7 +126,11 @@ declare_lint! { declare_lint! { pub PRIVATE_IN_PUBLIC, Warn, - "detect private items in public interfaces not caught by the old implementation" + "detect private items in public interfaces not caught by the old implementation", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { @@ -137,13 +142,21 @@ declare_lint! { declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, - "detect public re-exports of private extern crates" + "detect public re-exports of private extern crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { pub INVALID_TYPE_PARAM_DEFAULT, Deny, - "type parameter default erroneously allowed in invalid location" + "type parameter default erroneously allowed in invalid location", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36887 ", + edition: None, + }; } declare_lint! { @@ -155,56 +168,92 @@ declare_lint! { declare_lint! { pub SAFE_EXTERN_STATICS, Deny, - "safe access to extern statics was erroneously allowed" + "safe access to extern statics was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36247 ", + edition: None, + }; } declare_lint! { pub SAFE_PACKED_BORROWS, Warn, - "safe borrows of fields of packed structs were was erroneously allowed" + "safe borrows of fields of packed structs were was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46043 ", + edition: None, + }; } declare_lint! { pub PATTERNS_IN_FNS_WITHOUT_BODY, Warn, - "patterns in functions without body were erroneously allowed" + "patterns in functions without body were erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35203 ", + edition: None, + }; } declare_lint! { pub LEGACY_DIRECTORY_OWNERSHIP, Deny, "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \ - not named `mod.rs`" + not named `mod.rs`", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #37872 ", + edition: None, + }; } declare_lint! { pub LEGACY_CONSTRUCTOR_VISIBILITY, Deny, - "detects use of struct constructors that would be invisible with new visibility rules" + "detects use of struct constructors that would be invisible with new visibility rules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #39207 ", + edition: None, + }; } declare_lint! { pub MISSING_FRAGMENT_SPECIFIER, Deny, - "detects missing fragment specifiers in unused `macro_rules!` patterns" + "detects missing fragment specifiers in unused `macro_rules!` patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #40107 ", + edition: None, + }; } declare_lint! { pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, Deny, - "detects parenthesized generic parameters in type and module names" + "detects parenthesized generic parameters in type and module names", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42238 ", + edition: None, + }; } declare_lint! { pub LATE_BOUND_LIFETIME_ARGUMENTS, Warn, - "detects generic lifetime arguments in path segments with late bound lifetime parameters" + "detects generic lifetime arguments in path segments with late bound lifetime parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42868 ", + edition: None, + }; } declare_lint! { pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, - "trait-object types were treated as different depending on marker-trait order" + "trait-object types were treated as different depending on marker-trait order", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #56484 ", + edition: None, + }; } declare_lint! { @@ -247,7 +296,11 @@ declare_lint! { declare_lint! { pub TYVAR_BEHIND_RAW_POINTER, Warn, - "raw pointer to an inference variable" + "raw pointer to an inference variable", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46906 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -266,19 +319,33 @@ declare_lint! { pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, Allow, "fully qualified paths that start with a module name \ - instead of `crate`, `self`, or an extern crate name" + instead of `crate`, `self`, or an extern crate name", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #53130 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, Warn, - "floating-point literals cannot be used in patterns" + "floating-point literals cannot be used in patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41620 ", + edition: None, + }; } declare_lint! { pub UNSTABLE_NAME_COLLISIONS, Warn, - "detects name collision with an existing but unstable method" + "detects name collision with an existing but unstable method", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #48919 ", + edition: None, + // Note: this item represents future incompatibility of all unstable functions in the + // standard library, and thus should never be removed or changed to an error. + }; } declare_lint! { @@ -296,7 +363,11 @@ declare_lint! { declare_lint! { pub DUPLICATE_MACRO_EXPORTS, Deny, - "detects duplicate macro exports" + "detects duplicate macro exports", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35896 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -320,13 +391,21 @@ declare_lint! { declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, - "checks the object safety of where clauses" + "checks the object safety of where clauses", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #51443 ", + edition: None, + }; } declare_lint! { pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, Warn, - "detects proc macro derives using inaccessible names from parent modules" + "detects proc macro derives using inaccessible names from parent modules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #50504 ", + edition: None, + }; } declare_lint! { @@ -340,7 +419,11 @@ declare_lint! { pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, Deny, "macro-expanded `macro_export` macros from the current crate \ - cannot be referred to by absolute paths" + cannot be referred to by absolute paths", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #52234 ", + edition: None, + }; } declare_lint! { @@ -353,7 +436,11 @@ declare_lint! { pub INDIRECT_STRUCTURAL_MATCH, // defaulting to allow until rust-lang/rust#62614 is fixed. Allow, - "pattern with const indirectly referencing non-`#[structural_match]` type" + "pattern with const indirectly referencing non-`#[structural_match]` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #62411 ", + edition: None, + }; } /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. @@ -361,7 +448,11 @@ pub mod parser { declare_lint! { pub ILL_FORMED_ATTRIBUTE_INPUT, Warn, - "ill-formed attribute inputs that were previously accepted and used in practice" + "ill-formed attribute inputs that were previously accepted and used in practice", + @future_incompatible = super::FutureIncompatibleInfo { + reference: "issue #57571 ", + edition: None, + }; } declare_lint! { @@ -387,25 +478,41 @@ declare_lint! { declare_lint! { pub AMBIGUOUS_ASSOCIATED_ITEMS, Deny, - "ambiguous associated items" + "ambiguous associated items", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #57644 ", + edition: None, + }; } declare_lint! { pub NESTED_IMPL_TRAIT, Warn, - "nested occurrence of `impl Trait` type" + "nested occurrence of `impl Trait` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59014 ", + edition: None, + }; } declare_lint! { pub MUTABLE_BORROW_RESERVATION_CONFLICT, Warn, - "reservation of a two-phased borrow conflicts with other shared borrows" + "reservation of a two-phased borrow conflicts with other shared borrows", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59159 ", + edition: None, + }; } declare_lint! { pub SOFT_UNSTABLE, Deny, - "a feature gate that doesn't break dependent crates" + "a feature gate that doesn't break dependent crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #64266 ", + edition: None, + }; } declare_lint_pass! { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6e67c0315cf23..97b9f21163dbe 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer, FutureIncompatibleInfo}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -38,7 +38,6 @@ use std::default::Default as StdDefault; use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; -use syntax::edition; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; use syntax_pos::{MultiSpan, Span, symbol::Symbol}; @@ -69,10 +68,6 @@ pub struct LintStore { /// Map of registered lint groups to what lints they expand to. lint_groups: FxHashMap<&'static str, LintGroup>, - - /// Extra info for future incompatibility lints, describing the - /// issue or RFC that caused the incompatibility. - future_incompatible: FxHashMap, } /// Lints that are buffered up early on in the `Session` before the @@ -86,18 +81,6 @@ pub struct BufferedEarlyLint { pub diagnostic: BuiltinLintDiagnostics, } -/// Extra information for a future incompatibility lint. See the call -/// to `register_future_incompatible` in `librustc_lint/lib.rs` for -/// guidelines. -pub struct FutureIncompatibleInfo { - pub id: LintId, - /// e.g., a URL for an issue/PR/RFC or error code - pub reference: &'static str, - /// If this is an edition fixing lint, the edition in which - /// this lint becomes obsolete - pub edition: Option, -} - /// The target of the `by_name` map, which accounts for renaming/deprecation. enum TargetLint { /// A direct lint target @@ -152,7 +135,6 @@ impl LintStore { late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), - future_incompatible: Default::default(), lint_groups: Default::default(), } } @@ -198,36 +180,31 @@ impl LintStore { if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { bug!("duplicate specification of lint {}", lint.name_lower()) } - } - } - pub fn register_future_incompatible(&mut self, - lints: Vec) { + if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible { + if let Some(edition) = edition { + self.lint_groups.entry(edition.lint_name()) + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); + } - for edition in edition::ALL_EDITIONS { - let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) - .collect::>(); - if !lints.is_empty() { - self.register_group(false, edition.lint_name(), None, lints) + self.lint_groups.entry("future_incompatible") + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); } } - - let mut future_incompatible = Vec::with_capacity(lints.len()); - for lint in lints { - future_incompatible.push(lint.id); - self.future_incompatible.insert(lint.id, lint); - } - - self.register_group( - false, - "future_incompatible", - None, - future_incompatible, - ); } - pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> { - self.future_incompatible.get(&id) + pub fn future_incompatible(&self, id: LintId) -> Option { + id.lint.future_incompatible } pub fn register_group_alias( diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 76e6a28008a37..ba7ec0ed6e484 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -45,7 +45,7 @@ use syntax_pos::Span; pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore, check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult, - FutureIncompatibleInfo, BufferedEarlyLint,}; + BufferedEarlyLint,}; /// Specification of a single lint. #[derive(Copy, Clone, Debug)] @@ -77,9 +77,21 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + pub future_incompatible: Option, + pub is_plugin: bool, } +/// Extra information for a future incompatibility lint. +#[derive(Copy, Clone, Debug)] +pub struct FutureIncompatibleInfo { + /// e.g., a URL for an issue/PR/RFC or error code + pub reference: &'static str, + /// If this is an edition fixing lint, the edition in which + /// this lint becomes obsolete + pub edition: Option, +} + impl Lint { pub const fn default_fields_for_macro() -> Self { Lint { @@ -89,6 +101,7 @@ impl Lint { edition_lint_opts: None, is_plugin: false, report_in_external_macro: false, + future_incompatible: None, } } @@ -122,7 +135,8 @@ macro_rules! declare_lint { $vis $NAME, $Level, $desc, ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, + $(@future_incompatible = $fi:expr;)? $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, @@ -130,6 +144,7 @@ macro_rules! declare_lint { edition_lint_opts: None, is_plugin: false, $($v: true,)* + $(future_incompatible: Some($fi),)* ..$crate::lint::Lint::default_fields_for_macro() }; ); @@ -171,6 +186,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + future_incompatible: None, is_plugin: true, }; ); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2997e1d2ca942..bce04471cec48 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -27,6 +27,7 @@ use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx}; use rustc::{lint, util}; +use rustc::lint::FutureIncompatibleInfo; use hir::Node; use util::nodemap::HirIdSet; use lint::{LateContext, LintContext, LintArray}; @@ -601,7 +602,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { declare_lint! { pub ANONYMOUS_PARAMETERS, Allow, - "detects anonymous parameters" + "detects anonymous parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41686 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( @@ -1423,7 +1428,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { declare_lint! { pub KEYWORD_IDENTS, Allow, - "detects edition keywords being used as an identifier" + "detects edition keywords being used as an identifier", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #49716 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0026c2317d156..c83074c95ca0a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -33,13 +33,11 @@ use rustc::lint; use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, - ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, - parser::ILL_FORMED_ATTRIBUTE_INPUT, }; use rustc::hir; use rustc::hir::def_id::DefId; @@ -47,11 +45,9 @@ use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use syntax::ast; -use syntax::edition::Edition; use syntax_pos::Span; use lint::LintId; -use lint::FutureIncompatibleInfo; use redundant_semicolon::*; use nonstandard_style::*; @@ -276,159 +272,6 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); - // Guidelines for creating a future incompatibility lint: - // - // - Create a lint defaulting to warn as normal, with ideally the same error - // message you would normally give - // - Add a suitable reference, typically an RFC or tracking issue. Go ahead - // and include the full URL, sort items in ascending order of issue numbers. - // - Later, change lint to error - // - Eventually, remove lint - store.register_future_incompatible(vec![ - FutureIncompatibleInfo { - id: LintId::of(PRIVATE_IN_PUBLIC), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), - reference: "issue #35203 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(DUPLICATE_MACRO_EXPORTS), - reference: "issue #35896 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(KEYWORD_IDENTS), - reference: "issue #49716 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_EXTERN_STATICS), - reference: "issue #36247 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), - reference: "issue #36887 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), - reference: "issue #37872 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), - reference: "issue #39207 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MISSING_FRAGMENT_SPECIFIER), - reference: "issue #40107 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), - reference: "issue #41620 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ANONYMOUS_PARAMETERS), - reference: "issue #41686 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), - reference: "issue #42238 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), - reference: "issue #42868 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_PACKED_BORROWS), - reference: "issue #46043 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS), - reference: "issue #56484 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(TYVAR_BEHIND_RAW_POINTER), - reference: "issue #46906 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(UNSTABLE_NAME_COLLISIONS), - reference: "issue #48919 ", - edition: None, - // Note: this item represents future incompatibility of all unstable functions in the - // standard library, and thus should never be removed or changed to an error. - }, - FutureIncompatibleInfo { - id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE), - reference: "issue #53130 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY), - reference: "issue #51443 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK), - reference: "issue #50504 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS), - reference: "issue #52234 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILL_FORMED_ATTRIBUTE_INPUT), - reference: "issue #57571 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS), - reference: "issue #57644 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(NESTED_IMPL_TRAIT), - reference: "issue #59014 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT), - reference: "issue #59159 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INDIRECT_STRUCTURAL_MATCH), - reference: "issue #62411 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SOFT_UNSTABLE), - reference: "issue #64266 ", - edition: None, - }, - ]); - // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths"); From c4475c753b252060dbc76a73b83159484992bf06 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:51:18 -0400 Subject: [PATCH 13/35] Access future incompatibility information directly Avoid querying LintStore when not necessary --- src/librustc/lint/context.rs | 4 ---- src/librustc/lint/mod.rs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 97b9f21163dbe..4146606d443ec 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -203,10 +203,6 @@ impl LintStore { } } - pub fn future_incompatible(&self, id: LintId) -> Option { - id.lint.future_incompatible - } - pub fn register_group_alias( &mut self, lint_name: &'static str, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ba7ec0ed6e484..e3219b717905a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -672,9 +672,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, }; // Check for future incompatibility lints and issue a stronger warning. - let lints = sess.lint_store.borrow(); let lint_id = LintId::of(lint); - let future_incompatible = lints.future_incompatible(lint_id); + let future_incompatible = lint.future_incompatible; // If this code originates in a foreign macro, aka something that this crate // did not itself author, then it's likely that there's nothing this crate From da56d1d20113355047f5e6e3d5686ea1c7589d99 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 08:46:11 -0400 Subject: [PATCH 14/35] Remove all borrows of lint store from Session from librustc Access through tcx is fine -- by that point, the lint store is frozen, but direct access through Session will go away in future commits, as lint store is still mutable in early stages of Session, and will be removed completely. --- src/librustc/lint/context.rs | 21 +++++++++++++-------- src/librustc/lint/levels.rs | 16 +++++++--------- src/librustc/lint/mod.rs | 15 +++++++++------ src/librustc_interface/passes.rs | 9 ++++++++- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4146606d443ec..515d4d3cd7272 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -480,7 +480,7 @@ pub struct EarlyContext<'a> { builder: LintLevelsBuilder<'a>, /// The store of registered lints and the lint levels. - lint_store: ReadGuard<'a, LintStore>, + lint_store: &'a LintStore, buffered: LintBuffer, } @@ -569,14 +569,15 @@ pub trait LintContext: Sized { impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, + lint_store: &'a LintStore, krate: &'a ast::Crate, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { sess, krate, - lint_store: sess.lint_store.borrow(), - builder: LintLevelSets::builder(sess), + lint_store, + builder: LintLevelSets::builder(sess, lint_store), buffered, } } @@ -611,7 +612,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { f: F) where F: FnOnce(&mut Self) { - let push = self.context.builder.push(attrs); + let push = self.context.builder.push(attrs, &self.context.lint_store); self.check_id(id); self.enter_attrs(attrs); f(self); @@ -1473,12 +1474,13 @@ early_lint_methods!(early_lint_pass_impl, []); fn early_lint_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pass: T, buffered: LintBuffer, ) -> LintBuffer { let mut cx = EarlyContextAndPass { - context: EarlyContext::new(sess, krate, buffered), + context: EarlyContext::new(sess, lint_store, krate, buffered), pass, }; @@ -1497,28 +1499,30 @@ fn early_lint_crate( pub fn check_ast_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pre_expansion: bool, builtin_lints: T, ) { let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), + lint_store.pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), + lint_store.early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; if !sess.opts.debugging_opts.no_interleave_lints { - buffered = early_lint_crate(sess, krate, builtin_lints, buffered); + buffered = early_lint_crate(sess, lint_store, krate, builtin_lints, buffered); if !passes.is_empty() { buffered = early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: &mut passes[..] }, buffered, @@ -1529,6 +1533,7 @@ pub fn check_ast_crate( buffered = time(sess, &format!("running lint: {}", pass.name()), || { early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: slice::from_mut(pass) }, buffered, diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 60b1b192d10db..36c7c5b20fded 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -3,7 +3,7 @@ use std::cmp; use crate::hir::HirId; use crate::ich::StableHashingContext; use crate::lint::builtin; -use crate::lint::context::CheckLintNameResult; +use crate::lint::context::{LintStore, CheckLintNameResult}; use crate::lint::{self, Lint, LintId, Level, LintSource}; use crate::session::Session; use crate::util::nodemap::FxHashMap; @@ -35,21 +35,20 @@ enum LintSet { } impl LintLevelSets { - pub fn new(sess: &Session) -> LintLevelSets { + pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets { let mut me = LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid, }; - me.process_command_line(sess); + me.process_command_line(sess, lint_store); return me } - pub fn builder(sess: &Session) -> LintLevelsBuilder<'_> { - LintLevelsBuilder::new(sess, LintLevelSets::new(sess)) + pub fn builder<'a>(sess: &'a Session, store: &LintStore) -> LintLevelsBuilder<'a> { + LintLevelsBuilder::new(sess, LintLevelSets::new(sess, store)) } - fn process_command_line(&mut self, sess: &Session) { - let store = sess.lint_store.borrow(); + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { let mut specs = FxHashMap::default(); self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); @@ -186,9 +185,8 @@ impl<'a> LintLevelsBuilder<'a> { /// #[allow] /// /// Don't forget to call `pop`! - pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { + pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { let mut specs = FxHashMap::default(); - let store = self.sess.lint_store.borrow(); let sess = self.sess; let bad_attr = |span| { struct_span_err!(sess, span, E0452, "malformed lint attribute input") diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index e3219b717905a..ea06884d2c425 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -777,13 +777,15 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); + let store = tcx.sess.lint_store.borrow(); let mut builder = LintLevelMapBuilder { - levels: LintLevelSets::builder(tcx.sess), + levels: LintLevelSets::builder(tcx.sess, &store), tcx: tcx, + store: &*store, }; let krate = tcx.hir().krate(); - let push = builder.levels.push(&krate.attrs); + let push = builder.levels.push(&krate.attrs, &store); builder.levels.register_id(hir::CRATE_HIR_ID); for macro_def in &krate.exported_macros { builder.levels.register_id(macro_def.hir_id); @@ -794,19 +796,20 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { tcx.arena.alloc(builder.levels.build_map()) } -struct LintLevelMapBuilder<'tcx> { +struct LintLevelMapBuilder<'a, 'tcx> { levels: levels::LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, + store: &'a LintStore, } -impl LintLevelMapBuilder<'tcx> { +impl LintLevelMapBuilder<'_, '_> { fn with_lint_attrs(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F) where F: FnOnce(&mut Self) { - let push = self.levels.push(attrs); + let push = self.levels.push(attrs, self.store); if push.changed { self.levels.register_id(id); } @@ -815,7 +818,7 @@ impl LintLevelMapBuilder<'tcx> { } } -impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { +impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> { intravisit::NestedVisitorMap::All(&self.tcx.hir()) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index fdea437d37fbc..2fd7b2507a786 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -329,6 +329,7 @@ fn configure_and_expand_inner<'a>( time(sess, "pre-AST-expansion lint checks", || { lint::check_ast_crate( sess, + &*sess.lint_store.borrow(), &krate, true, rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); @@ -556,7 +557,13 @@ pub fn lower_to_hir( }); time(sess, "early lint checks", || { - lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new()) + lint::check_ast_crate( + sess, + &*sess.lint_store.borrow(), + &krate, + false, + rustc_lint::BuiltinCombinedEarlyLintPass::new(), + ) }); // Discard hygiene data, which isn't required after lowering to HIR. From dab3bd6cda23064e6726bd046c903096ef03cbd0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 09:53:13 -0400 Subject: [PATCH 15/35] Create lint store during plugin registration Remove lint store from Session --- Cargo.lock | 1 + src/librustc/lint/context.rs | 16 +++++----- src/librustc/lint/mod.rs | 4 +-- src/librustc/session/mod.rs | 11 +++---- src/librustc/ty/context.rs | 4 +++ src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/lib.rs | 18 +++++++---- src/librustc_interface/passes.rs | 38 ++++++++++------------- src/librustc_interface/queries.rs | 21 +++++++++---- src/librustc_interface/util.rs | 7 ----- src/librustc_lint/lib.rs | 15 ++++++++-- src/librustc_plugin/registry.rs | 50 ++++--------------------------- 12 files changed, 83 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5a7521abde13..04181e197258d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3483,6 +3483,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_interface", + "rustc_lint", "rustc_metadata", "rustc_mir", "rustc_plugin", diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 515d4d3cd7272..8208cc26ed30c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -452,7 +452,7 @@ pub struct LateContext<'a, 'tcx> { pub access_levels: &'a AccessLevels, /// The store of registered lints and the lint levels. - lint_store: ReadGuard<'a, LintStore>, + lint_store: &'tcx LintStore, last_node_with_lint_attrs: hir::HirId, @@ -1320,7 +1320,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: tcx.sess.lint_store.borrow(), + lint_store: &tcx.lint_store, last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(), generics: None, only_module: true, @@ -1352,7 +1352,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); - let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes + let mut passes: Vec<_> = tcx.lint_store.late_module_passes .iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { @@ -1370,7 +1370,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc tables: &ty::TypeckTables::empty(None), param_env: ty::ParamEnv::empty(), access_levels, - lint_store: tcx.sess.lint_store.borrow(), + lint_store: &tcx.lint_store, last_node_with_lint_attrs: hir::CRATE_HIR_ID, generics: None, only_module: false, @@ -1394,7 +1394,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.sess.lint_store.borrow() + let mut passes = tcx.lint_store .late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { @@ -1410,7 +1410,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } - let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes + let mut passes: Vec<_> = tcx.lint_store.late_module_passes .iter().map(|pass| (pass)()).collect(); for pass in &mut passes { @@ -1571,7 +1571,7 @@ impl Decodable for LintId { fn decode(d: &mut D) -> Result { let s = d.read_str()?; ty::tls::with(|tcx| { - match tcx.sess.lint_store.borrow().find_lints(&s) { + match tcx.lint_store.find_lints(&s) { Ok(ids) => { if ids.len() != 0 { panic!("invalid lint-id `{}`", s); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ea06884d2c425..3c35bdae66e9d 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -777,11 +777,11 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { assert_eq!(cnum, LOCAL_CRATE); - let store = tcx.sess.lint_store.borrow(); + let store = &tcx.lint_store; let mut builder = LintLevelMapBuilder { levels: LintLevelSets::builder(tcx.sess, &store), tcx: tcx, - store: &*store, + store: store, }; let krate = tcx.hir().krate(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b65bf2230b39d..bd2460cfab116 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported}; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ - self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering, + self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering, Ordering::SeqCst, }; @@ -77,9 +77,11 @@ pub struct Session { /// if the value stored here has been affected by path remapping. pub working_dir: (PathBuf, bool), - // FIXME: `lint_store` and `buffered_lints` are not thread-safe, - // but are only used in a single thread. - pub lint_store: RwLock, + /// This is intended to be used from a single thread. + /// + /// FIXME: there was a previous comment about this not being thread safe, + /// but it's not clear how or why that's the case. The LintBuffer itself is certainly thread + /// safe at least from a "Rust safety" standpoint. pub buffered_lints: Lock>, /// Set of `(DiagnosticId, Option, message)` tuples tracking @@ -1213,7 +1215,6 @@ fn build_session_( sysroot, local_crate_source_file, working_dir, - lint_store: RwLock::new(lint::LintStore::new()), buffered_lints: Lock::new(Some(Default::default())), one_time_diagnostics: Default::default(), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 256194cfb00ef..a70ff37b7a04c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1035,6 +1035,8 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, + pub lint_store: Lrc, + pub dep_graph: DepGraph, pub prof: SelfProfilerRef, @@ -1199,6 +1201,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, + lint_store: Lrc, cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, @@ -1268,6 +1271,7 @@ impl<'tcx> TyCtxt<'tcx> { GlobalCtxt { sess: s, + lint_store, cstore, arena: WorkerLocal::new(|_| Arena::default()), interners, diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index aa74966d0ab4c..a9e4e6db1c75f 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -16,6 +16,7 @@ log = "0.4" env_logger = { version = "0.7", default-features = false } rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } +rustc_lint = { path = "../librustc_lint" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5af1e8faccc8f..8793b7f5130a0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -202,9 +202,13 @@ pub fn run_compiler( interface::run_compiler(config, |compiler| { let sopts = &compiler.session().opts; if sopts.describe_lints { + let lint_store = rustc_lint::new_lint_store( + sopts.debugging_opts.no_interleave_lints, + compiler.session().unstable_options(), + ); describe_lints( compiler.session(), - &*compiler.session().lint_store.borrow(), + &lint_store, false ); return; @@ -321,12 +325,14 @@ pub fn run_compiler( return sess.compile_status(); } - compiler.register_plugins()?; + { + let (_, _, lint_store) = &*compiler.register_plugins()?.peek(); - // Lint plugins are registered; now we can process command line flags. - if sess.opts.describe_lints { - describe_lints(&sess, &sess.lint_store.borrow(), true); - return sess.compile_status(); + // Lint plugins are registered; now we can process command line flags. + if sess.opts.describe_lints { + describe_lints(&sess, &lint_store, true); + return sess.compile_status(); + } } compiler.expansion()?; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2fd7b2507a786..f9efd00f6983c 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -117,6 +117,7 @@ declare_box_region_type!( /// Returns `None` if we're aborting after handling -W help. pub fn configure_and_expand( sess: Lrc, + lint_store: Lrc, cstore: Lrc, krate: ast::Crate, crate_name: &str, @@ -134,6 +135,7 @@ pub fn configure_and_expand( let resolver_arenas = Resolver::arenas(); let res = configure_and_expand_inner( sess, + &lint_store, &*cstore, krate, &crate_name, @@ -227,7 +229,7 @@ pub fn register_plugins<'a>( cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, -) -> Result<(ast::Crate, PluginInfo)> { +) -> Result<(ast::Crate, PluginInfo, Lrc)> { krate = time(sess, "attributes injection", || { syntax_ext::cmdline_attrs::inject( krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr @@ -278,7 +280,12 @@ pub fn register_plugins<'a>( ) }); - let mut registry = Registry::new(sess, krate.span); + let mut lint_store = rustc_lint::new_lint_store( + sess.opts.debugging_opts.no_interleave_lints, + sess.unstable_options(), + ); + + let mut registry = Registry::new(sess, &mut lint_store, krate.span); time(sess, "plugin registration", || { for registrar in registrars { @@ -289,36 +296,20 @@ pub fn register_plugins<'a>( let Registry { syntax_exts, - early_lint_passes, - late_lint_passes, - lints, - lint_groups, llvm_passes, attributes, .. } = registry; - let mut ls = sess.lint_store.borrow_mut(); - ls.register_lints(&lints); - for pass in early_lint_passes { - ls.register_early_pass(pass); - } - for pass in late_lint_passes { - ls.register_late_pass(pass); - } - - for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(true, name, deprecated_name, to); - } - *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; *sess.plugin_attributes.borrow_mut() = attributes; - Ok((krate, PluginInfo { syntax_exts })) + Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store))) } fn configure_and_expand_inner<'a>( sess: &'a Session, + lint_store: &'a lint::LintStore, cstore: &'a CStore, mut krate: ast::Crate, crate_name: &str, @@ -329,7 +320,7 @@ fn configure_and_expand_inner<'a>( time(sess, "pre-AST-expansion lint checks", || { lint::check_ast_crate( sess, - &*sess.lint_store.borrow(), + lint_store, &krate, true, rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); @@ -539,6 +530,7 @@ fn configure_and_expand_inner<'a>( pub fn lower_to_hir( sess: &Session, + lint_store: &lint::LintStore, cstore: &CStore, resolver: &mut Resolver<'_>, dep_graph: &DepGraph, @@ -559,7 +551,7 @@ pub fn lower_to_hir( time(sess, "early lint checks", || { lint::check_ast_crate( sess, - &*sess.lint_store.borrow(), + lint_store, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new(), @@ -826,6 +818,7 @@ impl BoxedGlobalCtxt { pub fn create_global_ctxt( compiler: &Compiler, + lint_store: Lrc, mut hir_forest: hir::map::Forest, defs: hir::map::Definitions, resolutions: Resolutions, @@ -863,6 +856,7 @@ pub fn create_global_ctxt( let gcx = TyCtxt::create_global_ctxt( sess, + lint_store, cstore, local_providers, extern_providers, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index cd72dc9453c7e..bb1221ead98bc 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,9 +2,11 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo}; use rustc_incremental::DepGraphFuture; +use rustc_data_structures::sync::Lrc; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; +use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; use rustc::dep_graph::DepGraph; @@ -74,8 +76,8 @@ pub(crate) struct Queries { dep_graph_future: Query>, parse: Query, crate_name: Query, - register_plugins: Query<(ast::Crate, PluginInfo)>, - expansion: Query<(ast::Crate, Steal>>)>, + register_plugins: Query<(ast::Crate, PluginInfo, Lrc)>, + expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, lower_to_hir: Query<(Steal, ExpansionResult)>, prepare_outputs: Query, @@ -106,7 +108,7 @@ impl Compiler { }) } - pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> { + pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc)>> { self.queries.register_plugins.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); @@ -148,17 +150,20 @@ impl Compiler { pub fn expansion( &self - ) -> Result<&Query<(ast::Crate, Steal>>)>> { + ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { self.queries.expansion.compute(|| { let crate_name = self.crate_name()?.peek().clone(); - let (krate, plugin_info) = self.register_plugins()?.take(); + let (krate, plugin_info, lint_store) = self.register_plugins()?.take(); passes::configure_and_expand( self.sess.clone(), + lint_store.clone(), self.cstore().clone(), krate, &crate_name, plugin_info, - ).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver))))) + ).map(|(krate, resolver)| { + (krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store) + }) }) } @@ -185,9 +190,11 @@ impl Compiler { let peeked = expansion_result.peek(); let krate = &peeked.0; let resolver = peeked.1.steal(); + let lint_store = &peeked.2; let hir = Steal::new(resolver.borrow_mut().access(|resolver| { passes::lower_to_hir( self.session(), + lint_store, self.cstore(), resolver, &*self.dep_graph()?.peek(), @@ -212,11 +219,13 @@ impl Compiler { self.queries.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); + let lint_store = self.expansion()?.peek().2.clone(); let hir = self.lower_to_hir()?; let hir = hir.peek(); let (ref hir_forest, ref expansion) = *hir; Ok(passes::create_global_ctxt( self, + lint_store, hir_forest.steal(), expansion.defs.steal(), expansion.resolutions.steal(), diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 005f1a44acd6a..8f11dc9372728 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -13,7 +13,6 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc_errors::registry::Registry; -use rustc_lint; use rustc_metadata::dynamic_lib::DynamicLibrary; use rustc_mir; use rustc_passes; @@ -108,12 +107,6 @@ pub fn create_session( let codegen_backend = get_codegen_backend(&sess); - rustc_lint::register_builtins(&mut sess.lint_store.get_mut(), - sess.opts.debugging_opts.no_interleave_lints); - if sess.unstable_options() { - rustc_lint::register_internals(&mut sess.lint_store.get_mut()); - } - let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); add_configuration(&mut cfg, &sess, &*codegen_backend); sess.parse_sess.config = cfg; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c83074c95ca0a..3c2396f6cdb07 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -189,10 +189,21 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]) late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]); +pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore { + let mut lint_store = lint::LintStore::new(); + + register_builtins(&mut lint_store, no_interleave_lints); + if internal_lints { + register_internals(&mut lint_store); + } + + lint_store +} + /// Tell the `LintStore` about all the built-in lints (the ones /// defined in this crate and the ones defined in /// `rustc::lint::builtin`). -pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { +fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { ($name:expr, $($lint:ident),*) => ( store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); @@ -327,7 +338,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } -pub fn register_internals(store: &mut lint::LintStore) { +fn register_internals(store: &mut lint::LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 44318bf06aaaf..223956a4f5e3f 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -1,8 +1,7 @@ //! Used by plugin crates to tell `rustc` about the plugins they provide. -use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint}; +use rustc::lint::LintStore; use rustc::session::Session; -use rustc::util::nodemap::FxHashMap; use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension}; use syntax_expand::base::MacroExpanderFn; @@ -26,6 +25,8 @@ pub struct Registry<'a> { /// from the plugin registrar. pub sess: &'a Session, + pub lint_store: &'a mut LintStore, + #[doc(hidden)] pub args_hidden: Option>, @@ -35,18 +36,6 @@ pub struct Registry<'a> { #[doc(hidden)] pub syntax_exts: Vec, - #[doc(hidden)] - pub early_lint_passes: Vec EarlyLintPassObject>, - - #[doc(hidden)] - pub late_lint_passes: Vec LateLintPassObject>, - - #[doc(hidden)] - pub lints: Vec<&'static Lint>, - - #[doc(hidden)] - pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, - #[doc(hidden)] pub llvm_passes: Vec, @@ -56,16 +45,13 @@ pub struct Registry<'a> { impl<'a> Registry<'a> { #[doc(hidden)] - pub fn new(sess: &'a Session, krate_span: Span) -> Registry<'a> { + pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> { Registry { sess, + lint_store, args_hidden: None, krate_span, syntax_exts: vec![], - lints: vec![], - early_lint_passes: vec![], - late_lint_passes: vec![], - lint_groups: FxHashMap::default(), llvm_passes: vec![], attributes: vec![], } @@ -103,32 +89,6 @@ impl<'a> Registry<'a> { self.register_syntax_extension(Symbol::intern(name), ext); } - /// Register a compiler lint pass. - pub fn register_lints(&mut self, lints: &[&'static Lint]) { - self.lints.extend(lints); - } - - /// Register a compiler lint pass. - pub fn register_early_lint_pass(&mut self, lint_pass: fn() -> EarlyLintPassObject) { - self.early_lint_passes.push(lint_pass); - } - - /// Register a compiler lint pass. - pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) { - self.late_lint_passes.push(lint_pass); - } - /// Register a lint group. - pub fn register_lint_group( - &mut self, - name: &'static str, - deprecated_name: Option<&'static str>, - to: Vec<&'static Lint> - ) { - self.lint_groups.insert(name, - (to.into_iter().map(|x| LintId::of(x)).collect(), - deprecated_name)); - } - /// Register an LLVM pass. /// /// Registration with LLVM itself is handled through static C++ objects with From b761367d52b30c86a7d404a64a3b2dd854cd7418 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 15:41:17 -0400 Subject: [PATCH 16/35] Fix test fallout --- .../auxiliary/issue-40001-plugin.rs | 7 +++--- .../auxiliary/lint-for-crate-rpass.rs | 24 +++++++++---------- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 6 ++--- .../auxiliary/lint-group-plugin-test.rs | 8 ++++--- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 6 ++--- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 8 ++++--- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index bb0ebf693d0be..6b914f501ca79 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -15,15 +15,14 @@ use syntax::symbol::Symbol; use rustc::hir; use rustc::hir::intravisit; -use rustc::hir::map as hir_map; use hir::Node; use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use rustc::ty; -use syntax::{ast, source_map}; +use syntax::source_map; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box MissingWhitelistedAttrPass); + reg.lint_store.register_lints(&[&MISSING_WHITELISTED_ATTR]); + reg.lint_store.register_late_pass(|| box MissingWhitelistedAttrPass); reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 17386d7e1aa5f..6874c921c1cc1 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -7,24 +7,20 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; use syntax::symbol::Symbol; macro_rules! fake_lint_pass { - ($struct:ident, $lints:expr, $($attr:expr),*) => { + ($struct:ident, $($attr:expr),*) => { struct $struct; impl LintPass for $struct { fn name(&self) -> &'static str { stringify!($struct) } - - fn get_lints(&self) -> LintArray { - $lints - } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { @@ -49,25 +45,29 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); fake_lint_pass! { PassOkay, - lint_array!(CRATE_NOT_OKAY), // Single lint Symbol::intern("rustc_crate_okay") } fake_lint_pass! { PassRedBlue, - lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") } fake_lint_pass! { PassGreyGreen, - lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") } #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box PassOkay); - reg.register_late_lint_pass(box PassRedBlue); - reg.register_late_lint_pass(box PassGreyGreen); + reg.lint_store.register_lints(&[ + &CRATE_NOT_OKAY, + &CRATE_NOT_RED, + &CRATE_NOT_BLUE, + &CRATE_NOT_GREY, + &CRATE_NOT_GREEN, + ]); + reg.lint_store.register_late_pass(|| box PassOkay); + reg.lint_store.register_late_pass(|| box PassRedBlue); + reg.lint_store.register_late_pass(|| box PassGreyGreen); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index ba5b5d1906aea..1cd3e7b28dba7 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -7,7 +7,7 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; @@ -32,6 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint(&[&CRATE_NOT_OKAY]); - reg.register_late_lint_pass(|| box Pass); + reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]); + reg.lint_store.register_late_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index a377b07bd3dd2..cb793b4349885 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -9,7 +9,7 @@ extern crate rustc; extern crate rustc_driver; use rustc::hir; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray, LintId}; use rustc_driver::plugin::Registry; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -30,6 +30,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); - reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]); + reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]); + reg.lint_store.register_late_pass(|| box Pass); + reg.lint_store.register_group(true, "lint_me", None, + vec![LintId::of(&TEST_LINT), LintId::of(&PLEASE_LINT)]); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 02675191f785e..40c37eb570e2d 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -10,8 +10,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, - EarlyLintPassObject, LintArray}; +use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray}; use rustc_driver::plugin::Registry; use syntax::ast; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -28,5 +27,6 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass as EarlyLintPassObject); + reg.lint_store.register_lints(&[&TEST_LINT]); + reg.lint_store.register_early_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 40f8d490ac87c..67135d595f448 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -8,7 +8,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId}; use rustc_driver::plugin::Registry; use syntax::ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); @@ -40,6 +40,8 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass); - reg.register_lint_group("clippy::group", Some("clippy_group"), vec![TEST_LINT, TEST_GROUP]); + reg.lint_store.register_lints(&[&TEST_RUSTC_TOOL_LINT, &TEST_LINT, &TEST_GROUP]); + reg.lint_store.register_early_pass(|| box Pass); + reg.lint_store.register_group(true, "clippy::group", Some("clippy_group"), + vec![LintId::of(&TEST_LINT), LintId::of(&TEST_GROUP)]); } From 6be0a7081a9aafc4e0b39cae266fbed5eabd8993 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 10 Oct 2019 19:33:00 -0400 Subject: [PATCH 17/35] Update API to be more compatible with plugin needs Move to using Box ...> so that we can let plugins register state. This also adds a callback that'll get called from plugin registration so that Clippy and other tools can register lints without using the plugin API. The plugin API still works, but this new API is more compatible with drivers other than rustc. --- src/librustc/lint/context.rs | 30 +++++++++++-------- src/librustc_driver/lib.rs | 3 ++ src/librustc_interface/interface.rs | 4 +++ src/librustc_interface/passes.rs | 3 ++ src/librustc_interface/queries.rs | 7 +++++ src/librustdoc/core.rs | 1 + src/librustdoc/test.rs | 1 + src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 8208cc26ed30c..2a0cdba50cb5f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -57,11 +57,11 @@ pub struct LintStore { /// interior mutability, we don't enforce this (and lints should, in theory, /// be compatible with being constructed more than once, though not /// necessarily in a sane manner. This is safe though.) - pre_expansion_passes: Vec EarlyLintPassObject>, - early_passes: Vec EarlyLintPassObject>, - late_passes: Vec LateLintPassObject>, + pre_expansion_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + early_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + late_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// This is unique in that we construct them per-module, so not once. - late_module_passes: Vec LateLintPassObject>, + late_module_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// Lints indexed by name. by_name: FxHashMap, @@ -155,20 +155,24 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.push(pass); + pub fn register_early_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.push(pass); + pub fn register_pre_expansion_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.push(pass); + pub fn register_late_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_module_passes.push(Box::new(pass)); } // Helper method for register_early/late_pass diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8793b7f5130a0..2cf1552ed9683 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation { @@ -182,6 +183,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); config @@ -259,6 +261,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index b26bd75c974c6..34ec3c862a3e4 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -34,6 +34,7 @@ pub struct Compiler { pub(crate) queries: Queries, pub(crate) cstore: Lrc, pub(crate) crate_name: Option, + pub(crate) register_lints: Option>, } impl Compiler { @@ -80,6 +81,8 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + + pub register_lints: Option>, } pub fn run_compiler_in_existing_thread_pool(config: Config, f: F) -> R @@ -108,6 +111,7 @@ where output_file: config.output_file, queries: Default::default(), crate_name: config.crate_name, + register_lints: config.register_lints, }; let _sess_abort_error = OnDrop(|| { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index f9efd00f6983c..2044b73db8aa9 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -227,6 +227,7 @@ pub struct PluginInfo { pub fn register_plugins<'a>( sess: &'a Session, cstore: &'a CStore, + register_lints: impl Fn(&Session, &mut lint::LintStore), mut krate: ast::Crate, crate_name: &str, ) -> Result<(ast::Crate, PluginInfo, Lrc)> { @@ -285,6 +286,8 @@ pub fn register_plugins<'a>( sess.unstable_options(), ); + (register_lints)(&sess, &mut lint_store); + let mut registry = Registry::new(sess, &mut lint_store, krate.span); time(sess, "plugin registration", || { diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index bb1221ead98bc..84648ca8326fb 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -6,6 +6,8 @@ use rustc_data_structures::sync::Lrc; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; +use rustc::lint; +use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; @@ -113,9 +115,14 @@ impl Compiler { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); + let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), self.cstore(), + self.register_lints + .as_ref() + .map(|p| &**p) + .unwrap_or_else(|| empty), krate, &crate_name, ); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2a468d679a887..be6404b869760 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,6 +338,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt stderr: None, crate_name, lint_caps, + register_lints: None, }; interface::run_compiler_in_existing_thread_pool(config, |compiler| { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0be6340df96e8..03e37967c4b58 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -77,6 +77,7 @@ pub fn run(options: Options) -> i32 { stderr: None, crate_name: options.crate_name.clone(), lint_caps: Default::default(), + register_lints: None, }; let mut test_args = options.test_args.clone(); diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index e290f7fa6b13a..9582137eae91c 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -59,6 +59,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; interface::run_compiler(config, |compiler| { From c290293cf291951825b10830df4bce3bc03aabef Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 16 Oct 2019 10:33:16 +1100 Subject: [PATCH 18/35] Derive `Rustc{En,De}codable` for `TokenStream`. `TokenStream` used to be a complex type, but it is now just a newtype around a `Lrc>`. Currently it uses custom encoding that discards the `IsJoint` and custom decoding that adds `NonJoint` back in for every token tree. This requires building intermediate `Vec`s. This commit makes `TokenStream` derive `Rustc{En,De}codable`. This simplifies the code, and avoids the creation of the intermediate vectors, saving up to 3% on various benchmarks. It also changes the AST JSON output in one test. --- src/libsyntax/tokenstream.rs | 17 ++--------------- src/test/ui/ast-json/ast-json-output.stdout | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index ac155556cdae2..0559f224f1f4b 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -19,7 +19,6 @@ use syntax_pos::{BytePos, Span, DUMMY_SP}; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; use rustc_data_structures::sync::Lrc; -use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use smallvec::{SmallVec, smallvec}; use std::{iter, mem}; @@ -136,7 +135,7 @@ impl TokenTree { /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s /// instead of a representation of the abstract syntax tree. /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, RustcEncodable, RustcDecodable)] pub struct TokenStream(pub Lrc>); pub type TreeAndJoint = (TokenTree, IsJoint); @@ -145,7 +144,7 @@ pub type TreeAndJoint = (TokenTree, IsJoint); #[cfg(target_arch = "x86_64")] static_assert_size!(TokenStream, 8); -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)] pub enum IsJoint { Joint, NonJoint @@ -460,18 +459,6 @@ impl Cursor { } } -impl Encodable for TokenStream { - fn encode(&self, encoder: &mut E) -> Result<(), E::Error> { - self.trees().collect::>().encode(encoder) - } -} - -impl Decodable for TokenStream { - fn decode(decoder: &mut D) -> Result { - Vec::::decode(decoder).map(|vec| vec.into_iter().collect()) - } -} - #[derive(Debug, Copy, Clone, PartialEq, RustcEncodable, RustcDecodable)] pub struct DelimSpan { pub open: Span, diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout index 563885133a4c1..64c9f69311582 100644 --- a/src/test/ui/ast-json/ast-json-output.stdout +++ b/src/test/ui/ast-json/ast-json-output.stdout @@ -1 +1 @@ -{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"kind":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]}]}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}} +{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"kind":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":{"_field0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},"NonJoint"],[{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]},"NonJoint"]]}}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}} From 02edd14cde7d07a303ed2e7d2b233890f02033c1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Oct 2019 13:22:50 +1100 Subject: [PATCH 19/35] Convert some `InternedString`s to `Symbols`. This avoids the needs for various conversions, and makes the code slightly faster, because `Symbol` comparisons and hashing is faster. --- src/librustc/hir/mod.rs | 6 ++-- src/librustc/infer/mod.rs | 4 +-- src/librustc/infer/type_variable.rs | 4 +-- src/librustc/infer/unify_key.rs | 4 +-- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/object_safety.rs | 4 +-- src/librustc/traits/on_unimplemented.rs | 4 +-- src/librustc/traits/structural_impls.rs | 10 +++---- src/librustc/ty/context.rs | 8 +++--- src/librustc/ty/mod.rs | 4 +-- src/librustc/ty/print/pretty.rs | 28 +++++++++---------- src/librustc/ty/sty.rs | 18 ++++++------ .../debuginfo/metadata.rs | 4 +-- src/librustc_codegen_llvm/debuginfo/mod.rs | 4 +-- .../error_reporting/region_name.rs | 14 +++++----- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_typeck/astconv.rs | 6 ++-- src/librustc_typeck/check/intrinsic.rs | 6 ++-- src/librustc_typeck/collect.rs | 18 ++++++------ src/librustdoc/clean/mod.rs | 2 +- 21 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 568e051aaf08f..cd111ab9f9493 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -19,7 +19,7 @@ use crate::ty::query::Providers; use crate::util::nodemap::{NodeMap, FxHashSet}; use errors::FatalError; -use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan}; +use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use syntax::source_map::Spanned; use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect}; use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy}; @@ -628,9 +628,9 @@ impl Generics { own_counts } - pub fn get_named(&self, name: InternedString) -> Option<&GenericParam> { + pub fn get_named(&self, name: Symbol) -> Option<&GenericParam> { for param in &self.params { - if name == param.name.ident().as_interned_str() { + if name == param.name.ident().name { return Some(param); } } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index af74d13572431..61e49d32fcdd9 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -32,7 +32,7 @@ use std::cell::{Cell, Ref, RefCell, RefMut}; use std::collections::BTreeMap; use std::fmt; use syntax::ast; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use syntax_pos::Span; use self::combine::CombineFields; @@ -392,7 +392,7 @@ pub enum RegionVariableOrigin { Coercion(Span), /// Region variables created as the values for early-bound regions - EarlyBoundRegion(Span, InternedString), + EarlyBoundRegion(Span, Symbol), /// Region variables created for bound regions /// in a function or method that is called diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index ce1b54bb1c81d..f79a30c7ae8f3 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -1,4 +1,4 @@ -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use syntax_pos::Span; use crate::ty::{self, Ty, TyVid}; @@ -49,7 +49,7 @@ pub enum TypeVariableOriginKind { MiscVariable, NormalizeProjectionType, TypeInference, - TypeParameterDefinition(InternedString), + TypeParameterDefinition(Symbol), /// One of the upvars or closure kind parameters in a `ClosureSubsts` /// (before it has been determined). diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs index 846611db05427..b0b6d971c6087 100644 --- a/src/librustc/infer/unify_key.rs +++ b/src/librustc/infer/unify_key.rs @@ -3,7 +3,7 @@ use crate::mir::interpret::ConstValue; use rustc_data_structures::unify::{NoError, EqUnifyValue, UnifyKey, UnifyValue, UnificationTable}; use rustc_data_structures::unify::InPlace; use syntax_pos::{Span, DUMMY_SP}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use std::cmp; use std::marker::PhantomData; @@ -90,7 +90,7 @@ pub struct ConstVariableOrigin { pub enum ConstVariableOriginKind { MiscVariable, ConstInference, - ConstParameterDefinition(InternedString), + ConstParameterDefinition(Symbol), SubstitutionPlaceholder, } diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index daa4a215a238a..ae604b9eb13a6 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -406,7 +406,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }, GenericParamDefKind::Lifetime => continue, }; - let name = param.name.as_symbol(); + let name = param.name; flags.push((name, Some(value))); } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index e0ef179911b6c..e42c3a63541cc 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -19,7 +19,7 @@ use crate::ty::subst::{Subst, InternalSubsts}; use std::borrow::Cow; use std::iter::{self}; use syntax::ast::{self}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -560,7 +560,7 @@ impl<'tcx> TyCtxt<'tcx> { // are implemented let unsized_self_ty: Ty<'tcx> = self.mk_ty_param( ::std::u32::MAX, - InternedString::intern("RustaceansAreAwesome"), + Symbol::intern("RustaceansAreAwesome"), ); // `Receiver[Self => U]` diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 5a988d9509e80..c1c814f9b0371 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -250,7 +250,7 @@ impl<'tcx> OnUnimplementedFormatString { Position::ArgumentNamed(s) if s == sym::from_desugaring => (), // So is `{A}` if A is a type parameter Position::ArgumentNamed(s) => match generics.params.iter().find(|param| { - param.name.as_symbol() == s + param.name == s }) { Some(_) => (), None => { @@ -289,7 +289,7 @@ impl<'tcx> OnUnimplementedFormatString { }, GenericParamDefKind::Lifetime => return None }; - let name = param.name.as_symbol(); + let name = param.name; Some((name, value)) }).collect::>(); let empty_string = String::new(); diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index dab62a6bcb5b1..2a53dcab8a9ff 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -4,7 +4,7 @@ use crate::traits; use crate::traits::project::Normalized; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::{self, Lift, Ty, TyCtxt}; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use std::fmt; use std::rc::Rc; @@ -261,11 +261,11 @@ impl fmt::Display for traits::QuantifierKind { /// for debug output in tests anyway. struct BoundNamesCollector { // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway. - regions: BTreeSet, + regions: BTreeSet, // Sort by `BoundVar` index, so usually this should be equivalent to the order given // by the list of type parameters. - types: BTreeMap, + types: BTreeMap, binder_index: ty::DebruijnIndex, } @@ -319,7 +319,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { match bound_ty.kind { ty::BoundTyKind::Param(name) => name, ty::BoundTyKind::Anon => - InternedString::intern(&format!("^{}", bound_ty.var.as_u32()), + Symbol::intern(&format!("^{}", bound_ty.var.as_u32()), ), } ); @@ -340,7 +340,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector { } ty::BoundRegion::BrAnon(var) => { - self.regions.insert(InternedString::intern(&format!("'^{}", var))); + self.regions.insert(Symbol::intern(&format!("'^{}", var))); } _ => (), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 665d4c2d0696a..d34e8d6872085 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -72,7 +72,7 @@ use syntax::ast; use syntax::attr; use syntax::source_map::MultiSpan; use syntax::feature_gate; -use syntax::symbol::{Symbol, InternedString, kw, sym}; +use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::Span; pub struct AllArenas { @@ -949,7 +949,7 @@ impl<'tcx> CommonTypes<'tcx> { f64: mk(Float(ast::FloatTy::F64)), self_param: mk(ty::Param(ty::ParamTy { index: 0, - name: kw::SelfUpper.as_interned_str(), + name: kw::SelfUpper, })), trait_object_dummy_self: mk(Infer(ty::FreshTy(0))), @@ -2552,7 +2552,7 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_ty_param(self, index: u32, name: InternedString) -> Ty<'tcx> { + pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> { self.mk_ty(Param(ParamTy { index, name: name })) } @@ -2560,7 +2560,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_const_param( self, index: u32, - name: InternedString, + name: Symbol, ty: Ty<'tcx> ) -> &'tcx Const<'tcx> { self.mk_const(ty::Const { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d46ab3769ad55..9703ed8385325 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -849,7 +849,7 @@ impl ty::EarlyBoundRegion { /// Does this early bound region have a name? Early bound regions normally /// always have names except when using anonymous lifetimes (`'_`). pub fn has_name(&self) -> bool { - self.name != kw::UnderscoreLifetime.as_interned_str() + self.name != kw::UnderscoreLifetime } } @@ -866,7 +866,7 @@ pub enum GenericParamDefKind { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub struct GenericParamDef { - pub name: InternedString, + pub name: Symbol, pub def_id: DefId, pub index: u32, diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 363109a0582df..f1042813e5ea1 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -14,7 +14,7 @@ use rustc_apfloat::Float; use rustc_target::spec::abi::Abi; use syntax::ast; use syntax::attr::{SignedInt, UnsignedInt}; -use syntax::symbol::{kw, InternedString}; +use syntax::symbol::{kw, Symbol}; use std::cell::Cell; use std::fmt::{self, Write as _}; @@ -992,7 +992,7 @@ pub struct FmtPrinterData<'a, 'tcx, F> { empty_path: bool, in_value: bool, - used_region_names: FxHashSet, + used_region_names: FxHashSet, region_index: usize, binder_depth: usize, @@ -1332,16 +1332,16 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { match *region { ty::ReEarlyBound(ref data) => { - data.name.as_symbol() != kw::Invalid && - data.name.as_symbol() != kw::UnderscoreLifetime + data.name != kw::Invalid && + data.name != kw::UnderscoreLifetime } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name.as_symbol() != kw::Invalid && - name.as_symbol() != kw::UnderscoreLifetime { + if name != kw::Invalid && + name != kw::UnderscoreLifetime { return true; } } @@ -1397,7 +1397,7 @@ impl FmtPrinter<'_, '_, F> { // `explain_region()` or `note_and_explain_region()`. match *region { ty::ReEarlyBound(ref data) => { - if data.name.as_symbol() != kw::Invalid { + if data.name != kw::Invalid { p!(write("{}", data.name)); return Ok(self); } @@ -1406,8 +1406,8 @@ impl FmtPrinter<'_, '_, F> { ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => { if let ty::BrNamed(_, name) = br { - if name.as_symbol() != kw::Invalid && - name.as_symbol() != kw::UnderscoreLifetime { + if name != kw::Invalid && + name != kw::UnderscoreLifetime { p!(write("{}", name)); return Ok(self); } @@ -1474,11 +1474,11 @@ impl FmtPrinter<'_, 'tcx, F> { where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, { - fn name_by_region_index(index: usize) -> InternedString { + fn name_by_region_index(index: usize) -> Symbol { match index { - 0 => InternedString::intern("'r"), - 1 => InternedString::intern("'s"), - i => InternedString::intern(&format!("'t{}", i-2)), + 0 => Symbol::intern("'r"), + 1 => Symbol::intern("'s"), + i => Symbol::intern(&format!("'t{}", i-2)), } } @@ -1541,7 +1541,7 @@ impl FmtPrinter<'_, 'tcx, F> { where T: TypeFoldable<'tcx> { - struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); + struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet); impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { match *r { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 4af73fa389a7d..f4de0cd7b6b16 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -24,7 +24,7 @@ use std::marker::PhantomData; use std::ops::Range; use rustc_target::spec::abi; use syntax::ast::{self, Ident}; -use syntax::symbol::{kw, InternedString}; +use syntax::symbol::{kw, Symbol}; use self::InferTy::*; use self::TyKind::*; @@ -55,7 +55,7 @@ pub enum BoundRegion { /// /// The `DefId` is needed to distinguish free regions in /// the event of shadowing. - BrNamed(DefId, InternedString), + BrNamed(DefId, Symbol), /// Anonymous region for the implicit env pointer parameter /// to a closure @@ -1123,16 +1123,16 @@ pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder>>; Hash, RustcEncodable, RustcDecodable, HashStable)] pub struct ParamTy { pub index: u32, - pub name: InternedString, + pub name: Symbol, } impl<'tcx> ParamTy { - pub fn new(index: u32, name: InternedString) -> ParamTy { + pub fn new(index: u32, name: Symbol) -> ParamTy { ParamTy { index, name: name } } pub fn for_self() -> ParamTy { - ParamTy::new(0, kw::SelfUpper.as_interned_str()) + ParamTy::new(0, kw::SelfUpper) } pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { @@ -1148,11 +1148,11 @@ impl<'tcx> ParamTy { Eq, PartialEq, Ord, PartialOrd, HashStable)] pub struct ParamConst { pub index: u32, - pub name: InternedString, + pub name: Symbol, } impl<'tcx> ParamConst { - pub fn new(index: u32, name: InternedString) -> ParamConst { + pub fn new(index: u32, name: Symbol) -> ParamConst { ParamConst { index, name } } @@ -1325,7 +1325,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Region<'tcx> {} pub struct EarlyBoundRegion { pub def_id: DefId, pub index: u32, - pub name: InternedString, + pub name: Symbol, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] @@ -1389,7 +1389,7 @@ pub struct BoundTy { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum BoundTyKind { Anon, - Param(InternedString), + Param(Symbol), } impl_stable_hash_for!(struct BoundTy { var, kind }); diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 438a660b8a867..d0bfbe051483b 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -46,7 +46,7 @@ use std::iter; use std::ptr; use std::path::{Path, PathBuf}; use syntax::ast; -use syntax::symbol::{Interner, InternedString}; +use syntax::symbol::{Interner, Symbol}; use syntax_pos::{self, Span, FileName}; impl PartialEq for llvm::Metadata { @@ -2127,7 +2127,7 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&' fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) - -> Vec { + -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_parameter_names(cx, cx.tcx.generics_of(def_id)) }); diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 6e4ed42c45e97..5b59f4c28de20 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -36,7 +36,7 @@ use std::ffi::{CStr, CString}; use syntax_pos::{self, Span, Pos}; use syntax::ast; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; use rustc_codegen_ssa::traits::*; @@ -490,7 +490,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) - -> Vec { + -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_parameter_names(cx, cx.tcx.generics_of(def_id)) }); diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 6fb976e0d84b2..d6e84940291a5 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -18,14 +18,14 @@ use rustc::ty::print::RegionHighlightMode; use rustc_errors::DiagnosticBuilder; use syntax::symbol::kw; use rustc_data_structures::fx::FxHashMap; -use syntax_pos::{Span, symbol::InternedString}; +use syntax_pos::{Span, symbol::Symbol}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. #[derive(Debug, Clone)] crate struct RegionName { /// The name of the region (interned). - crate name: InternedString, + crate name: Symbol, /// Where the region comes from. crate source: RegionNameSource, } @@ -109,7 +109,7 @@ impl RegionName { } #[allow(dead_code)] - crate fn name(&self) -> InternedString { + crate fn name(&self) -> Symbol { self.name } @@ -273,7 +273,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } ty::ReStatic => Some(RegionName { - name: kw::StaticLifetime.as_interned_str(), + name: kw::StaticLifetime, source: RegionNameSource::Static }), @@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, tcx: TyCtxt<'tcx>, error_region: &RegionKind, - name: InternedString, + name: Symbol, ) -> Span { let scope = error_region.free_region_binding_scope(tcx); let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); @@ -837,10 +837,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Creates a synthetic region named `'1`, incrementing the counter. - fn synthesize_region_name(&self, renctx: &mut RegionErrorNamingCtx) -> InternedString { + fn synthesize_region_name(&self, renctx: &mut RegionErrorNamingCtx) -> Symbol { let c = renctx.counter; renctx.counter += 1; - InternedString::intern(&format!("'{:?}", c)) + Symbol::intern(&format!("'{:?}", c)) } } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 5f6951856434e..b39aa483a6a6d 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -790,7 +790,7 @@ fn for_each_late_bound_region_defined_on<'tcx>( owner: fn_def_id.index, local_id: *late_bound, }; - let name = tcx.hir().name(hir_id).as_interned_str(); + let name = tcx.hir().name(hir_id); let region_def_id = tcx.hir().local_def_id(hir_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: fn_def_id, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index e6f7a042f1c2b..7bb96661bb746 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -908,7 +908,7 @@ fn convert_path_expr<'a, 'tcx>( let generics = cx.tcx.generics_of(item_def_id); let local_def_id = cx.tcx.hir().local_def_id(hir_id); let index = generics.param_def_id_to_index[&local_def_id]; - let name = cx.tcx.hir().name(hir_id).as_interned_str(); + let name = cx.tcx.hir().name(hir_id); let val = ConstValue::Param(ty::ParamConst::new(index, name)); ExprKind::Literal { literal: cx.tcx.mk_const( diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7e0a9bc4011c0..f2502ab3648f5 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -131,7 +131,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { let tcx = self.tcx(); let lifetime_name = |def_id| { - tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap()).as_interned_str() + tcx.hir().name(tcx.hir().as_local_hir_id(def_id).unwrap()) }; let r = match tcx.named_region(lifetime.hir_id) { @@ -2023,7 +2023,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let item_def_id = tcx.hir().local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&def_id]; - tcx.mk_ty_param(index, tcx.hir().name(hir_id).as_interned_str()) + tcx.mk_ty_param(index, tcx.hir().name(hir_id)) } Res::SelfTy(Some(_), None) => { // `Self` in trait or type alias. @@ -2204,7 +2204,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let item_def_id = tcx.hir().local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)]; - let name = tcx.hir().name(hir_id).as_interned_str(); + let name = tcx.hir().name(hir_id); const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index aeb2c40e2ef83..72a0fe887b964 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -7,7 +7,7 @@ use rustc::ty::subst::Subst; use crate::require_same_types; use rustc_target::spec::abi::Abi; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::hir; @@ -80,7 +80,7 @@ pub fn intrinsic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs, /// and in libcore/intrinsics.rs pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { - let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n))); + let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); let name = it.ident.as_str(); let mk_va_list_ty = |mutbl| { @@ -387,7 +387,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { /// Type-check `extern "platform-intrinsic" { ... }` functions. pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem) { let param = |n| { - let name = InternedString::intern(&format!("P{}", n)); + let name = Symbol::intern(&format!("P{}", n)); tcx.mk_ty_param(n, name) }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 1749fd1075e05..d4c64512f984b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -36,7 +36,7 @@ use syntax::ast; use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used}; use syntax::feature_gate; -use syntax::symbol::{InternedString, kw, Symbol, sym}; +use syntax::symbol::{kw, Symbol, sym}; use syntax_pos::{Span, DUMMY_SP}; use rustc::hir::def::{CtorKind, Res, DefKind}; @@ -265,7 +265,7 @@ fn type_param_predicates( let param_owner_def_id = tcx.hir().local_def_id(param_owner); let generics = tcx.generics_of(param_owner_def_id); let index = generics.param_def_id_to_index[&def_id]; - let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id).as_interned_str()); + let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(param_id)); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner_def_id { @@ -961,7 +961,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { opt_self = Some(ty::GenericParamDef { index: 0, - name: kw::SelfUpper.as_interned_str(), + name: kw::SelfUpper, def_id: tcx.hir().local_def_id(param_id), pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -1006,7 +1006,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { early_lifetimes .enumerate() .map(|(i, param)| ty::GenericParamDef { - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, index: own_start + i as u32, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, @@ -1060,7 +1060,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { let param_def = ty::GenericParamDef { index: type_start + i as u32, - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id), pure_wrt_drop: param.pure_wrt_drop, kind, @@ -1090,7 +1090,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { .enumerate() .map(|(i, &arg)| ty::GenericParamDef { index: type_start + i as u32, - name: InternedString::intern(arg), + name: Symbol::intern(arg), def_id, pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -1105,7 +1105,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { params.extend(upvars.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| { ty::GenericParamDef { index: type_start + i, - name: InternedString::intern(""), + name: Symbol::intern(""), def_id, pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -2198,7 +2198,7 @@ fn explicit_predicates_of( let region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { def_id: tcx.hir().local_def_id(param.hir_id), index, - name: param.name.ident().as_interned_str(), + name: param.name.ident().name, })); index += 1; @@ -2221,7 +2221,7 @@ fn explicit_predicates_of( // type parameter (e.g., ``). for param in &ast_generics.params { if let GenericParamKind::Type { .. } = param.kind { - let name = param.name.ident().as_interned_str(); + let name = param.name.ident().name; let param_ty = ty::ParamTy::new(index, name).to_ty(tcx); index += 1; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c355f661410e5..3f8fca53cd423 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1682,7 +1682,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime => None, ty::GenericParamDefKind::Type { synthetic, .. } => { - if param.name.as_symbol() == kw::SelfUpper { + if param.name == kw::SelfUpper { assert_eq!(param.index, 0); return None; } From c325553a30ec0de8e156c28533e55ddee71013f0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Oct 2019 15:01:51 +1100 Subject: [PATCH 20/35] Convert `InternedString`s to `Symbols` in `UnsafetyViolation`. --- src/librustc/mir/mod.rs | 6 ++--- src/librustc_mir/transform/check_unsafety.rs | 27 ++++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9ac1465cb0ba9..b0830fb72eb07 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -37,7 +37,7 @@ use std::slice; use std::vec::IntoIter; use std::{iter, mem, option, u32}; use syntax::ast::Name; -use syntax::symbol::{InternedString, Symbol}; +use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; pub use crate::mir::interpret::AssertMessage; @@ -2736,8 +2736,8 @@ pub enum UnsafetyViolationKind { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)] pub struct UnsafetyViolation { pub source_info: SourceInfo, - pub description: InternedString, - pub details: InternedString, + pub description: Symbol, + pub details: Symbol, pub kind: UnsafetyViolationKind, } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 70855d70228b3..3ff36e01275b9 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -12,7 +12,7 @@ use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSA use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext}; -use syntax::symbol::{InternedString, sym}; +use syntax::symbol::{Symbol, sym}; use std::ops::Bound; @@ -167,9 +167,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { (CastTy::FnPtr, CastTy::Int(_)) => { self.register_violations(&[UnsafetyViolation { source_info: self.source_info, - description: InternedString::intern("cast of pointer to int"), - details: InternedString::intern( - "casting pointers to integers in constants"), + description: Symbol::intern("cast of pointer to int"), + details: Symbol::intern("casting pointers to integers in constants"), kind: UnsafetyViolationKind::General, }], &[]); }, @@ -185,8 +184,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind { self.register_violations(&[UnsafetyViolation { source_info: self.source_info, - description: InternedString::intern("pointer operation"), - details: InternedString::intern("operations on pointers in constants"), + description: Symbol::intern("pointer operation"), + details: Symbol::intern("operations on pointers in constants"), kind: UnsafetyViolationKind::General, }], &[]); } @@ -219,8 +218,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_scope_local_data[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern("use of extern static"), - details: InternedString::intern( + description: Symbol::intern("use of extern static"), + details: Symbol::intern( "extern statics are not controlled by the Rust type system: \ invalid data, aliasing violations or data races will cause \ undefined behavior"), @@ -240,8 +239,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { self.source_scope_local_data[source_info.scope].lint_root; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern("borrow of packed field"), - details: InternedString::intern( + description: Symbol::intern("borrow of packed field"), + details: Symbol::intern( "fields of packed structs might be misaligned: dereferencing a \ misaligned pointer or even just creating a misaligned reference \ is undefined behavior"), @@ -334,8 +333,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { let source_info = self.source_info; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern(description), - details: InternedString::intern(details), + description: Symbol::intern(description), + details: Symbol::intern(details), kind, }], &[]); } @@ -438,8 +437,8 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { let source_info = self.source_info; self.register_violations(&[UnsafetyViolation { source_info, - description: InternedString::intern(description), - details: InternedString::intern(details), + description: Symbol::intern(description), + details: Symbol::intern(details), kind: UnsafetyViolationKind::GeneralAndConstFn, }], &[]); } From 78c342730840248a98d81f7cc10b06c69831751b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Sun, 20 Oct 2019 09:59:26 +1100 Subject: [PATCH 21/35] Remove unnecessary `impl Clean for InternedString`. --- src/librustdoc/clean/mod.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3f8fca53cd423..b84540d899ee2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -31,7 +31,6 @@ use syntax::attr; use syntax_expand::base::MacroKind; use syntax::source_map::DUMMY_SP; use syntax::symbol::{Symbol, kw, sym}; -use syntax::symbol::InternedString; use syntax_pos::{self, Pos, FileName}; use std::collections::hash_map::Entry; @@ -3701,13 +3700,6 @@ impl Clean for ast::Name { } } -impl Clean for InternedString { - #[inline] - fn clean(&self, _: &DocContext<'_>) -> String { - self.to_string() - } -} - #[derive(Clone, Debug)] pub struct Typedef { pub type_: Type, From ddc1c279753897021ae81c6c75f04f510b11740d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Sep 2019 13:57:43 +1000 Subject: [PATCH 22/35] Eliminate `intersect_opt`. Its fourth argument is always `Some(pred)`, so the pattern matching is unnecessary. This commit inlines and removes it. --- .../graph/dominators/mod.rs | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 29a8a98d229cc..444463c08e557 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -17,7 +17,7 @@ pub fn dominators(graph: &G) -> Dominators { dominators_given_rpo(graph, &rpo) } -pub fn dominators_given_rpo( +fn dominators_given_rpo( graph: &G, rpo: &[G::Node], ) -> Dominators { @@ -43,14 +43,12 @@ pub fn dominators_given_rpo( let mut new_idom = None; for pred in graph.predecessors(node) { if immediate_dominators[pred].is_some() { - // (*) // (*) dominators for `pred` have been calculated - new_idom = intersect_opt( - &post_order_rank, - &immediate_dominators, - new_idom, - Some(pred), - ); + new_idom = Some(if let Some(new_idom) = new_idom { + intersect(&post_order_rank, &immediate_dominators, new_idom, pred) + } else { + pred + }); } } @@ -67,19 +65,6 @@ pub fn dominators_given_rpo( } } -fn intersect_opt( - post_order_rank: &IndexVec, - immediate_dominators: &IndexVec>, - node1: Option, - node2: Option, -) -> Option { - match (node1, node2) { - (None, None) => None, - (Some(n), None) | (None, Some(n)) => Some(n), - (Some(n1), Some(n2)) => Some(intersect(post_order_rank, immediate_dominators, n1, n2)), - } -} - fn intersect( post_order_rank: &IndexVec, immediate_dominators: &IndexVec>, From b8214e9b44a5796749a70d7806e575412333e27c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 14:25:08 +1100 Subject: [PATCH 23/35] Convert fields within `DefPathData` from `InternedString` to `Symbol`. It's a full conversion, except in `DefKey::compute_stable_hash()` where a `Symbol` now is converted to an `InternedString` before being hashed. This was necessary to avoid test failures. --- src/librustc/hir/lowering.rs | 8 ++-- src/librustc/hir/map/def_collector.rs | 29 ++++++------ src/librustc/hir/map/definitions.rs | 44 +++++++++---------- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc/lint/context.rs | 2 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/print/obsolete.rs | 4 +- src/librustc/ty/print/pretty.rs | 6 +-- .../debuginfo/namespace.rs | 2 +- .../debuginfo/type_names.rs | 2 +- .../symbol_names/legacy.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 9 ++-- .../interpret/intrinsics/type_name.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- src/librustc_resolve/build_reduced_graph.rs | 4 +- 16 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index d5287fd415b7f..7971c33426b2e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -792,15 +792,15 @@ impl<'a> LoweringContext<'a> { // really show up for end-user. let (str_name, kind) = match hir_name { ParamName::Plain(ident) => ( - ident.as_interned_str(), + ident.name, hir::LifetimeParamKind::InBand, ), ParamName::Fresh(_) => ( - kw::UnderscoreLifetime.as_interned_str(), + kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided, ), ParamName::Error => ( - kw::UnderscoreLifetime.as_interned_str(), + kw::UnderscoreLifetime, hir::LifetimeParamKind::Error, ), }; @@ -1590,7 +1590,7 @@ impl<'a> LoweringContext<'a> { self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, - DefPathData::LifetimeNs(name.ident().as_interned_str()), + DefPathData::LifetimeNs(name.ident().name), ExpnId::root(), lifetime.span); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 9be339be7034f..7c8fdcc8b12e9 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -57,7 +57,7 @@ impl<'a> DefCollector<'a> { // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. - let fn_def_data = DefPathData::ValueNs(name.as_interned_str()); + let fn_def_data = DefPathData::ValueNs(name); let fn_def = self.create_def(id, fn_def_data, span); return self.with_parent(fn_def, |this| { this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); @@ -83,8 +83,7 @@ impl<'a> DefCollector<'a> { .unwrap_or_else(|| { let node_id = NodeId::placeholder_from_expn_id(self.expansion); sym::integer(self.definitions.placeholder_field_indices[&node_id]) - }) - .as_interned_str(); + }); let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span); self.with_parent(def, |this| visit::walk_struct_field(this, field)); } @@ -109,7 +108,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | - ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.as_interned_str()), + ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), ItemKind::Fn( ref decl, ref header, @@ -127,8 +126,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { ) } ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => - DefPathData::ValueNs(i.ident.as_interned_str()), - ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()), + DefPathData::ValueNs(i.ident.name), + ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.name), ItemKind::Mac(..) => return self.visit_macro_invoc(i.id), ItemKind::GlobalAsm(..) => DefPathData::Misc, ItemKind::Use(..) => { @@ -162,7 +161,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } let def = self.create_def(foreign_item.id, - DefPathData::ValueNs(foreign_item.ident.as_interned_str()), + DefPathData::ValueNs(foreign_item.ident.name), foreign_item.span); self.with_parent(def, |this| { @@ -175,7 +174,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { return self.visit_macro_invoc(v.id); } let def = self.create_def(v.id, - DefPathData::TypeNs(v.ident.as_interned_str()), + DefPathData::TypeNs(v.ident.name), v.span); self.with_parent(def, |this| { if let Some(ctor_hir_id) = v.data.ctor_id() { @@ -202,7 +201,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { self.visit_macro_invoc(param.id); return; } - let name = param.ident.as_interned_str(); + let name = param.ident.name; let def_path_data = match param.kind { GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name), GenericParamKind::Type { .. } => DefPathData::TypeNs(name), @@ -216,9 +215,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_trait_item(&mut self, ti: &'a TraitItem) { let def_data = match ti.kind { TraitItemKind::Method(..) | TraitItemKind::Const(..) => - DefPathData::ValueNs(ti.ident.as_interned_str()), + DefPathData::ValueNs(ti.ident.name), TraitItemKind::Type(..) => { - DefPathData::TypeNs(ti.ident.as_interned_str()) + DefPathData::TypeNs(ti.ident.name) }, TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id), }; @@ -243,12 +242,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { body, ) } - ImplItemKind::Method(..) | ImplItemKind::Const(..) => - DefPathData::ValueNs(ii.ident.as_interned_str()), + ImplItemKind::Method(..) | + ImplItemKind::Const(..) => DefPathData::ValueNs(ii.ident.name), ImplItemKind::TyAlias(..) | - ImplItemKind::OpaqueTy(..) => { - DefPathData::TypeNs(ii.ident.as_interned_str()) - }, + ImplItemKind::OpaqueTy(..) => DefPathData::TypeNs(ii.ident.name), ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id), }; diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index d2732c92d2688..893b295c60a28 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -18,7 +18,7 @@ use std::fmt::Write; use std::hash::Hash; use syntax::ast; use syntax_expand::hygiene::ExpnId; -use syntax::symbol::{Symbol, sym, InternedString}; +use syntax::symbol::{Symbol, sym}; use syntax_pos::{Span, DUMMY_SP}; /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa. @@ -136,7 +136,9 @@ impl DefKey { ::std::mem::discriminant(data).hash(&mut hasher); if let Some(name) = data.get_opt_name() { - name.hash(&mut hasher); + // Get a stable hash by considering the symbol chars rather than + // the symbol index. + name.as_str().hash(&mut hasher); } disambiguator.hash(&mut hasher); @@ -218,7 +220,7 @@ impl DefPath { for component in &self.data { write!(s, "::{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -238,11 +240,11 @@ impl DefPath { for component in &self.data { if component.disambiguator == 0 { - write!(s, "::{}", component.data.as_interned_str()).unwrap(); + write!(s, "::{}", component.data.as_symbol()).unwrap(); } else { write!(s, "{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -262,11 +264,11 @@ impl DefPath { opt_delimiter.map(|d| s.push(d)); opt_delimiter = Some('-'); if component.disambiguator == 0 { - write!(s, "{}", component.data.as_interned_str()).unwrap(); + write!(s, "{}", component.data.as_symbol()).unwrap(); } else { write!(s, "{}[{}]", - component.data.as_interned_str(), + component.data.as_symbol(), component.disambiguator) .unwrap(); } @@ -290,13 +292,13 @@ pub enum DefPathData { /// An impl. Impl, /// Something in the type namespace. - TypeNs(InternedString), + TypeNs(Symbol), /// Something in the value namespace. - ValueNs(InternedString), + ValueNs(Symbol), /// Something in the macro namespace. - MacroNs(InternedString), + MacroNs(Symbol), /// Something in the lifetime namespace. - LifetimeNs(InternedString), + LifetimeNs(Symbol), /// A closure expression. ClosureExpr, @@ -311,7 +313,7 @@ pub enum DefPathData { /// Identifies a piece of crate metadata that is global to a whole crate /// (as opposed to just one item). `GlobalMetaData` components are only /// supposed to show up right below the crate root. - GlobalMetaData(InternedString), + GlobalMetaData(Symbol), } #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, @@ -545,7 +547,7 @@ impl Definitions { } impl DefPathData { - pub fn get_opt_name(&self) -> Option { + pub fn get_opt_name(&self) -> Option { use self::DefPathData::*; match *self { TypeNs(name) | @@ -564,15 +566,15 @@ impl DefPathData { } } - pub fn as_interned_str(&self) -> InternedString { + pub fn as_symbol(&self) -> Symbol { use self::DefPathData::*; - let s = match *self { + match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | GlobalMetaData(name) => { - return name + name } // Note that this does not show up in user print-outs. CrateRoot => sym::double_braced_crate, @@ -582,13 +584,11 @@ impl DefPathData { Ctor => sym::double_braced_constructor, AnonConst => sym::double_braced_constant, ImplTrait => sym::double_braced_opaque, - }; - - s.as_interned_str() + } } pub fn to_string(&self) -> String { - self.as_interned_str().to_string() + self.as_symbol().to_string() } } @@ -611,7 +611,7 @@ macro_rules! define_global_metadata_kind { definitions.create_def_with_parent( CRATE_DEF_INDEX, ast::DUMMY_NODE_ID, - DefPathData::GlobalMetaData(instance.name().as_interned_str()), + DefPathData::GlobalMetaData(instance.name()), ExpnId::root(), DUMMY_SP ); @@ -625,7 +625,7 @@ macro_rules! define_global_metadata_kind { let def_key = DefKey { parent: Some(CRATE_DEF_INDEX), disambiguated_data: DisambiguatedDefPathData { - data: DefPathData::GlobalMetaData(self.name().as_interned_str()), + data: DefPathData::GlobalMetaData(self.name()), disambiguator: 0, } }; diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f6068855e630c..7e1dcdfe18f90 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -542,7 +542,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { disambiguated_data: &DisambiguatedDefPathData, ) -> Result { let mut path = print_prefix(self)?; - path.push(disambiguated_data.data.as_interned_str().to_string()); + path.push(disambiguated_data.data.as_symbol().to_string()); Ok(path) } fn path_generic_args( diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index fa73a3c6c4628..1b38c908917b8 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -875,7 +875,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { _ => {} } - path.push(disambiguated_data.data.as_interned_str().as_symbol()); + path.push(disambiguated_data.data.as_symbol()); Ok(path) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9703ed8385325..f52d1bc5ffab1 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3019,7 +3019,7 @@ impl<'tcx> TyCtxt<'tcx> { }), _ => def_key.disambiguated_data.data.get_opt_name().unwrap_or_else(|| { bug!("item_name: no name for {:?}", self.def_path(id)); - }).as_symbol(), + }), } } } diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs index df39d0ccc9eed..e72916de6a9c7 100644 --- a/src/librustc/ty/print/obsolete.rs +++ b/src/librustc/ty/print/obsolete.rs @@ -218,9 +218,9 @@ impl DefPathBasedNames<'tcx> { // foo::bar::ItemName:: for part in self.tcx.def_path(def_id).data { if self.omit_disambiguators { - write!(output, "{}::", part.data.as_interned_str()).unwrap(); + write!(output, "{}::", part.data.as_symbol()).unwrap(); } else { - write!(output, "{}[{}]::", part.data.as_interned_str(), part.disambiguator) + write!(output, "{}[{}]::", part.data.as_symbol(), part.disambiguator) .unwrap(); } } diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index f1042813e5ea1..8a98a5d83615f 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -384,7 +384,7 @@ pub trait PrettyPrinter<'tcx>: let reexport = self.tcx().item_children(visible_parent) .iter() .find(|child| child.res.def_id() == def_id) - .map(|child| child.ident.as_interned_str()); + .map(|child| child.ident.name); if let Some(reexport) = reexport { *name = reexport; } @@ -392,7 +392,7 @@ pub trait PrettyPrinter<'tcx>: // Re-exported `extern crate` (#43189). DefPathData::CrateRoot => { data = DefPathData::TypeNs( - self.tcx().original_crate_name(def_id.krate).as_interned_str(), + self.tcx().original_crate_name(def_id.krate), ); } _ => {} @@ -1222,7 +1222,7 @@ impl Printer<'tcx> for FmtPrinter<'_, 'tcx, F> { // FIXME(eddyb) `name` should never be empty, but it // currently is for `extern { ... }` "foreign modules". - let name = disambiguated_data.data.as_interned_str().as_str(); + let name = disambiguated_data.data.as_symbol().as_str(); if !name.is_empty() { if !self.empty_path { write!(self, "::")?; diff --git a/src/librustc_codegen_llvm/debuginfo/namespace.rs b/src/librustc_codegen_llvm/debuginfo/namespace.rs index 889984749fdf7..628d1372b5702 100644 --- a/src/librustc_codegen_llvm/debuginfo/namespace.rs +++ b/src/librustc_codegen_llvm/debuginfo/namespace.rs @@ -35,7 +35,7 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { let namespace_name = match def_key.disambiguated_data.data { DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(), - data => data.as_interned_str().as_str() + data => data.as_symbol().as_str() }; let namespace_name = SmallCStr::new(&namespace_name); diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs index d875c60959cba..166a74fe48795 100644 --- a/src/librustc_codegen_ssa/debuginfo/type_names.rs +++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs @@ -221,7 +221,7 @@ pub fn push_debuginfo_type_name<'tcx>( output.push_str(&tcx.crate_name(def_id.krate).as_str()); for path_element in tcx.def_path(def_id).data { output.push_str("::"); - output.push_str(&path_element.data.as_interned_str().as_str()); + output.push_str(&path_element.data.as_symbol().as_str()); } } else { output.push_str(&tcx.item_name(def_id).as_str()); diff --git a/src/librustc_codegen_utils/symbol_names/legacy.rs b/src/librustc_codegen_utils/symbol_names/legacy.rs index cf575c54293c7..601a33a66bb32 100644 --- a/src/librustc_codegen_utils/symbol_names/legacy.rs +++ b/src/librustc_codegen_utils/symbol_names/legacy.rs @@ -335,7 +335,7 @@ impl Printer<'tcx> for SymbolPrinter<'tcx> { self.path.finalize_pending_component(); } - self.write_str(&disambiguated_data.data.as_interned_str().as_str())?; + self.write_str(&disambiguated_data.data.as_symbol().as_str())?; Ok(self) } fn path_generic_args( diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 4cd1ff7b4a4ff..6aba66a79ab3b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -460,7 +460,7 @@ impl cstore::CStore { LoadedMacro::MacroDef(ast::Item { // FIXME: cross-crate hygiene - ident: ast::Ident::with_dummy_span(name.as_symbol()), + ident: ast::Ident::with_dummy_span(name), id: ast::DUMMY_NODE_ID, span: local_span, attrs: attrs.iter().cloned().collect(), diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b8b0030244028..c9851694d4465 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -35,7 +35,7 @@ use syntax::ast::{self, Ident}; use syntax::source_map::{self, respan, Spanned}; use syntax::symbol::{Symbol, sym}; use syntax_expand::base::{MacroKind, SyntaxExtensionKind, SyntaxExtension}; -use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, symbol::{InternedString}}; +use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP}; use log::debug; use proc_macro::bridge::client::ProcMacro; use syntax_expand::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro}; @@ -514,7 +514,6 @@ impl<'a, 'tcx> CrateMetadata { .data .get_opt_name() .expect("no name in item_name") - .as_symbol() } else { Symbol::intern(self.raw_proc_macro(item_index).name()) } @@ -864,7 +863,7 @@ impl<'a, 'tcx> CrateMetadata { let span = self.get_span(child_index, sess); if let (Some(kind), Some(name)) = (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name()) { - let ident = Ident::from_interned_str(name); + let ident = Ident::with_dummy_span(name); let vis = self.get_visibility(child_index); let def_id = self.local_def_id(child_index); let res = Res::Def(kind, def_id); @@ -987,7 +986,7 @@ impl<'a, 'tcx> CrateMetadata { }; ty::AssocItem { - ident: Ident::from_interned_str(name), + ident: Ident::with_dummy_span(name), kind, vis: self.get_visibility(id), defaultness: container.defaultness(), @@ -1262,7 +1261,7 @@ impl<'a, 'tcx> CrateMetadata { let mut key = self.def_path_table.def_key(index); if self.is_proc_macro(index) { let name = self.raw_proc_macro(index).name(); - key.disambiguated_data.data = DefPathData::MacroNs(InternedString::intern(name)); + key.disambiguated_data.data = DefPathData::MacroNs(Symbol::intern(name)); } key } diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs index f9200f8c1c042..f1f9fac08ca3a 100644 --- a/src/librustc_mir/interpret/intrinsics/type_name.rs +++ b/src/librustc_mir/interpret/intrinsics/type_name.rs @@ -148,7 +148,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { self.path.push_str("::"); - self.path.push_str(&disambiguated_data.data.as_interned_str().as_str()); + self.path.push_str(&disambiguated_data.data.as_symbol().as_str()); Ok(self) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index b9d38028b72a8..b09f9e9e536a5 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -762,7 +762,7 @@ fn compute_codegen_unit_name( let components = def_path .data .iter() - .map(|part| part.data.as_interned_str()); + .map(|part| part.data.as_symbol()); let volatile_suffix = if volatile { Some("volatile") diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e261d3af61ff8..6444a82fd7379 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -110,14 +110,14 @@ impl<'a> Resolver<'a> { } let (name, parent) = if def_id.index == CRATE_DEF_INDEX { - (self.cstore.crate_name_untracked(def_id.krate).as_interned_str(), None) + (self.cstore.crate_name_untracked(def_id.krate), None) } else { let def_key = self.cstore.def_key(def_id); (def_key.disambiguated_data.data.get_opt_name().unwrap(), Some(self.get_module(DefId { index: def_key.parent.unwrap(), ..def_id }))) }; - let kind = ModuleKind::Def(DefKind::Mod, def_id, name.as_symbol()); + let kind = ModuleKind::Def(DefKind::Mod, def_id, name); let module = self.arenas.alloc_module(ModuleData::new( parent, kind, def_id, ExpnId::root(), DUMMY_SP )); From dddacf1eb3efb3c2111b27456be43c21e4497ffd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 15:53:37 +1100 Subject: [PATCH 24/35] Change `SymbolName::name` from `InternedString` to `Symbol`. This requires changing the `PartialOrd`/`Ord` implementations to look at the chars rather than the symbol index. --- src/librustc/mir/mono.rs | 4 ++-- src/librustc/ty/mod.rs | 21 ++++++++++++++++---- src/librustc/ty/query/values.rs | 4 ++-- src/librustc_codegen_llvm/consts.rs | 2 +- src/librustc_codegen_utils/symbol_names.rs | 23 ++++++++++------------ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 265ac975ed7a2..1f52672199ca8 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,6 @@ use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use crate::hir::HirId; -use syntax::symbol::InternedString; +use syntax::symbol::{InternedString, Symbol}; use syntax::attr::InlineAttr; use syntax::source_map::Span; use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; @@ -80,7 +80,7 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(hir_id) => { let def_id = tcx.hir().local_def_id(hir_id); SymbolName { - name: InternedString::intern(&format!("global_asm_{:?}", def_id)) + name: Symbol::intern(&format!("global_asm_{:?}", def_id)) } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f52d1bc5ffab1..f72a221fe3962 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -46,7 +46,7 @@ use std::ops::Range; use syntax::ast::{self, Name, Ident, NodeId}; use syntax::attr; use syntax_expand::hygiene::ExpnId; -use syntax::symbol::{kw, sym, Symbol, InternedString}; +use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; use smallvec; @@ -3429,11 +3429,11 @@ pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>, } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable)] pub struct SymbolName { // FIXME: we don't rely on interning or equality here - better have // this be a `&'tcx str`. - pub name: InternedString + pub name: Symbol } impl_stable_hash_for!(struct self::SymbolName { @@ -3443,11 +3443,24 @@ impl_stable_hash_for!(struct self::SymbolName { impl SymbolName { pub fn new(name: &str) -> SymbolName { SymbolName { - name: InternedString::intern(name) + name: Symbol::intern(name) } } } +impl PartialOrd for SymbolName { + fn partial_cmp(&self, other: &SymbolName) -> Option { + self.name.as_str().partial_cmp(&other.name.as_str()) + } +} + +/// Ordering must use the chars to ensure reproducible builds. +impl Ord for SymbolName { + fn cmp(&self, other: &SymbolName) -> Ordering { + self.name.as_str().cmp(&other.name.as_str()) + } +} + impl fmt::Display for SymbolName { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.name, fmt) diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs index 0149f75716477..f0d1639f72f59 100644 --- a/src/librustc/ty/query/values.rs +++ b/src/librustc/ty/query/values.rs @@ -1,7 +1,7 @@ use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint}; use crate::ty::util::NeedsDrop; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; pub(super) trait Value<'tcx>: Sized { fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self; @@ -22,7 +22,7 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> { impl<'tcx> Value<'tcx> for ty::SymbolName { fn from_cycle_error(_: TyCtxt<'tcx>) -> Self { - ty::SymbolName { name: InternedString::intern("") } + ty::SymbolName { name: Symbol::intern("") } } } diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index d4df5b4a804ef..fd7054a5a0ada 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> { def_id); let ty = instance.ty(self.tcx); - let sym = self.tcx.symbol_name(instance).name.as_symbol(); + let sym = self.tcx.symbol_name(instance).name; debug!("get_static: sym={} instance={:?}", sym, instance); diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 7ccd024769f75..c52c6cfa83c91 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -95,7 +95,7 @@ use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt, Instance}; use rustc::mir::mono::{MonoItem, InstantiationMode}; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use log::debug; @@ -112,7 +112,7 @@ pub fn provide(providers: &mut Providers<'_>) { }; } -fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { +fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Symbol { let def_id = instance.def_id(); let substs = instance.substs; @@ -123,13 +123,11 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { if def_id.is_local() { if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return - InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)); + return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator)); } if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) { let disambiguator = tcx.sess.local_crate_disambiguator(); - return - InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)); + return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator)); } } @@ -146,23 +144,22 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { let attrs = tcx.codegen_fn_attrs(def_id); if is_foreign { if let Some(name) = attrs.link_name { - return name.as_interned_str(); + return name; } // Don't mangle foreign items. - return tcx.item_name(def_id).as_interned_str(); + return tcx.item_name(def_id); } - if let Some(name) = &attrs.export_name { + if let Some(name) = attrs.export_name { // Use provided name - return name.as_interned_str(); + return name; } if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { // Don't mangle - return tcx.item_name(def_id).as_interned_str(); + return tcx.item_name(def_id); } - let is_generic = substs.non_erasable_generics().next().is_some(); let avoid_cross_crate_conflicts = // If this is an instance of a generic function, we also hash in @@ -222,5 +219,5 @@ fn symbol_name(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> InternedString { SymbolManglingVersion::V0 => v0::mangle(tcx, instance, instantiating_crate), }; - InternedString::intern(&mangled) + Symbol::intern(&mangled) } From 2da7a9c0d943e694eef17c0b47e87cbcde03a957 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 17:14:03 +1100 Subject: [PATCH 25/35] Use `Symbol` for codegen unit names. This is a straightforward replacement except for two places where we have to convert to `LocalInternedString` to get a stable sort. --- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/mir/mono.rs | 20 +++++----- src/librustc/query/mod.rs | 4 +- src/librustc/ty/query/keys.rs | 4 +- src/librustc/ty/query/mod.rs | 1 - src/librustc_codegen_llvm/base.rs | 6 +-- src/librustc_codegen_llvm/lib.rs | 3 +- src/librustc_codegen_ssa/base.rs | 4 +- src/librustc_codegen_ssa/traits/backend.rs | 4 +- .../assert_module_sources.rs | 8 ++-- src/librustc_mir/monomorphize/partitioning.rs | 39 +++++++++---------- 11 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 0686bec0621f4..dea8d70aaf4e6 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -59,7 +59,7 @@ use crate::ich::{Fingerprint, StableHashingContext}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::fmt; use std::hash::Hash; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use crate::traits; use crate::traits::query::{ CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpAscribeUserTypeGoal, @@ -426,7 +426,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [anon] TraitSelect, - [] CompileCodegenUnit(InternedString), + [] CompileCodegenUnit(Symbol), [eval_always] Analysis(CrateNum), ]); diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 1f52672199ca8..9be741a165606 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,6 @@ use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use crate::hir::HirId; -use syntax::symbol::{InternedString, Symbol}; +use syntax::symbol::Symbol; use syntax::attr::InlineAttr; use syntax::source_map::Span; use crate::ty::{Instance, InstanceDef, TyCtxt, SymbolName, subst::InternalSubsts}; @@ -246,7 +246,7 @@ pub struct CodegenUnit<'tcx> { /// name be unique amongst **all** crates. Therefore, it should /// contain something unique to this crate (e.g., a module path) /// as well as the crate name and disambiguator. - name: InternedString, + name: Symbol, items: FxHashMap, (Linkage, Visibility)>, size_estimate: Option, } @@ -294,7 +294,7 @@ impl_stable_hash_for!(enum self::Visibility { }); impl<'tcx> CodegenUnit<'tcx> { - pub fn new(name: InternedString) -> CodegenUnit<'tcx> { + pub fn new(name: Symbol) -> CodegenUnit<'tcx> { CodegenUnit { name: name, items: Default::default(), @@ -302,11 +302,11 @@ impl<'tcx> CodegenUnit<'tcx> { } } - pub fn name(&self) -> &InternedString { - &self.name + pub fn name(&self) -> Symbol { + self.name } - pub fn set_name(&mut self, name: InternedString) { + pub fn set_name(&mut self, name: Symbol) { self.name = name; } @@ -474,7 +474,7 @@ impl CodegenUnitNameBuilder<'tcx> { cnum: CrateNum, components: I, special_suffix: Option) - -> InternedString + -> Symbol where I: IntoIterator, C: fmt::Display, S: fmt::Display, @@ -487,7 +487,7 @@ impl CodegenUnitNameBuilder<'tcx> { cgu_name } else { let cgu_name = &cgu_name.as_str()[..]; - InternedString::intern(&CodegenUnit::mangle_name(cgu_name)) + Symbol::intern(&CodegenUnit::mangle_name(cgu_name)) } } @@ -497,7 +497,7 @@ impl CodegenUnitNameBuilder<'tcx> { cnum: CrateNum, components: I, special_suffix: Option) - -> InternedString + -> Symbol where I: IntoIterator, C: fmt::Display, S: fmt::Display, @@ -543,6 +543,6 @@ impl CodegenUnitNameBuilder<'tcx> { write!(cgu_name, ".{}", special_suffix).unwrap(); } - InternedString::intern(&cgu_name[..]) + Symbol::intern(&cgu_name[..]) } } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 2c407a24493ff..fdca6d0e17a1d 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -15,7 +15,7 @@ use crate::traits::query::{ }; use std::borrow::Cow; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method @@ -924,7 +924,7 @@ rustc_queries! { desc { "collect_and_partition_mono_items" } } query is_codegened_item(_: DefId) -> bool {} - query codegen_unit(_: InternedString) -> Arc> { + query codegen_unit(_: Symbol) -> Arc> { no_force desc { "codegen_unit" } } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index 30a3e53dddfbb..0c48ae9717864 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -11,7 +11,7 @@ use crate::mir; use std::fmt::Debug; use std::hash::Hash; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; /// The `Key` trait controls what types can legally be used as the key /// for a query. @@ -190,7 +190,7 @@ impl<'tcx> Key for traits::Environment<'tcx> { } } -impl Key for InternedString { +impl Key for Symbol { fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 4279ca8c3daf6..9b15ad560b5d2 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -55,7 +55,6 @@ use std::ops::Deref; use std::sync::Arc; use std::any::type_name; use syntax_pos::{Span, DUMMY_SP}; -use syntax_pos::symbol::InternedString; use syntax::attr; use syntax::ast; use syntax::feature_gate; diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index bd7d0d4017dce..edd34b52eade7 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -36,7 +36,7 @@ use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm; use std::ffi::CString; use std::time::Instant; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; use rustc::hir::CodegenFnAttrs; use crate::value::Value; @@ -105,7 +105,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> { pub fn compile_codegen_unit( tcx: TyCtxt<'tcx>, - cgu_name: InternedString, + cgu_name: Symbol, tx_to_llvm_workers: &std::sync::mpsc::Sender>, ) { let prof_timer = tcx.prof.generic_activity("codegen_module"); @@ -131,7 +131,7 @@ pub fn compile_codegen_unit( fn module_codegen( tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, ) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 9b55bef0c514d..8c1797cfb7de4 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -50,7 +50,6 @@ use rustc_codegen_ssa::CompiledModule; use errors::{FatalError, Handler}; use rustc::dep_graph::WorkProduct; use syntax_expand::allocator::AllocatorKind; -use syntax_pos::symbol::InternedString; pub use llvm_util::target_features; use std::any::Any; use std::sync::Arc; @@ -123,7 +122,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend { } fn compile_codegen_unit( &self, tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, tx: &std::sync::mpsc::Sender>, ) { base::compile_codegen_unit(tcx, cgu_name, tx); diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index f4f3dd4d2d295..516fd5049f260 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -515,7 +515,7 @@ pub fn codegen_crate( // unnecessarily. if tcx.dep_graph.is_fully_enabled() { for cgu in &codegen_units { - tcx.codegen_unit(cgu.name().clone()); + tcx.codegen_unit(cgu.name()); } } @@ -603,7 +603,7 @@ pub fn codegen_crate( match cgu_reuse { CguReuse::No => { let start_time = Instant::now(); - backend.compile_codegen_unit(tcx, *cgu.name(), &ongoing_codegen.coordinator_send); + backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send); total_codegen_time += start_time.elapsed(); false } diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 7cae3e9ade590..1fff740d7403f 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -10,7 +10,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend; use std::sync::Arc; use std::sync::mpsc; use syntax_expand::allocator::AllocatorKind; -use syntax_pos::symbol::InternedString; +use syntax_pos::symbol::Symbol; pub trait BackendTypes { type Value: CodegenObject; @@ -50,7 +50,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se fn compile_codegen_unit( &self, tcx: TyCtxt<'_>, - cgu_name: InternedString, + cgu_name: Symbol, tx_to_llvm_workers: &mpsc::Sender>, ); // If find_features is true this won't access `sess.crate_types` by assuming diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index e08eeaf85758e..ca035d0cdcb19 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -27,7 +27,7 @@ use rustc::mir::mono::CodegenUnitNameBuilder; use rustc::ty::TyCtxt; use std::collections::BTreeSet; use syntax::ast; -use syntax::symbol::{InternedString, Symbol, sym}; +use syntax::symbol::{Symbol, sym}; use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED, ATTR_EXPECTED_CGU_REUSE}; @@ -45,8 +45,8 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { .collect_and_partition_mono_items(LOCAL_CRATE) .1 .iter() - .map(|cgu| *cgu.name()) - .collect::>(); + .map(|cgu| cgu.name()) + .collect::>(); let ams = AssertModuleSource { tcx, @@ -61,7 +61,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) { struct AssertModuleSource<'tcx> { tcx: TyCtxt<'tcx>, - available_cgus: BTreeSet, + available_cgus: BTreeSet, } impl AssertModuleSource<'tcx> { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index b09f9e9e536a5..42f08771f866d 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -96,7 +96,7 @@ use std::collections::hash_map::Entry; use std::cmp; use std::sync::Arc; -use syntax::symbol::InternedString; +use syntax::symbol::Symbol; use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def::DefKind; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX}; @@ -121,7 +121,7 @@ pub enum PartitioningStrategy { } // Anything we can't find a proper codegen unit for goes into this. -fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> InternedString { +fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_>) -> Symbol { name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu")) } @@ -185,9 +185,7 @@ where internalization_candidates: _, } = post_inlining; - result.sort_by(|cgu1, cgu2| { - cgu1.name().cmp(cgu2.name()) - }); + result.sort_by_cached_key(|cgu| cgu.name().as_str()); result } @@ -203,7 +201,7 @@ struct PreInliningPartitioning<'tcx> { /// to keep track of that. #[derive(Clone, PartialEq, Eq, Debug)] enum MonoItemPlacement { - SingleCgu { cgu_name: InternedString }, + SingleCgu { cgu_name: Symbol }, MultipleCgus, } @@ -251,8 +249,8 @@ where None => fallback_cgu_name(cgu_name_builder), }; - let codegen_unit = codegen_units.entry(codegen_unit_name.clone()) - .or_insert_with(|| CodegenUnit::new(codegen_unit_name.clone())); + let codegen_unit = codegen_units.entry(codegen_unit_name) + .or_insert_with(|| CodegenUnit::new(codegen_unit_name)); let mut can_be_internalized = true; let (linkage, visibility) = mono_item_linkage_and_visibility( @@ -273,8 +271,7 @@ where // crate with just types (for example), we could wind up with no CGU. if codegen_units.is_empty() { let codegen_unit_name = fallback_cgu_name(cgu_name_builder); - codegen_units.insert(codegen_unit_name.clone(), - CodegenUnit::new(codegen_unit_name.clone())); + codegen_units.insert(codegen_unit_name, CodegenUnit::new(codegen_unit_name)); } PreInliningPartitioning { @@ -492,7 +489,7 @@ fn merge_codegen_units<'tcx>( // smallest into each other) we're sure to start off with a deterministic // order (sorted by name). This'll mean that if two cgus have the same size // the stable sort below will keep everything nice and deterministic. - codegen_units.sort_by_key(|cgu| *cgu.name()); + codegen_units.sort_by_cached_key(|cgu| cgu.name().as_str()); // Merge the two smallest codegen units until the target size is reached. while codegen_units.len() > target_cgu_count { @@ -537,7 +534,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< follow_inlining(*root, inlining_map, &mut reachable); } - let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name().clone()); + let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name()); // Add all monomorphizations that are not already there. for mono_item in reachable { @@ -564,8 +561,8 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< Entry::Occupied(e) => { let placement = e.into_mut(); debug_assert!(match *placement { - MonoItemPlacement::SingleCgu { ref cgu_name } => { - *cgu_name != *new_codegen_unit.name() + MonoItemPlacement::SingleCgu { cgu_name } => { + cgu_name != new_codegen_unit.name() } MonoItemPlacement::MultipleCgus => true, }); @@ -573,7 +570,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< } Entry::Vacant(e) => { e.insert(MonoItemPlacement::SingleCgu { - cgu_name: new_codegen_unit.name().clone() + cgu_name: new_codegen_unit.name() }); } } @@ -638,7 +635,7 @@ fn internalize_symbols<'tcx>( // accessed from outside its defining codegen unit. for cgu in &mut partitioning.codegen_units { let home_cgu = MonoItemPlacement::SingleCgu { - cgu_name: cgu.name().clone() + cgu_name: cgu.name() }; for (accessee, linkage_and_visibility) in cgu.items_mut() { @@ -717,7 +714,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( } } -type CguNameCache = FxHashMap<(DefId, bool), InternedString>; +type CguNameCache = FxHashMap<(DefId, bool), Symbol>; fn compute_codegen_unit_name( tcx: TyCtxt<'_>, @@ -725,7 +722,7 @@ fn compute_codegen_unit_name( def_id: DefId, volatile: bool, cache: &mut CguNameCache, -) -> InternedString { +) -> Symbol { // Find the innermost module that is not nested within a function. let mut current_def_id = def_id; let mut cgu_def_id = None; @@ -777,7 +774,7 @@ fn compute_codegen_unit_name( fn numbered_codegen_unit_name( name_builder: &mut CodegenUnitNameBuilder<'_>, index: usize, -) -> InternedString { +) -> Symbol { name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index)) } @@ -929,7 +926,7 @@ fn collect_and_partition_mono_items( for (&mono_item, &linkage) in cgu.items() { item_to_cgus.entry(mono_item) .or_default() - .push((cgu.name().clone(), linkage)); + .push((cgu.name(), linkage)); } } @@ -991,7 +988,7 @@ pub fn provide(providers: &mut Providers<'_>) { providers.codegen_unit = |tcx, name| { let (_, all) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); all.iter() - .find(|cgu| *cgu.name() == name) + .find(|cgu| cgu.name() == name) .cloned() .unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name)) }; From 08e2f05549de74022f2e596251ed88e784514640 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 21 Oct 2019 18:25:03 +1100 Subject: [PATCH 26/35] Remove `InternedString`. By using `LocalInternedString` instead for the few remaining uses. --- src/librustc/hir/map/collector.rs | 4 +- src/librustc/ich/impls_syntax.rs | 19 ++--- src/libsyntax_pos/symbol.rs | 120 ++---------------------------- src/tools/linkchecker/main.rs | 1 - 4 files changed, 17 insertions(+), 127 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 1a970c7a2c1e0..307dbe7dab080 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -186,13 +186,13 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }); let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| { - let name = cstore.crate_name_untracked(cnum).as_interned_str(); + let name = cstore.crate_name_untracked(cnum); let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint(); let hash = cstore.crate_hash_untracked(cnum); (name, disambiguator, hash) }).collect(); - upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name, dis)); + upstream_crates.sort_unstable_by_key(|&(name, dis, _)| (name.as_str(), dis)); // We hash the final, remapped names of all local source files so we // don't have to include the path prefix remapping commandline args. diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index defc3fb25bc52..dc1f6fd3131bd 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -9,7 +9,7 @@ use std::mem; use syntax::ast; use syntax::feature_gate; use syntax::parse::token; -use syntax::symbol::InternedString; +use syntax::symbol::LocalInternedString; use syntax::tokenstream; use syntax_pos::SourceFile; @@ -18,20 +18,21 @@ use crate::hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher}; -impl<'a> HashStable> for InternedString { +impl<'a> HashStable> for LocalInternedString { #[inline] fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - self.with(|s| s.hash_stable(hcx, hasher)) + let str = self as &str; + str.hash_stable(hcx, hasher) } } -impl<'a> ToStableHashKey> for InternedString { - type KeyType = InternedString; +impl<'a> ToStableHashKey> for LocalInternedString { + type KeyType = LocalInternedString; #[inline] fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) - -> InternedString { + -> LocalInternedString { self.clone() } } @@ -44,13 +45,13 @@ impl<'a> HashStable> for ast::Name { } impl<'a> ToStableHashKey> for ast::Name { - type KeyType = InternedString; + type KeyType = LocalInternedString; #[inline] fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) - -> InternedString { - self.as_interned_str() + -> LocalInternedString { + self.as_str() } } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index fa9567fb62c0f..4b947c5b857cc 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -9,7 +9,7 @@ use rustc_macros::symbols; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; -use std::cmp::{PartialEq, Ordering, PartialOrd, Ord}; +use std::cmp::{PartialEq, PartialOrd, Ord}; use std::fmt; use std::hash::{Hash, Hasher}; use std::str; @@ -766,11 +766,6 @@ impl Ident { Ident::with_dummy_span(kw::Invalid) } - /// Maps an interned string to an identifier with an empty syntax context. - pub fn from_interned_str(string: InternedString) -> Ident { - Ident::with_dummy_span(string.as_symbol()) - } - /// Maps a string to an identifier with a dummy span. pub fn from_str(string: &str) -> Ident { Ident::with_dummy_span(Symbol::intern(string)) @@ -813,11 +808,6 @@ impl Ident { pub fn as_str(self) -> LocalInternedString { self.name.as_str() } - - /// Convert the name to an `InternedString`. - pub fn as_interned_str(self) -> InternedString { - self.name.as_interned_str() - } } impl PartialEq for Ident { @@ -903,15 +893,6 @@ impl Symbol { }) } - /// Access two symbols' chars. This is a slowish operation because it - /// requires locking the symbol interner, but it is faster than calling - /// `with()` twice. - fn with2 R, R>(self, other: Symbol, f: F) -> R { - with_interner(|interner| { - f(interner.get(self), interner.get(other)) - }) - } - /// Convert to a `LocalInternedString`. This is a slowish operation because /// it requires locking the symbol interner. pub fn as_str(self) -> LocalInternedString { @@ -922,11 +903,6 @@ impl Symbol { }) } - /// Convert to an `InternedString`. - pub fn as_interned_str(self) -> InternedString { - InternedString { symbol: self } - } - pub fn as_u32(self) -> u32 { self.0.as_u32() } @@ -1105,9 +1081,9 @@ fn with_interner T>(f: F) -> T { GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock())) } -/// An alternative to `Symbol` and `InternedString`, useful when the chars -/// within the symbol need to be accessed. It deliberately has limited -/// functionality and should only be used for temporary values. +/// An alternative to `Symbol`, useful when the chars within the symbol need to +/// be accessed. It deliberately has limited functionality and should only be +/// used for temporary values. /// /// Because the interner outlives any thread which uses this type, we can /// safely treat `string` which points to interner data, as an immortal string, @@ -1116,7 +1092,7 @@ fn with_interner T>(f: F) -> T { // FIXME: ensure that the interner outlives any thread which uses // `LocalInternedString`, by creating a new thread right after constructing the // interner. -#[derive(Eq, PartialOrd, Ord)] +#[derive(Clone, Eq, PartialOrd, Ord)] pub struct LocalInternedString { string: &'static str, } @@ -1157,89 +1133,3 @@ impl fmt::Display for LocalInternedString { fmt::Display::fmt(self.string, f) } } - -/// An alternative to `Symbol` that is focused on string contents. -/// -/// Its implementations of `Hash`, `PartialOrd` and `Ord` work with the -/// string chars rather than the symbol integer. This is useful when hash -/// stability is required across compile sessions, or a guaranteed sort -/// ordering is required. -#[derive(Clone, Copy, PartialEq, Eq)] -pub struct InternedString { - symbol: Symbol, -} - -impl InternedString { - /// Maps a string to its interned representation. - pub fn intern(string: &str) -> Self { - InternedString { - symbol: Symbol::intern(string) - } - } - - pub fn with R, R>(self, f: F) -> R { - self.symbol.with(f) - } - - fn with2 R, R>(self, other: &InternedString, f: F) -> R { - self.symbol.with2(other.symbol, f) - } - - pub fn as_symbol(self) -> Symbol { - self.symbol - } - - /// Convert to a `LocalInternedString`. This is a slowish operation because it - /// requires locking the symbol interner. - pub fn as_str(self) -> LocalInternedString { - self.symbol.as_str() - } -} - -impl Hash for InternedString { - fn hash(&self, state: &mut H) { - self.with(|str| str.hash(state)) - } -} - -impl PartialOrd for InternedString { - fn partial_cmp(&self, other: &InternedString) -> Option { - if self.symbol == other.symbol { - return Some(Ordering::Equal); - } - self.with2(other, |self_str, other_str| self_str.partial_cmp(other_str)) - } -} - -impl Ord for InternedString { - fn cmp(&self, other: &InternedString) -> Ordering { - if self.symbol == other.symbol { - return Ordering::Equal; - } - self.with2(other, |self_str, other_str| self_str.cmp(other_str)) - } -} - -impl fmt::Debug for InternedString { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Debug::fmt(&str, f)) - } -} - -impl fmt::Display for InternedString { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Display::fmt(&str, f)) - } -} - -impl Decodable for InternedString { - fn decode(d: &mut D) -> Result { - Ok(InternedString::intern(&d.read_str()?)) - } -} - -impl Encodable for InternedString { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.with(|string| s.emit_str(string)) - } -} diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index e8a7252cb767c..79c98b780eb65 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -126,7 +126,6 @@ fn check(cache: &mut Cache, // FIXME(#32129) if file.ends_with("std/string/struct.String.html") || file.ends_with("interpret/struct.ImmTy.html") || - file.ends_with("symbol/struct.InternedString.html") || file.ends_with("ast/struct.ThinVec.html") || file.ends_with("util/struct.ThinVec.html") || file.ends_with("layout/struct.TyLayout.html") || From 33910f9d86cf8c283c51800085c3e863261ec5ae Mon Sep 17 00:00:00 2001 From: wangxiangqing Date: Tue, 22 Oct 2019 00:08:14 +0800 Subject: [PATCH 27/35] Deprecated proc_macro doesn't trigger warning on build library Change-Id: Ib3a396e7334d209fe6c6ef425bbfc7b2ae471378 --- src/libsyntax_ext/proc_macro_harness.rs | 10 ++++++++++ .../ui/proc-macro/proc-macro-deprecated-attr.rs | 15 +++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/test/ui/proc-macro/proc-macro-deprecated-attr.rs diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 96d0c3fcab1c5..bbf5b1255510f 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -416,6 +416,16 @@ fn mk_decls( ).map(|mut i| { let attr = cx.meta_word(span, sym::rustc_proc_macro_decls); i.attrs.push(cx.attribute(attr)); + + let deprecated_attr = attr::mk_nested_word_item( + Ident::new(sym::deprecated, span) + ); + let allow_deprecated_attr = attr::mk_list_item( + Ident::new(sym::allow, span), + vec![deprecated_attr] + ); + i.attrs.push(cx.attribute(allow_deprecated_attr)); + i }); diff --git a/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs b/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs new file mode 100644 index 0000000000000..32ccc24904283 --- /dev/null +++ b/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs @@ -0,0 +1,15 @@ +// build-pass + +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro] +#[deprecated(since = "1.0.0", note = "test")] +pub fn test_compile_without_warning_with_deprecated(_: TokenStream) -> TokenStream { + " + extern crate proc_macro; + fn foo() { } + ".parse().unwrap() +} From c027be0dd09a440927071dea69378d01322373cd Mon Sep 17 00:00:00 2001 From: wangxiangqing Date: Tue, 22 Oct 2019 00:08:14 +0800 Subject: [PATCH 28/35] Deprecated proc_macro doesn't trigger warning on build library Change-Id: Ib3a396e7334d209fe6c6ef425bbfc7b2ae471378 --- src/libsyntax_ext/proc_macro_harness.rs | 1 + src/test/ui/proc-macro/proc-macro-deprecated-attr.rs | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index bbf5b1255510f..c874f1ffb1175 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -337,6 +337,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // use proc_macro::bridge::client::ProcMacro; // // #[rustc_proc_macro_decls] +// #[allow(deprecated)] // static DECLS: &[ProcMacro] = &[ // ProcMacro::custom_derive($name_trait1, &[], ::$name1); // ProcMacro::custom_derive($name_trait2, &["attribute_name"], ::$name2); diff --git a/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs b/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs index 32ccc24904283..25ce53b70a5bd 100644 --- a/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs +++ b/src/test/ui/proc-macro/proc-macro-deprecated-attr.rs @@ -1,4 +1,6 @@ -// build-pass +// check-pass + +#![deny(deprecated)] #![crate_type = "proc-macro"] @@ -8,8 +10,5 @@ use proc_macro::*; #[proc_macro] #[deprecated(since = "1.0.0", note = "test")] pub fn test_compile_without_warning_with_deprecated(_: TokenStream) -> TokenStream { - " - extern crate proc_macro; - fn foo() { } - ".parse().unwrap() + TokenStream::new() } From ed965f1b6a299b729efad94836ff7498093f3236 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 22 Oct 2019 11:52:05 +0200 Subject: [PATCH 29/35] Update E0659 error code long explanation to 2018 edition --- src/librustc_resolve/error_codes.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs index 8ccb27078d569..a7a3d71b5395d 100644 --- a/src/librustc_resolve/error_codes.rs +++ b/src/librustc_resolve/error_codes.rs @@ -1822,7 +1822,7 @@ An item usage is ambiguous. Erroneous code example: -```compile_fail,E0659 +```compile_fail,edition2018,E0659 pub mod moon { pub fn foo() {} } @@ -1832,12 +1832,12 @@ pub mod earth { } mod collider { - pub use moon::*; - pub use earth::*; + pub use crate::moon::*; + pub use crate::earth::*; } fn main() { - collider::foo(); // ERROR: `foo` is ambiguous + crate::collider::foo(); // ERROR: `foo` is ambiguous } ``` @@ -1849,7 +1849,7 @@ functions collide. To solve this error, the best solution is generally to keep the path before the item when using it. Example: -``` +```edition2018 pub mod moon { pub fn foo() {} } @@ -1859,13 +1859,13 @@ pub mod earth { } mod collider { - pub use moon; - pub use earth; + pub use crate::moon; + pub use crate::earth; } fn main() { - collider::moon::foo(); // ok! - collider::earth::foo(); // ok! + crate::collider::moon::foo(); // ok! + crate::collider::earth::foo(); // ok! } ``` "##, From 74db3e8a9e31adf0ed7b3e9f4e1093e6b6a40fc4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Oct 2019 21:22:41 +0300 Subject: [PATCH 30/35] rustc_metadata: use a table for super_predicates. --- src/librustc_metadata/decoder.rs | 14 ++++---------- src/librustc_metadata/encoder.rs | 23 +++++++++++++++-------- src/librustc_metadata/schema.rs | 13 ++++--------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b8b0030244028..1ec7702af79d7 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -448,7 +448,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Mod(_) => DefKind::Mod, EntryKind::Variant(_) => DefKind::Variant, EntryKind::Trait(_) => DefKind::Trait, - EntryKind::TraitAlias(_) => DefKind::TraitAlias, + EntryKind::TraitAlias => DefKind::TraitAlias, EntryKind::Enum(..) => DefKind::Enum, EntryKind::MacroDef(_) => DefKind::Macro(MacroKind::Bang), EntryKind::ForeignType => DefKind::ForeignTy, @@ -575,7 +575,7 @@ impl<'a, 'tcx> CrateMetadata { data.is_marker, self.def_path_table.def_path_hash(item_id)) }, - EntryKind::TraitAlias(_) => { + EntryKind::TraitAlias => { ty::TraitDef::new(self.local_def_id(item_id), hir::Unsafety::Normal, false, @@ -680,13 +680,7 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'tcx>, ) -> ty::GenericPredicates<'tcx> { - let super_predicates = match self.kind(item_id) { - EntryKind::Trait(data) => data.decode(self).super_predicates, - EntryKind::TraitAlias(data) => data.decode(self).super_predicates, - _ => bug!("def-index does not refer to trait or trait alias"), - }; - - super_predicates.decode((self, tcx)) + self.root.per_def.super_predicates.get(self, item_id).unwrap().decode((self, tcx)) } crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics { @@ -1118,7 +1112,7 @@ impl<'a, 'tcx> CrateMetadata { def_key.parent.and_then(|parent_index| { match self.kind(parent_index) { EntryKind::Trait(_) | - EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)), + EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), _ => None, } }) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6ae8c2fc6c694..79a7caa292b08 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -76,6 +76,7 @@ struct PerDefTables<'tcx> { generics: PerDefTable>, predicates: PerDefTable>>, predicates_defined_on: PerDefTable>>, + super_predicates: PerDefTable>>, mir: PerDefTable>>, promoted_mir: PerDefTable>>>, @@ -513,6 +514,7 @@ impl<'tcx> EncodeContext<'tcx> { generics: self.per_def.generics.encode(&mut self.opaque), predicates: self.per_def.predicates.encode(&mut self.opaque), predicates_defined_on: self.per_def.predicates_defined_on.encode(&mut self.opaque), + super_predicates: self.per_def.super_predicates.encode(&mut self.opaque), mir: self.per_def.mir.encode(&mut self.opaque), promoted_mir: self.per_def.promoted_mir.encode(&mut self.opaque), @@ -835,6 +837,11 @@ impl EncodeContext<'tcx> { self.tcx.predicates_defined_on(def_id)) } + fn encode_super_predicates(&mut self, def_id: DefId) { + debug!("EncodeContext::encode_super_predicates({:?})", def_id); + record!(self.per_def.super_predicates[def_id] <- self.tcx.super_predicates_of(def_id)); + } + fn encode_info_for_trait_item(&mut self, def_id: DefId) { debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id); let tcx = self.tcx; @@ -1166,18 +1173,11 @@ impl EncodeContext<'tcx> { paren_sugar: trait_def.paren_sugar, has_auto_impl: self.tcx.trait_is_auto(def_id), is_marker: trait_def.is_marker, - super_predicates: self.lazy(tcx.super_predicates_of(def_id)), }; EntryKind::Trait(self.lazy(data)) } - hir::ItemKind::TraitAlias(..) => { - let data = TraitAliasData { - super_predicates: self.lazy(tcx.super_predicates_of(def_id)), - }; - - EntryKind::TraitAlias(self.lazy(data)) - } + hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias, hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), }); @@ -1269,6 +1269,13 @@ impl EncodeContext<'tcx> { } _ => {} // not *wrong* for other kinds of items, but not needed } + match item.kind { + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => { + self.encode_super_predicates(def_id); + } + _ => {} + } let mir = match item.kind { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 96f35783278fa..b681078ee0d5d 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -243,6 +243,7 @@ crate struct LazyPerDefTables<'tcx> { pub generics: Lazy!(PerDefTable>), pub predicates: Lazy!(PerDefTable)>), pub predicates_defined_on: Lazy!(PerDefTable)>), + pub super_predicates: Lazy!(PerDefTable)>), pub mir: Lazy!(PerDefTable)>), pub promoted_mir: Lazy!(PerDefTable>)>), @@ -273,13 +274,13 @@ crate enum EntryKind<'tcx> { MacroDef(Lazy), Closure(Lazy!(ClosureData<'tcx>)), Generator(Lazy!(GeneratorData<'tcx>)), - Trait(Lazy!(TraitData<'tcx>)), + Trait(Lazy), Impl(Lazy!(ImplData<'tcx>)), Method(Lazy!(MethodData<'tcx>)), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, ConstQualif, Lazy), - TraitAlias(Lazy!(TraitAliasData<'tcx>)), + TraitAlias, } /// Additional data for EntryKind::Const and EntryKind::AssocConst @@ -324,17 +325,11 @@ crate struct VariantData<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -crate struct TraitData<'tcx> { +crate struct TraitData { pub unsafety: hir::Unsafety, pub paren_sugar: bool, pub has_auto_impl: bool, pub is_marker: bool, - pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>), -} - -#[derive(RustcEncodable, RustcDecodable)] -crate struct TraitAliasData<'tcx> { - pub super_predicates: Lazy!(ty::GenericPredicates<'tcx>), } #[derive(RustcEncodable, RustcDecodable)] From 7a80a11a83f1b00e750f3d1c235b67ef8ab70c29 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 18 Oct 2019 22:15:14 +0300 Subject: [PATCH 31/35] rustc_metadata: use a table for fn_sig. --- src/librustc_metadata/decoder.rs | 13 ++------ src/librustc_metadata/encoder.rs | 53 +++++++++++++++----------------- src/librustc_metadata/schema.rs | 32 ++++++++----------- 3 files changed, 38 insertions(+), 60 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1ec7702af79d7..9c7b721fb7f63 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -458,7 +458,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Impl(_) | EntryKind::Field | EntryKind::Generator(_) | - EntryKind::Closure(_) => return None, + EntryKind::Closure => return None, }) } } @@ -1239,16 +1239,7 @@ impl<'a, 'tcx> CrateMetadata { } crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { - let sig = match self.kind(id) { - EntryKind::Fn(data) | - EntryKind::ForeignFn(data) => data.decode(self).sig, - EntryKind::Method(data) => data.decode(self).fn_data.sig, - EntryKind::Variant(data) | - EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(), - EntryKind::Closure(data) => data.decode(self).sig, - _ => bug!(), - }; - sig.decode((self, tcx)) + self.root.per_def.fn_sig.get(self, id).unwrap().decode((self, tcx)) } #[inline] diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 79a7caa292b08..e3ad1c5e197b5 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -71,6 +71,7 @@ struct PerDefTables<'tcx> { deprecation: PerDefTable>, ty: PerDefTable>>, + fn_sig: PerDefTable>>, inherent_impls: PerDefTable>, variances: PerDefTable>, generics: PerDefTable>, @@ -509,6 +510,7 @@ impl<'tcx> EncodeContext<'tcx> { deprecation: self.per_def.deprecation.encode(&mut self.opaque), ty: self.per_def.ty.encode(&mut self.opaque), + fn_sig: self.per_def.fn_sig.encode(&mut self.opaque), inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), variances: self.per_def.variances.encode(&mut self.opaque), generics: self.per_def.generics.encode(&mut self.opaque), @@ -637,13 +639,7 @@ impl EncodeContext<'tcx> { let data = VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, - // FIXME(eddyb) deduplicate these with `encode_enum_variant_ctor`. ctor: variant.ctor_def_id.map(|did| did.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - variant.ctor_def_id.map(|ctor_def_id| self.lazy(&tcx.fn_sig(ctor_def_id))) - } else { - None - }, }; let enum_id = tcx.hir().as_local_hir_id(enum_did).unwrap(); @@ -662,6 +658,11 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. + if let Some(ctor_def_id) = variant.ctor_def_id { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); + } + // FIXME(eddyb) is this ever used? self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -681,15 +682,11 @@ impl EncodeContext<'tcx> { let def_id = variant.ctor_def_id.unwrap(); debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id); + // FIXME(eddyb) encode only the `CtorKind` for constructors. let data = VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(tcx.fn_sig(def_id))) - } else { - None - } }; // Variant constructors have the same visibility as the parent enums, unless marked as @@ -708,6 +705,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -782,11 +780,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: Some(def_id.index), - ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(tcx.fn_sig(def_id))) - } else { - None - } }; let struct_id = tcx.hir().as_local_hir_id(adt_def_id).unwrap(); @@ -813,6 +806,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -881,7 +875,6 @@ impl EncodeContext<'tcx> { asyncness: m_sig.header.asyncness, constness: hir::Constness::NotConst, param_names, - sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() @@ -913,6 +906,7 @@ impl EncodeContext<'tcx> { ty::AssocKind::OpaqueTy => unreachable!(), } if trait_item.kind == ty::AssocKind::Method { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -959,7 +953,6 @@ impl EncodeContext<'tcx> { asyncness: sig.header.asyncness, constness: sig.header.constness, param_names: self.encode_fn_param_names_for_body(body), - sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() @@ -980,6 +973,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if impl_item.kind == ty::AssocKind::Method { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); @@ -1088,7 +1082,6 @@ impl EncodeContext<'tcx> { asyncness: header.asyncness, constness: header.constness, param_names: self.encode_fn_param_names_for_body(body), - sig: self.lazy(tcx.fn_sig(def_id)), }; EntryKind::Fn(self.lazy(data)) @@ -1116,7 +1109,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor, - ctor_sig: None, }), adt_def.repr) } hir::ItemKind::Union(..) => { @@ -1127,7 +1119,6 @@ impl EncodeContext<'tcx> { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: None, - ctor_sig: None, }), adt_def.repr) } hir::ItemKind::Impl(_, _, defaultness, ..) => { @@ -1232,6 +1223,9 @@ impl EncodeContext<'tcx> { hir::ItemKind::Impl(..) => self.encode_item_type(def_id), _ => {} } + if let hir::ItemKind::Fn(..) = item.kind { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); + } self.encode_inherent_implementations(def_id); match item.kind { hir::ItemKind::Enum(..) | @@ -1328,10 +1322,12 @@ impl EncodeContext<'tcx> { fn encode_info_for_closure(&mut self, def_id: DefId) { debug!("EncodeContext::encode_info_for_closure({:?})", def_id); - let tables = self.tcx.typeck_tables_of(def_id); + // NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic, + // including on the signature, which is inferred in `typeck_tables_of. let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap(); + let ty = self.tcx.typeck_tables_of(def_id).node_type(hir_id); - record!(self.per_def.kind[def_id] <- match tables.node_type(hir_id).kind { + record!(self.per_def.kind[def_id] <- match ty.kind { ty::Generator(def_id, ..) => { let layout = self.tcx.generator_layout(def_id); let data = GeneratorData { @@ -1340,11 +1336,7 @@ impl EncodeContext<'tcx> { EntryKind::Generator(self.lazy(data)) } - ty::Closure(def_id, substs) => { - let sig = substs.as_closure().sig(def_id, self.tcx); - let data = ClosureData { sig: self.lazy(sig) }; - EntryKind::Closure(self.lazy(data)) - } + ty::Closure(..) => EntryKind::Closure, _ => bug!("closure that is neither generator nor closure"), }); @@ -1352,6 +1344,9 @@ impl EncodeContext<'tcx> { record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id)); record!(self.per_def.attributes[def_id] <- &self.tcx.get_attrs(def_id)[..]); self.encode_item_type(def_id); + if let ty::Closure(def_id, substs) = ty.kind { + record!(self.per_def.fn_sig[def_id] <- substs.as_closure().sig(def_id, self.tcx)); + } self.encode_generics(def_id); self.encode_optimized_mir(def_id); self.encode_promoted_mir(def_id); @@ -1560,7 +1555,6 @@ impl EncodeContext<'tcx> { asyncness: hir::IsAsync::NotAsync, constness: hir::Constness::NotConst, param_names: self.encode_fn_param_names(names), - sig: self.lazy(tcx.fn_sig(def_id)), }; EntryKind::ForeignFn(self.lazy(data)) } @@ -1576,6 +1570,7 @@ impl EncodeContext<'tcx> { self.encode_deprecation(def_id); self.encode_item_type(def_id); if let hir::ForeignItemKind::Fn(..) = nitem.kind { + record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } self.encode_generics(def_id); diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index b681078ee0d5d..03754c92252a3 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -238,6 +238,7 @@ crate struct LazyPerDefTables<'tcx> { pub deprecation: Lazy!(PerDefTable>), pub ty: Lazy!(PerDefTable)>), + pub fn_sig: Lazy!(PerDefTable)>), pub inherent_impls: Lazy!(PerDefTable>), pub variances: Lazy!(PerDefTable>), pub generics: Lazy!(PerDefTable>), @@ -265,18 +266,18 @@ crate enum EntryKind<'tcx> { OpaqueTy, Enum(ReprOptions), Field, - Variant(Lazy!(VariantData<'tcx>)), - Struct(Lazy!(VariantData<'tcx>), ReprOptions), - Union(Lazy!(VariantData<'tcx>), ReprOptions), - Fn(Lazy!(FnData<'tcx>)), - ForeignFn(Lazy!(FnData<'tcx>)), + Variant(Lazy), + Struct(Lazy, ReprOptions), + Union(Lazy, ReprOptions), + Fn(Lazy), + ForeignFn(Lazy), Mod(Lazy), MacroDef(Lazy), - Closure(Lazy!(ClosureData<'tcx>)), + Closure, Generator(Lazy!(GeneratorData<'tcx>)), Trait(Lazy), Impl(Lazy!(ImplData<'tcx>)), - Method(Lazy!(MethodData<'tcx>)), + Method(Lazy), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), AssocConst(AssocContainer, ConstQualif, Lazy), @@ -306,22 +307,18 @@ crate struct MacroDef { } #[derive(RustcEncodable, RustcDecodable)] -crate struct FnData<'tcx> { +crate struct FnData { pub asyncness: hir::IsAsync, pub constness: hir::Constness, pub param_names: Lazy<[ast::Name]>, - pub sig: Lazy!(ty::PolyFnSig<'tcx>), } #[derive(RustcEncodable, RustcDecodable)] -crate struct VariantData<'tcx> { +crate struct VariantData { pub ctor_kind: CtorKind, pub discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. pub ctor: Option, - /// If this is a tuple struct or variant - /// ctor, this is its "function" signature. - pub ctor_sig: Option)>, } #[derive(RustcEncodable, RustcDecodable)] @@ -383,17 +380,12 @@ impl AssocContainer { } #[derive(RustcEncodable, RustcDecodable)] -crate struct MethodData<'tcx> { - pub fn_data: FnData<'tcx>, +crate struct MethodData { + pub fn_data: FnData, pub container: AssocContainer, pub has_self: bool, } -#[derive(RustcEncodable, RustcDecodable)] -crate struct ClosureData<'tcx> { - pub sig: Lazy!(ty::PolyFnSig<'tcx>), -} - #[derive(RustcEncodable, RustcDecodable)] crate struct GeneratorData<'tcx> { pub layout: mir::GeneratorLayout<'tcx>, From 371cc39b256d0fa5ec0da3193e0ec6f9377bd903 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 19 Oct 2019 01:10:58 +0300 Subject: [PATCH 32/35] rustc_metadata: use a table for impl_trait_ref. --- src/librustc_metadata/decoder.rs | 4 ++-- src/librustc_metadata/encoder.rs | 8 +++++++- src/librustc_metadata/schema.rs | 7 ++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 9c7b721fb7f63..1333e3fb3ce3e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -711,7 +711,7 @@ impl<'a, 'tcx> CrateMetadata { } } - fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> { + fn get_impl_data(&self, id: DefIndex) -> ImplData { match self.kind(id) { EntryKind::Impl(data) => data.decode(self), _ => bug!(), @@ -738,7 +738,7 @@ impl<'a, 'tcx> CrateMetadata { } crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option> { - self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx))) + self.root.per_def.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx))) } /// Iterates over all the stability attributes in the given crate. diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e3ad1c5e197b5..0dc9f91ae00e1 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -72,6 +72,7 @@ struct PerDefTables<'tcx> { ty: PerDefTable>>, fn_sig: PerDefTable>>, + impl_trait_ref: PerDefTable>>, inherent_impls: PerDefTable>, variances: PerDefTable>, generics: PerDefTable>, @@ -511,6 +512,7 @@ impl<'tcx> EncodeContext<'tcx> { ty: self.per_def.ty.encode(&mut self.opaque), fn_sig: self.per_def.fn_sig.encode(&mut self.opaque), + impl_trait_ref: self.per_def.impl_trait_ref.encode(&mut self.opaque), inherent_impls: self.per_def.inherent_impls.encode(&mut self.opaque), variances: self.per_def.variances.encode(&mut self.opaque), generics: self.per_def.generics.encode(&mut self.opaque), @@ -1152,7 +1154,6 @@ impl EncodeContext<'tcx> { defaultness, parent_impl: parent, coerce_unsized_info, - trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)), }; EntryKind::Impl(self.lazy(data)) @@ -1226,6 +1227,11 @@ impl EncodeContext<'tcx> { if let hir::ItemKind::Fn(..) = item.kind { record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); } + if let hir::ItemKind::Impl(..) = item.kind { + if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { + record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); + } + } self.encode_inherent_implementations(def_id); match item.kind { hir::ItemKind::Enum(..) | diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 03754c92252a3..ad39aa34fd5c8 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -239,6 +239,7 @@ crate struct LazyPerDefTables<'tcx> { pub ty: Lazy!(PerDefTable)>), pub fn_sig: Lazy!(PerDefTable)>), + pub impl_trait_ref: Lazy!(PerDefTable)>), pub inherent_impls: Lazy!(PerDefTable>), pub variances: Lazy!(PerDefTable>), pub generics: Lazy!(PerDefTable>), @@ -276,7 +277,7 @@ crate enum EntryKind<'tcx> { Closure, Generator(Lazy!(GeneratorData<'tcx>)), Trait(Lazy), - Impl(Lazy!(ImplData<'tcx>)), + Impl(Lazy), Method(Lazy), AssocType(AssocContainer), AssocOpaqueTy(AssocContainer), @@ -330,14 +331,14 @@ crate struct TraitData { } #[derive(RustcEncodable, RustcDecodable)] -crate struct ImplData<'tcx> { +crate struct ImplData { pub polarity: ty::ImplPolarity, pub defaultness: hir::Defaultness, pub parent_impl: Option, /// This is `Some` only for impls of `CoerceUnsized`. + // FIXME(eddyb) perhaps compute this on the fly if cheap enough? pub coerce_unsized_info: Option, - pub trait_ref: Option)>, } From fe84809394fbc6ad2d36f6f142671bea7a492a4c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 22 Oct 2019 18:06:30 +0200 Subject: [PATCH 33/35] relax ExactSizeIterator bound on write_bytes: too many iterators don't have that bound --- src/librustc/mir/interpret/allocation.rs | 7 +++++-- src/librustc_mir/interpret/memory.rs | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 796d293e2c63c..aa8ac4902a894 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -353,11 +353,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &mut self, cx: &impl HasDataLayout, ptr: Pointer, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let mut src = src.into_iter(); - let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?; + let (lower, upper) = src.size_hint(); + let len = upper.expect("can only write bounded iterators"); + assert_eq!(lower, len, "can only write iterators with a precise length"); + let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(len as u64))?; // `zip` would stop when the first iterator ends; we want to definitely // cover all of `bytes`. for dest in bytes { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index eef1868ec65b6..d113ee33162d2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -7,7 +7,7 @@ //! short-circuiting the empty case! use std::collections::VecDeque; -use std::{ptr, iter}; +use std::ptr; use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; @@ -791,11 +791,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn write_bytes( &mut self, ptr: Scalar, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let src = src.into_iter(); - let size = Size::from_bytes(src.len() as u64); + let size = Size::from_bytes(src.size_hint().0 as u64); + // `write_bytes` checks that this lower bound matches the upper bound matches reality. let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? { Some(ptr) => ptr, None => return Ok(()), // zero-sized access From 4e8d1b229217c7c83ce96b44410ccae9470db973 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 22 Oct 2019 16:53:28 -0400 Subject: [PATCH 34/35] Add some documentation --- src/librustc/lint/context.rs | 24 ++++++++++++++++-------- src/librustc_driver/lib.rs | 1 + src/librustc_interface/interface.rs | 5 +++++ src/librustc_plugin/registry.rs | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 2a0cdba50cb5f..595b715c02ef6 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -155,23 +155,31 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_early_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync + ) { self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_pre_expansion_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_mod_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_module_passes.push(Box::new(pass)); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2cf1552ed9683..a18ef014b4dc0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + /// Called early during compilation to allow other drivers to easily register lints. fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 34ec3c862a3e4..3f832f95bd408 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -82,6 +82,11 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + /// This is a callback from the driver that is called when we're registering lints; + /// it is called during plugin registration when we have the LintStore in a non-shared state. + /// + /// Note that if you find a Some here you probably want to call that function in the new + /// function being registered. pub register_lints: Option>, } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 223956a4f5e3f..2e23b8c870cfc 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -25,6 +25,7 @@ pub struct Registry<'a> { /// from the plugin registrar. pub sess: &'a Session, + /// The `LintStore` allows plugins to register new lints. pub lint_store: &'a mut LintStore, #[doc(hidden)] From eeb549bfc31c27c6cec98eb852409a51f0a8162c Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Sat, 5 Oct 2019 18:23:37 -0400 Subject: [PATCH 35/35] Add Cow::is_borrowed and Cow::is_owned --- src/liballoc/borrow.rs | 41 +++++++++++++++++++++++++++++++++++++++++ src/liballoc/lib.rs | 1 + 2 files changed, 42 insertions(+) diff --git a/src/liballoc/borrow.rs b/src/liballoc/borrow.rs index a9c5bce4c25fc..d2bdda83fa998 100644 --- a/src/liballoc/borrow.rs +++ b/src/liballoc/borrow.rs @@ -207,6 +207,47 @@ impl Clone for Cow<'_, B> { } impl Cow<'_, B> { + /// Returns true if the data is borrowed, i.e. if `to_mut` would require additional work. + /// + /// # Examples + /// + /// ``` + /// #![feature(cow_is_borrowed)] + /// use std::borrow::Cow; + /// + /// let cow = Cow::Borrowed("moo"); + /// assert!(cow.is_borrowed()); + /// + /// let bull: Cow<'_, str> = Cow::Owned("...moo?".to_string()); + /// assert!(!bull.is_borrowed()); + /// ``` + #[unstable(feature = "cow_is_borrowed", issue = "65143")] + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + Owned(_) => false, + } + } + + /// Returns true if the data is owned, i.e. if `to_mut` would be a no-op. + /// + /// # Examples + /// + /// ``` + /// #![feature(cow_is_borrowed)] + /// use std::borrow::Cow; + /// + /// let cow: Cow<'_, str> = Cow::Owned("moo".to_string()); + /// assert!(cow.is_owned()); + /// + /// let bull = Cow::Borrowed("...moo?"); + /// assert!(!bull.is_owned()); + /// ``` + #[unstable(feature = "cow_is_borrowed", issue = "65143")] + pub fn is_owned(&self) -> bool { + !self.is_borrowed() + } + /// Acquires a mutable reference to the owned form of the data. /// /// Clones the data if it is not already owned. diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3684162d8b187..94379afc2bd45 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -85,6 +85,7 @@ #![feature(const_generic_impls_guard)] #![feature(const_generics)] #![feature(const_in_array_repeat_expressions)] +#![feature(cow_is_borrowed)] #![feature(dispatch_from_dyn)] #![feature(core_intrinsics)] #![feature(container_error_extra)]