diff --git a/.gitignore b/.gitignore index 1c50d9b054d..5f7135e38d1 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ __pycache__/ /inst/ /llvm/ /mingw-build/ +/src/tools/x/target # Created by default with `src/ci/docker/run.sh`: /obj/ /unicode-downloads diff --git a/Cargo.lock b/Cargo.lock index b992552a521..30b7628120b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1966,18 +1966,6 @@ dependencies = [ "toml", ] -[[package]] -name = "measureme" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef709d3257013bba7cff14fc504e07e80631d3fe0f6d38ce63b8f6510ccb932" -dependencies = [ - "byteorder", - "memmap", - "parking_lot 0.9.0", - "rustc-hash", -] - [[package]] name = "measureme" version = "9.0.0" @@ -2705,9 +2693,9 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.39" +version = "2.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9424b4650b9c1134d0a1b34dab82319691e1c95fa8af1658fc640deb1b6823c" +checksum = "68c5fb83bc092c10e12ca863ab8922b1833382d5d248aaafca779886d3396a44" dependencies = [ "bitflags", "clap", @@ -3033,19 +3021,18 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_arena" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e941a8fc3878a111d2bbfe78e39522d884136f0b412b12592195f26f653476" +checksum = "477085eefed2f12085c68577cc3827c8c39a31a4a750978aacb9af10f7903174" dependencies = [ - "rustc-ap-rustc_data_structures", "smallvec 1.4.2", ] [[package]] name = "rustc-ap-rustc_ast" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b58b6b035710df7f339a2bf86f6dafa876efd95439540970e24609e33598ca6" +checksum = "4d4ad5ec25f6b3d122354595be0d1b513f37fca3299d9b448b1db28f4a9e4b12" dependencies = [ "bitflags", "rustc-ap-rustc_data_structures", @@ -3060,9 +3047,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_passes" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d379a900d6a1f098490d92ab83e87487dcee2e4ec3f04c3ac4512b5117b64e2" +checksum = "0c6d8635298d7736decdb3c6e92e784d3eccde557462a9c10ac11a34fec3d756" dependencies = [ "itertools 0.9.0", "rustc-ap-rustc_ast", @@ -3079,9 +3066,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_pretty" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658d925c0da9e3c5cddc5e54f4fa8c03b41aff1fc6dc5e41837c1118ad010ac0" +checksum = "7a61bdb5252e1a95b7715038949e10f07ce770a436fcd497cdd9bc7255471de9" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_span", @@ -3091,9 +3078,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_attr" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f387037534f34c148aed753622677500e42d190a095670e7ac3fffc09811a59" +checksum = "84520a16cb61bd31e9c27e87eca5d933a9c94ac84f25649bddcc19989275ab2a" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_pretty", @@ -3110,10 +3097,11 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ffd17a37e00d77926a0713f191c59ff3aeb2b551a024c7cfffce14bab79be8" +checksum = "b1cb2b6a38759cf7c0c1434c8b4cbfcab9cd24970d05f960f2ca01226ddb4d68" dependencies = [ + "arrayvec", "bitflags", "cfg-if 0.1.10", "crossbeam-utils 0.7.2", @@ -3121,7 +3109,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme 0.7.1", + "measureme", "parking_lot 0.11.0", "rustc-ap-rustc_graphviz", "rustc-ap-rustc_index", @@ -3140,9 +3128,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b3263ddcfa9eb911e54a4e8088878dd9fd10e00d8b99b01033ba4a2733fe91d" +checksum = "46cfb19536426bf9252827a78552d635be207a4be74f4e92832aad82d7f2135c" dependencies = [ "annotate-snippets 0.8.0", "atty", @@ -3159,9 +3147,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_expand" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1ab7e68cede8a2273fd8b8623002ce9dc832e061dfc3330e9bcc1fc2a722d73" +checksum = "6273e60042a0ef31f6cfe783c519873993eb426f055be2bc058a48b6ca3934d0" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_passes", @@ -3182,9 +3170,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_feature" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea2dc95421bc19bbd4d939399833a882c46b684283b4267ad1fcf982fc043d9" +checksum = "2936e8346157e2848305e509f38aa3ed4e97697975ef68027587f5db6a38703f" dependencies = [ "rustc-ap-rustc_data_structures", "rustc-ap-rustc_span", @@ -3192,21 +3180,21 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_fs_util" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e44c1804f09635f83f6cf1e04c2e92f8aeb7b4e850ac6c53d373dab02c13053" +checksum = "9b4c3ae17776b5a5aa441ca510a650f75805e1f5569edd231caa8378552195a4" [[package]] name = "rustc-ap-rustc_graphviz" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc491f2b9be6e928f6df6b287549b8d50c48e8eff8638345155f40fa2cfb785d" +checksum = "5611bf0ac0ac49c2a22c959c7d8b17f85f69959293f0e8c4f753eca832fe7ad0" [[package]] name = "rustc-ap-rustc_index" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa73f3fed413cdb6290738a10267da17b9ae8e02087334778b9a8c9491c5efc0" +checksum = "ca67cf37c427057192e451c7f912e94ae9a8ca5ad69fd481c011fad3f86982cb" dependencies = [ "arrayvec", "rustc-ap-rustc_macros", @@ -3215,18 +3203,18 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_lexer" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e993881244a92f3b44cf43c8f22ae2ca5cefe4f55a34e2b65b72ee66fe5ad077" +checksum = "a5b04cd2159495584d976d501c5394498470c2e94e4f0cebb8186562d407a678" dependencies = [ "unicode-xid", ] [[package]] name = "rustc-ap-rustc_macros" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4effe366556e1d75344764adf4d54cba7c2fad33dbd07588e96d0853831ddc7c" +checksum = "61ec6d623853449acd3c65050d249d3674edab5f6e4d9f074c7bac183269f9c8" dependencies = [ "proc-macro2", "quote", @@ -3236,9 +3224,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_parse" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0342675835251571471d3dca9ea1576a853a8dfa1f4b0084db283c861223cb60" +checksum = "ca524bafce4b04d2b49fee2d40b4b26c3ebab9f1a4f731fdf561f00617862f02" dependencies = [ "bitflags", "rustc-ap-rustc_ast", @@ -3256,9 +3244,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_serialize" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438255ed968d73bf6573aa18d3b8d33c0a85ecdfd14160ef09ff813938e0606c" +checksum = "c67920561e58f98c4de864407c92b2dd05ace5d5e5301e17444f10f742c005b7" dependencies = [ "indexmap", "smallvec 1.4.2", @@ -3266,9 +3254,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_session" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d61ff76dede8eb827f6805754900d1097a7046f938f950231b62b448f55bf78" +checksum = "0762fd855792e06ef639327237898e4e092ad68150e6a8e19aeb7dc06276ad7a" dependencies = [ "bitflags", "getopts", @@ -3287,9 +3275,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_span" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c267f15c3cfc82a8a441d2bf86bcccf299d1eb625822468e3d8ee6f7c5a1c89" +checksum = "0bf3db7b4ca5d21c14c45475df155e5e020c9a3760346945a662c9a9053b49c8" dependencies = [ "cfg-if 0.1.10", "md-5 0.8.0", @@ -3306,9 +3294,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_target" -version = "679.0.0" +version = "686.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1b4b266c4d44aac0f7f83b6741d8f0545b03d1ce32f3b5254f2014225cb96c" +checksum = "3aa6560bb9742b276064d67ab9edb5766ecb303f8ae3854835ad3fad4b432188" dependencies = [ "bitflags", "rustc-ap-rustc_data_structures", @@ -3393,6 +3381,7 @@ dependencies = [ name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ + "byteorder", "crossbeam-utils 0.7.2", "proc-macro2", "quote", @@ -3523,7 +3512,7 @@ version = "0.0.0" dependencies = [ "bitflags", "libc", - "measureme 9.0.0", + "measureme", "rustc-demangle", "rustc_ast", "rustc_attr", @@ -3589,7 +3578,7 @@ dependencies = [ "indexmap", "jobserver", "libc", - "measureme 9.0.0", + "measureme", "parking_lot 0.11.0", "rustc-hash", "rustc-rayon", @@ -3907,7 +3896,7 @@ version = "0.0.0" dependencies = [ "bitflags", "chalk-ir", - "measureme 9.0.0", + "measureme", "polonius-engine", "rustc-rayon-core", "rustc_apfloat", @@ -4340,7 +4329,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.22" +version = "1.4.24" dependencies = [ "annotate-snippets 0.6.1", "anyhow", @@ -5263,7 +5252,7 @@ dependencies = [ "chrono", "lazy_static", "matchers", - "parking_lot 0.11.0", + "parking_lot 0.9.0", "regex", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index c27e5c469cf..e1a36d88086 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,11 +29,17 @@ members = [ "src/tools/unicode-table-generator", "src/tools/expand-yaml-anchors", ] + exclude = [ "build", "compiler/rustc_codegen_cranelift", # HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`. "obj", + # The `x` binary is a thin wrapper that calls `x.py`, which initializes + # submodules, before which workspace members cannot be invoked because + # not all `Cargo.toml` files are available, so we exclude the `x` binary, + # so it can be invoked before the current checkout is set up. + "src/tools/x", ] [profile.release.package.compiler_builtins] diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 0cffca17271..e413564fb3f 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -313,25 +313,24 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> { // Implement the proposal described in // https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449 // - // The macro invocation expands to the list of statements. - // If the list of statements is empty, then 'parse' - // the trailing semicolon on the original invocation - // as an empty statement. That is: + // The macro invocation expands to the list of statements. If the + // list of statements is empty, then 'parse' the trailing semicolon + // on the original invocation as an empty statement. That is: // // `empty();` is parsed as a single `StmtKind::Empty` // - // If the list of statements is non-empty, see if the - // final statement alreayd has a trailing semicolon. + // If the list of statements is non-empty, see if the final + // statement already has a trailing semicolon. // - // If it doesn't have a semicolon, then 'parse' the trailing semicolon - // from the invocation as part of the final statement, + // If it doesn't have a semicolon, then 'parse' the trailing + // semicolon from the invocation as part of the final statement, // using `stmt.add_trailing_semicolon()` // // If it does have a semicolon, then 'parse' the trailing semicolon // from the invocation as a new StmtKind::Empty - // FIXME: We will need to preserve the original - // semicolon token and span as part of #15701 + // FIXME: We will need to preserve the original semicolon token and + // span as part of #15701 let empty_stmt = ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Empty, diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index b16e22e8d77..8fa6e6a7101 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -16,9 +16,8 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: }) }); - let body_visit = s.fold(quote!(), |acc, bind| { + let body_visit = s.each(|bind| { quote! { - #acc ::rustc_middle::ty::fold::TypeFoldable::visit_with(#bind, __folder)?; } }); diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs index fb89b36060a..a8457043278 100644 --- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs +++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs @@ -61,22 +61,35 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { fn lint_const_item_usage( &self, + place: &Place<'tcx>, const_item: DefId, location: Location, decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b>, ) { - let source_info = self.body.source_info(location); - let lint_root = self.body.source_scopes[source_info.scope] - .local_data - .as_ref() - .assert_crate_local() - .lint_root; + // Don't lint on borrowing/assigning to a dereference + // e.g: + // + // `unsafe { *FOO = 0; *BAR.field = 1; }` + // `unsafe { &mut *FOO }` + if !matches!(place.projection.last(), Some(PlaceElem::Deref)) { + let source_info = self.body.source_info(location); + let lint_root = self.body.source_scopes[source_info.scope] + .local_data + .as_ref() + .assert_crate_local() + .lint_root; - self.tcx.struct_span_lint_hir(CONST_ITEM_MUTATION, lint_root, source_info.span, |lint| { - decorate(lint) - .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit() - }); + self.tcx.struct_span_lint_hir( + CONST_ITEM_MUTATION, + lint_root, + source_info.span, + |lint| { + decorate(lint) + .span_note(self.tcx.def_span(const_item), "`const` item defined here") + .emit() + }, + ); + } } } @@ -88,15 +101,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { // so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) { - // Don't lint on writes through a pointer - // (e.g. `unsafe { *FOO = 0; *BAR.field = 1; }`) - if !matches!(lhs.projection.last(), Some(PlaceElem::Deref)) { - self.lint_const_item_usage(def_id, loc, |lint| { - let mut lint = lint.build("attempting to modify a `const` item"); - lint.note("each usage of a `const` item creates a new temporary - the original `const` item will not be modified"); - lint - }) - } + self.lint_const_item_usage(&lhs, def_id, loc, |lint| { + let mut lint = lint.build("attempting to modify a `const` item"); + lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified"); + lint + }) } } // We are looking for MIR of the form: @@ -127,7 +136,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ConstMutationChecker<'a, 'tcx> { }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; - self.lint_const_item_usage(def_id, lint_loc, |lint| { + self.lint_const_item_usage(place, def_id, lint_loc, |lint| { let mut lint = lint.build("taking a mutable reference to a `const` item"); lint .note("each usage of a `const` item creates a new temporary") diff --git a/compiler/rustc_mir/src/transform/coverage/debug.rs b/compiler/rustc_mir/src/transform/coverage/debug.rs index cc697dfd7fe..ffa795134e2 100644 --- a/compiler/rustc_mir/src/transform/coverage/debug.rs +++ b/compiler/rustc_mir/src/transform/coverage/debug.rs @@ -147,8 +147,8 @@ impl DebugOptions { let mut counter_format = ExpressionFormat::default(); if let Ok(env_debug_options) = std::env::var(RUSTC_COVERAGE_DEBUG_OPTIONS) { - for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(",") { - let mut setting = setting_str.splitn(2, "="); + for setting_str in env_debug_options.replace(" ", "").replace("-", "_").split(',') { + let mut setting = setting_str.splitn(2, '='); match setting.next() { Some(option) if option == "allow_unused_expressions" => { allow_unused_expressions = bool_option_val(option, setting.next()); @@ -210,7 +210,7 @@ fn bool_option_val(option: &str, some_strval: Option<&str>) -> bool { fn counter_format_option_val(strval: &str) -> ExpressionFormat { let mut counter_format = ExpressionFormat { id: false, block: false, operation: false }; - let components = strval.splitn(3, "+"); + let components = strval.splitn(3, '+'); for component in components { match component { "id" => counter_format.id = true, @@ -695,7 +695,7 @@ pub(crate) fn dump_coverage_graphviz( let from_bcb_data = &basic_coverage_blocks[from_bcb]; let from_terminator = from_bcb_data.terminator(mir_body); let mut edge_labels = from_terminator.kind.fmt_successor_labels(); - edge_labels.retain(|label| label.to_string() != "unreachable"); + edge_labels.retain(|label| label != "unreachable"); let edge_counters = from_terminator .successors() .map(|&successor_bb| graphviz_data.get_edge_counter(from_bcb, successor_bb)); diff --git a/compiler/rustc_mir/src/transform/inline.rs b/compiler/rustc_mir/src/transform/inline.rs index 4de93739992..f3d2ab9590e 100644 --- a/compiler/rustc_mir/src/transform/inline.rs +++ b/compiler/rustc_mir/src/transform/inline.rs @@ -425,7 +425,7 @@ impl Inliner<'tcx> { } let dest = if dest_needs_borrow(destination.0) { - debug!("creating temp for return destination"); + trace!("creating temp for return destination"); let dest = Rvalue::Ref( self.tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, @@ -633,7 +633,7 @@ impl Inliner<'tcx> { } } - debug!("creating temp for argument {:?}", arg); + trace!("creating temp for argument {:?}", arg); // Otherwise, create a temporary for the arg let arg = Rvalue::Use(arg); @@ -703,19 +703,19 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { Local::new(self.new_locals.start.index() + (idx - self.args.len())) } }; - debug!("mapping local `{:?}` to `{:?}`", local, new); + trace!("mapping local `{:?}` to `{:?}`", local, new); new } fn map_scope(&self, scope: SourceScope) -> SourceScope { let new = SourceScope::new(self.new_scopes.start.index() + scope.index()); - debug!("mapping scope `{:?}` to `{:?}`", scope, new); + trace!("mapping scope `{:?}` to `{:?}`", scope, new); new } fn map_block(&self, block: BasicBlock) -> BasicBlock { let new = BasicBlock::new(self.new_blocks.start.index() + block.index()); - debug!("mapping block `{:?}` to `{:?}`", block, new); + trace!("mapping block `{:?}` to `{:?}`", block, new); new } } diff --git a/compiler/rustc_mir/src/util/generic_graphviz.rs b/compiler/rustc_mir/src/util/generic_graphviz.rs index 91499bb61c2..8bd4a512bbb 100644 --- a/compiler/rustc_mir/src/util/generic_graphviz.rs +++ b/compiler/rustc_mir/src/util/generic_graphviz.rs @@ -174,7 +174,7 @@ impl< where W: Write, { - let lines = label.split("\n").map(|s| dot::escape_html(s)).collect::>(); + let lines = label.split('\n').map(|s| dot::escape_html(s)).collect::>(); let escaped_label = lines.join(r#"
"#); writeln!(w, r#" label=<

