]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #92080 - Aaron1011:pattern-ice, r=cjgillot
authorbors <bors@rust-lang.org>
Mon, 3 Jan 2022 06:59:52 +0000 (06:59 +0000)
committerbors <bors@rust-lang.org>
Mon, 3 Jan 2022 06:59:52 +0000 (06:59 +0000)
Move `PatKind::Lit` checking from ast_validation to ast lowering

Fixes #92074

This allows us to insert an `ExprKind::Err` when an invalid expression
is used in a literal pattern, preventing later stages of compilation
from seeing an unexpected literal pattern.

62 files changed:
Cargo.lock
compiler/rustc_builtin_macros/src/concat_bytes.rs
compiler/rustc_codegen_gcc/config.sh
compiler/rustc_codegen_gcc/test.sh
compiler/rustc_data_structures/src/thin_vec.rs
compiler/rustc_interface/src/interface.rs
compiler/rustc_interface/src/tests.rs
compiler/rustc_metadata/src/rmeta/decoder.rs
compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_metadata/src/rmeta/mod.rs
compiler/rustc_session/src/config.rs
compiler/rustc_session/src/options.rs
compiler/rustc_symbol_mangling/src/lib.rs
library/alloc/src/vec/mod.rs
library/core/src/slice/mod.rs
library/std/src/collections/hash/map.rs
library/std/src/collections/hash/set.rs
library/std/src/sys_common/process.rs
library/std/src/thread/mod.rs
rustfmt.toml
src/bootstrap/Cargo.toml
src/bootstrap/bin/rustc.rs
src/bootstrap/bin/rustdoc.rs
src/bootstrap/builder.rs
src/bootstrap/cache.rs
src/bootstrap/config.rs
src/bootstrap/dylib_util.rs [new file with mode: 0644]
src/bootstrap/lib.rs
src/bootstrap/util.rs
src/doc/unstable-book/src/compiler-flags/instrument-coverage.md
src/librustdoc/clean/inline.rs
src/librustdoc/clean/types.rs
src/librustdoc/clean/utils.rs
src/test/codegen/inline-hint.rs
src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile
src/test/run-make-fulldeps/share-generics-dylib/Makefile
src/test/rustdoc/where-clause-order.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs [new file with mode: 0644]
src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr [new file with mode: 0644]
src/test/ui/lifetimes/issue-84604.rs
src/test/ui/macros/concat-bytes-error.rs
src/test/ui/macros/concat-bytes-error.stderr
src/test/ui/macros/concat-bytes.rs
src/test/ui/no-link.rs
src/test/ui/no-link.stderr [deleted file]
src/test/ui/panics/issue-47429-short-backtraces.rs
src/test/ui/polymorphization/closure_in_upvar/fn.rs
src/test/ui/polymorphization/closure_in_upvar/fnmut.rs
src/test/ui/polymorphization/closure_in_upvar/fnonce.rs
src/test/ui/polymorphization/closure_in_upvar/other.rs
src/test/ui/polymorphization/symbol-ambiguity.rs
src/test/ui/symbol-names/basic.rs
src/test/ui/symbol-names/const-generics-demangling.rs
src/test/ui/symbol-names/const-generics-str-demangling.rs
src/test/ui/symbol-names/const-generics-structural-demangling.rs
src/test/ui/symbol-names/const-generics.rs
src/test/ui/symbol-names/impl1.rs
src/test/ui/symbol-names/issue-60925.rs
src/test/ui/symbol-names/issue-75326.rs
src/test/ui/symbol-names/issue-76365.rs
src/test/ui/symbol-names/trait-objects.rs

index 959c8161e984dd9636ef480d9b58ef0a6b503349..a912eee97dbf20ce638bcc7e2538a0185d88d4cd 100644 (file)
@@ -175,9 +175,7 @@ dependencies = [
  "filetime",
  "getopts",
  "ignore",
- "lazy_static",
  "libc",
- "merge",
  "num_cpus",
  "once_cell",
  "opener",
@@ -2221,28 +2219,6 @@ dependencies = [
  "autocfg",
 ]
 
-[[package]]
-name = "merge"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
-dependencies = [
- "merge_derive",
- "num-traits",
-]
-
-[[package]]
-name = "merge_derive"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
-dependencies = [
- "proc-macro-error",
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "minifier"
 version = "0.0.41"
index a107f5993b546312d74d791f308568a15640ea00..eb08170959bfb1e5f9bd63e08cb33255f037b67d 100644 (file)
@@ -72,6 +72,52 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
     }
 }
 
