diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/state.rs | 72 | ||||
| -rw-r--r-- | compiler/rustc_interface/src/tests.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/cross_crate_inline.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 24 |
5 files changed, 97 insertions, 43 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index e71f421659e..48421ff7140 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -146,37 +146,49 @@ pub fn print_crate<'a>( s.s.eof() } -/// This makes printed token streams look slightly nicer, -/// and also addresses some specific regressions described in #63896 and #73345. -fn space_between(prev: &TokenTree, curr: &TokenTree) -> bool { - if let TokenTree::Token(token, _) = prev { - // No space after these tokens, e.g. `x.y`, `$e` - // (The carets point to `prev`.) ^ ^ - if matches!(token.kind, token::Dot | token::Dollar) { - return false; - } - if let token::DocComment(comment_kind, ..) = token.kind { - return comment_kind != CommentKind::Line; - } - } - match curr { - // No space before these tokens, e.g. `foo,`, `println!`, `x.y` - // (The carets point to `curr`.) ^ ^ ^ +/// Should two consecutive tokens be printed with a space between them? +/// +/// Note: some old proc macros parse pretty-printed output, so changes here can +/// break old code. For example: +/// - #63896: `#[allow(unused,` must be printed rather than `#[allow(unused ,` +/// - #73345: `#[allow(unused)] must be printed rather than `# [allow(unused)] +/// +fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool { + use token::*; + use Delimiter::*; + use TokenTree::Delimited as Del; + use TokenTree::Token as Tok; + + // Each match arm has one or more examples in comments. The default is to + // insert space between adjacent tokens, except for the cases listed in + // this match. + match (tt1, tt2) { + // No space after line doc comments. + (Tok(Token { kind: DocComment(CommentKind::Line, ..), .. }, _), _) => false, + + // `.` + ANYTHING: `x.y`, `tup.0` + // `$` + ANYTHING: `$e` + (Tok(Token { kind: Dot | Dollar, .. }, _), _) => false, + + // ANYTHING + `,`: `foo,` + // ANYTHING + `.`: `x.y`, `tup.0` + // ANYTHING + `!`: `foo! { ... }` // - // FIXME: having `Not` here works well for macro invocations like - // `println!()`, but is bad when `!` means "logical not" or "the never - // type", where the lack of space causes ugliness like this: - // `Fn() ->!`, `x =! y`, `if! x { f(); }`. - TokenTree::Token(token, _) => !matches!(token.kind, token::Comma | token::Not | token::Dot), - // No space before parentheses if preceded by these tokens, e.g. `foo(...)` - TokenTree::Delimited(_, Delimiter::Parenthesis, _) => { - !matches!(prev, TokenTree::Token(Token { kind: token::Ident(..), .. }, _)) - } - // No space before brackets if preceded by these tokens, e.g. `#[...]` - TokenTree::Delimited(_, Delimiter::Bracket, _) => { - !matches!(prev, TokenTree::Token(Token { kind: token::Pound, .. }, _)) - } - TokenTree::Delimited(..) => true, + // FIXME: Incorrect cases: + // - Logical not: `x =! y`, `if! x { f(); }` + // - Never type: `Fn() ->!` + (_, Tok(Token { kind: Comma | Dot | Not, .. }, _)) => false, + + // IDENT + `(`: `f(3)` + // + // FIXME: Incorrect cases: + // - Let: `let(a, b) = (1, 2)` + (Tok(Token { kind: Ident(..), .. }, _), Del(_, Parenthesis, _)) => false, + + // `#` + `[`: `#[attr]` + (Tok(Token { kind: Pound, .. }, _), Del(_, Bracket, _)) => false, + + _ => true, } } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 8e66083a390..d3081695523 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -4,11 +4,11 @@ use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ build_configuration, build_session_options, rustc_optgroups, BranchProtection, CFGuard, Cfg, - DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, Input, - InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, - MirSpanview, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, - Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, - TraitSolver, WasiExecModel, + DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs, + InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, + LinkerPluginLto, LocationDetail, LtoCli, MirSpanview, OomStrategy, Options, OutFileName, + OutputType, OutputTypes, PAuthKey, PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, + SwitchWithOptPath, SymbolManglingVersion, TraitSolver, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -748,7 +748,7 @@ fn test_unstable_options_tracking_hash() { ); tracked!(codegen_backend, Some("abc".to_string())); tracked!(crate_attr, vec!["abc".to_string()]); - tracked!(cross_crate_inline_threshold, Some(200)); + tracked!(cross_crate_inline_threshold, InliningThreshold::Always); tracked!(debug_info_for_profiling, true); tracked!(debug_macros, true); tracked!(dep_info_omit_d_target, true); diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs index 4d0e261ed1f..261d9dd448d 100644 --- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs +++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs @@ -7,6 +7,7 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; +use rustc_session::config::InliningThreshold; use rustc_session::config::OptLevel; pub fn provide(providers: &mut Providers) { @@ -54,6 +55,12 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } + let threshold = match tcx.sess.opts.unstable_opts.cross_crate_inline_threshold { + InliningThreshold::Always => return true, + InliningThreshold::Sometimes(threshold) => threshold, + InliningThreshold::Never => return false, + }; + let mir = tcx.optimized_mir(def_id); let mut checker = CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 }; @@ -61,8 +68,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { checker.calls == 0 && checker.resumes == 0 && checker.landing_pads == 0 - && checker.statements - <= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100) + && checker.statements <= threshold } struct CostChecker<'b, 'tcx> { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 930fb693eb6..f745bc390ca 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3161,10 +3161,10 @@ impl PpMode { pub(crate) mod dep_tracking { use super::{ BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression, - ErrorOutputType, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, - LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Polonius, - RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, - SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, + ErrorOutputType, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, + LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, + Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, + SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, TraitSolver, TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -3270,6 +3270,7 @@ pub(crate) mod dep_tracking { LanguageIdentifier, TraitSolver, Polonius, + InliningThreshold, ); impl<T1, T2> DepTrackingHash for (T1, T2) @@ -3435,3 +3436,16 @@ impl Polonius { matches!(self, Polonius::Next) } } + +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum InliningThreshold { + Always, + Sometimes(usize), + Never, +} + +impl Default for InliningThreshold { + fn default() -> Self { + Self::Sometimes(100) + } +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7510a41485a..964a26e94fe 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -428,6 +428,8 @@ mod desc { "one of supported execution strategies (`same-thread`, or `cross-thread`)"; pub const parse_dump_solver_proof_tree: &str = "one of: `always`, `on-request`, `on-error`"; pub const parse_remap_path_scope: &str = "comma separated list of scopes: `macro`, `diagnostics`, `unsplit-debuginfo`, `split-debuginfo`, `split-debuginfo-path`, `object`, `all`"; + pub const parse_inlining_threshold: &str = + "either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number"; } mod parse { @@ -1310,6 +1312,26 @@ mod parse { }; true } + + pub(crate) fn parse_inlining_threshold(slot: &mut InliningThreshold, v: Option<&str>) -> bool { + match v { + Some("always" | "yes") => { + *slot = InliningThreshold::Always; + } + Some("never") => { + *slot = InliningThreshold::Never; + } + Some(v) => { + if let Ok(threshold) = v.parse() { + *slot = InliningThreshold::Sometimes(threshold); + } else { + return false; + } + } + None => return false, + } + true + } } options! { @@ -1479,7 +1501,7 @@ options! { "combine CGUs into a single one"), crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED], "inject the given attribute in the crate"), - cross_crate_inline_threshold: Option<usize> = (None, parse_opt_number, [TRACKED], + cross_crate_inline_threshold: InliningThreshold = (InliningThreshold::Sometimes(100), parse_inlining_threshold, [TRACKED], "threshold to allow cross crate inlining of functions"), debug_info_for_profiling: bool = (false, parse_bool, [TRACKED], "emit discriminators and other data necessary for AutoFDO"), |