{}



>;"#, escaped_label) } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 4e115c62c9e..5c7a7c1d0ae 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1021,17 +1021,11 @@ impl<'a> Resolver<'a> { ("", "") }; - let article = if built_in.is_empty() { res.article() } else { "a" }; - format!( - "{a}{built_in} {thing}{from}", - a = article, - thing = res.descr(), - built_in = built_in, - from = from - ) + let a = if built_in.is_empty() { res.article() } else { "a" }; + format!("{a}{built_in} {thing}{from}", thing = res.descr()) } else { let introduced = if b.is_import() { "imported" } else { "defined" }; - format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) + format!("the {thing} {introduced} here", thing = res.descr()) } } @@ -1049,19 +1043,13 @@ impl<'a> Resolver<'a> { ident.span, E0659, "`{ident}` is ambiguous ({why})", - ident = ident, why = kind.descr() ); err.span_label(ident.span, "ambiguous name"); let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); - let note_msg = format!( - "`{ident}` could{also} refer to {what}", - ident = ident, - also = also, - what = what - ); + let note_msg = format!("`{ident}` could{also} refer to {what}"); let thing = b.res().descr(); let mut help_msgs = Vec::new(); @@ -1071,30 +1059,18 @@ impl<'a> Resolver<'a> { || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) { help_msgs.push(format!( - "consider adding an explicit import of \ - `{ident}` to disambiguate", - ident = ident + "consider adding an explicit import of `{ident}` to disambiguate" )) } if b.is_extern_crate() && ident.span.rust_2018() { - help_msgs.push(format!( - "use `::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously")) } if misc == AmbiguityErrorMisc::SuggestCrate { - help_msgs.push(format!( - "use `crate::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs + .push(format!("use `crate::{ident}` to refer to this {thing} unambiguously")) } else if misc == AmbiguityErrorMisc::SuggestSelf { - help_msgs.push(format!( - "use `self::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) + help_msgs + .push(format!("use `self::{ident}` to refer to this {thing} unambiguously")) } err.span_note(b.span, ¬e_msg); @@ -1167,12 +1143,10 @@ impl<'a> Resolver<'a> { }; let first = ptr::eq(binding, first_binding); - let descr = get_descr(binding); let msg = format!( "{and_refers_to}the {item} `{name}`{which} is defined here{dots}", and_refers_to = if first { "" } else { "...and refers to " }, - item = descr, - name = name, + item = get_descr(binding), which = if first { "" } else { " which" }, dots = if next_binding.is_some() { "..." } else { "" }, ); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 14f8c7b09f8..00e6d5ca381 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -865,7 +865,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, &format!("use struct {} syntax instead", descr), - format!("{} {{{pad}{}{pad}}}", path_str, fields, pad = pad), + format!("{path_str} {{{pad}{fields}{pad}}}"), applicability, ); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 30cd9944b1a..f1e30470f8e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -11,6 +11,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] +#![feature(format_args_capture)] #![feature(nll)] #![feature(or_patterns)] #![recursion_limit = "256"] diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index a886e17f5a9..5ebc4d6c4c1 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -309,13 +309,13 @@ //! * `?` ⇒ [`Debug`] //! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers //! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers -//! * `o` ⇒ [`Octal`](trait.Octal.html) -//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html) -//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html) -//! * `p` ⇒ [`Pointer`](trait.Pointer.html) +//! * `o` ⇒ [`Octal`] +//! * `x` ⇒ [`LowerHex`] +//! * `X` ⇒ [`UpperHex`] +//! * `p` ⇒ [`Pointer`] //! * `b` ⇒ [`Binary`] -//! * `e` ⇒ [`LowerExp`](trait.LowerExp.html) -//! * `E` ⇒ [`UpperExp`](trait.UpperExp.html) +//! * `e` ⇒ [`LowerExp`] +//! * `E` ⇒ [`UpperExp`] //! //! What this means is that any type of argument which implements the //! [`fmt::Binary`][`Binary`] trait can then be formatted with `{:b}`. Implementations diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 405667e0b2a..15092d463ec 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -119,7 +119,6 @@ #![feature(raw_ref_op)] #![feature(rustc_attrs)] #![feature(receiver_trait)] -#![feature(renamed_spin_loop)] #![feature(min_specialization)] #![feature(slice_ptr_get)] #![feature(slice_ptr_len)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index ef2a5dd570f..b2afb702eeb 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -406,7 +406,8 @@ impl Cell { /// assert_eq!(five, 5); /// ``` #[stable(feature = "move_cell", since = "1.17.0")] - pub fn into_inner(self) -> T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> T { self.value.into_inner() } } @@ -573,7 +574,7 @@ pub struct RefCell { value: UnsafeCell, } -/// An error returned by [`RefCell::try_borrow`](struct.RefCell.html#method.try_borrow). +/// An error returned by [`RefCell::try_borrow`]. #[stable(feature = "try_borrow", since = "1.13.0")] pub struct BorrowError { _private: (), @@ -593,7 +594,7 @@ impl Display for BorrowError { } } -/// An error returned by [`RefCell::try_borrow_mut`](struct.RefCell.html#method.try_borrow_mut). +/// An error returned by [`RefCell::try_borrow_mut`]. #[stable(feature = "try_borrow", since = "1.13.0")] pub struct BorrowMutError { _private: (), @@ -668,12 +669,11 @@ impl RefCell { /// let five = c.into_inner(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] #[inline] - pub fn into_inner(self) -> T { + pub const fn into_inner(self) -> T { // Since this function takes `self` (the `RefCell`) by value, the // compiler statically verifies that it is not currently borrowed. - // Therefore the following assertion is just a `debug_assert!`. - debug_assert!(self.borrow.get() == UNUSED); self.value.into_inner() } @@ -1682,7 +1682,8 @@ impl UnsafeCell { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn into_inner(self) -> T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> T { self.value } } diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index a048f65a149..bbb3a3dea43 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,7 +29,7 @@ use self::Ordering::*; /// /// This trait allows for partial equality, for types that do not have a full /// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not [`Eq`](Eq). +/// so floating point types implement `PartialEq` but not [`Eq`]. /// /// Formally, the equality must be (for all `a`, `b` and `c`): /// diff --git a/library/core/src/fmt/builders.rs b/library/core/src/fmt/builders.rs index 63866a5d110..d95d43f0854 100644 --- a/library/core/src/fmt/builders.rs +++ b/library/core/src/fmt/builders.rs @@ -1,4 +1,6 @@ -use crate::fmt; +#![allow(unused_imports)] + +use crate::fmt::{self, Debug, Formatter}; struct PadAdapter<'buf, 'state> { buf: &'buf mut (dyn fmt::Write + 'buf), @@ -53,14 +55,12 @@ impl fmt::Write for PadAdapter<'_, '_> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted struct as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_struct`](struct.Formatter.html#method.debug_struct) -/// method. +/// This can be constructed by the [`Formatter::debug_struct`] method. /// /// # Examples /// @@ -257,14 +257,12 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted tuple as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_tuple`](struct.Formatter.html#method.debug_tuple) -/// method. +/// This can be constructed by the [`Formatter::debug_tuple`] method. /// /// # Examples /// @@ -428,14 +426,12 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted set of items as a part -/// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// of your [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_set`](struct.Formatter.html#method.debug_set) -/// method. +/// This can be constructed by the [`Formatter::debug_set`] method. /// /// # Examples /// @@ -560,14 +556,12 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted list of items as a part -/// of your [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// of your [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_list`](struct.Formatter.html#method.debug_list) -/// method. +/// This can be constructed by the [`Formatter::debug_list`] method. /// /// # Examples /// @@ -692,14 +686,12 @@ impl<'a, 'b: 'a> DebugList<'a, 'b> { } } -/// A struct to help with [`fmt::Debug`](trait.Debug.html) implementations. +/// A struct to help with [`fmt::Debug`](Debug) implementations. /// /// This is useful when you wish to output a formatted map as a part of your -/// [`Debug::fmt`](trait.Debug.html#tymethod.fmt) implementation. +/// [`Debug::fmt`] implementation. /// -/// This can be constructed by the -/// [`Formatter::debug_map`](struct.Formatter.html#method.debug_map) -/// method. +/// This can be constructed by the [`Formatter::debug_map`] method. /// /// # Examples /// diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 454fb34e77e..979a5f8cf50 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -1,6 +1,7 @@ #![stable(feature = "core_hint", since = "1.27.0")] //! Hints to compiler that affects how code should be emitted or optimized. +//! Hints may be compile time or runtime. use crate::intrinsics; @@ -24,7 +25,6 @@ use crate::intrinsics; /// Otherwise, consider using the [`unreachable!`] macro, which does not allow /// optimizations but will panic when executed. /// -/// /// # Example /// /// ``` @@ -51,18 +51,62 @@ pub const unsafe fn unreachable_unchecked() -> ! { unsafe { intrinsics::unreachable() } } -/// Emits a machine instruction hinting to the processor that it is running in busy-wait -/// spin-loop ("spin lock"). +/// Emits a machine instruction to signal the processor that it is running in +/// a busy-wait spin-loop ("spin lock"). /// -/// For a discussion of different locking strategies and their trade-offs, see -/// [`core::sync::atomic::spin_loop_hint`]. +/// Upon receiving the spin-loop signal the processor can optimize its behavior by, +/// for example, saving power or switching hyper-threads. /// -/// **Note**: On platforms that do not support receiving spin-loop hints this function does not -/// do anything at all. +/// This function is different from [`thread::yield_now`] which directly +/// yields to the system's scheduler, whereas `spin_loop` does not interact +/// with the operating system. /// -/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint +/// A common use case for `spin_loop` is implementing bounded optimistic +/// spinning in a CAS loop in synchronization primitives. To avoid problems +/// like priority inversion, it is strongly recommended that the spin loop is +/// terminated after a finite amount of iterations and an appropriate blocking +/// syscall is made. +/// +/// **Note**: On platforms that do not support receiving spin-loop hints this +/// function does not do anything at all. +/// +/// # Examples +/// +/// ``` +/// use std::sync::atomic::{AtomicBool, Ordering}; +/// use std::sync::Arc; +/// use std::{hint, thread}; +/// +/// // A shared atomic value that threads will use to coordinate +/// let live = Arc::new(AtomicBool::new(false)); +/// +/// // In a background thread we'll eventually set the value +/// let bg_work = { +/// let live = live.clone(); +/// thread::spawn(move || { +/// // Do some work, then make the value live +/// do_some_work(); +/// live.store(true, Ordering::Release); +/// }) +/// }; +/// +/// // Back on our current thread, we wait for the value to be set +/// while live.load(Ordering::Acquire) { +/// // The spin loop is a hint to the CPU that we're waiting, but probably +/// // not for very long +/// hint::spin_loop(); +/// } +/// +/// // The value is now set +/// # fn do_some_work() {} +/// do_some_work(); +/// bg_work.join()?; +/// # Ok::<(), Box>(()) +/// ``` +/// +/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html #[inline] -#[unstable(feature = "renamed_spin_loop", issue = "55002")] +#[stable(feature = "renamed_spin_loop", since = "1.49.0")] pub fn spin_loop() { #[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))] { diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 35adb4f69d8..96d0a60a327 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -121,7 +121,7 @@ where /// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`flatten`]: trait.Iterator.html#method.flatten +/// [`flatten`]: Iterator::flatten /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_flatten", since = "1.29.0")] diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index 9c8e639c2d8..9586284e1d7 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -85,7 +85,7 @@ pub unsafe trait SourceIter { /// * whatever remains in the source after iteration has stopped /// * the memory that has become unused by advancing a consuming iterator /// - /// [`next()`]: trait.Iterator.html#method.next + /// [`next()`]: Iterator::next unsafe fn as_inner(&mut self) -> &mut Self::Source; } @@ -94,7 +94,7 @@ pub unsafe trait SourceIter { /// This `struct` is created by the [`rev`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`rev`]: trait.Iterator.html#method.rev +/// [`rev`]: Iterator::rev /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -228,7 +228,7 @@ unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator { /// This `struct` is created by the [`copied`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`copied`]: trait.Iterator.html#method.copied +/// [`copied`]: Iterator::copied /// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_copied", since = "1.36.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -380,7 +380,7 @@ where /// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`cloned`]: trait.Iterator.html#method.cloned +/// [`cloned`]: Iterator::cloned /// [`Iterator`]: trait.Iterator.html #[stable(feature = "iter_cloned", since = "1.1.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -515,7 +515,7 @@ where /// This `struct` is created by the [`cycle`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`cycle`]: trait.Iterator.html#method.cycle +/// [`cycle`]: Iterator::cycle /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -600,7 +600,7 @@ impl FusedIterator for Cycle where I: Clone + Iterator {} /// This `struct` is created by the [`step_by`] method on [`Iterator`]. See /// its documentation for more. /// -/// [`step_by`]: trait.Iterator.html#method.step_by +/// [`step_by`]: Iterator::step_by /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "iterator_step_by", since = "1.28.0")] @@ -833,7 +833,7 @@ impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} /// This `struct` is created by the [`map`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`map`]: trait.Iterator.html#method.map +/// [`map`]: Iterator::map /// [`Iterator`]: trait.Iterator.html /// /// # Notes about side effects @@ -1042,7 +1042,7 @@ unsafe impl InPlaceIterable for Map where F: FnM /// This `struct` is created by the [`filter`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`filter`]: trait.Iterator.html#method.filter +/// [`filter`]: Iterator::filter /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1191,7 +1191,7 @@ unsafe impl InPlaceIterable for Filter where P: FnM /// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`filter_map`]: trait.Iterator.html#method.filter_map +/// [`filter_map`]: Iterator::filter_map /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1338,7 +1338,7 @@ unsafe impl InPlaceIterable for FilterMap where /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`enumerate`]: trait.Iterator.html#method.enumerate +/// [`enumerate`]: Iterator::enumerate /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -1574,7 +1574,7 @@ unsafe impl InPlaceIterable for Enumerate {} /// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`peekable`]: trait.Iterator.html#method.peekable +/// [`peekable`]: Iterator::peekable /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -1743,7 +1743,7 @@ impl Peekable { /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. /// But if the iteration is over, `None` is returned. /// - /// [`next`]: trait.Iterator.html#tymethod.next + /// [`next`]: Iterator::next /// /// Because `peek()` returns a reference, and many iterators iterate over /// references, there can be a possibly confusing situation where the @@ -1871,7 +1871,7 @@ unsafe impl InPlaceIterable for Peekable {} /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`skip_while`]: trait.Iterator.html#method.skip_while +/// [`skip_while`]: Iterator::skip_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -1993,7 +1993,7 @@ unsafe impl InPlaceIterable for SkipWhile where /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`take_while`]: trait.Iterator.html#method.take_while +/// [`take_while`]: Iterator::take_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2128,7 +2128,7 @@ unsafe impl InPlaceIterable for TakeWhile where /// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`map_while`]: trait.Iterator.html#method.map_while +/// [`map_while`]: Iterator::map_while /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")] @@ -2226,7 +2226,7 @@ unsafe impl InPlaceIterable for MapWhile where /// This `struct` is created by the [`skip`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`skip`]: trait.Iterator.html#method.skip +/// [`skip`]: Iterator::skip /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -2422,7 +2422,7 @@ unsafe impl InPlaceIterable for Skip {} /// This `struct` is created by the [`take`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`take`]: trait.Iterator.html#method.take +/// [`take`]: Iterator::take /// [`Iterator`]: trait.Iterator.html #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] @@ -2627,7 +2627,7 @@ unsafe impl TrustedLen for Take {} /// This `struct` is created by the [`scan`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`scan`]: trait.Iterator.html#method.scan +/// [`scan`]: Iterator::scan /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] @@ -2735,7 +2735,7 @@ unsafe impl InPlaceIterable for Scan whe /// This `struct` is created by the [`inspect`] method on [`Iterator`]. See its /// documentation for more. /// -/// [`inspect`]: trait.Iterator.html#method.inspect +/// [`inspect`]: Iterator::inspect /// [`Iterator`]: trait.Iterator.html #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 069e6e7e718..ea560288c28 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -70,6 +70,7 @@ #![feature(cfg_target_has_atomic)] #![feature(const_alloc_layout)] #![feature(const_discriminant)] +#![feature(const_cell_into_inner)] #![feature(const_checked_int_methods)] #![feature(const_euclidean_int_methods)] #![feature(const_float_classify)] diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 4f64e30ccf8..c90887b89d0 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -130,7 +130,7 @@ impl i128 { #[cfg(target_pointer_width = "16")] #[lang = "isize"] impl isize { - int_impl! { isize, i16, u16, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", + int_impl! { isize, i16, usize, 16, -32768, 32767, "", "", 4, "-0x5ffd", "0x3a", "0x1234", "0x3412", "0x2c48", "[0x34, 0x12]", "[0x12, 0x34]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } } @@ -138,7 +138,7 @@ impl isize { #[cfg(target_pointer_width = "32")] #[lang = "isize"] impl isize { - int_impl! { isize, i32, u32, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", + int_impl! { isize, i32, usize, 32, -2147483648, 2147483647, "", "", 8, "0x10000b3", "0xb301", "0x12345678", "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() } @@ -147,7 +147,7 @@ impl isize { #[cfg(target_pointer_width = "64")] #[lang = "isize"] impl isize { - int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "", + int_impl! { isize, i64, usize, 64, -9223372036854775808, 9223372036854775807, "", "", 12, "0xaa00000000006e1", "0x6e10aa", "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48", "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]", diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 2edeb81011a..d48c02bf59c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -115,23 +115,13 @@ use crate::hint::spin_loop; /// Signals the processor that it is inside a busy-wait spin-loop ("spin lock"). /// -/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving -/// power or switching hyper-threads. -/// -/// This function is different from [`std::thread::yield_now`] which directly yields to the -/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system. -/// -/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS -/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly -/// recommended that the spin loop is terminated after a finite amount of iterations and an -/// appropriate blocking syscall is made. +/// This function is expected to be deprecated in favor of +/// [`hint::spin_loop`]. /// /// **Note**: On platforms that do not support receiving spin-loop hints this function does not /// do anything at all. /// -/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html -/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html -/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html +/// [`hint::spin_loop`]: crate::hint::spin_loop #[inline] #[stable(feature = "spin_loop_hint", since = "1.24.0")] pub fn spin_loop_hint() { @@ -365,7 +355,8 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - pub fn into_inner(self) -> bool { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> bool { self.v.into_inner() != 0 } @@ -941,7 +932,8 @@ impl AtomicPtr { /// ``` #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] - pub fn into_inner(self) -> *mut T { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> *mut T { self.p.into_inner() } @@ -1462,7 +1454,8 @@ assert_eq!(some_var.into_inner(), 5); ```"), #[inline] #[$stable_access] - pub fn into_inner(self) -> $int_type { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> $int_type { self.v.into_inner() } } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 4e987a53b2c..6851f3fcd2f 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -39,15 +39,17 @@ impl Poll { /// Returns `true` if this is `Poll::Ready` #[inline] + #[rustc_const_stable(feature = "const_poll", since = "1.49.0")] #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_ready(&self) -> bool { + pub const fn is_ready(&self) -> bool { matches!(*self, Poll::Ready(_)) } /// Returns `true` if this is `Poll::Pending` #[inline] + #[rustc_const_stable(feature = "const_poll", since = "1.49.0")] #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_pending(&self) -> bool { + pub const fn is_pending(&self) -> bool { !self.is_ready() } } diff --git a/library/core/tests/cell.rs b/library/core/tests/cell.rs index 40be01f4439..77517879dd2 100644 --- a/library/core/tests/cell.rs +++ b/library/core/tests/cell.rs @@ -422,3 +422,15 @@ fn refcell_format() { let msg = format!("{name} {}", &*what.borrow(), name = &*name.borrow()); assert_eq!(msg, "rust rocks".to_string()); } + +#[allow(dead_code)] +fn const_cells() { + const UNSAFE_CELL: UnsafeCell = UnsafeCell::new(3); + const _: i32 = UNSAFE_CELL.into_inner(); + + const REF_CELL: RefCell = RefCell::new(3); + const _: i32 = REF_CELL.into_inner(); + + const CELL: Cell = Cell::new(3); + const _: i32 = CELL.into_inner(); +} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 0c4ce867f54..c9f9b890c39 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -9,6 +9,7 @@ #![feature(box_syntax)] #![feature(cell_update)] #![feature(const_assume)] +#![feature(const_cell_into_inner)] #![feature(core_intrinsics)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] @@ -91,5 +92,6 @@ mod result; mod slice; mod str; mod str_lossy; +mod task; mod time; mod tuple; diff --git a/library/core/tests/task.rs b/library/core/tests/task.rs new file mode 100644 index 00000000000..d71fef9e5c8 --- /dev/null +++ b/library/core/tests/task.rs @@ -0,0 +1,14 @@ +use core::task::Poll; + +#[test] +fn poll_const() { + // test that the methods of `Poll` are usable in a const context + + const POLL: Poll = Poll::Pending; + + const IS_READY: bool = POLL.is_ready(); + assert!(!IS_READY); + + const IS_PENDING: bool = POLL.is_pending(); + assert!(IS_PENDING); +} diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index d1244c2ca53..fa229251703 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1390,8 +1390,6 @@ pub struct IntoValues { /// A builder for computing where in a HashMap a key-value pair would be stored. /// /// See the [`HashMap::raw_entry_mut`] docs for usage examples. -/// -/// [`HashMap::raw_entry_mut`]: HashMap::raw_entry_mut #[unstable(feature = "hash_raw_entry", issue = "56167")] pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> { map: &'a mut HashMap, @@ -1430,8 +1428,6 @@ pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> { /// A builder for computing where in a HashMap a key-value pair would be stored. /// /// See the [`HashMap::raw_entry`] docs for usage examples. -/// -/// [`HashMap::raw_entry`]: HashMap::raw_entry #[unstable(feature = "hash_raw_entry", issue = "56167")] pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> { map: &'a HashMap, diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 5733735dc4a..bbee2cc9842 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -94,7 +94,8 @@ impl Cursor { /// # force_inference(&buff); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(inner: T) -> Cursor { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn new(inner: T) -> Cursor { Cursor { pos: 0, inner } } @@ -130,7 +131,8 @@ impl Cursor { /// let reference = buff.get_ref(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_ref(&self) -> &T { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn get_ref(&self) -> &T { &self.inner } @@ -175,7 +177,8 @@ impl Cursor { /// assert_eq!(buff.position(), 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn position(&self) -> u64 { + #[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] + pub const fn position(&self) -> u64 { self.pos } diff --git a/library/std/src/io/cursor/tests.rs b/library/std/src/io/cursor/tests.rs index 80d88ca66f6..5da31ce0ba7 100644 --- a/library/std/src/io/cursor/tests.rs +++ b/library/std/src/io/cursor/tests.rs @@ -514,3 +514,10 @@ fn test_eq() { let _: AssertEq>> = AssertEq(Cursor::new(Vec::new())); } + +#[allow(dead_code)] +fn const_cursor() { + const CURSOR: Cursor<&[u8]> = Cursor::new(&[0]); + const _: &&[u8] = CURSOR.get_ref(); + const _: u64 = CURSOR.position(); +} diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs index dc05b9648fd..2b1f371129e 100644 --- a/library/std/src/io/util.rs +++ b/library/std/src/io/util.rs @@ -102,7 +102,8 @@ pub struct Empty { /// assert!(buffer.is_empty()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn empty() -> Empty { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn empty() -> Empty { Empty { _priv: () } } @@ -159,7 +160,8 @@ pub struct Repeat { /// assert_eq!(buffer, [0b101, 0b101, 0b101]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn repeat(byte: u8) -> Repeat { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn repeat(byte: u8) -> Repeat { Repeat { byte } } @@ -226,7 +228,8 @@ pub struct Sink { /// assert_eq!(num_bytes, 5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub fn sink() -> Sink { +#[rustc_const_unstable(feature = "const_io_structs", issue = "78812")] +pub const fn sink() -> Sink { Sink { _priv: () } } diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs index e5e32ecb405..9450b1ee124 100644 --- a/library/std/src/io/util/tests.rs +++ b/library/std/src/io/util/tests.rs @@ -1,5 +1,5 @@ use crate::io::prelude::*; -use crate::io::{copy, empty, repeat, sink}; +use crate::io::{copy, empty, repeat, sink, Empty, Repeat, Sink}; #[test] fn copy_copies() { @@ -43,3 +43,10 @@ fn take_some_bytes() { assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); } + +#[allow(dead_code)] +fn const_utils() { + const _: Empty = empty(); + const _: Repeat = repeat(b'c'); + const _: Sink = sink(); +} diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 96a7755c688..bc218b77c87 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -242,6 +242,7 @@ #![feature(const_fn_transmute)] #![feature(const_fn)] #![feature(const_fn_fn_ptr_basics)] +#![feature(const_io_structs)] #![feature(const_ip)] #![feature(const_ipv6)] #![feature(const_raw_ptr_deref)] @@ -296,7 +297,6 @@ #![feature(raw)] #![feature(raw_ref_macros)] #![feature(ready_macro)] -#![feature(renamed_spin_loop)] #![feature(rustc_attrs)] #![feature(rustc_private)] #![feature(shrink_to)] diff --git a/library/std/src/sync/mpsc/mod.rs b/library/std/src/sync/mpsc/mod.rs index dc13c9433f1..db0777ee9f0 100644 --- a/library/std/src/sync/mpsc/mod.rs +++ b/library/std/src/sync/mpsc/mod.rs @@ -535,9 +535,6 @@ unsafe impl Send for SyncSender {} /// A **send** operation can only fail if the receiving end of a channel is /// disconnected, implying that the data could never be received. The error /// contains the data being sent as a payload so it can be recovered. -/// -/// [`Sender::send`]: Sender::send -/// [`SyncSender::send`]: SyncSender::send #[stable(feature = "rust1", since = "1.0.0")] #[derive(PartialEq, Eq, Clone, Copy)] pub struct SendError(#[stable(feature = "rust1", since = "1.0.0")] pub T); diff --git a/library/std/src/sys/cloudabi/abi/cloudabi.rs b/library/std/src/sys/cloudabi/abi/cloudabi.rs index 5c4e3fd85c4..d67f0f81a9f 100644 --- a/library/std/src/sys/cloudabi/abi/cloudabi.rs +++ b/library/std/src/sys/cloudabi/abi/cloudabi.rs @@ -143,7 +143,7 @@ pub enum advice { WILLNEED = 6, } -/// Enumeration describing the kind of value stored in [`auxv`](struct.auxv.html). +/// Enumeration describing the kind of value stored in [`auxv`]. #[repr(u32)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] #[non_exhaustive] @@ -246,7 +246,7 @@ pub struct condvar(pub u32); pub const CONDVAR_HAS_NO_WAITERS: condvar = condvar(0); /// Identifier for a device containing a file system. Can be used -/// in combination with [`inode`](struct.inode.html) to uniquely identify a file on the +/// in combination with [`inode`] to uniquely identify a file on the /// local system. #[repr(C)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] @@ -808,7 +808,7 @@ bitflags! { const FILE_SYMLINK = 0x0000000001000000; /// The right to invoke [`file_unlink()`](fn.file_unlink.html). const FILE_UNLINK = 0x0000000002000000; - /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`](struct.mprot.html) set to + /// The right to invoke [`mem_map()`](fn.mem_map.html) with [`mprot`] set to /// zero. const MEM_MAP = 0x0000000004000000; /// If [`MEM_MAP`](struct.rights.html#associatedconstant.MEM_MAP) is set, the right to invoke @@ -1020,7 +1020,7 @@ bitflags! { /// written it into locks when acquiring them for writing. It is /// not advised to use these identifiers for any other purpose. /// -/// As the thread identifier is also stored in [`lock`](struct.lock.html) when +/// As the thread identifier is also stored in [`lock`] when /// [`LOCK_WRLOCKED`](constant.LOCK_WRLOCKED.html) is set, the top two bits of the thread /// must always be set to zero. #[repr(C)] @@ -1373,7 +1373,7 @@ fn lookup_layout_test() { /// Entry point for a process (`_start`). /// /// **auxv**: -/// The auxiliary vector. See [`auxv`](struct.auxv.html). +/// The auxiliary vector. See [`auxv`]. pub type processentry = unsafe extern "C" fn(auxv: *const auxv) -> (); /// Arguments of [`sock_recv()`](fn.sock_recv.html). @@ -2372,7 +2372,7 @@ pub unsafe fn file_open( /// /// When successful, the contents of the output buffer consist of /// a sequence of directory entries. Each directory entry consists -/// of a [`dirent`](struct.dirent.html) object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes +/// of a [`dirent`] object, followed by [`dirent.d_namlen`](struct.dirent.html#structfield.d_namlen) bytes /// holding the name of the directory entry. /// /// This system call fills the output buffer as much as possible, diff --git a/library/std/src/sys/sgx/ext/io.rs b/library/std/src/sys/sgx/ext/io.rs index 8aa84a550d2..f79874a4aec 100644 --- a/library/std/src/sys/sgx/ext/io.rs +++ b/library/std/src/sys/sgx/ext/io.rs @@ -1,7 +1,7 @@ //! SGX-specific extensions to general I/O primitives //! //! SGX file descriptors behave differently from Unix file descriptors. See the -//! description of [`TryIntoRawFd`](trait.TryIntoRawFd.html) for more details. +//! description of [`TryIntoRawFd`] for more details. #![unstable(feature = "sgx_platform", issue = "56975")] use crate::net; diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index 74c7db27226..378d690f8bf 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -55,9 +55,18 @@ impl Socket { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result { unsafe { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { - // On Linux we pass the SOCK_CLOEXEC flag to atomically create - // the socket and set it as CLOEXEC, added in 2.6.27. + if #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { + // On platforms that support it we pass the SOCK_CLOEXEC + // flag to atomically create the socket and set it as + // CLOEXEC. On Linux this was added in 2.6.27. let fd = cvt(libc::socket(fam, ty | libc::SOCK_CLOEXEC, 0))?; Ok(Socket(FileDesc::new(fd))) } else { @@ -83,7 +92,15 @@ impl Socket { let mut fds = [0, 0]; cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { // Like above, set cloexec atomically cvt(libc::socketpair(fam, ty | libc::SOCK_CLOEXEC, 0, fds.as_mut_ptr()))?; Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1])))) @@ -174,13 +191,28 @@ impl Socket { pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result { // Unfortunately the only known way right now to accept a socket and // atomically set the CLOEXEC flag is to use the `accept4` syscall on - // Linux. This was added in 2.6.28, glibc 2.10 and musl 0.9.5. + // platforms that support it. On Linux, this was added in 2.6.28, + // glibc 2.10 and musl 0.9.5. cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { + if #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "netbsd", + target_os = "opensbd", + ))] { let fd = cvt_r(|| unsafe { libc::accept4(self.0.raw(), storage, len, libc::SOCK_CLOEXEC) })?; Ok(Socket(FileDesc::new(fd))) + // While the Android kernel supports the syscall, + // it is not included in all versions of Android's libc. + } else if #[cfg(target_os = "android")] { + let fd = cvt_r(|| unsafe { + libc::syscall(libc::SYS_accept4, self.0.raw(), storage, len, libc::SOCK_CLOEXEC) + })?; + Ok(Socket(FileDesc::new(fd as c_int))) } else { let fd = cvt_r(|| unsafe { libc::accept(self.0.raw(), storage, len) })?; let fd = FileDesc::new(fd); diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index d8db5d1aa69..dd438858c37 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -255,7 +255,7 @@ impl LocalKey { /// /// This will lazily initialize the value if this thread has not referenced /// this key yet. If the key has been destroyed (which may happen if this is called - /// in a destructor), this function will return an [`AccessError`](struct.AccessError.html). + /// in a destructor), this function will return an [`AccessError`]. /// /// # Panics /// diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index bdb8fc7807b..fefaa77a2a1 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -137,7 +137,6 @@ //! [`thread::current`]: current //! [`thread::Result`]: Result //! [`unpark`]: Thread::unpark -//! [`Thread::name`]: Thread::name //! [`thread::park_timeout`]: park_timeout //! [`Cell`]: crate::cell::Cell //! [`RefCell`]: crate::cell::RefCell diff --git a/library/test/src/helpers/concurrency.rs b/library/test/src/helpers/concurrency.rs index 7e9bd50f556..c39a9b0ec02 100644 --- a/library/test/src/helpers/concurrency.rs +++ b/library/test/src/helpers/concurrency.rs @@ -1,18 +1,14 @@ //! Helper module which helps to determine amount of threads to be used //! during tests execution. -use std::env; -use std::thread; +use std::{env, num::NonZeroUsize, thread}; -#[allow(deprecated)] pub fn get_concurrency() -> usize { - match env::var("RUST_TEST_THREADS") { - Ok(s) => { - let opt_n: Option = s.parse().ok(); - match opt_n { - Some(n) if n > 0 => n, - _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", s), - } + if let Ok(value) = env::var("RUST_TEST_THREADS") { + match value.parse::().ok() { + Some(n) => n.get(), + _ => panic!("RUST_TEST_THREADS is `{}`, should be a positive integer.", value), } - Err(..) => thread::available_concurrency().map(|n| n.get()).unwrap_or(1), + } else { + thread::available_concurrency().map(|n| n.get()).unwrap_or(1) } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 7698ff62880..40ea9afb6f6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -913,11 +913,18 @@ impl Config { set(&mut config.missing_tools, t.missing_tools); } - // Cargo does not provide a RUSTFMT environment variable, so we - // synthesize it manually. Note that we also later check the config.toml - // and set this to that path if necessary. - let rustfmt = config.initial_rustc.with_file_name(exe("rustfmt", config.build)); - config.initial_rustfmt = if rustfmt.exists() { Some(rustfmt) } else { None }; + config.initial_rustfmt = config.initial_rustfmt.or_else({ + let build = config.build; + let initial_rustc = &config.initial_rustc; + + move || { + // Cargo does not provide a RUSTFMT environment variable, so we + // synthesize it manually. + let rustfmt = initial_rustc.with_file_name(exe("rustfmt", build)); + + if rustfmt.exists() { Some(rustfmt) } else { None } + } + }); // Now that we've reached the end of our configuration, infer the // default values for all options that we haven't otherwise stored yet. diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index b48e9696c9a..2b87c4b91af 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1205,17 +1205,6 @@ note: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { - cmd.arg("--cc") - .arg(builder.cc(target)) - .arg("--cxx") - .arg(builder.cxx(target).unwrap()) - .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); - copts_passed = true; - if let Some(ar) = builder.ar(target) { - cmd.arg("--ar").arg(ar); - } - // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. let llvm_bin_path = llvm_config @@ -1241,6 +1230,21 @@ note: if you're sure you want to do this, please open an issue as to why. In the } } + // Only pass correct values for these flags for the `run-make` suite as it + // requires that a C++ compiler was configured which isn't always the case. + if !builder.config.dry_run && matches!(suite, "run-make" | "run-make-fulldeps") { + cmd.arg("--cc") + .arg(builder.cc(target)) + .arg("--cxx") + .arg(builder.cxx(target).unwrap()) + .arg("--cflags") + .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + copts_passed = true; + if let Some(ar) = builder.ar(target) { + cmd.arg("--ar").arg(ar); + } + } + if !llvm_components_passed { cmd.arg("--llvm-components").arg(""); } diff --git a/src/test/ui/lint/lint-const-item-mutation.rs b/src/test/ui/lint/lint-const-item-mutation.rs index c49a13f1065..ef55f31593b 100644 --- a/src/test/ui/lint/lint-const-item-mutation.rs +++ b/src/test/ui/lint/lint-const-item-mutation.rs @@ -29,6 +29,7 @@ const RAW_PTR: *mut u8 = 1 as *mut u8; const MUTABLE: Mutable = Mutable { msg: "" }; const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() }; const VEC: Vec = Vec::new(); +const PTR: *mut () = 1 as *mut _; fn main() { ARRAY[0] = 5; //~ WARN attempting to modify @@ -50,4 +51,8 @@ fn main() { MUTABLE.msg = "wow"; // no warning, because Drop observes the mutation MUTABLE2.msg = "wow"; //~ WARN attempting to modify VEC.push(0); //~ WARN taking a mutable reference to a `const` item + + // Test that we don't warn when converting a raw pointer + // into a mutable reference + unsafe { &mut *PTR }; } diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr index 11b5124b2d2..ae95abc72f3 100644 --- a/src/test/ui/lint/lint-const-item-mutation.stderr +++ b/src/test/ui/lint/lint-const-item-mutation.stderr @@ -1,11 +1,11 @@ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:34:5 + --> $DIR/lint-const-item-mutation.rs:35:5 | LL | ARRAY[0] = 5; | ^^^^^^^^^^^^ | = note: `#[warn(const_item_mutation)]` on by default - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:26:1 | @@ -13,12 +13,12 @@ LL | const ARRAY: [u8; 1] = [25]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:35:5 + --> $DIR/lint-const-item-mutation.rs:36:5 | LL | MY_STRUCT.field = false; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:27:1 | @@ -26,12 +26,12 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:36:5 + --> $DIR/lint-const-item-mutation.rs:37:5 | LL | MY_STRUCT.inner_array[0] = 'b'; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:27:1 | @@ -39,7 +39,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:37:5 + --> $DIR/lint-const-item-mutation.rs:38:5 | LL | MY_STRUCT.use_mut(); | ^^^^^^^^^^^^^^^^^^^ @@ -58,7 +58,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:38:5 + --> $DIR/lint-const-item-mutation.rs:39:5 | LL | &mut MY_STRUCT; | ^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:39:5 + --> $DIR/lint-const-item-mutation.rs:40:5 | LL | (&mut MY_STRUCT).use_mut(); | ^^^^^^^^^^^^^^^^ @@ -86,12 +86,12 @@ LL | const MY_STRUCT: MyStruct = MyStruct { field: true, inner_array: ['a'], raw | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: attempting to modify a `const` item - --> $DIR/lint-const-item-mutation.rs:51:5 + --> $DIR/lint-const-item-mutation.rs:52:5 | LL | MUTABLE2.msg = "wow"; | ^^^^^^^^^^^^^^^^^^^^ | - = note: each usage of a `const` item creates a new temporary - the original `const` item will not be modified + = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:30:1 | @@ -99,7 +99,7 @@ LL | const MUTABLE2: Mutable2 = Mutable2 { msg: "", other: String::new() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: taking a mutable reference to a `const` item - --> $DIR/lint-const-item-mutation.rs:52:5 + --> $DIR/lint-const-item-mutation.rs:53:5 | LL | VEC.push(0); | ^^^^^^^^^^^ diff --git a/src/test/ui/print_type_sizes/anonymous.rs b/src/test/ui/print_type_sizes/anonymous.rs index b96348640fa..2b008ca3b3a 100644 --- a/src/test/ui/print_type_sizes/anonymous.rs +++ b/src/test/ui/print_type_sizes/anonymous.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // All of the types that occur in this function are uninteresting, in // that one cannot control the sizes of these types with the same sort diff --git a/src/test/ui/print_type_sizes/generics.rs b/src/test/ui/print_type_sizes/generics.rs index f165526dffa..3ef7b60db2c 100644 --- a/src/test/ui/print_type_sizes/generics.rs +++ b/src/test/ui/print_type_sizes/generics.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/multiple_types.rs b/src/test/ui/print_type_sizes/multiple_types.rs index 4cb7ae03b54..f1ad27ec131 100644 --- a/src/test/ui/print_type_sizes/multiple_types.rs +++ b/src/test/ui/print_type_sizes/multiple_types.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates that when multiple structural types occur in // a function, every one of them is included in the output. diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index d9845fd6d70..37ac45f7e05 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/no_duplicates.rs b/src/test/ui/print_type_sizes/no_duplicates.rs index 4495a7770a7..e45e4794a35 100644 --- a/src/test/ui/print_type_sizes/no_duplicates.rs +++ b/src/test/ui/print_type_sizes/no_duplicates.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/packed.rs b/src/test/ui/print_type_sizes/packed.rs index dce4a61ef33..269cc3cc282 100644 --- a/src/test/ui/print_type_sizes/packed.rs +++ b/src/test/ui/print_type_sizes/packed.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/padding.rs b/src/test/ui/print_type_sizes/padding.rs index 1f894c5e252..d1acad16d7e 100644 --- a/src/test/ui/print_type_sizes/padding.rs +++ b/src/test/ui/print_type_sizes/padding.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates how padding is handled: alignment // requirements can lead to the introduction of padding, either before diff --git a/src/test/ui/print_type_sizes/repr-align.rs b/src/test/ui/print_type_sizes/repr-align.rs index 1e6f7ccca40..07544935b2f 100644 --- a/src/test/ui/print_type_sizes/repr-align.rs +++ b/src/test/ui/print_type_sizes/repr-align.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/repr_int_c.rs b/src/test/ui/print_type_sizes/repr_int_c.rs index 7aad2715bc0..b8067c112ee 100644 --- a/src/test/ui/print_type_sizes/repr_int_c.rs +++ b/src/test/ui/print_type_sizes/repr_int_c.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This test makes sure that the tag is not grown for `repr(C)` or `repr(u8)` // variants (see https://github.com/rust-lang/rust/issues/50098 for the original bug). diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index ae4e492456a..c234547bd14 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // ^-- needed because `--pass check` does not emit the output needed. // FIXME: consider using an attribute instead of side-effects. diff --git a/src/test/ui/print_type_sizes/variants.rs b/src/test/ui/print_type_sizes/variants.rs index 77e2b4befba..6c8553cc23d 100644 --- a/src/test/ui/print_type_sizes/variants.rs +++ b/src/test/ui/print_type_sizes/variants.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // This file illustrates two things: // diff --git a/src/test/ui/print_type_sizes/zero-sized-fields.rs b/src/test/ui/print_type_sizes/zero-sized-fields.rs index 71d09167747..e02a33109e5 100644 --- a/src/test/ui/print_type_sizes/zero-sized-fields.rs +++ b/src/test/ui/print_type_sizes/zero-sized-fields.rs @@ -1,5 +1,5 @@ // compile-flags: -Z print-type-sizes -// build-pass (FIXME(62277): could be check-pass?) +// build-pass // ignore-pass // At one point, zero-sized fields such as those in this file were causing diff --git a/src/tools/rls b/src/tools/rls index 1f686d5f707..dab1468d6ae 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 1f686d5f707269b1086f6afcdced36225c0c5ff7 +Subproject commit dab1468d6aeed0e49f7d0569c1d2128b5a7751e0 diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index 213cb07fddf..337d65e4da4 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -61,6 +61,7 @@ features = [ ] [dependencies] +byteorder = { version = "1", features = ['default', 'std'] } curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } crossbeam-utils = { version = "0.7.2", features = ["nightly"] } proc-macro2 = { version = "1", features = ["default"] } diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 97d03010115..eb894d53708 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 97d0301011533e1c131c0edd660d77b4bd476c8b +Subproject commit eb894d53708122a67762de9489881c11aa8ce257 diff --git a/src/tools/x/Cargo.lock b/src/tools/x/Cargo.lock new file mode 100644 index 00000000000..723d6cb25ed --- /dev/null +++ b/src/tools/x/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "x" +version = "0.1.0" diff --git a/src/tools/x/Cargo.toml b/src/tools/x/Cargo.toml new file mode 100644 index 00000000000..72c4948c617 --- /dev/null +++ b/src/tools/x/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "x" +version = "0.1.0" +description = "Run x.py slightly more conveniently" +authors = ["Casey Rodarmor "] +edition = "2018" +publish = false diff --git a/src/tools/x/README.md b/src/tools/x/README.md new file mode 100644 index 00000000000..3b3cf2847c2 --- /dev/null +++ b/src/tools/x/README.md @@ -0,0 +1,3 @@ +# x + +`x` invokes `x.py` from any subdirectory. diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs new file mode 100644 index 00000000000..6c0311433d6 --- /dev/null +++ b/src/tools/x/src/main.rs @@ -0,0 +1,92 @@ +//! Run `x.py` from any subdirectory of a rust compiler checkout. +//! +//! We prefer `exec`, to avoid adding an extra process in the process tree. +//! However, since `exec` isn't available on Windows, we indirect through +//! `exec_or_status`, which will call `exec` on unix and `status` on Windows. +//! +//! We use `python`, `python3`, or `python2` as the python interpreter to run +//! `x.py`, in that order of preference. + +use std::{ + env, io, + process::{self, Command, ExitStatus}, +}; + +const PYTHON: &str = "python"; +const PYTHON2: &str = "python2"; +const PYTHON3: &str = "python3"; + +fn python() -> &'static str { + let val = match env::var_os("PATH") { + Some(val) => val, + None => return PYTHON, + }; + + let mut python2 = false; + let mut python3 = false; + + for dir in env::split_paths(&val) { + if dir.join(PYTHON).exists() { + return PYTHON; + } + + python2 |= dir.join(PYTHON2).exists(); + python3 |= dir.join(PYTHON3).exists(); + } + + if python3 { + PYTHON3 + } else if python2 { + PYTHON2 + } else { + PYTHON + } +} + +#[cfg(unix)] +fn exec_or_status(command: &mut Command) -> io::Result { + use std::os::unix::process::CommandExt; + Err(command.exec()) +} + +#[cfg(not(unix))] +fn exec_or_status(command: &mut Command) -> io::Result { + command.status() +} + +fn main() { + let current = match env::current_dir() { + Ok(dir) => dir, + Err(err) => { + eprintln!("Failed to get current directory: {}", err); + process::exit(1); + } + }; + + for dir in current.ancestors() { + let candidate = dir.join("x.py"); + + if candidate.exists() { + let mut python = Command::new(python()); + + python.arg(&candidate).args(env::args().skip(1)).current_dir(dir); + + let result = exec_or_status(&mut python); + + match result { + Err(error) => { + eprintln!("Failed to invoke `{}`: {}", candidate.display(), error); + } + Ok(status) => { + process::exit(status.code().unwrap_or(1)); + } + } + } + } + + eprintln!( + "x.py not found. Please run inside of a checkout of `https://github.com/rust-lang/rust`." + ); + + process::exit(1); +}