"filetime",
"getopts",
"ignore",
- "lazy_static",
"libc",
- "merge",
"num_cpus",
"once_cell",
"opener",
"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"
}
}
+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,
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 {
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
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"
/// 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> {
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> {
}
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) {
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;
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) => {
};
}
- 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"`"#);
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"));
}
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;
};
// 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(_)) =
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);
}
}
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;
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
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
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;
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;
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,
native_libraries,
foreign_modules,
source_map,
- impls,
traits,
+ impls,
exported_symbols,
interpret_alloc_index,
tables,
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);
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
})
.collect();
- (self.lazy(&all_traits), self.lazy(&all_impls))
+ self.lazy(&all_impls)
}
// Encodes all symbols exported from this crate into the metadata.
}
}
-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(
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
+ };
+}
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;
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};
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);
+}
},
}
}
+
+ pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
+ self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
+ }
}
impl DebuggingOptions {
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
);
}
+ // 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)
{
);
}
- // `-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) => {}
"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],
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`
// 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
// 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)
};
#[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
///
#[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];
/// ```
#[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
/// ```
#[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
/// ```
#[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)
/// ```
#[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)
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`.
///
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)`.
///
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.
///
{
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>
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
{
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")]
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()
}
/// 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
///
"library/backtrace",
"library/portable-simd",
"library/stdarch",
- "compiler/rustc_codegen_cranelift",
"compiler/rustc_codegen_gcc",
"src/doc/book",
"src/doc/edition-guide",
"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",
]
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]
//! 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};
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 =
eprintln!(
"{} command: {:?}={:?} {:?}",
prefix,
- bootstrap::util::dylib_path_var(),
+ dylib_path_var(),
env::join_paths(&dylib_path).unwrap(),
cmd,
);
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");
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
if verbose > 1 {
eprintln!(
"rustdoc command: {:?}={:?} {:?}",
- bootstrap::util::dylib_path_var(),
+ dylib_path_var(),
env::join_paths(&dylib_path).unwrap(),
cmd,
);
Check,
Clippy,
Fix,
- Format,
Test,
Bench,
Dist,
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,
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;
}
}
-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,
use crate::flags::{Color, Flags};
use crate::util::exe;
use build_helper::t;
-use merge::Merge;
use serde::Deserialize;
macro_rules! check_ci_llvm {
profile: Option<String>,
}
+trait Merge {
+ fn merge(&mut self, other: Self);
+}
+
impl Merge for TomlConfig {
fn merge(
&mut self,
}
}
-/// 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)]
}
}
-/// 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 {
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)
}
--- /dev/null
+// 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()
+}
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)]
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.
///
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 {
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) {
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.
[`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
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;
name: prim_ty.as_sym(),
args: clean::GenericArgs::AngleBracketed {
args: Vec::new(),
- bindings: Vec::new(),
+ bindings: ThinVec::new(),
},
}],
},
#[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 {
// `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 {
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};
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
// };
GenericArgs::Parenthesized { inputs, output }
} else {
- GenericArgs::AngleBracketed { args, bindings }
+ GenericArgs::AngleBracketed { args, bindings: bindings.into() }
}
}
/// 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
// 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() {
# 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)
-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
--- /dev/null
+#![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
+{}
--- /dev/null
+// compile-flags: --cfg )
+// error-pattern: invalid `--cfg` argument: `)` (expected `key` or `key="value"`)
+fn main() {}
--- /dev/null
+error: invalid `--cfg` argument: `)` (expected `key` or `key="value"`)
+
// run-pass
-// compile-flags: -Zsymbol-mangling-version=v0
+// compile-flags: -Csymbol-mangling-version=v0
pub fn f<T: ?Sized>() {}
pub trait Frob<T: ?Sized> {}
]);
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
}
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
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",
+ );
}
+// 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 {};
}
+++ /dev/null
-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`.
// 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!()
// 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 = |_: ()| ();
// 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`.
// 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`.
// 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 = |_: ()| ();
// 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);
// 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)]
// 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)]
// 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)]
// 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}).
// 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>;
// 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)]
// 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)]
// 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)]
// 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>;
// 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)]