+fn handle_array_element(
+    cx: &mut base::ExtCtxt<'_>,
+    has_errors: &mut bool,
+    missing_literals: &mut Vec<rustc_span::Span>,
+    expr: &P<rustc_ast::Expr>,
+) -> Option<u8> {
+    match expr.kind {
+        ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
+            if !*has_errors {
+                cx.span_err(expr.span, "cannot concatenate doubly nested array");
+            }
+            *has_errors = true;
+            None
+        }
+        ast::ExprKind::Lit(ref lit) => match lit.kind {
+            ast::LitKind::Int(
+                val,
+                ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
+            ) if val <= u8::MAX.into() => Some(val as u8),
+
+            ast::LitKind::Byte(val) => Some(val),
+            ast::LitKind::ByteStr(_) => {
+                if !*has_errors {
+                    cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
+                        .note("byte strings are treated as arrays of bytes")
+                        .help("try flattening the array")
+                        .emit();
+                }
+                *has_errors = true;
+                None
+            }
+            _ => {
+                if !*has_errors {
+                    invalid_type_err(cx, expr, true);
+                }
+                *has_errors = true;
+                None
+            }
+        },
+        _ => {
+            missing_literals.push(expr.span);
+            None
+        }
+    }
+}
+
 pub fn expand_concat_bytes(
     cx: &mut base::ExtCtxt<'_>,
     sp: rustc_span::Span,
@@ -88,48 +134,27 @@ pub fn expand_concat_bytes(
         match e.kind {
             ast::ExprKind::Array(ref exprs) => {
                 for expr in exprs {
-                    match expr.kind {
-                        ast::ExprKind::Array(_) => {
-                            if !has_errors {
-                                cx.span_err(expr.span, "cannot concatenate doubly nested array");
-                            }
-                            has_errors = true;
-                        }
-                        ast::ExprKind::Lit(ref lit) => match lit.kind {
-                            ast::LitKind::Int(
-                                val,
-                                ast::LitIntType::Unsuffixed
-                                | ast::LitIntType::Unsigned(ast::UintTy::U8),
-                            ) if val <= u8::MAX.into() => {
-                                accumulator.push(val as u8);
-                            }
-
-                            ast::LitKind::Byte(val) => {
-                                accumulator.push(val);
-                            }
-                            ast::LitKind::ByteStr(_) => {
-                                if !has_errors {
-                                    cx.struct_span_err(
-                                        expr.span,
-                                        "cannot concatenate doubly nested array",
-                                    )
-                                    .note("byte strings are treated as arrays of bytes")
-                                    .help("try flattening the array")
-                                    .emit();
-                                }
-                                has_errors = true;
-                            }
-                            _ => {
-                                if !has_errors {
-                                    invalid_type_err(cx, expr, true);
-                                }
-                                has_errors = true;
-                            }
-                        },
-                        _ => {
-                            missing_literals.push(expr.span);
+                    if let Some(elem) =
+                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                    {
+                        accumulator.push(elem);
+                    }
+                }
+            }
+            ast::ExprKind::Repeat(ref expr, ref count) => {
+                if let ast::ExprKind::Lit(ast::Lit {
+                    kind: ast::LitKind::Int(count_val, _), ..
+                }) = count.value.kind
+                {
+                    if let Some(elem) =
+                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                    {
+                        for _ in 0..count_val {
+                            accumulator.push(elem);
                         }
                     }
+                } else {
+                    cx.span_err(count.value.span, "repeat count is not a positive number");
                 }
             }
             ast::ExprKind::Lit(ref lit) => match lit.kind {
index 87df2f2102bcd42dd3ede437a72a30552ff147e3..a932c1c8372b488dc479bbba4d8fd85f864d14f5 100644 (file)
@@ -38,7 +38,7 @@ if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
    fi
 fi
 
-export RUSTFLAGS="$linker -Cpanic=abort -Zsymbol-mangling-version=v0 -Cdebuginfo=2 -Clto=off -Zpanic-abort-tests -Zcodegen-backend=$(pwd)/target/${CHANNEL:-debug}/librustc_codegen_gcc.$dylib_ext --sysroot $(pwd)/build_sysroot/sysroot"
+export RUSTFLAGS="$linker -Cpanic=abort -Csymbol-mangling-version=v0 -Cdebuginfo=2 -Clto=off -Zpanic-abort-tests -Zcodegen-backend=$(pwd)/target/${CHANNEL:-debug}/librustc_codegen_gcc.$dylib_ext --sysroot $(pwd)/build_sysroot/sysroot"
 
 # FIXME(antoyo): remove once the atomic shim is gone
 if [[ `uname` == 'Darwin' ]]; then
index 944d0ce516e0f553b4e2f1a10471a85212eae9f3..b9aeee795504780d4a1355019eeee0bfa5832243 100755 (executable)
@@ -183,7 +183,7 @@ EOF
     git checkout src/test/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
     rm src/test/ui/llvm-asm/llvm-asm-in-out-operand.rs || true # TODO(antoyo): Enable back this test if I ever implement the llvm_asm! macro.
 
-    RUSTC_ARGS="-Zpanic-abort-tests -Zsymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot -Cpanic=abort"
+    RUSTC_ARGS="-Zpanic-abort-tests -Csymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot -Cpanic=abort"
 
     echo "[TEST] rustc test suite"
     COMPILETEST_FORCE_STAGE0=1 ./x.py test --run always --stage 0 src/test/ui/ --rustc-args "$RUSTC_ARGS"
index b5d2d24736cdc4b89d30e9dc4a84e83a84abebc2..716259142d18b22062149c4faa2c58de3c0966b6 100644 (file)
@@ -5,7 +5,7 @@
 /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVec`).
 /// The `Option<Box<..>>` wrapping allows us to represent a zero sized vector with `None`,
 /// which uses only a single (null) pointer.
-#[derive(Clone, Encodable, Decodable, Debug)]
+#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
 pub struct ThinVec<T>(Option<Box<Vec<T>>>);
 
 impl<T> ThinVec<T> {
@@ -20,6 +20,13 @@ pub fn iter(&self) -> std::slice::Iter<'_, T> {
     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
         self.into_iter()
     }
+
+    pub fn push(&mut self, item: T) {
+        match *self {
+            ThinVec(Some(ref mut vec)) => vec.push(item),
+            ThinVec(None) => *self = vec![item].into(),
+        }
+    }
 }
 
 impl<T> From<Vec<T>> for ThinVec<T> {
@@ -101,10 +108,7 @@ fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
     }
 
     fn extend_one(&mut self, item: T) {
-        match *self {
-            ThinVec(Some(ref mut vec)) => vec.push(item),
-            ThinVec(None) => *self = vec![item].into(),
-        }
+        self.push(item)
     }
 
     fn extend_reserve(&mut self, additional: usize) {
index 2904b3f5b7071bd5f54ed664a200d1bb0b1ac353..3804e10030733309293866cc5383da930661a2d8 100644 (file)
@@ -11,7 +11,7 @@
 use rustc_errors::{ErrorReported, Handler};
 use rustc_lint::LintStore;
 use rustc_middle::ty;
-use rustc_parse::new_parser_from_source_str;
+use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_query_impl::QueryCtxt;
 use rustc_session::config::{self, ErrorOutputType, Input, OutputFilenames};
 use rustc_session::early_error;
@@ -91,7 +91,6 @@ pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String
                     s
                 )));
                 let filename = FileName::cfg_spec_source_code(&s);
-                let mut parser = new_parser_from_source_str(&sess, filename, s.to_string());
 
                 macro_rules! error {
                     ($reason: expr) => {
@@ -102,26 +101,27 @@ macro_rules! error {
                     };
                 }
 
-                match &mut parser.parse_meta_item() {
-                    Ok(meta_item) if parser.token == token::Eof => {
-                        if meta_item.path.segments.len() != 1 {
-                            error!("argument key must be an identifier");
-                        }
-                        match &meta_item.kind {
-                            MetaItemKind::List(..) => {
-                                error!(r#"expected `key` or `key="value"`"#);
-                            }
-                            MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
-                                error!("argument value must be a string");
+                match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) {
+                    Ok(mut parser) => match &mut parser.parse_meta_item() {
+                        Ok(meta_item) if parser.token == token::Eof => {
+                            if meta_item.path.segments.len() != 1 {
+                                error!("argument key must be an identifier");
                             }
-                            MetaItemKind::NameValue(..) | MetaItemKind::Word => {
-                                let ident = meta_item.ident().expect("multi-segment cfg key");
-                                return (ident.name, meta_item.value_str());
+                            match &meta_item.kind {
+                                MetaItemKind::List(..) => {}
+                                MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
+                                    error!("argument value must be a string");
+                                }
+                                MetaItemKind::NameValue(..) | MetaItemKind::Word => {
+                                    let ident = meta_item.ident().expect("multi-segment cfg key");
+                                    return (ident.name, meta_item.value_str());
+                                }
                             }
                         }
-                    }
-                    Ok(..) => {}
-                    Err(err) => err.cancel(),
+                        Ok(..) => {}
+                        Err(err) => err.cancel(),
+                    },
+                    Err(errs) => errs.into_iter().for_each(|mut err| err.cancel()),
                 }
 
                 error!(r#"expected `key` or `key="value"`"#);
index 4a181ce544de0204ee490912eb165bb3802a540b..816e770f01252ed97e1b5f4aa0ec81839d1ee8af 100644 (file)
@@ -594,6 +594,7 @@ macro_rules! tracked {
     tracked!(relocation_model, Some(RelocModel::Pic));
     tracked!(soft_float, true);
     tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
+    tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
     tracked!(target_cpu, Some(String::from("abc")));
     tracked!(target_feature, String::from("all the features, all of them"));
 }
index 2b4504531a47d5b7ab3bd279d1ad65c89e1e3d32..8ff3b1e72d8047d142c806495e2908a72f5e7f51 100644 (file)
@@ -45,7 +45,8 @@
 use std::path::Path;
 use tracing::debug;
 
-pub use cstore_impl::{provide, provide_extern};
+pub(super) use cstore_impl::provide;
+pub use cstore_impl::provide_extern;
 use rustc_span::hygiene::HygieneDecodeContext;
 
 mod cstore_impl;
@@ -1099,10 +1100,7 @@ fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), ses
         };
 
         // Iterate over all children.
-        let macros_only = self.dep_kind.lock().macros_only();
-        if !macros_only {
-            let children = self.root.tables.children.get(self, id).unwrap_or_else(Lazy::empty);
-
+        if let Some(children) = self.root.tables.children.get(self, id) {
             for child_index in children.decode((self, sess)) {
                 // FIXME: Merge with the logic below.
                 if let None | Some(EntryKind::ForeignMod | EntryKind::Impl(_)) =
@@ -1171,11 +1169,6 @@ fn each_child_of_item(&self, id: DefIndex, mut callback: impl FnMut(Export), ses
 
         if let EntryKind::Mod(exports) = kind {
             for exp in exports.decode((self, sess)) {
-                match exp.res {
-                    Res::Def(DefKind::Macro(..), _) => {}
-                    _ if macros_only => continue,
-                    _ => {}
-                }
                 callback(exp);
             }
         }
index 6ca190c9adddf177ab1bb852065c8aaaafc8f620..7ffc586fda3a5e88c4064d0dbbdc83181415dc07 100644 (file)
@@ -4,11 +4,9 @@
 
 use rustc_ast as ast;
 use rustc_data_structures::stable_map::FxHashMap;
-use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
-use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_middle::hir::exports::Export;
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::middle::stability::DeprecationEntry;
@@ -243,7 +241,7 @@ fn into_args(self) -> (DefId, DefId) {
     expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(in crate::rmeta) fn provide(providers: &mut Providers) {
     // FIXME(#44234) - almost all of these queries have no sub-queries and
     // therefore no actual inputs, they're just reading tables calculated in
     // resolve! Does this work? Unsure! That's what the issue is about
@@ -289,28 +287,6 @@ pub fn provide(providers: &mut Providers) {
                 foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect();
             Lrc::new(modules)
         },
-        traits_in_crate: |tcx, cnum| {
-            assert_eq!(cnum, LOCAL_CRATE);
-
-            #[derive(Default)]
-            struct TraitsVisitor {
-                traits: Vec<DefId>,
-            }
-            impl ItemLikeVisitor<'_> for TraitsVisitor {
-                fn visit_item(&mut self, item: &hir::Item<'_>) {
-                    if let hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) = item.kind {
-                        self.traits.push(item.def_id.to_def_id());
-                    }
-                }
-                fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
-                fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
-                fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
-            }
-
-            let mut visitor = TraitsVisitor::default();
-            tcx.hir().visit_all_item_likes(&mut visitor);
-            tcx.arena.alloc_slice(&visitor.traits)
-        },
 
         // Returns a map from a sufficiently visible external item (i.e., an
         // external item that is visible from at least one local module) to a
index 42bce0da6fdf32d66fee2eab8cf4197a312110c2..3942846e79df069b6151648f79d4036db093551b 100644 (file)
@@ -27,6 +27,7 @@
 use rustc_middle::traits::specialization_graph;
 use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
+use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
 use rustc_serialize::{opaque, Encodable, Encoder};
 use rustc_session::config::CrateType;
@@ -612,10 +613,15 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
         self.encode_def_path_table();
         let def_path_table_bytes = self.position() - i;
 
+        // Encode the def IDs of traits, for rustdoc and diagnostics.
+        i = self.position();
+        let traits = self.encode_traits();
+        let traits_bytes = self.position() - i;
+
         // Encode the def IDs of impls, for coherence checking.
         i = self.position();
-        let (traits, impls) = self.encode_traits_and_impls();
-        let traits_and_impls_bytes = self.position() - i;
+        let impls = self.encode_impls();
+        let impls_bytes = self.position() - i;
 
         let tcx = self.tcx;
 
@@ -715,7 +721,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
             no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
             panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
             profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
-            symbol_mangling_version: tcx.sess.opts.debugging_opts.get_symbol_mangling_version(),
+            symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
 
             crate_deps,
             dylib_dependency_formats,
@@ -726,8 +732,8 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
             native_libraries,
             foreign_modules,
             source_map,
-            impls,
             traits,
+            impls,
             exported_symbols,
             interpret_alloc_index,
             tables,
@@ -754,7 +760,8 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
             eprintln!(" diagnostic item bytes: {}", diagnostic_item_bytes);
             eprintln!("          native bytes: {}", native_lib_bytes);
             eprintln!("      source_map bytes: {}", source_map_bytes);
-            eprintln!("traits and impls bytes: {}", traits_and_impls_bytes);
+            eprintln!("          traits bytes: {}", traits_bytes);
+            eprintln!("           impls bytes: {}", impls_bytes);
             eprintln!("    exp. symbols bytes: {}", exported_symbols_bytes);
             eprintln!("  def-path table bytes: {}", def_path_table_bytes);
             eprintln!(" def-path hashes bytes: {}", def_path_hash_map_bytes);
@@ -1791,24 +1798,22 @@ fn encode_lang_items_missing(&mut self) -> Lazy<[lang_items::LangItem]> {
         self.lazy(&tcx.lang_items().missing)
     }
 
+    fn encode_traits(&mut self) -> Lazy<[DefIndex]> {
+        empty_proc_macro!(self);
+        self.lazy(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index))
+    }
+
     /// Encodes an index, mapping each trait to its (local) implementations.
-    fn encode_traits_and_impls(&mut self) -> (Lazy<[DefIndex]>, Lazy<[TraitImpls]>) {
-        if self.is_proc_macro {
-            return (Lazy::empty(), Lazy::empty());
-        }
+    fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
         debug!("EncodeContext::encode_traits_and_impls()");
+        empty_proc_macro!(self);
         let tcx = self.tcx;
-        let mut visitor =
-            TraitsAndImplsVisitor { tcx, impls: FxHashMap::default(), traits: Default::default() };
+        let mut visitor = ImplsVisitor { tcx, impls: FxHashMap::default() };
         tcx.hir().visit_all_item_likes(&mut visitor);
 
-        let mut all_traits = visitor.traits;
         let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
 
         // Bring everything into deterministic order for hashing
-        all_traits.sort_by_cached_key(|&local_def_index| {
-            tcx.hir().def_path_hash(LocalDefId { local_def_index })
-        });
         all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
 
         let all_impls: Vec<_> = all_impls
@@ -1826,7 +1831,7 @@ fn encode_traits_and_impls(&mut self) -> (Lazy<[DefIndex]>, Lazy<[TraitImpls]>)
             })
             .collect();
 
-        (self.lazy(&all_traits), self.lazy(&all_impls))
+        self.lazy(&all_impls)
     }
 
     // Encodes all symbols exported from this crate into the metadata.
@@ -2048,18 +2053,14 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
     }
 }
 
-struct TraitsAndImplsVisitor<'tcx> {
+struct ImplsVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    traits: Vec<DefIndex>,
     impls: FxHashMap<DefId, Vec<(DefIndex, Option<fast_reject::SimplifiedType>)>>,
 }
 
-impl<'tcx, 'v> ItemLikeVisitor<'v> for TraitsAndImplsVisitor<'tcx> {
+impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
         match item.kind {
-            hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => {
-                self.traits.push(item.def_id.local_def_index);
-            }
             hir::ItemKind::Impl(..) => {
                 if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
                     let simplified_self_ty = fast_reject::simplify_type(
@@ -2224,3 +2225,34 @@ fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
 
     EncodedMetadata { raw_data: result }
 }
+
+pub fn provide(providers: &mut Providers) {
+    *providers = Providers {
+        traits_in_crate: |tcx, cnum| {
+            assert_eq!(cnum, LOCAL_CRATE);
+
+            #[derive(Default)]
+            struct TraitsVisitor {
+                traits: Vec<DefId>,
+            }
+            impl ItemLikeVisitor<'_> for TraitsVisitor {
+                fn visit_item(&mut self, item: &hir::Item<'_>) {
+                    if let hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) = item.kind {
+                        self.traits.push(item.def_id.to_def_id());
+                    }
+                }
+                fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
+                fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
+                fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
+            }
+
+            let mut visitor = TraitsVisitor::default();
+            tcx.hir().visit_all_item_likes(&mut visitor);
+            // Bring everything into deterministic order.
+            visitor.traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
+            tcx.arena.alloc_slice(&visitor.traits)
+        },
+
+        ..*providers
+    };
+}
index efe02451a2af90ea575b2ad0e42e30b8b3b12814..35016453369b59468abead6823818507868fca88 100644 (file)
@@ -16,6 +16,7 @@
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir;
 use rustc_middle::thir;
+use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, ReprOptions, Ty};
 use rustc_serialize::opaque::Encoder;
 use rustc_session::config::SymbolManglingVersion;
@@ -29,8 +30,8 @@
 use std::marker::PhantomData;
 use std::num::NonZeroUsize;
 
+pub use decoder::provide_extern;
 use decoder::DecodeContext;
-pub use decoder::{provide, provide_extern};
 crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
 use encoder::EncodeContext;
 pub use encoder::{encode_metadata, EncodedMetadata};
@@ -454,3 +455,8 @@ struct GeneratorData<'tcx> {
 const TAG_VALID_SPAN_LOCAL: u8 = 0;
 const TAG_VALID_SPAN_FOREIGN: u8 = 1;
 const TAG_PARTIAL_SPAN: u8 = 2;
+
+pub fn provide(providers: &mut Providers) {
+    encoder::provide(providers);
+    decoder::provide(providers);
+}
index 607ee8da975ccb0457455e0d52921355a2dd58b8..f2c7959ddb6e3212248166b52643d6e6dc87978c 100644 (file)
@@ -781,6 +781,10 @@ pub fn share_generics(&self) -> bool {
             },
         }
     }
+
+    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
+        self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
+    }
 }
 
 impl DebuggingOptions {
@@ -794,10 +798,6 @@ pub fn diagnostic_handler_flags(&self, can_emit_warnings: bool) -> HandlerFlags
             deduplicate_diagnostics: self.deduplicate_diagnostics,
         }
     }
-
-    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
-        self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
-    }
 }
 
 // The type of entry function, so users can have their own entry functions
@@ -2116,6 +2116,34 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         );
     }
 
+    // Handle both `-Z symbol-mangling-version` and `-C symbol-mangling-version`; the latter takes
+    // precedence.
+    match (cg.symbol_mangling_version, debugging_opts.symbol_mangling_version) {
+        (Some(smv_c), Some(smv_z)) if smv_c != smv_z => {
+            early_error(
+                error_format,
+                "incompatible values passed for `-C symbol-mangling-version` \
+                and `-Z symbol-mangling-version`",
+            );
+        }
+        (Some(SymbolManglingVersion::V0), _) => {}
+        (Some(_), _) if !debugging_opts.unstable_options => {
+            early_error(
+                error_format,
+                "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
+            );
+        }
+        (None, None) => {}
+        (None, smv) => {
+            early_warn(
+                error_format,
+                "`-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`",
+            );
+            cg.symbol_mangling_version = smv;
+        }
+        _ => {}
+    }
+
     if debugging_opts.instrument_coverage.is_some()
         && debugging_opts.instrument_coverage != Some(InstrumentCoverage::Off)
     {
@@ -2127,19 +2155,17 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             );
         }
 
-        // `-Z instrument-coverage` implies `-Z symbol-mangling-version=v0` - to ensure consistent
+        // `-Z instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
         // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
         // multiple runs, including some changes to source code; so mangled names must be consistent
         // across compilations.
-        match debugging_opts.symbol_mangling_version {
-            None => {
-                debugging_opts.symbol_mangling_version = Some(SymbolManglingVersion::V0);
-            }
+        match cg.symbol_mangling_version {
+            None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
             Some(SymbolManglingVersion::Legacy) => {
                 early_warn(
                     error_format,
                     "-Z instrument-coverage requires symbol mangling version `v0`, \
-                    but `-Z symbol-mangling-version=legacy` was specified",
+                    but `-C symbol-mangling-version=legacy` was specified",
                 );
             }
             Some(SymbolManglingVersion::V0) => {}
index f59b9b304ca6f21361967ff12d6799258065aa84..c8adc9f00a1b93e96ee8c33619eafa25a270af62 100644 (file)
@@ -1083,6 +1083,9 @@ mod parse {
         "how to handle split-debuginfo, a platform-specific option"),
     strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
         "tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
+    symbol_mangling_version: Option<SymbolManglingVersion> = (None,
+        parse_symbol_mangling_version, [TRACKED],
+        "which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
     target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
         "select target processor (`rustc --print target-cpus` for details)"),
     target_feature: String = (String::new(), parse_target_feature, [TRACKED],
@@ -1227,7 +1230,7 @@ mod parse {
     instrument_coverage: Option<InstrumentCoverage> = (None, parse_instrument_coverage, [TRACKED],
         "instrument the generated code to support LLVM source-based code coverage \
         reports (note, the compiler build config must include `profiler = true`); \
-        implies `-Z symbol-mangling-version=v0`. Optional values are:
+        implies `-C symbol-mangling-version=v0`. Optional values are:
         `=all` (implicit value)
         `=except-unused-generics`
         `=except-unused-functions`
index 65b5852bc39839caf06fa128dce5533222d383bd..1f38240ee41461b4832d92b2156ae01112b0a584 100644 (file)
@@ -237,7 +237,7 @@ fn compute_symbol_name<'tcx>(
 
     // Pick the crate responsible for the symbol mangling version, which has to:
     // 1. be stable for each instance, whether it's being defined or imported
-    // 2. obey each crate's own `-Z symbol-mangling-version`, as much as possible
+    // 2. obey each crate's own `-C symbol-mangling-version`, as much as possible
     // We solve these as follows:
     // 1. because symbol names depend on both `def_id` and `instantiating_crate`,
     // both their `CrateNum`s are stable for any given instance, so we can pick
@@ -245,7 +245,7 @@ fn compute_symbol_name<'tcx>(
     // 2. we favor `instantiating_crate` where possible (i.e. when `Some`)
     let mangling_version_crate = instantiating_crate.unwrap_or(def_id.krate);
     let mangling_version = if mangling_version_crate == LOCAL_CRATE {
-        tcx.sess.opts.debugging_opts.get_symbol_mangling_version()
+        tcx.sess.opts.get_symbol_mangling_version()
     } else {
         tcx.symbol_mangling_version(mangling_version_crate)
     };
index fffdc2c3ac09d234e25defd6d2da3dd3842dd26c..6fdaa8b950aa10d084ea33eaffad046375f2e7d9 100644 (file)
 #[cfg(not(no_global_oom_handling))]
 mod spec_extend;
 
-/// A contiguous growable array type, written as `Vec<T>` and pronounced 'vector'.
+/// A contiguous growable array type, written as `Vec<T>`, short for 'vector'.
 ///
 /// # Examples
 ///
index 49dce89a494c862eda3347db08ac852ad779c41e..0599f2740139410d67f745078e91393c4fbdbaa0 100644 (file)
@@ -585,6 +585,7 @@ pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_swap", issue = "83163")]
     #[inline]
+    #[track_caller]
     pub const fn swap(&mut self, a: usize, b: usize) {
         let _ = &self[a];
         let _ = &self[b];
@@ -1501,6 +1502,7 @@ pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[track_caller]
     pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
         assert!(mid <= self.len());
         // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
@@ -1531,6 +1533,7 @@ pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[track_caller]
     pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
         assert!(mid <= self.len());
         // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
@@ -1670,6 +1673,7 @@ pub unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [
     /// ```
     #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
     #[inline]
+    #[track_caller]
     pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]) {
         let (a, b) = self.split_at(N);
         // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at)
@@ -1701,6 +1705,7 @@ pub unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [
     /// ```
     #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
     #[inline]
+    #[track_caller]
     pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]) {
         let (a, b) = self.split_at_mut(N);
         // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
index 5ef23871e8b5f37f9c4d369e07fe30b161cc5ee2..c64377dfbc8acd9a8383e4ea9f84c31c01c39c63 100644 (file)
@@ -349,6 +349,33 @@ pub fn keys(&self) -> Keys<'_, K, V> {
         Keys { inner: self.iter() }
     }
 
+    /// Creates a consuming iterator visiting all the keys in arbitrary order.
+    /// The map cannot be used after calling this.
+    /// The iterator element type is `K`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let map = HashMap::from([
+    ///     ("a", 1),
+    ///     ("b", 2),
+    ///     ("c", 3),
+    /// ]);
+    ///
+    /// let mut vec: Vec<&str> = map.into_keys().collect();
+    /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
+    /// // keys must be sorted to test them against a sorted array.
+    /// vec.sort_unstable();
+    /// assert_eq!(vec, ["a", "b", "c"]);
+    /// ```
+    #[inline]
+    #[stable(feature = "map_into_keys_values", since = "1.54.0")]
+    pub fn into_keys(self) -> IntoKeys<K, V> {
+        IntoKeys { inner: self.into_iter() }
+    }
+
     /// An iterator visiting all values in arbitrary order.
     /// The iterator element type is `&'a V`.
     ///
@@ -399,6 +426,33 @@ pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
         ValuesMut { inner: self.iter_mut() }
     }
 
+    /// Creates a consuming iterator visiting all the values in arbitrary order.
+    /// The map cannot be used after calling this.
+    /// The iterator element type is `V`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let map = HashMap::from([
+    ///     ("a", 1),
+    ///     ("b", 2),
+    ///     ("c", 3),
+    /// ]);
+    ///
+    /// let mut vec: Vec<i32> = map.into_values().collect();
+    /// // The `IntoValues` iterator produces values in arbitrary order, so
+    /// // the values must be sorted to test them against a sorted array.
+    /// vec.sort_unstable();
+    /// assert_eq!(vec, [1, 2, 3]);
+    /// ```
+    #[inline]
+    #[stable(feature = "map_into_keys_values", since = "1.54.0")]
+    pub fn into_values(self) -> IntoValues<K, V> {
+        IntoValues { inner: self.into_iter() }
+    }
+
     /// An iterator visiting all key-value pairs in arbitrary order.
     /// The iterator element type is `(&'a K, &'a V)`.
     ///
@@ -555,6 +609,29 @@ pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F>
         DrainFilter { base: self.base.drain_filter(pred) }
     }
 
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
+    /// map.retain(|&k, _| k % 2 == 0);
+    /// assert_eq!(map.len(), 4);
+    /// ```
+    #[inline]
+    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
+    pub fn retain<F>(&mut self, f: F)
+    where
+        F: FnMut(&K, &mut V) -> bool,
+    {
+        self.base.retain(f)
+    }
+
     /// Clears the map, removing all key-value pairs. Keeps the allocated memory
     /// for reuse.
     ///
@@ -937,83 +1014,6 @@ pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
     {
         self.base.remove_entry(k)
     }
-
-    /// Retains only the elements specified by the predicate.
-    ///
-    /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
-    /// The elements are visited in unsorted (and unspecified) order.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
-    /// map.retain(|&k, _| k % 2 == 0);
-    /// assert_eq!(map.len(), 4);
-    /// ```
-    #[inline]
-    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
-    pub fn retain<F>(&mut self, f: F)
-    where
-        F: FnMut(&K, &mut V) -> bool,
-    {
-        self.base.retain(f)
-    }
-
-    /// Creates a consuming iterator visiting all the keys in arbitrary order.
-    /// The map cannot be used after calling this.
-    /// The iterator element type is `K`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let map = HashMap::from([
-    ///     ("a", 1),
-    ///     ("b", 2),
-    ///     ("c", 3),
-    /// ]);
-    ///
-    /// let mut vec: Vec<&str> = map.into_keys().collect();
-    /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
-    /// // keys must be sorted to test them against a sorted array.
-    /// vec.sort_unstable();
-    /// assert_eq!(vec, ["a", "b", "c"]);
-    /// ```
-    #[inline]
-    #[stable(feature = "map_into_keys_values", since = "1.54.0")]
-    pub fn into_keys(self) -> IntoKeys<K, V> {
-        IntoKeys { inner: self.into_iter() }
-    }
-
-    /// Creates a consuming iterator visiting all the values in arbitrary order.
-    /// The map cannot be used after calling this.
-    /// The iterator element type is `V`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let map = HashMap::from([
-    ///     ("a", 1),
-    ///     ("b", 2),
-    ///     ("c", 3),
-    /// ]);
-    ///
-    /// let mut vec: Vec<i32> = map.into_values().collect();
-    /// // The `IntoValues` iterator produces values in arbitrary order, so
-    /// // the values must be sorted to test them against a sorted array.
-    /// vec.sort_unstable();
-    /// assert_eq!(vec, [1, 2, 3]);
-    /// ```
-    #[inline]
-    #[stable(feature = "map_into_keys_values", since = "1.54.0")]
-    pub fn into_values(self) -> IntoValues<K, V> {
-        IntoValues { inner: self.into_iter() }
-    }
 }
 
 impl<K, V, S> HashMap<K, V, S>
index a1e28c0b0a695acba54719d5dee8187918124421..0d087772bf931053a54660844e15e6f7997e189a 100644 (file)
@@ -290,6 +290,28 @@ pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, T, F>
         DrainFilter { base: self.base.drain_filter(pred) }
     }
 
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
+    /// The elements are visited in unsorted (and unspecified) order.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
+    /// set.retain(|&k| k % 2 == 0);
+    /// assert_eq!(set.len(), 3);
+    /// ```
+    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
+    pub fn retain<F>(&mut self, f: F)
+    where
+        F: FnMut(&T) -> bool,
+    {
+        self.base.retain(f)
+    }
+
     /// Clears the set, removing all values.
     ///
     /// # Examples
@@ -906,28 +928,6 @@ pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
     {
         self.base.take(value)
     }
-
-    /// Retains only the elements specified by the predicate.
-    ///
-    /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
-    /// The elements are visited in unsorted (and unspecified) order.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set = HashSet::from([1, 2, 3, 4, 5, 6]);
-    /// set.retain(|&k| k % 2 == 0);
-    /// assert_eq!(set.len(), 3);
-    /// ```
-    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
-    pub fn retain<F>(&mut self, f: F)
-    where
-        F: FnMut(&T) -> bool,
-    {
-        self.base.retain(f)
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 2cd1e29f6c45ddfcc05bb6b93c272e899fee6fca..9f978789a62322c782245759d1cc4d66f0227405 100644 (file)
@@ -39,22 +39,6 @@ pub fn capture(&self) -> BTreeMap<EnvKey, OsString> {
         result
     }
 
-    // Apply these changes directly to the current environment
-    pub fn apply(&self) {
-        if self.clear {
-            for (k, _) in env::vars_os() {
-                env::remove_var(k);
-            }
-        }
-        for (key, maybe_val) in self.vars.iter() {
-            if let Some(ref val) = maybe_val {
-                env::set_var(key, val);
-            } else {
-                env::remove_var(key);
-            }
-        }
-    }
-
     pub fn is_unchanged(&self) -> bool {
         !self.clear && self.vars.is_empty()
     }
index bcf2ec06022d9a0d7d4f8f170f7ef0b12fee83c0..9f7f10d0d00813a2a7006d6b2390e9d0f2751aae 100644 (file)
@@ -972,10 +972,13 @@ pub fn park_timeout(dur: Duration) {
 
 /// A unique identifier for a running thread.
 ///
-/// A `ThreadId` is an opaque object that has a unique value for each thread
-/// that creates one. `ThreadId`s are not guaranteed to correspond to a thread's
-/// system-designated identifier. A `ThreadId` can be retrieved from the [`id`]
-/// method on a [`Thread`].
+/// A `ThreadId` is an opaque object that uniquely identifies each thread
+/// created during the lifetime of a process. `ThreadId`s are guaranteed not to
+/// be reused, even when a thread terminates. `ThreadId`s are under the control
+/// of Rust's standard library and there may not be any relationship between
+/// `ThreadId` and the underlying platform's notion of a thread identifier --
+/// the two concepts cannot, therefore, be used interchangeably. A `ThreadId`
+/// can be retrieved from the [`id`] method on a [`Thread`].
 ///
 /// # Examples
 ///
index 265f2194fef8d0ce03c61d1c2222828a7c823dde..aa0d4888f082dadf7f889c8b18286f0a14dfe54b 100644 (file)
@@ -19,7 +19,6 @@ ignore = [
     "library/backtrace",
     "library/portable-simd",
     "library/stdarch",
-    "compiler/rustc_codegen_cranelift",
     "compiler/rustc_codegen_gcc",
     "src/doc/book",
     "src/doc/edition-guide",
@@ -36,4 +35,9 @@ ignore = [
     "src/tools/rust-analyzer",
     "src/tools/rustfmt",
     "src/tools/rust-installer",
+
+    # these are ignored by a standard cargo fmt run
+    "compiler/rustc_codegen_cranelift/y.rs", # running rustfmt breaks this file
+    "compiler/rustc_codegen_cranelift/example",
+    "compiler/rustc_codegen_cranelift/scripts",
 ]
index 1ce1f0b26db58030254cf0a903fa10d751476da3..b68b2163f873a07291342ffef28dc7e7edbf8bd3 100644 (file)
@@ -44,11 +44,9 @@ libc = "0.2"
 serde = { version = "1.0.8", features = ["derive"] }
 serde_json = "1.0.2"
 toml = "0.5"
-lazy_static = "1.3.0"
 time = "0.1"
 ignore = "0.4.10"
 opener = "0.5"
-merge = "0.1.0"
 once_cell = "1.7.2"
 
 [target.'cfg(windows)'.dependencies.winapi]
index ed53a98e9a53f69967796a0da077cb4c10d139db..7105a2457e282329ebee43f59d269ffcd50bc635 100644 (file)
@@ -15,6 +15,8 @@
 //! switching compilers for the bootstrap and for build scripts will probably
 //! never get replaced.
 
+include!("../dylib_util.rs");
+
 use std::env;
 use std::path::PathBuf;
 use std::process::{Child, Command};
@@ -50,11 +52,11 @@ fn main() {
 
     let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
     let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
-    let mut dylib_path = bootstrap::util::dylib_path();
+    let mut dylib_path = dylib_path();
     dylib_path.insert(0, PathBuf::from(&libdir));
 
     let mut cmd = Command::new(rustc);
-    cmd.args(&args).env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
+    cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
 
     // Get the name of the crate we're compiling, if any.
     let crate_name =
@@ -161,7 +163,7 @@ fn main() {
         eprintln!(
             "{} command: {:?}={:?} {:?}",
             prefix,
-            bootstrap::util::dylib_path_var(),
+            dylib_path_var(),
             env::join_paths(&dylib_path).unwrap(),
             cmd,
         );
index e4396d53016ea5cf6cf0b95a90de99249cb2f0ab..ad3800834b07cc3f8d1892e3835fcfa01c3de612 100644 (file)
@@ -7,6 +7,8 @@
 use std::path::PathBuf;
 use std::process::Command;
 
+include!("../dylib_util.rs");
+
 fn main() {
     let args = env::args_os().skip(1).collect::<Vec<_>>();
     let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set");
@@ -20,14 +22,14 @@ fn main() {
         Err(_) => 0,
     };
 
-    let mut dylib_path = bootstrap::util::dylib_path();
+    let mut dylib_path = dylib_path();
     dylib_path.insert(0, PathBuf::from(libdir.clone()));
 
     let mut cmd = Command::new(rustdoc);
     cmd.args(&args)
         .arg("--sysroot")
         .arg(&sysroot)
-        .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
+        .env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
 
     // Force all crates compiled by this compiler to (a) be unstable and (b)
     // allow the `rustc_private` feature to link to other unstable crates
@@ -59,7 +61,7 @@ fn main() {
     if verbose > 1 {
         eprintln!(
             "rustdoc command: {:?}={:?} {:?}",
-            bootstrap::util::dylib_path_var(),
+            dylib_path_var(),
             env::join_paths(&dylib_path).unwrap(),
             cmd,
         );
index bbd2c087ccabbc8858f47eaae444a61d99fe1e1b..917abde9de1ce34eb81a2783e23d0f475142b341 100644 (file)
@@ -351,7 +351,6 @@ pub enum Kind {
     Check,
     Clippy,
     Fix,
-    Format,
     Test,
     Bench,
     Dist,
@@ -399,7 +398,7 @@ macro_rules! describe {
                 native::Lld,
                 native::CrtBeginEnd
             ),
-            Kind::Check | Kind::Clippy { .. } | Kind::Fix | Kind::Format => describe!(
+            Kind::Check | Kind::Clippy { .. } | Kind::Fix => describe!(
                 check::Std,
                 check::Rustc,
                 check::Rustdoc,
index 0c16fae01bca788ac7f2f7ba407c8db159da87d2..fac5d8db5119df6da5c7b4ab1a06241e19eba326 100644 (file)
@@ -13,7 +13,8 @@
 use std::path::{Path, PathBuf};
 use std::sync::Mutex;
 
-use lazy_static::lazy_static;
+// FIXME: replace with std::lazy after it gets stabilized and reaches beta
+use once_cell::sync::Lazy;
 
 use crate::builder::Step;
 
@@ -222,9 +223,7 @@ pub fn intern_path(&self, s: PathBuf) -> Interned<PathBuf> {
     }
 }
 
-lazy_static! {
-    pub static ref INTERNER: Interner = Interner::default();
-}
+pub static INTERNER: Lazy<Interner> = Lazy::new(Interner::default);
 
 /// This is essentially a `HashMap` which allows storing any type in its input and
 /// any type in its output. It is a write-once cache; values are never evicted,
index 7a4593a75f280b06cd6bf9324a5947dce8d74b2d..5af9248583caefd33ec026ef7b8feb01ce933189 100644 (file)
@@ -18,7 +18,6 @@
 use crate::flags::{Color, Flags};
 use crate::util::exe;
 use build_helper::t;
-use merge::Merge;
 use serde::Deserialize;
 
 macro_rules! check_ci_llvm {
@@ -334,6 +333,10 @@ struct TomlConfig {
     profile: Option<String>,
 }
 
+trait Merge {
+    fn merge(&mut self, other: Self);
+}
+
 impl Merge for TomlConfig {
     fn merge(
         &mut self,
@@ -357,105 +360,136 @@ fn do_merge<T: Merge>(x: &mut Option<T>, y: Option<T>) {
     }
 }
 
-/// TOML representation of various global build decisions.
-#[derive(Deserialize, Default, Clone, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct Build {
-    build: Option<String>,
-    host: Option<Vec<String>>,
-    target: Option<Vec<String>>,
-    // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable
-    build_dir: Option<String>,
-    cargo: Option<String>,
-    rustc: Option<String>,
-    rustfmt: Option<PathBuf>,
-    docs: Option<bool>,
-    compiler_docs: Option<bool>,
-    docs_minification: Option<bool>,
-    submodules: Option<bool>,
-    fast_submodules: Option<bool>,
-    gdb: Option<String>,
-    nodejs: Option<String>,
-    npm: Option<String>,
-    python: Option<String>,
-    locked_deps: Option<bool>,
-    vendor: Option<bool>,
-    full_bootstrap: Option<bool>,
-    extended: Option<bool>,
-    tools: Option<HashSet<String>>,
-    verbose: Option<usize>,
-    sanitizers: Option<bool>,
-    profiler: Option<bool>,
-    cargo_native_static: Option<bool>,
-    low_priority: Option<bool>,
-    configure_args: Option<Vec<String>>,
-    local_rebuild: Option<bool>,
-    print_step_timings: Option<bool>,
-    print_step_rusage: Option<bool>,
-    check_stage: Option<u32>,
-    doc_stage: Option<u32>,
-    build_stage: Option<u32>,
-    test_stage: Option<u32>,
-    install_stage: Option<u32>,
-    dist_stage: Option<u32>,
-    bench_stage: Option<u32>,
-    patch_binaries_for_nix: Option<bool>,
+// We are using a decl macro instead of a derive proc macro here to reduce the compile time of
+// rustbuild.
+macro_rules! derive_merge {
+    ($(#[$attr:meta])* struct $name:ident {
+        $($field:ident: $field_ty:ty,)*
+    }) => {
+        $(#[$attr])*
+        struct $name {
+            $($field: $field_ty,)*
+        }
+
+        impl Merge for $name {
+            fn merge(&mut self, other: Self) {
+                $(
+                    if !self.$field.is_some() {
+                        self.$field = other.$field;
+                    }
+                )*
+            }
+        }
+    }
 }
 
-/// TOML representation of various global install decisions.
-#[derive(Deserialize, Default, Clone, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct Install {
-    prefix: Option<String>,
-    sysconfdir: Option<String>,
-    docdir: Option<String>,
-    bindir: Option<String>,
-    libdir: Option<String>,
-    mandir: Option<String>,
-    datadir: Option<String>,
+derive_merge! {
+    /// TOML representation of various global build decisions.
+    #[derive(Deserialize, Default, Clone)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct Build {
+        build: Option<String>,
+        host: Option<Vec<String>>,
+        target: Option<Vec<String>>,
+        // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable
+        build_dir: Option<String>,
+        cargo: Option<String>,
+        rustc: Option<String>,
+        rustfmt: Option<PathBuf>,
+        docs: Option<bool>,
+        compiler_docs: Option<bool>,
+        docs_minification: Option<bool>,
+        submodules: Option<bool>,
+        fast_submodules: Option<bool>,
+        gdb: Option<String>,
+        nodejs: Option<String>,
+        npm: Option<String>,
+        python: Option<String>,
+        locked_deps: Option<bool>,
+        vendor: Option<bool>,
+        full_bootstrap: Option<bool>,
+        extended: Option<bool>,
+        tools: Option<HashSet<String>>,
+        verbose: Option<usize>,
+        sanitizers: Option<bool>,
+        profiler: Option<bool>,
+        cargo_native_static: Option<bool>,
+        low_priority: Option<bool>,
+        configure_args: Option<Vec<String>>,
+        local_rebuild: Option<bool>,
+        print_step_timings: Option<bool>,
+        print_step_rusage: Option<bool>,
+        check_stage: Option<u32>,
+        doc_stage: Option<u32>,
+        build_stage: Option<u32>,
+        test_stage: Option<u32>,
+        install_stage: Option<u32>,
+        dist_stage: Option<u32>,
+        bench_stage: Option<u32>,
+        patch_binaries_for_nix: Option<bool>,
+    }
 }
 
-/// TOML representation of how the LLVM build is configured.
-#[derive(Deserialize, Default, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct Llvm {
-    skip_rebuild: Option<bool>,
-    optimize: Option<bool>,
-    thin_lto: Option<bool>,
-    release_debuginfo: Option<bool>,
-    assertions: Option<bool>,
-    tests: Option<bool>,
-    plugins: Option<bool>,
-    ccache: Option<StringOrBool>,
-    version_check: Option<bool>,
-    static_libstdcpp: Option<bool>,
-    ninja: Option<bool>,
-    targets: Option<String>,
-    experimental_targets: Option<String>,
-    link_jobs: Option<u32>,
-    link_shared: Option<bool>,
-    version_suffix: Option<String>,
-    clang_cl: Option<String>,
-    cflags: Option<String>,
-    cxxflags: Option<String>,
-    ldflags: Option<String>,
-    use_libcxx: Option<bool>,
-    use_linker: Option<String>,
-    allow_old_toolchain: Option<bool>,
-    polly: Option<bool>,
-    clang: Option<bool>,
-    download_ci_llvm: Option<StringOrBool>,
+derive_merge! {
+    /// TOML representation of various global install decisions.
+    #[derive(Deserialize, Default, Clone)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct Install {
+        prefix: Option<String>,
+        sysconfdir: Option<String>,
+        docdir: Option<String>,
+        bindir: Option<String>,
+        libdir: Option<String>,
+        mandir: Option<String>,
+        datadir: Option<String>,
+    }
 }
 
-#[derive(Deserialize, Default, Clone, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct Dist {
-    sign_folder: Option<String>,
-    gpg_password_file: Option<String>,
-    upload_addr: Option<String>,
-    src_tarball: Option<bool>,
-    missing_tools: Option<bool>,
-    compression_formats: Option<Vec<String>>,
+derive_merge! {
+    /// TOML representation of how the LLVM build is configured.
+    #[derive(Deserialize, Default)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct Llvm {
+        skip_rebuild: Option<bool>,
+        optimize: Option<bool>,
+        thin_lto: Option<bool>,
+        release_debuginfo: Option<bool>,
+        assertions: Option<bool>,
+        tests: Option<bool>,
+        plugins: Option<bool>,
+        ccache: Option<StringOrBool>,
+        version_check: Option<bool>,
+        static_libstdcpp: Option<bool>,
+        ninja: Option<bool>,
+        targets: Option<String>,
+        experimental_targets: Option<String>,
+        link_jobs: Option<u32>,
+        link_shared: Option<bool>,
+        version_suffix: Option<String>,
+        clang_cl: Option<String>,
+        cflags: Option<String>,
+        cxxflags: Option<String>,
+        ldflags: Option<String>,
+        use_libcxx: Option<bool>,
+        use_linker: Option<String>,
+        allow_old_toolchain: Option<bool>,
+        polly: Option<bool>,
+        clang: Option<bool>,
+        download_ci_llvm: Option<StringOrBool>,
+    }
+}
+
+derive_merge! {
+    #[derive(Deserialize, Default, Clone)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct Dist {
+        sign_folder: Option<String>,
+        gpg_password_file: Option<String>,
+        upload_addr: Option<String>,
+        src_tarball: Option<bool>,
+        missing_tools: Option<bool>,
+        compression_formats: Option<Vec<String>>,
+    }
 }
 
 #[derive(Deserialize)]
@@ -471,80 +505,84 @@ fn default() -> StringOrBool {
     }
 }
 
-/// TOML representation of how the Rust build is configured.
-#[derive(Deserialize, Default, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct Rust {
-    optimize: Option<bool>,
-    debug: Option<bool>,
-    codegen_units: Option<u32>,
-    codegen_units_std: Option<u32>,
-    debug_assertions: Option<bool>,
-    debug_assertions_std: Option<bool>,
-    overflow_checks: Option<bool>,
-    overflow_checks_std: Option<bool>,
-    debug_logging: Option<bool>,
-    debuginfo_level: Option<u32>,
-    debuginfo_level_rustc: Option<u32>,
-    debuginfo_level_std: Option<u32>,
-    debuginfo_level_tools: Option<u32>,
-    debuginfo_level_tests: Option<u32>,
-    run_dsymutil: Option<bool>,
-    backtrace: Option<bool>,
-    incremental: Option<bool>,
-    parallel_compiler: Option<bool>,
-    default_linker: Option<String>,
-    channel: Option<String>,
-    description: Option<String>,
-    musl_root: Option<String>,
-    rpath: Option<bool>,
-    verbose_tests: Option<bool>,
-    optimize_tests: Option<bool>,
-    codegen_tests: Option<bool>,
-    ignore_git: Option<bool>,
-    dist_src: Option<bool>,
-    save_toolstates: Option<String>,
-    codegen_backends: Option<Vec<String>>,
-    lld: Option<bool>,
-    use_lld: Option<bool>,
-    llvm_tools: Option<bool>,
-    deny_warnings: Option<bool>,
-    backtrace_on_ice: Option<bool>,
-    verify_llvm_ir: Option<bool>,
-    thin_lto_import_instr_limit: Option<u32>,
-    remap_debuginfo: Option<bool>,
-    jemalloc: Option<bool>,
-    test_compare_mode: Option<bool>,
-    llvm_libunwind: Option<String>,
-    control_flow_guard: Option<bool>,
-    new_symbol_mangling: Option<bool>,
-    profile_generate: Option<String>,
-    profile_use: Option<String>,
-    // ignored; this is set from an env var set by bootstrap.py
-    download_rustc: Option<StringOrBool>,
+derive_merge! {
+    /// TOML representation of how the Rust build is configured.
+    #[derive(Deserialize, Default)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct Rust {
+        optimize: Option<bool>,
+        debug: Option<bool>,
+        codegen_units: Option<u32>,
+        codegen_units_std: Option<u32>,
+        debug_assertions: Option<bool>,
+        debug_assertions_std: Option<bool>,
+        overflow_checks: Option<bool>,
+        overflow_checks_std: Option<bool>,
+        debug_logging: Option<bool>,
+        debuginfo_level: Option<u32>,
+        debuginfo_level_rustc: Option<u32>,
+        debuginfo_level_std: Option<u32>,
+        debuginfo_level_tools: Option<u32>,
+        debuginfo_level_tests: Option<u32>,
+        run_dsymutil: Option<bool>,
+        backtrace: Option<bool>,
+        incremental: Option<bool>,
+        parallel_compiler: Option<bool>,
+        default_linker: Option<String>,
+        channel: Option<String>,
+        description: Option<String>,
+        musl_root: Option<String>,
+        rpath: Option<bool>,
+        verbose_tests: Option<bool>,
+        optimize_tests: Option<bool>,
+        codegen_tests: Option<bool>,
+        ignore_git: Option<bool>,
+        dist_src: Option<bool>,
+        save_toolstates: Option<String>,
+        codegen_backends: Option<Vec<String>>,
+        lld: Option<bool>,
+        use_lld: Option<bool>,
+        llvm_tools: Option<bool>,
+        deny_warnings: Option<bool>,
+        backtrace_on_ice: Option<bool>,
+        verify_llvm_ir: Option<bool>,
+        thin_lto_import_instr_limit: Option<u32>,
+        remap_debuginfo: Option<bool>,
+        jemalloc: Option<bool>,
+        test_compare_mode: Option<bool>,
+        llvm_libunwind: Option<String>,
+        control_flow_guard: Option<bool>,
+        new_symbol_mangling: Option<bool>,
+        profile_generate: Option<String>,
+        profile_use: Option<String>,
+        // ignored; this is set from an env var set by bootstrap.py
+        download_rustc: Option<StringOrBool>,
+    }
 }
 
-/// TOML representation of how each build target is configured.
-#[derive(Deserialize, Default, Merge)]
-#[serde(deny_unknown_fields, rename_all = "kebab-case")]
-struct TomlTarget {
-    cc: Option<String>,
-    cxx: Option<String>,
-    ar: Option<String>,
-    ranlib: Option<String>,
-    default_linker: Option<PathBuf>,
-    linker: Option<String>,
-    llvm_config: Option<String>,
-    llvm_filecheck: Option<String>,
-    android_ndk: Option<String>,
-    sanitizers: Option<bool>,
-    profiler: Option<bool>,
-    crt_static: Option<bool>,
-    musl_root: Option<String>,
-    musl_libdir: Option<String>,
-    wasi_root: Option<String>,
-    qemu_rootfs: Option<String>,
-    no_std: Option<bool>,
+derive_merge! {
+    /// TOML representation of how each build target is configured.
+    #[derive(Deserialize, Default)]
+    #[serde(deny_unknown_fields, rename_all = "kebab-case")]
+    struct TomlTarget {
+        cc: Option<String>,
+        cxx: Option<String>,
+        ar: Option<String>,
+        ranlib: Option<String>,
+        default_linker: Option<PathBuf>,
+        linker: Option<String>,
+        llvm_config: Option<String>,
+        llvm_filecheck: Option<String>,
+        android_ndk: Option<String>,
+        sanitizers: Option<bool>,
+        profiler: Option<bool>,
+        crt_static: Option<bool>,
+        musl_root: Option<String>,
+        musl_libdir: Option<String>,
+        wasi_root: Option<String>,
+        qemu_rootfs: Option<String>,
+        no_std: Option<bool>,
+    }
 }
 
 impl Config {
@@ -1111,10 +1149,6 @@ pub fn verbose(&self) -> bool {
         self.verbose > 0
     }
 
-    pub fn very_verbose(&self) -> bool {
-        self.verbose > 1
-    }
-
     pub fn sanitizers_enabled(&self, target: TargetSelection) -> bool {
         self.target_config.get(&target).map(|t| t.sanitizers).flatten().unwrap_or(self.sanitizers)
     }
diff --git a/src/bootstrap/dylib_util.rs b/src/bootstrap/dylib_util.rs
new file mode 100644 (file)
index 0000000..6d75272
--- /dev/null
@@ -0,0 +1,28 @@
+// Various utilities for working with dylib paths.
+//
+// This file is meant to be included directly to avoid a dependency on the bootstrap library from
+// the rustc and rustdoc wrappers. This improves compilation time by reducing the linking time.
+
+/// Returns the environment variable which the dynamic library lookup path
+/// resides in for this platform.
+pub fn dylib_path_var() -> &'static str {
+    if cfg!(target_os = "windows") {
+        "PATH"
+    } else if cfg!(target_os = "macos") {
+        "DYLD_LIBRARY_PATH"
+    } else if cfg!(target_os = "haiku") {
+        "LIBRARY_PATH"
+    } else {
+        "LD_LIBRARY_PATH"
+    }
+}
+
+/// Parses the `dylib_path_var()` environment variable, returning a list of
+/// paths that are members of this lookup path.
+pub fn dylib_path() -> Vec<PathBuf> {
+    let var = match env::var_os(dylib_path_var()) {
+        Some(v) => v,
+        None => return vec![],
+    };
+    env::split_paths(&var).collect()
+}
index 82462f9758e5c08853d2f59aa434888db863089a..8569089f70128beff3440f296c6859c3b853dd59 100644 (file)
 use std::io::{Read, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
 use std::process::{self, Command};
-use std::slice;
 use std::str;
 
 #[cfg(unix)]
@@ -472,10 +471,6 @@ pub fn new(config: Config) -> Build {
         build
     }
 
-    pub fn build_triple(&self) -> &[Interned<String>] {
-        slice::from_ref(&self.build.triple)
-    }
-
     // modified from `check_submodule` and `update_submodule` in bootstrap.py
     /// Given a path to the directory of a submodule, update it.
     ///
index 57178aa382ffd789ac68a6fb9b9cf9051aceb7b8..ee58bedcc8735104091947eead2b8b5af2dcd833 100644 (file)
 use crate::builder::Builder;
 use crate::config::{Config, TargetSelection};
 
-/// Returns the `name` as the filename of a static library for `target`.
-pub fn staticlib(name: &str, target: TargetSelection) -> String {
-    if target.contains("windows") { format!("{}.lib", name) } else { format!("lib{}.a", name) }
-}
-
 /// Given an executable called `name`, return the filename for the
 /// executable for a particular target.
 pub fn exe(name: &str, target: TargetSelection) -> String {
@@ -54,29 +49,7 @@ pub fn add_dylib_path(path: Vec<PathBuf>, cmd: &mut Command) {
     cmd.env(dylib_path_var(), t!(env::join_paths(list)));
 }
 
-/// Returns the environment variable which the dynamic library lookup path
-/// resides in for this platform.
-pub fn dylib_path_var() -> &'static str {
-    if cfg!(target_os = "windows") {
-        "PATH"
-    } else if cfg!(target_os = "macos") {
-        "DYLD_LIBRARY_PATH"
-    } else if cfg!(target_os = "haiku") {
-        "LIBRARY_PATH"
-    } else {
-        "LD_LIBRARY_PATH"
-    }
-}
-
-/// Parses the `dylib_path_var()` environment variable, returning a list of
-/// paths that are members of this lookup path.
-pub fn dylib_path() -> Vec<PathBuf> {
-    let var = match env::var_os(dylib_path_var()) {
-        Some(v) => v,
-        None => return vec![],
-    };
-    env::split_paths(&var).collect()
-}
+include!("dylib_util.rs");
 
 /// Adds a list of lookup paths to `cmd`'s link library lookup path.
 pub fn add_link_lib_path(path: Vec<PathBuf>, cmd: &mut Command) {
@@ -103,21 +76,6 @@ fn link_lib_path() -> Vec<PathBuf> {
     env::split_paths(&var).collect()
 }
 
-/// `push` all components to `buf`. On windows, append `.exe` to the last component.
-pub fn push_exe_path(mut buf: PathBuf, components: &[&str]) -> PathBuf {
-    let (&file, components) = components.split_last().expect("at least one component required");
-    let mut file = file.to_owned();
-
-    if cfg!(windows) {
-        file.push_str(".exe");
-    }
-
-    buf.extend(components);
-    buf.push(file);
-
-    buf
-}
-
 pub struct TimeIt(bool, Instant);
 
 /// Returns an RAII structure that prints out how long it took to drop.
index f4d1ca0ec691130ffe2bcd74006655ae213d1012..39eb407269c1180931a07d1d10054aec8502bada 100644 (file)
@@ -27,7 +27,7 @@ When running a coverage-instrumented program, the counter values are written to
 [`llvm.instrprof.increment`]: https://llvm.org/docs/LangRef.html#llvm-instrprof-increment-intrinsic
 [llvm code coverage mapping format]: https://llvm.org/docs/CoverageMappingFormat.html
 
-> **Note**: `-Z instrument-coverage` also automatically enables `-Z symbol-mangling-version=v0` (tracking issue [#60705]). The `v0` symbol mangler is strongly recommended, but be aware that this demangler is also experimental. The `v0` demangler can be overridden by explicitly adding `-Z symbol-mangling-version=legacy`.
+> **Note**: `-Z instrument-coverage` also automatically enables `-C symbol-mangling-version=v0` (tracking issue [#60705]). The `v0` symbol mangler is strongly recommended, but be aware that this demangler is also experimental. The `v0` demangler can be overridden by explicitly adding `-Z unstable-options -C symbol-mangling-version=legacy`.
 
 [#60705]: https://github.com/rust-lang/rust/issues/60705
 
index 5da20953bf2e30e4a8bcc2f9a8eb43d9b796a4f0..ce0ac322af914e87d69937853950faf7b9f9e9f4 100644 (file)
@@ -5,6 +5,7 @@
 
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::thin_vec::ThinVec;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -540,7 +541,7 @@ fn build_module(
                                     name: prim_ty.as_sym(),
                                     args: clean::GenericArgs::AngleBracketed {
                                         args: Vec::new(),
-                                        bindings: Vec::new(),
+                                        bindings: ThinVec::new(),
                                     },
                                 }],
                             },
index 2b1a1d4a600d64f84ea9a9a03defb2a9140ceee9..2ee5de24687f17a7aad370987d16abb1f49cbb65 100644 (file)
@@ -2060,14 +2060,14 @@ impl Path {
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate enum GenericArgs {
-    AngleBracketed { args: Vec<GenericArg>, bindings: Vec<TypeBinding> },
+    AngleBracketed { args: Vec<GenericArg>, bindings: ThinVec<TypeBinding> },
     Parenthesized { inputs: Vec<Type>, output: Option<Box<Type>> },
 }
 
 // `GenericArgs` is in every `PathSegment`, so its size can significantly
 // affect rustdoc's memory usage.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(GenericArgs, 56);
+rustc_data_structures::static_assert_size!(GenericArgs, 40);
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 crate struct PathSegment {
@@ -2078,7 +2078,7 @@ impl Path {
 // `PathSegment` usually occurs multiple times in every `Path`, so its size can
 // significantly affect rustdoc's memory usage.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(PathSegment, 64);
+rustc_data_structures::static_assert_size!(PathSegment, 48);
 
 #[derive(Clone, Debug)]
 crate struct Typedef {
index 28bd0f0a405f9306952163f4f44da147e3e3e641..43dcb611a377df1a0c75196f4565717b80ff7612 100644 (file)
@@ -10,6 +10,7 @@
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenTree;
+use rustc_data_structures::thin_vec::ThinVec;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -108,7 +109,7 @@ fn external_generic_args(
     if cx.tcx.fn_trait_kind_from_lang_item(did).is_some() {
         let inputs = match ty_kind.unwrap() {
             ty::Tuple(tys) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(),
-            _ => return GenericArgs::AngleBracketed { args, bindings },
+            _ => return GenericArgs::AngleBracketed { args, bindings: bindings.into() },
         };
         let output = None;
         // FIXME(#20299) return type comes from a projection now
@@ -118,7 +119,7 @@ fn external_generic_args(
         // };
         GenericArgs::Parenthesized { inputs, output }
     } else {
-        GenericArgs::AngleBracketed { args, bindings }
+        GenericArgs::AngleBracketed { args, bindings: bindings.into() }
     }
 }
 
@@ -143,7 +144,7 @@ pub(super) fn external_path(
 /// Remove the generic arguments from a path.
 crate fn strip_path_generics(mut path: Path) -> Path {
     for ps in path.segments.iter_mut() {
-        ps.args = GenericArgs::AngleBracketed { args: vec![], bindings: vec![] }
+        ps.args = GenericArgs::AngleBracketed { args: vec![], bindings: ThinVec::new() }
     }
 
     path
index a2571c2e532a73f80777b2a609546fb3ba4f9d16..ad41badf38169036d03b02a6a1fb599e0f86d583 100644 (file)
@@ -1,7 +1,7 @@
 // Checks that closures, constructors, and shims except
 // for a drop glue receive inline hint by default.
 //
-// compile-flags: -Cno-prepopulate-passes -Zsymbol-mangling-version=v0
+// compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0
 #![crate_type = "lib"]
 
 pub fn f() {
index 54526e8ef23b3df36886334fb91d74d2bebfaca3..4a9b3d70933e4980345c6429dcf84d821a1fd0b6 100644 (file)
@@ -8,8 +8,8 @@
 # and will probably get removed once `legacy` is gone.
 
 all:
-       $(RUSTC) a.rs --cfg x -C prefer-dynamic -Z symbol-mangling-version=legacy
-       $(RUSTC) b.rs -C prefer-dynamic -Z symbol-mangling-version=legacy
+       $(RUSTC) a.rs --cfg x -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
+       $(RUSTC) b.rs -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
        $(call RUN,b)
-       $(RUSTC) a.rs --cfg y -C prefer-dynamic -Z symbol-mangling-version=legacy
+       $(RUSTC) a.rs --cfg y -C prefer-dynamic -Z unstable-options -C symbol-mangling-version=legacy
        $(call FAIL,b)
index c6b5efcb4cdd8269ff14e1370dbc9dacf47568b7..282cb2461f69a7b494f987af2fb7ab893e059dcb 100644 (file)
@@ -11,7 +11,7 @@
 
 -include ../../run-make-fulldeps/tools.mk
 
-COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Zsymbol-mangling-version=v0
+COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Csymbol-mangling-version=v0
 
 all:
        $(RUSTC) instance_provider_a.rs $(COMMON_ARGS) --crate-type=rlib
diff --git a/src/test/rustdoc/where-clause-order.rs b/src/test/rustdoc/where-clause-order.rs
new file mode 100644 (file)
index 0000000..d0d89cb
--- /dev/null
@@ -0,0 +1,15 @@
+#![crate_name = "foo"]
+
+pub trait SomeTrait<Rhs = Self>
+where Rhs: ?Sized
+{}
+
+// @has 'foo/trait.SomeTrait.html'
+// @has - "//div[@id='impl-SomeTrait%3C(A%2C%20B%2C%20C%2C%20D%2C%20E)%3E-for-(A%2C%20B%2C%20C%2C%20D%2C%20E)']/h3" "impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where A: PartialOrd<A> + PartialEq<A>, B: PartialOrd<B> + PartialEq<B>, C: PartialOrd<C> + PartialEq<C>, D: PartialOrd<D> + PartialEq<D>, E: PartialOrd<E> + PartialEq<E> + ?Sized, "
+impl<A, B, C, D, E> SomeTrait<(A, B, C, D, E)> for (A, B, C, D, E) where
+    A: PartialOrd<A> + PartialEq<A>,
+    B: PartialOrd<B> + PartialEq<B>,
+    C: PartialOrd<C> + PartialEq<C>,
+    D: PartialOrd<D> + PartialEq<D>,
+    E: PartialOrd<E> + PartialEq<E> + ?Sized
+{}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.rs
new file mode 100644 (file)
index 0000000..1d7fa78
--- /dev/null
@@ -0,0 +1,3 @@
+// compile-flags: --cfg )
+// error-pattern: invalid `--cfg` argument: `)` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-8.stderr
new file mode 100644 (file)
index 0000000..7bb1814
--- /dev/null
@@ -0,0 +1,2 @@
+error: invalid `--cfg` argument: `)` (expected `key` or `key="value"`)
+
index df8368da0a09a0a1fcab45e6ffce638f487492cf..b315ef05190719647ef94a7014e147bbb4366391 100644 (file)
@@ -1,5 +1,5 @@
 // run-pass
-// compile-flags: -Zsymbol-mangling-version=v0
+// compile-flags: -Csymbol-mangling-version=v0
 
 pub fn f<T: ?Sized>() {}
 pub trait Frob<T: ?Sized> {}
index 9b4a9c2cf811d5393423b65a3e4e20514647ef3e..db5d3cab0bd8a905ccba171a66b61d44e71654c4 100644 (file)
@@ -39,4 +39,12 @@ fn main() {
     ]);
     concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
     concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
+    concat_bytes!([3; ()]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([3; -2]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([pie; -2]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([pie; 2]); //~ ERROR expected a byte literal
+    concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals
+    concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array
+    concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array
 }
index 1fc2d5c4843a027f53b4543be64a40c66261c8b3..d6cd1a3d178b0b4312b5a992ccc17227ad39fc03 100644 (file)
@@ -127,5 +127,55 @@ error: numeric literal is not a `u8`
 LL |     concat_bytes!([5u16]);
    |                    ^^^^
 
-error: aborting due to 20 previous errors
+error: repeat count is not a positive number
+  --> $DIR/concat-bytes-error.rs:42:23
+   |
+LL |     concat_bytes!([3; ()]);
+   |                       ^^
+
+error: repeat count is not a positive number
+  --> $DIR/concat-bytes-error.rs:43:23
+   |
+LL |     concat_bytes!([3; -2]);
+   |                       ^^
+
+error: repeat count is not a positive number
+  --> $DIR/concat-bytes-error.rs:44:25
+   |
+LL |     concat_bytes!([pie; -2]);
+   |                         ^^
+
+error: expected a byte literal
+  --> $DIR/concat-bytes-error.rs:45:20
+   |
+LL |     concat_bytes!([pie; 2]);
+   |                    ^^^
+   |
+   = note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
+
+error: cannot concatenate float literals
+  --> $DIR/concat-bytes-error.rs:46:20
+   |
+LL |     concat_bytes!([2.2; 0]);
+   |                    ^^^
+
+error: repeat count is not a positive number
+  --> $DIR/concat-bytes-error.rs:47:25
+   |
+LL |     concat_bytes!([5.5; ()]);
+   |                         ^^
+
+error: cannot concatenate doubly nested array
+  --> $DIR/concat-bytes-error.rs:48:20
+   |
+LL |     concat_bytes!([[1, 2, 3]; 3]);
+   |                    ^^^^^^^^^
+
+error: cannot concatenate doubly nested array
+  --> $DIR/concat-bytes-error.rs:49:20
+   |
+LL |     concat_bytes!([[42; 2]; 3]);
+   |                    ^^^^^^^
+
+error: aborting due to 28 previous errors
 
index 5415cf3fe2235b260012a377725596898bf09b77..fd8f99417ec985d548e2e02c094e1e1b447cbfde 100644 (file)
@@ -3,5 +3,15 @@
 
 fn main() {
     assert_eq!(concat_bytes!(), &[]);
-    assert_eq!(concat_bytes!(b'A', b"BC", [68, b'E', 70]), b"ABCDEF");
+    assert_eq!(
+        concat_bytes!(b'A', b"BC", [68, b'E', 70], [b'G'; 1], [72; 2], [73u8; 3], [65; 0]),
+        b"ABCDEFGHHIII",
+    );
+    assert_eq!(
+        concat_bytes!(
+            concat_bytes!(b"AB", b"CD"),
+            concat_bytes!(b"EF", b"GH"),
+        ),
+        b"ABCDEFGH",
+    );
 }
index 939271832e3df82409f06542f61524184324117a..c80e61b451116b7e45cd140bb377aec86fc9470e 100644 (file)
@@ -1,8 +1,9 @@
+// check-pass
 // aux-build:empty-struct.rs
 
 #[no_link]
 extern crate empty_struct;
 
 fn main() {
-    empty_struct::XEmpty1; //~ ERROR cannot find value `XEmpty1` in crate `empty_struct`
+    empty_struct::XEmpty1 {};
 }
diff --git a/src/test/ui/no-link.stderr b/src/test/ui/no-link.stderr
deleted file mode 100644 (file)
index 66a74ff..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find value `XEmpty1` in crate `empty_struct`
-  --> $DIR/no-link.rs:7:19
-   |
-LL |     empty_struct::XEmpty1;
-   |                   ^^^^^^^ not found in `empty_struct`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0425`.
index 35ecfc0b27158720d8e493fcb31efd2ef1c62724..c34e00bab7cdd8ec23bf823e16d416822a0a16a5 100644 (file)
@@ -14,8 +14,8 @@
 
 // NOTE(eddyb) output differs between symbol mangling schemes
 // revisions: legacy v0
-// [legacy] compile-flags: -Zsymbol-mangling-version=legacy
-//     [v0] compile-flags: -Zsymbol-mangling-version=v0
+// [legacy] compile-flags: -Zunstable-options -Csymbol-mangling-version=legacy
+//     [v0] compile-flags: -Csymbol-mangling-version=v0
 
 fn main() {
     panic!()
index b0b39dbd3df61c630e009bd35c93c4ba435a8cb2..e1030858814e0978786c1c3329d17e1c3d4601f5 100644 (file)
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0
+// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0
 
 fn foo(f: impl Fn()) {
     let x = |_: ()| ();
index ba75f6c5a1099dc7530965e56ea94e28b9357d30..62164ff94850814edb44e2dab8de115fae01142e 100644 (file)
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0
+// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0
 
 fn foo(f: impl Fn()) {
     // Mutate an upvar from `x` so that it implements `FnMut`.
index e9761ad0bcb20653d44bf470cde48ceb7258054e..7a364882fb8fd5d56afddb878037679624199703 100644 (file)
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0
+// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0
 
 fn foo(f: impl Fn()) {
     // Move a non-copy type into `x` so that it implements `FnOnce`.
index 7614aa83fcd1541fecd0734b45719e383bb6b6e1..27d59ec8899800cf9c3861eb734cfd2fed847f27 100644 (file)
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0
+// compile-flags:-Zpolymorphize=on -Csymbol-mangling-version=v0
 
 fn y_uses_f(f: impl Fn()) {
     let x = |_: ()| ();
index d97bae183d9c21712d1be11eef2fba9285a62e52..6277a902fa213c9d2fe10567a4d279f32bd1d6af 100644 (file)
@@ -1,5 +1,5 @@
 // build-pass
-// compile-flags: -Zpolymorphize=on -Zsymbol-mangling-version=v0
+// compile-flags: -Zpolymorphize=on -Csymbol-mangling-version=v0
 
 pub(crate) struct Foo<'a, I, E>(I, &'a E);
 
index a6fbe98e6ed4194d3e851e3f24fbf9776ca5ebaf..65a63262810feadb45b9da166693f60a4ce545e6 100644 (file)
@@ -1,7 +1,7 @@
 // build-fail
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy
-    //[v0]compile-flags: -Z symbol-mangling-version=v0
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy
+    //[v0]compile-flags: -C symbol-mangling-version=v0
 
 #![feature(rustc_attrs)]
 
index d44c8f0abaec81d10b4c71b4db398b718b43782f..5c40c391a9e0b621bac86c75fb113e52d2280fd4 100644 (file)
@@ -1,5 +1,5 @@
 // build-fail
-// compile-flags: -Z symbol-mangling-version=v0 --crate-name=c
+// compile-flags: -C symbol-mangling-version=v0 --crate-name=c
 // normalize-stderr-test: "c\[.*?\]" -> "c[HASH]"
 #![feature(rustc_attrs)]
 
index 300f6510380f416876bdf7fd907a2b7f26804bd4..619b34f2559a80040db39929bdc65a21c5ad0c92 100644 (file)
@@ -1,5 +1,5 @@
 // build-fail
-// compile-flags: -Z symbol-mangling-version=v0 --crate-name=c
+// compile-flags: -C symbol-mangling-version=v0 --crate-name=c
 // normalize-stderr-test: "c\[.*?\]" -> "c[HASH]"
 #![feature(adt_const_params, rustc_attrs)]
 #![allow(incomplete_features)]
index 73de48fed6c60cbd50002af0e2d98682a72e88e4..df09ba494a74f76ebaef9f2be76998e345d82103 100644 (file)
@@ -1,5 +1,5 @@
 // build-fail
-// compile-flags: -Z symbol-mangling-version=v0 --crate-name=c
+// compile-flags: -C symbol-mangling-version=v0 --crate-name=c
 
 // NOTE(eddyb) we need `core` for `core::option::Option`, normalize away its
 // disambiguator hash, which can/should change (including between stage{1,2}).
index 2d136e6a99a831f5badae45f34e16b27e54abbd3..1242126e0cceee01cc897bf72e969b761c2b113e 100644 (file)
@@ -1,7 +1,7 @@
 // check-pass
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib
-//[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy --crate-type=lib
+//[v0]compile-flags: -C symbol-mangling-version=v0 --crate-type=lib
 
 // `char`
 pub struct Char<const F: char>;
index f20cb1c01fd7350df3a39fa50d2f3c4fe99ca2d1..86f0a8b0bef4dfc8c47c9d198c2aa7e1abde2336 100644 (file)
@@ -1,7 +1,7 @@
 // build-fail
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy
-    //[v0]compile-flags: -Z symbol-mangling-version=v0
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy
+    //[v0]compile-flags: -C symbol-mangling-version=v0
 //[legacy]normalize-stderr-test: "h[\w]{16}E?\)" -> "<SYMBOL_HASH>)"
 
 #![feature(auto_traits, rustc_attrs)]
index 57114ca1f15822308d5814de83361a9589f4a942..ab0a3a7df1d15ec1ca717defcf8133e86387b940 100644 (file)
@@ -1,7 +1,7 @@
 // build-fail
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy
-    //[v0]compile-flags: -Z symbol-mangling-version=v0
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy
+    //[v0]compile-flags: -C symbol-mangling-version=v0
 
 #![feature(rustc_attrs)]
 
index d1bc152af5c609c6c672efcbb00ccd2c2d8efa35..4a1f5a21263dd309fc1a6cd7b5c111f1c59206bf 100644 (file)
@@ -1,7 +1,7 @@
 // build-fail
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy
-//[v0]compile-flags: -Z symbol-mangling-version=v0
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy
+//[v0]compile-flags: -C symbol-mangling-version=v0
 //[legacy]normalize-stderr-test: "h[\w{16}]+" -> "SYMBOL_HASH"
 
 #![feature(rustc_attrs)]
index c2e9f92f7b539c28635ee83de38d80185607619d..932057b659081e53602983322fb3b4bf00b5319e 100644 (file)
@@ -1,7 +1,7 @@
 // check-pass
 // revisions: legacy v0
-//[legacy]compile-flags: -Z symbol-mangling-version=legacy --crate-type=lib
-//[v0]compile-flags: -Z symbol-mangling-version=v0 --crate-type=lib
+//[legacy]compile-flags: -Z unstable-options -C symbol-mangling-version=legacy --crate-type=lib
+//[v0]compile-flags: -C symbol-mangling-version=v0 --crate-type=lib
 
 
 pub struct Bar<const F: bool>;
index 502afebcb5ae8ea69c252312fb8672e5cb7b2394..5bcbc08413fe10b83cf5c364bf2cc9cbc0e19823 100644 (file)
@@ -2,7 +2,7 @@
 
 // build-fail
 // revisions: v0
-//[v0]compile-flags: -Z symbol-mangling-version=v0
+//[v0]compile-flags: -C symbol-mangling-version=v0
 //[v0]normalize-stderr-test: "core\[.*?\]" -> "core[HASH]"
 
 #![feature(rustc_attrs)]