From f72e17f8fbcc96b103bb5c9b7b63e2f0e21e5f75 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 22 Jan 2023 13:05:47 +0100 Subject: [PATCH 01/12] Remove dependency on slice_internals feature in rustc_ast --- Cargo.lock | 1 + compiler/rustc_ast/Cargo.toml | 1 + compiler/rustc_ast/src/lib.rs | 1 - compiler/rustc_ast/src/util/unicode.rs | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da47b08c7df55..6251a4ca5162a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3633,6 +3633,7 @@ name = "rustc_ast" version = "0.0.0" dependencies = [ "bitflags", + "memchr", "rustc_data_structures", "rustc_index", "rustc_lexer", diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 9253b7e6891a2..10d7fa1db605a 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] bitflags = "1.2.1" +memchr = "2.5.0" rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 9c1dfeb1a6142..90c18de966008 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -16,7 +16,6 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(negative_impls)] -#![feature(slice_internals)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_ast/src/util/unicode.rs b/compiler/rustc_ast/src/util/unicode.rs index 0eae791b25e1c..6f57d66b2273a 100644 --- a/compiler/rustc_ast/src/util/unicode.rs +++ b/compiler/rustc_ast/src/util/unicode.rs @@ -17,7 +17,7 @@ pub fn contains_text_flow_control_chars(s: &str) -> bool { // U+2069 - E2 81 A9 let mut bytes = s.as_bytes(); loop { - match core::slice::memchr::memchr(0xE2, bytes) { + match memchr::memchr(0xE2, bytes) { Some(idx) => { // bytes are valid UTF-8 -> E2 must be followed by two bytes let ch = &bytes[idx..idx + 3]; From 77d7c63872c2a09ffc082bfd947b98ab216f2a76 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Thu, 26 Jan 2023 05:49:37 +0000 Subject: [PATCH 02/12] Update snap from `1.0.1` to `1.1.0` As spotted by @mejrs, snap 1.0.1 emits a future compatibility warning. This was fixed in https://github.com/BurntSushi/rust-snappy/pull/39 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3175e98e81e53..c81bf9fddf607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5214,9 +5214,9 @@ checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2" [[package]] name = "snap" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e" +checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" [[package]] name = "snapbox" From 727b987e0668fb87a328b7312cafdd40b75e8ed9 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 26 Jan 2023 10:57:11 +0100 Subject: [PATCH 03/12] solver comments + remove `TyCtxt::evaluate_goal` --- .../rustc_trait_selection/src/solve/mod.rs | 20 +++++++++---------- .../src/solve/project_goals.rs | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index f44648c95d742..7880cbad5fe03 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -141,17 +141,6 @@ type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>; /// solver, merge the two responses again. pub type QueryResult<'tcx> = Result, NoSolution>; -pub trait TyCtxtExt<'tcx> { - fn evaluate_goal(self, goal: CanonicalGoal<'tcx>) -> QueryResult<'tcx>; -} - -impl<'tcx> TyCtxtExt<'tcx> for TyCtxt<'tcx> { - fn evaluate_goal(self, goal: CanonicalGoal<'tcx>) -> QueryResult<'tcx> { - let mut search_graph = search_graph::SearchGraph::new(self); - EvalCtxt::evaluate_canonical_goal(self, &mut search_graph, goal) - } -} - pub trait InferCtxtEvalExt<'tcx> { /// Evaluates a goal from **outside** of the trait solver. /// @@ -194,6 +183,15 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.infcx.tcx } + /// The entry point of the solver. + /// + /// This function deals with (coinductive) cycles, overflow, and caching + /// and then calls [`EvalCtxt::compute_goal`] which contains the actual + /// logic of the solver. + /// + /// Instead of calling this function directly, use either [EvalCtxt::evaluate_goal] + /// if you're inside of the solver or [InferCtxtEvalExt::evaluate_root_goal] if you're + /// outside of it. #[instrument(level = "debug", skip(tcx, search_graph), ret)] fn evaluate_canonical_goal( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index b583705ac4369..30902c2bc4506 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -28,8 +28,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // To only compute normalization once for each projection we only // normalize if the expected term is an unconstrained inference variable. // - // E.g. for `::Assoc = u32` we recursively compute the goal - // `exists ::Assoc = U` and then take the resulting type for + // E.g. for `::Assoc == u32` we recursively compute the goal + // `exists ::Assoc == U` and then take the resulting type for // `U` and equate it with `u32`. This means that we don't need a separate // projection cache in the solver. if self.term_is_fully_unconstrained(goal) { From ac3ec77f0726daef011cfd6e44a4a52b1ef89803 Mon Sep 17 00:00:00 2001 From: chansuke Date: Fri, 27 Jan 2023 01:21:21 +0900 Subject: [PATCH 04/12] Fix woriding from `rustbuild` to `bootstrap` --- src/bootstrap/bootstrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 9cf43fc7a2193..abdd12127d366 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -712,7 +712,7 @@ def bootstrap_binary(self): def build_bootstrap(self, color): """Build bootstrap""" - print("Building rustbuild") + print("Building bootstrap") build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) From cce452d8c89ce69002bdafb3cbca83d86203d55c Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Fri, 27 Jan 2023 07:52:44 +0200 Subject: [PATCH 05/12] reduce rightward-drift --- compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index d9a73c7a5c904..240a9d2f37184 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -295,9 +295,8 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) { DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator ) { return None; - } else if ignore_unused_generics - && tcx.generics_of(def_id).requires_monomorphization(tcx) - { + } + if ignore_unused_generics && tcx.generics_of(def_id).requires_monomorphization(tcx) { return None; } Some(local_def_id.to_def_id()) From 9ef84076109ca9b6dd87fca7040781d778eb7605 Mon Sep 17 00:00:00 2001 From: Sergey Prytkov Date: Mon, 23 Jan 2023 21:03:06 +0300 Subject: [PATCH 06/12] Revisit fix_is_ci_llvm_available logic; read build triple from toml --- src/bootstrap/config.rs | 3 ++ src/bootstrap/config/tests.rs | 7 ++++ src/bootstrap/native.rs | 65 +++++++++++++++++------------------ 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index b41d60d51a8b5..fdd659c60ca7f 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -965,6 +965,9 @@ impl Config { config.changelog_seen = toml.changelog_seen; let build = toml.build.unwrap_or_default(); + if let Some(file_build) = build.build { + config.build = TargetSelection::from_user(&file_build); + }; set(&mut config.out, flags.build_dir.or_else(|| build.build_dir.map(PathBuf::from))); // NOTE: Bootstrap spawns various commands with different working directories. diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index c30c9131745c8..681ecbfeb5b8f 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -19,6 +19,13 @@ fn download_ci_llvm() { assert_eq!(parse_llvm(""), if_available); assert_eq!(parse_llvm("rust.channel = \"dev\""), if_available); assert!(!parse_llvm("rust.channel = \"stable\"")); + assert!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\"")); + assert!(parse_llvm( + "llvm.assertions = true \r\n build.build = \"x86_64-unknown-linux-gnu\" \r\n llvm.download-ci-llvm = \"if-available\"" + )); + assert!(!parse_llvm( + "llvm.assertions = true \r\n build.build = \"aarch64-apple-darwin\" \r\n llvm.download-ci-llvm = \"if-available\"" + )); } // FIXME: add test for detecting `src` and `out` diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index cb5706ca0a651..3acc2d4b5c4b1 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -180,43 +180,40 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { // https://doc.rust-lang.org/rustc/platform-support.html#tier-1 let supported_platforms = [ // tier 1 - "aarch64-unknown-linux-gnu", - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-msvc", + ("aarch64-unknown-linux-gnu", false), + ("i686-pc-windows-gnu", false), + ("i686-pc-windows-msvc", false), + ("i686-unknown-linux-gnu", false), + ("x86_64-unknown-linux-gnu", true), + ("x86_64-apple-darwin", true), + ("x86_64-pc-windows-gnu", true), + ("x86_64-pc-windows-msvc", true), // tier 2 with host tools - "aarch64-apple-darwin", - "aarch64-pc-windows-msvc", - "aarch64-unknown-linux-musl", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "armv7-unknown-linux-gnueabihf", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "riscv64gc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", + ("aarch64-apple-darwin", false), + ("aarch64-pc-windows-msvc", false), + ("aarch64-unknown-linux-musl", false), + ("arm-unknown-linux-gnueabi", false), + ("arm-unknown-linux-gnueabihf", false), + ("armv7-unknown-linux-gnueabihf", false), + ("mips-unknown-linux-gnu", false), + ("mips64-unknown-linux-gnuabi64", false), + ("mips64el-unknown-linux-gnuabi64", false), + ("mipsel-unknown-linux-gnu", false), + ("powerpc-unknown-linux-gnu", false), + ("powerpc64-unknown-linux-gnu", false), + ("powerpc64le-unknown-linux-gnu", false), + ("riscv64gc-unknown-linux-gnu", false), + ("s390x-unknown-linux-gnu", false), + ("x86_64-unknown-freebsd", false), + ("x86_64-unknown-illumos", false), + ("x86_64-unknown-linux-musl", false), + ("x86_64-unknown-netbsd", false), ]; - if !supported_platforms.contains(&&*config.build.triple) { - return false; - } - let triple = &*config.build.triple; - if (triple == "aarch64-unknown-linux-gnu" || triple.contains("i686")) && asserts { - // No alt builder for aarch64-unknown-linux-gnu today. - return false; + if !supported_platforms.contains(&(&*config.build.triple, asserts)) { + if asserts == true || !supported_platforms.contains(&(&*config.build.triple, true)) { + return false; + } } if CiEnv::is_ci() { From 0abf8a0617877a160f1ac6c46129ca428685cbca Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 13 Jan 2023 13:32:49 +0100 Subject: [PATCH 07/12] Replace format flags u32 by enums and bools. --- compiler/rustc_ast/src/format.rs | 26 ++++++- compiler/rustc_ast_lowering/src/format.rs | 9 ++- .../rustc_ast_pretty/src/pprust/state/expr.rs | 28 +++---- compiler/rustc_builtin_macros/src/format.rs | 13 +++- compiler/rustc_parse_format/src/lib.rs | 65 +++++++++------- compiler/rustc_parse_format/src/tests.rs | 75 +++++++++++++++---- 6 files changed, 154 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_ast/src/format.rs b/compiler/rustc_ast/src/format.rs index da05b09b37dcc..d021bea5ecacb 100644 --- a/compiler/rustc_ast/src/format.rs +++ b/compiler/rustc_ast/src/format.rs @@ -227,8 +227,30 @@ pub struct FormatOptions { pub alignment: Option, /// The fill character. E.g. the `.` in `{:.>10}`. pub fill: Option, - /// The `+`, `-`, `0`, `#`, `x?` and `X?` flags. - pub flags: u32, + /// The `+` or `-` flag. + pub sign: Option, + /// The `#` flag. + pub alternate: bool, + /// The `0` flag. E.g. the `0` in `{:02x}`. + pub zero_pad: bool, + /// The `x` or `X` flag (for `Debug` only). E.g. the `x` in `{:x?}`. + pub debug_hex: Option, +} + +#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq)] +pub enum FormatSign { + /// The `+` flag. + Plus, + /// The `-` flag. + Minus, +} + +#[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq)] +pub enum FormatDebugHex { + /// The `x` flag in `{:x?}`. + Lower, + /// The `X` flag in `{:X?}`. + Upper, } #[derive(Copy, Clone, Encodable, Decodable, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 776b532b0de86..5d1770c734d5d 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -148,7 +148,14 @@ fn make_format_spec<'hir>( None => sym::Unknown, }, ); - let flags = ctx.expr_u32(sp, placeholder.format_options.flags); + // This needs to match `FlagV1` in library/core/src/fmt/mod.rs. + let flags: u32 = ((placeholder.format_options.sign == Some(FormatSign::Plus)) as u32) + | ((placeholder.format_options.sign == Some(FormatSign::Minus)) as u32) << 1 + | (placeholder.format_options.alternate as u32) << 2 + | (placeholder.format_options.zero_pad as u32) << 3 + | ((placeholder.format_options.debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4 + | ((placeholder.format_options.debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5; + let flags = ctx.expr_u32(sp, flags); let prec = make_count(ctx, sp, &placeholder.format_options.precision, argmap); let width = make_count(ctx, sp, &placeholder.format_options.width, argmap); let format_placeholder_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative( diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 99ffa19016f27..cacfe9eb2f107 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -6,7 +6,10 @@ use rustc_ast::token; use rustc_ast::util::literal::escape_byte_str_symbol; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast::{self as ast, BlockCheckMode}; -use rustc_ast::{FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount, FormatTrait}; +use rustc_ast::{ + FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount, FormatDebugHex, FormatSign, + FormatTrait, +}; use std::fmt::Write; impl<'a> State<'a> { @@ -675,17 +678,15 @@ pub fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> St Some(FormatAlignment::Center) => template.push_str("^"), None => {} } - let flags = p.format_options.flags; - if flags >> (rustc_parse_format::FlagSignPlus as usize) & 1 != 0 { - template.push('+'); - } - if flags >> (rustc_parse_format::FlagSignMinus as usize) & 1 != 0 { - template.push('-'); + match p.format_options.sign { + Some(FormatSign::Plus) => template.push('+'), + Some(FormatSign::Minus) => template.push('-'), + None => {} } - if flags >> (rustc_parse_format::FlagAlternate as usize) & 1 != 0 { + if p.format_options.alternate { template.push('#'); } - if flags >> (rustc_parse_format::FlagSignAwareZeroPad as usize) & 1 != 0 { + if p.format_options.zero_pad { template.push('0'); } if let Some(width) = &p.format_options.width { @@ -709,11 +710,10 @@ pub fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> St } } } - if flags >> (rustc_parse_format::FlagDebugLowerHex as usize) & 1 != 0 { - template.push('x'); - } - if flags >> (rustc_parse_format::FlagDebugUpperHex as usize) & 1 != 0 { - template.push('X'); + match p.format_options.debug_hex { + Some(FormatDebugHex::Lower) => template.push('x'), + Some(FormatDebugHex::Upper) => template.push('X'), + None => {} } template.push_str(match p.format_trait { FormatTrait::Display => "", diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 469f0dc130383..e93a23394c03f 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -4,7 +4,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ Expr, ExprKind, FormatAlignment, FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind, FormatArguments, FormatCount, - FormatOptions, FormatPlaceholder, FormatTrait, + FormatDebugHex, FormatOptions, FormatPlaceholder, FormatSign, FormatTrait, }; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, Applicability, MultiSpan, PResult}; @@ -435,7 +435,16 @@ pub fn make_format_args( format_options: FormatOptions { fill: format.fill, alignment, - flags: format.flags, + sign: format.sign.map(|s| match s { + parse::Sign::Plus => FormatSign::Plus, + parse::Sign::Minus => FormatSign::Minus, + }), + alternate: format.alternate, + zero_pad: format.zero_pad, + debug_hex: format.debug_hex.map(|s| match s { + parse::DebugHex::Lower => FormatDebugHex::Lower, + parse::DebugHex::Upper => FormatDebugHex::Upper, + }), precision, width, }, diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 7b016cadac320..a6dfcd2976247 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -16,7 +16,6 @@ pub use Alignment::*; pub use Count::*; -pub use Flag::*; pub use Piece::*; pub use Position::*; @@ -111,8 +110,14 @@ pub struct FormatSpec<'a> { pub fill: Option, /// Optionally specified alignment. pub align: Alignment, - /// Packed version of various flags provided. - pub flags: u32, + /// The `+` or `-` flag. + pub sign: Option, + /// The `#` flag. + pub alternate: bool, + /// The `0` flag. + pub zero_pad: bool, + /// The `x` or `X` flag. (Only for `Debug`.) + pub debug_hex: Option, /// The integer precision to use. pub precision: Count<'a>, /// The span of the precision formatting flag (for diagnostics). @@ -162,24 +167,22 @@ pub enum Alignment { AlignUnknown, } -/// Various flags which can be applied to format strings. The meaning of these -/// flags is defined by the formatters themselves. +/// Enum for the sign flags. #[derive(Copy, Clone, Debug, PartialEq)] -pub enum Flag { - /// A `+` will be used to denote positive numbers. - FlagSignPlus, - /// A `-` will be used to denote negative numbers. This is the default. - FlagSignMinus, - /// An alternate form will be used for the value. In the case of numbers, - /// this means that the number will be prefixed with the supplied string. - FlagAlternate, - /// For numbers, this means that the number will be padded with zeroes, - /// and the sign (`+` or `-`) will precede them. - FlagSignAwareZeroPad, - /// For Debug / `?`, format integers in lower-case hexadecimal. - FlagDebugLowerHex, - /// For Debug / `?`, format integers in upper-case hexadecimal. - FlagDebugUpperHex, +pub enum Sign { + /// The `+` flag. + Plus, + /// The `-` flag. + Minus, +} + +/// Enum for the debug hex flags. +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum DebugHex { + /// The `x` flag in `{:x?}`. + Lower, + /// The `X` flag in `{:X?}`. + Upper, } /// A count is used for the precision and width parameters of an integer, and @@ -597,7 +600,10 @@ impl<'a> Parser<'a> { let mut spec = FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, precision_span: None, width: CountImplied, @@ -626,13 +632,13 @@ impl<'a> Parser<'a> { } // Sign flags if self.consume('+') { - spec.flags |= 1 << (FlagSignPlus as u32); + spec.sign = Some(Sign::Plus); } else if self.consume('-') { - spec.flags |= 1 << (FlagSignMinus as u32); + spec.sign = Some(Sign::Minus); } // Alternate marker if self.consume('#') { - spec.flags |= 1 << (FlagAlternate as u32); + spec.alternate = true; } // Width and precision let mut havewidth = false; @@ -647,7 +653,7 @@ impl<'a> Parser<'a> { spec.width_span = Some(self.span(end - 1, end + 1)); havewidth = true; } else { - spec.flags |= 1 << (FlagSignAwareZeroPad as u32); + spec.zero_pad = true; } } @@ -678,14 +684,14 @@ impl<'a> Parser<'a> { // Optional radix followed by the actual format specifier if self.consume('x') { if self.consume('?') { - spec.flags |= 1 << (FlagDebugLowerHex as u32); + spec.debug_hex = Some(DebugHex::Lower); spec.ty = "?"; } else { spec.ty = "x"; } } else if self.consume('X') { if self.consume('?') { - spec.flags |= 1 << (FlagDebugUpperHex as u32); + spec.debug_hex = Some(DebugHex::Upper); spec.ty = "?"; } else { spec.ty = "X"; @@ -708,7 +714,10 @@ impl<'a> Parser<'a> { let mut spec = FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, precision_span: None, width: CountImplied, diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs index 2992ba845ab16..45314e2fb5500 100644 --- a/compiler/rustc_parse_format/src/tests.rs +++ b/compiler/rustc_parse_format/src/tests.rs @@ -10,7 +10,10 @@ fn fmtdflt() -> FormatSpec<'static> { return FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -126,7 +129,10 @@ fn format_type() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -147,7 +153,10 @@ fn format_align_fill() { format: FormatSpec { fill: None, align: AlignRight, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -165,7 +174,10 @@ fn format_align_fill() { format: FormatSpec { fill: Some('0'), align: AlignLeft, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -183,7 +195,10 @@ fn format_align_fill() { format: FormatSpec { fill: Some('*'), align: AlignLeft, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -204,7 +219,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, precision_span: None, width: CountIs(10), @@ -222,7 +240,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIs(10), precision_span: Some(InnerSpan { start: 6, end: 9 }), width: CountIsParam(10), @@ -240,7 +261,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIs(10), precision_span: Some(InnerSpan { start: 6, end: 9 }), width: CountIsParam(0), @@ -258,7 +282,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIsStar(0), precision_span: Some(InnerSpan { start: 3, end: 5 }), width: CountImplied, @@ -276,7 +303,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIsParam(10), width: CountImplied, precision_span: Some(InnerSpan::new(3, 7)), @@ -294,7 +324,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIsName("b", InnerSpan { start: 6, end: 7 }), precision_span: Some(InnerSpan { start: 5, end: 8 }), width: CountIsName("a", InnerSpan { start: 3, end: 4 }), @@ -312,7 +345,10 @@ fn format_counts() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountIs(4), precision_span: Some(InnerSpan { start: 3, end: 5 }), width: CountImplied, @@ -333,7 +369,10 @@ fn format_flags() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: (1 << FlagSignMinus as u32), + sign: Some(Sign::Minus), + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -351,7 +390,10 @@ fn format_flags() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: (1 << FlagSignPlus as u32) | (1 << FlagAlternate as u32), + sign: Some(Sign::Plus), + alternate: true, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, @@ -374,7 +416,10 @@ fn format_mixture() { format: FormatSpec { fill: None, align: AlignUnknown, - flags: 0, + sign: None, + alternate: false, + zero_pad: false, + debug_hex: None, precision: CountImplied, width: CountImplied, precision_span: None, From be69002dd704a918885de493355705a545fa908a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 13 Jan 2023 13:56:51 +0100 Subject: [PATCH 08/12] Update clippy for restructured format flags fields. --- src/tools/clippy/clippy_utils/src/macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs index a8f8da67b5171..659063b97e74a 100644 --- a/src/tools/clippy/clippy_utils/src/macros.rs +++ b/src/tools/clippy/clippy_utils/src/macros.rs @@ -711,8 +711,8 @@ pub struct FormatSpec<'tcx> { pub fill: Option, /// Optionally specified alignment. pub align: Alignment, - /// Packed version of various flags provided, see [`rustc_parse_format::Flag`]. - pub flags: u32, + /// Whether all flag options are set to default (no flags specified). + pub no_flags: bool, /// Represents either the maximum width or the integer precision. pub precision: Count<'tcx>, /// The minimum width, will be padded according to `width`/`align` @@ -728,7 +728,7 @@ impl<'tcx> FormatSpec<'tcx> { Some(Self { fill: spec.fill, align: spec.align, - flags: spec.flags, + no_flags: spec.sign.is_none() && !spec.alternate && !spec.zero_pad && spec.debug_hex.is_none(), precision: Count::new( FormatParamUsage::Precision, spec.precision, @@ -773,7 +773,7 @@ impl<'tcx> FormatSpec<'tcx> { self.width.is_implied() && self.precision.is_implied() && self.align == Alignment::AlignUnknown - && self.flags == 0 + && self.no_flags } } From 706132d409d4a0156e88eeedeca255a19554841f Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 27 Jan 2023 10:58:58 +0100 Subject: [PATCH 09/12] compiler: Fix E0587 explanation We meant to use 8 as the packed argument. Signed-off-by: Samuel Ortiz --- compiler/rustc_error_codes/src/error_codes/E0587.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0587.md b/compiler/rustc_error_codes/src/error_codes/E0587.md index ee9031dc3796c..d7998af85b94f 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0587.md +++ b/compiler/rustc_error_codes/src/error_codes/E0587.md @@ -11,6 +11,6 @@ You cannot use `packed` and `align` hints on a same type. If you want to pack a type to a given size, you should provide a size to packed: ``` -#[repr(packed)] // ok! +#[repr(packed(8))] // ok! struct Umbrella(i32); ``` From 21cf9dbc8540656cb137ef31f9db8fd9f1398fd9 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 27 Jan 2023 11:43:38 +0100 Subject: [PATCH 10/12] Destructure format_options in make_format_spec. --- compiler/rustc_ast_lowering/src/format.rs | 32 +++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 5d1770c734d5d..e7dd0b18a03b9 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -137,11 +137,21 @@ fn make_format_spec<'hir>( } Err(_) => ctx.expr(sp, hir::ExprKind::Err), }; - let fill = ctx.expr_char(sp, placeholder.format_options.fill.unwrap_or(' ')); + let &FormatOptions { + ref width, + ref precision, + alignment, + fill, + sign, + alternate, + zero_pad, + debug_hex, + } = &placeholder.format_options; + let fill = ctx.expr_char(sp, fill.unwrap_or(' ')); let align = ctx.expr_lang_item_type_relative( sp, hir::LangItem::FormatAlignment, - match placeholder.format_options.alignment { + match alignment { Some(FormatAlignment::Left) => sym::Left, Some(FormatAlignment::Right) => sym::Right, Some(FormatAlignment::Center) => sym::Center, @@ -149,21 +159,21 @@ fn make_format_spec<'hir>( }, ); // This needs to match `FlagV1` in library/core/src/fmt/mod.rs. - let flags: u32 = ((placeholder.format_options.sign == Some(FormatSign::Plus)) as u32) - | ((placeholder.format_options.sign == Some(FormatSign::Minus)) as u32) << 1 - | (placeholder.format_options.alternate as u32) << 2 - | (placeholder.format_options.zero_pad as u32) << 3 - | ((placeholder.format_options.debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4 - | ((placeholder.format_options.debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5; + let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) + | ((sign == Some(FormatSign::Minus)) as u32) << 1 + | (alternate as u32) << 2 + | (zero_pad as u32) << 3 + | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4 + | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5; let flags = ctx.expr_u32(sp, flags); - let prec = make_count(ctx, sp, &placeholder.format_options.precision, argmap); - let width = make_count(ctx, sp, &placeholder.format_options.width, argmap); + let precision = make_count(ctx, sp, &precision, argmap); + let width = make_count(ctx, sp, &width, argmap); let format_placeholder_new = ctx.arena.alloc(ctx.expr_lang_item_type_relative( sp, hir::LangItem::FormatPlaceholder, sym::new, )); - let args = ctx.arena.alloc_from_iter([position, fill, align, flags, prec, width]); + let args = ctx.arena.alloc_from_iter([position, fill, align, flags, precision, width]); ctx.expr_call_mut(sp, format_placeholder_new, args) } From b8c44fa414ebd27c21035b5e9247902723fa2590 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Jan 2023 12:09:50 +0100 Subject: [PATCH 11/12] Fix infinite loop in rustdoc get_all_import_attributes function --- src/librustdoc/clean/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3cb6ad10e72b8..4b1cd78c4adf9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2112,10 +2112,12 @@ fn get_all_import_attributes<'hir>( ) { let hir_map = tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); + let mut visited = FxHashSet::default(); // If the item is an import and has at least a path with two parts, we go into it. while let hir::ItemKind::Use(path, _) = item.kind && path.segments.len() > 1 && - let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res + let hir::def::Res::Def(_, def_id) = path.segments[path.segments.len() - 2].res && + visited.insert(def_id) { if let Some(hir::Node::Item(parent_item)) = hir_map.get_if_local(def_id) { // We add the attributes from this import into the list. From 1b64e16643eb3322b61f916c8cfec436e30e7bf3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 27 Jan 2023 12:10:05 +0100 Subject: [PATCH 12/12] Add regression test for #107350 --- tests/rustdoc/issue-107350.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 tests/rustdoc/issue-107350.rs diff --git a/tests/rustdoc/issue-107350.rs b/tests/rustdoc/issue-107350.rs new file mode 100644 index 0000000000000..75f378ed24980 --- /dev/null +++ b/tests/rustdoc/issue-107350.rs @@ -0,0 +1,18 @@ +// This is a regression test for . +// It shouldn't loop indefinitely. + +#![crate_name = "foo"] + +// @has 'foo/oops/enum.OhNo.html' + +pub mod oops { + pub use crate::oops::OhNo; + + mod inner { + pub enum OhNo { + Item = 1, + } + } + + pub use self::inner::*; +}