mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #67220 - Centril:rollup-n3u9wd5, r=Centril
Rollup of 6 pull requests Successful merges: - #66881 (Optimize Ord trait implementation for bool) - #67015 (Fix constant propagation for scalar pairs) - #67074 (Add options to --extern flag.) - #67164 (Ensure that panicking in constants eventually errors) - #67174 (Remove `checked_add` in `Layout::repeat`) - #67205 (Make `publish_toolstate.sh` executable) Failed merges: r? @ghost
This commit is contained in:
commit
033662dfbc
0
src/ci/publish_toolstate.sh
Normal file → Executable file
0
src/ci/publish_toolstate.sh
Normal file → Executable file
@ -239,8 +239,11 @@ impl Layout {
|
||||
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
|
||||
#[inline]
|
||||
pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
|
||||
let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
|
||||
.ok_or(LayoutErr { private: () })?;
|
||||
// This cannot overflow. Quoting from the invariant of Layout:
|
||||
// > `size`, when rounded up to the nearest multiple of `align`,
|
||||
// > must not overflow (i.e., the rounded value must be less than
|
||||
// > `usize::MAX`)
|
||||
let padded_size = self.size() + self.padding_needed_for(self.align());
|
||||
let alloc_size = padded_size.checked_mul(n)
|
||||
.ok_or(LayoutErr { private: () })?;
|
||||
|
||||
|
@ -1005,6 +1005,7 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
|
||||
|
||||
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
|
||||
mod impls {
|
||||
use crate::hint::unreachable_unchecked;
|
||||
use crate::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
|
||||
macro_rules! partial_eq_impl {
|
||||
@ -1125,7 +1126,16 @@ mod impls {
|
||||
impl Ord for bool {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &bool) -> Ordering {
|
||||
(*self as u8).cmp(&(*other as u8))
|
||||
// Casting to i8's and converting the difference to an Ordering generates
|
||||
// more optimal assembly.
|
||||
// See <https://github.com/rust-lang/rust/issues/66780> for more info.
|
||||
match (*self as i8) - (*other as i8) {
|
||||
-1 => Less,
|
||||
0 => Equal,
|
||||
1 => Greater,
|
||||
// SAFETY: bool as i8 returns 0 or 1, so the difference can't be anything else
|
||||
_ => unsafe { unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,14 @@ fn test_int_totalord() {
|
||||
assert_eq!(12.cmp(&-5), Greater);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bool_totalord() {
|
||||
assert_eq!(true.cmp(&false), Greater);
|
||||
assert_eq!(false.cmp(&true), Less);
|
||||
assert_eq!(true.cmp(&true), Equal);
|
||||
assert_eq!(false.cmp(&false), Equal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_int_totalord() {
|
||||
assert_eq!((&mut 5).cmp(&&mut 10), Less);
|
||||
|
@ -7,7 +7,7 @@ use rustc::middle::cstore;
|
||||
use rustc::session::config::{build_configuration, build_session_options, to_crate_config};
|
||||
use rustc::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
|
||||
use rustc::session::config::{Externs, OutputType, OutputTypes, SymbolManglingVersion};
|
||||
use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes};
|
||||
use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes, ExternLocation};
|
||||
use rustc::session::{build_session, Session};
|
||||
use rustc::session::search_paths::SearchPath;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
@ -38,14 +38,15 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
|
||||
fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
|
||||
where
|
||||
S: Into<String>,
|
||||
I: IntoIterator<Item = Option<S>>,
|
||||
I: IntoIterator<Item = S>,
|
||||
{
|
||||
let locations: BTreeSet<_> = locations.into_iter().map(|o| o.map(|s| s.into()))
|
||||
let locations: BTreeSet<_> = locations.into_iter().map(|s| s.into())
|
||||
.collect();
|
||||
|
||||
ExternEntry {
|
||||
locations,
|
||||
is_private_dep: false
|
||||
location: ExternLocation::ExactPaths(locations),
|
||||
is_private_dep: false,
|
||||
add_prelude: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,33 +161,33 @@ fn test_externs_tracking_hash_different_construction_order() {
|
||||
v1.externs = Externs::new(mk_map(vec![
|
||||
(
|
||||
String::from("a"),
|
||||
new_public_extern_entry(vec![Some("b"), Some("c")])
|
||||
new_public_extern_entry(vec!["b", "c"])
|
||||
),
|
||||
(
|
||||
String::from("d"),
|
||||
new_public_extern_entry(vec![Some("e"), Some("f")])
|
||||
new_public_extern_entry(vec!["e", "f"])
|
||||
),
|
||||
]));
|
||||
|
||||
v2.externs = Externs::new(mk_map(vec![
|
||||
(
|
||||
String::from("d"),
|
||||
new_public_extern_entry(vec![Some("e"), Some("f")])
|
||||
new_public_extern_entry(vec!["e", "f"])
|
||||
),
|
||||
(
|
||||
String::from("a"),
|
||||
new_public_extern_entry(vec![Some("b"), Some("c")])
|
||||
new_public_extern_entry(vec!["b", "c"])
|
||||
),
|
||||
]));
|
||||
|
||||
v3.externs = Externs::new(mk_map(vec![
|
||||
(
|
||||
String::from("a"),
|
||||
new_public_extern_entry(vec![Some("b"), Some("c")])
|
||||
new_public_extern_entry(vec!["b", "c"])
|
||||
),
|
||||
(
|
||||
String::from("d"),
|
||||
new_public_extern_entry(vec![Some("f"), Some("e")])
|
||||
new_public_extern_entry(vec!["f", "e"])
|
||||
),
|
||||
]));
|
||||
|
||||
|
@ -218,13 +218,14 @@ impl<'a> CrateLoader<'a> {
|
||||
let source = self.cstore.get_crate_data(cnum).source();
|
||||
if let Some(entry) = self.sess.opts.externs.get(&name.as_str()) {
|
||||
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
|
||||
let found = entry.locations.iter().filter_map(|l| l.as_ref()).any(|l| {
|
||||
let l = fs::canonicalize(l).ok();
|
||||
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
|
||||
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
|
||||
});
|
||||
if found {
|
||||
ret = Some(cnum);
|
||||
if let Some(mut files) = entry.files() {
|
||||
if files.any(|l| {
|
||||
let l = fs::canonicalize(l).ok();
|
||||
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
|
||||
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
|
||||
}) {
|
||||
ret = Some(cnum);
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -328,8 +328,9 @@ impl<'a> CrateLocator<'a> {
|
||||
crate_name,
|
||||
exact_paths: if hash.is_none() {
|
||||
sess.opts.externs.get(&crate_name.as_str()).into_iter()
|
||||
.flat_map(|entry| entry.locations.iter())
|
||||
.filter_map(|location| location.clone().map(PathBuf::from)).collect()
|
||||
.filter_map(|entry| entry.files())
|
||||
.flatten()
|
||||
.map(|location| PathBuf::from(location)).collect()
|
||||
} else {
|
||||
// SVH being specified means this is a transitive dependency,
|
||||
// so `--extern` options do not apply.
|
||||
|
@ -65,7 +65,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
_ => false,
|
||||
};
|
||||
|
||||
unpack!(block = this.as_local_rvalue(block, source));
|
||||
// (#66975) Source could be a const of type `!`, so has to
|
||||
// exist in the generated MIR.
|
||||
unpack!(block = this.as_temp(
|
||||
block,
|
||||
this.local_scope(),
|
||||
source,
|
||||
Mutability::Mut,
|
||||
));
|
||||
|
||||
// This is an optimization. If the expression was a call then we already have an
|
||||
// unreachable block. Don't bother to terminate it and create a new one.
|
||||
|
@ -636,19 +636,45 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
ScalarMaybeUndef::Scalar(one),
|
||||
ScalarMaybeUndef::Scalar(two)
|
||||
) => {
|
||||
// Found a value represented as a pair. For now only do cont-prop if type of
|
||||
// Rvalue is also a pair with two scalars. The more general case is more
|
||||
// complicated to implement so we'll do it later.
|
||||
let ty = &value.layout.ty.kind;
|
||||
// Only do it for tuples
|
||||
if let ty::Tuple(substs) = ty {
|
||||
*rval = Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Tuple),
|
||||
vec![
|
||||
self.operand_from_scalar(
|
||||
one, substs[0].expect_ty(), source_info.span
|
||||
),
|
||||
self.operand_from_scalar(
|
||||
two, substs[1].expect_ty(), source_info.span
|
||||
),
|
||||
],
|
||||
);
|
||||
// Only do it if tuple is also a pair with two scalars
|
||||
if substs.len() == 2 {
|
||||
let opt_ty1_ty2 = self.use_ecx(source_info, |this| {
|
||||
let ty1 = substs[0].expect_ty();
|
||||
let ty2 = substs[1].expect_ty();
|
||||
let ty_is_scalar = |ty| {
|
||||
this.ecx
|
||||
.layout_of(ty)
|
||||
.ok()
|
||||
.map(|ty| ty.details.abi.is_scalar())
|
||||
== Some(true)
|
||||
};
|
||||
if ty_is_scalar(ty1) && ty_is_scalar(ty2) {
|
||||
Ok(Some((ty1, ty2)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(Some((ty1, ty2))) = opt_ty1_ty2 {
|
||||
*rval = Rvalue::Aggregate(
|
||||
Box::new(AggregateKind::Tuple),
|
||||
vec![
|
||||
self.operand_from_scalar(
|
||||
one, ty1, source_info.span
|
||||
),
|
||||
self.operand_from_scalar(
|
||||
two, ty2, source_info.span
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => { }
|
||||
|
@ -1136,8 +1136,10 @@ impl<'a> Resolver<'a> {
|
||||
definitions.create_root_def(crate_name, session.local_crate_disambiguator());
|
||||
|
||||
let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> =
|
||||
session.opts.externs.iter().map(|kv| (Ident::from_str(kv.0), Default::default()))
|
||||
.collect();
|
||||
session.opts.externs.iter()
|
||||
.filter(|(_, entry)| entry.add_prelude)
|
||||
.map(|(name, _)| (Ident::from_str(name), Default::default()))
|
||||
.collect();
|
||||
|
||||
if !attr::contains_name(&krate.attrs, sym::no_core) {
|
||||
extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
|
||||
|
@ -1,3 +1,5 @@
|
||||
// ignore-tidy-filelength
|
||||
|
||||
//! Contains infrastructure for configuring the compiler, including parsing
|
||||
//! command-line options.
|
||||
|
||||
@ -31,7 +33,7 @@ use std::fmt;
|
||||
use std::str::{self, FromStr};
|
||||
use std::hash::Hasher;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::iter::FromIterator;
|
||||
use std::iter::{self, FromIterator};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub struct Config {
|
||||
@ -322,10 +324,35 @@ impl OutputTypes {
|
||||
#[derive(Clone)]
|
||||
pub struct Externs(BTreeMap<String, ExternEntry>);
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExternEntry {
|
||||
pub locations: BTreeSet<Option<String>>,
|
||||
pub is_private_dep: bool
|
||||
pub location: ExternLocation,
|
||||
/// Indicates this is a "private" dependency for the
|
||||
/// `exported_private_dependencies` lint.
|
||||
///
|
||||
/// This can be set with the `priv` option like
|
||||
/// `--extern priv:name=foo.rlib`.
|
||||
pub is_private_dep: bool,
|
||||
/// Add the extern entry to the extern prelude.
|
||||
///
|
||||
/// This can be disabled with the `noprelude` option like
|
||||
/// `--extern noprelude:name`.
|
||||
pub add_prelude: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ExternLocation {
|
||||
/// Indicates to look for the library in the search paths.
|
||||
///
|
||||
/// Added via `--extern name`.
|
||||
FoundInLibrarySearchDirectories,
|
||||
/// The locations where this extern entry must be found.
|
||||
///
|
||||
/// The `CrateLoader` is responsible for loading these and figuring out
|
||||
/// which one to use.
|
||||
///
|
||||
/// Added via `--extern prelude_name=some_file.rlib`
|
||||
ExactPaths(BTreeSet<String>),
|
||||
}
|
||||
|
||||
impl Externs {
|
||||
@ -342,6 +369,18 @@ impl Externs {
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternEntry {
|
||||
fn new(location: ExternLocation) -> ExternEntry {
|
||||
ExternEntry { location, is_private_dep: false, add_prelude: false }
|
||||
}
|
||||
|
||||
pub fn files(&self) -> Option<impl Iterator<Item = &String>> {
|
||||
match &self.location {
|
||||
ExternLocation::ExactPaths(set) => Some(set.iter()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! hash_option {
|
||||
($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => ({});
|
||||
@ -1869,12 +1908,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
|
||||
"Specify where an external rust library is located",
|
||||
"NAME[=PATH]",
|
||||
),
|
||||
opt::multi_s(
|
||||
"",
|
||||
"extern-private",
|
||||
"Specify where an extern rust library is located, marking it as a private dependency",
|
||||
"NAME=PATH",
|
||||
),
|
||||
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
|
||||
opt::multi("Z", "", "Set internal debugging options", "FLAG"),
|
||||
opt::opt_s(
|
||||
@ -2435,43 +2468,105 @@ fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_externs(
|
||||
pub fn parse_externs(
|
||||
matches: &getopts::Matches,
|
||||
debugging_opts: &DebuggingOptions,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Externs {
|
||||
if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
"'--extern-private' is unstable and only \
|
||||
available for nightly builds of rustc."
|
||||
)
|
||||
}
|
||||
|
||||
// We start out with a `Vec<(Option<String>, bool)>>`,
|
||||
// and later convert it into a `BTreeSet<(Option<String>, bool)>`
|
||||
// This allows to modify entries in-place to set their correct
|
||||
// 'public' value.
|
||||
let is_unstable_enabled = debugging_opts.unstable_options;
|
||||
let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
|
||||
for (arg, private) in matches.opt_strs("extern").into_iter().map(|v| (v, false))
|
||||
.chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, true))) {
|
||||
|
||||
for arg in matches.opt_strs("extern") {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let name = parts.next().unwrap_or_else(||
|
||||
early_error(error_format, "--extern value must not be empty"));
|
||||
let location = parts.next().map(|s| s.to_string());
|
||||
let name = parts
|
||||
.next()
|
||||
.unwrap_or_else(|| early_error(error_format, "--extern value must not be empty"));
|
||||
let path = parts.next().map(|s| s.to_string());
|
||||
|
||||
let entry = externs
|
||||
.entry(name.to_owned())
|
||||
.or_default();
|
||||
let mut name_parts = name.splitn(2, ':');
|
||||
let first_part = name_parts.next();
|
||||
let second_part = name_parts.next();
|
||||
let (options, name) = match (first_part, second_part) {
|
||||
(Some(opts), Some(name)) => (Some(opts), name),
|
||||
(Some(name), None) => (None, name),
|
||||
(None, None) => early_error(error_format, "--extern name must not be empty"),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let entry = externs.entry(name.to_owned());
|
||||
|
||||
entry.locations.insert(location.clone());
|
||||
use std::collections::btree_map::Entry;
|
||||
|
||||
// Crates start out being not private,
|
||||
// and go to being private if we see an '--extern-private'
|
||||
// flag
|
||||
entry.is_private_dep |= private;
|
||||
let entry = if let Some(path) = path {
|
||||
// --extern prelude_name=some_file.rlib
|
||||
match entry {
|
||||
Entry::Vacant(vacant) => {
|
||||
let files = BTreeSet::from_iter(iter::once(path));
|
||||
vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
|
||||
}
|
||||
Entry::Occupied(occupied) => {
|
||||
let ext_ent = occupied.into_mut();
|
||||
match ext_ent {
|
||||
ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
|
||||
files.insert(path);
|
||||
}
|
||||
ExternEntry {
|
||||
location: location @ ExternLocation::FoundInLibrarySearchDirectories,
|
||||
..
|
||||
} => {
|
||||
// Exact paths take precedence over search directories.
|
||||
let files = BTreeSet::from_iter(iter::once(path));
|
||||
*location = ExternLocation::ExactPaths(files);
|
||||
}
|
||||
}
|
||||
ext_ent
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// --extern prelude_name
|
||||
match entry {
|
||||
Entry::Vacant(vacant) => {
|
||||
vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
|
||||
}
|
||||
Entry::Occupied(occupied) => {
|
||||
// Ignore if already specified.
|
||||
occupied.into_mut()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut is_private_dep = false;
|
||||
let mut add_prelude = true;
|
||||
if let Some(opts) = options {
|
||||
if !is_unstable_enabled {
|
||||
early_error(
|
||||
error_format,
|
||||
"the `-Z unstable-options` flag must also be passed to \
|
||||
enable `--extern options",
|
||||
);
|
||||
}
|
||||
for opt in opts.split(',') {
|
||||
match opt {
|
||||
"priv" => is_private_dep = true,
|
||||
"noprelude" => {
|
||||
if let ExternLocation::ExactPaths(_) = &entry.location {
|
||||
add_prelude = false;
|
||||
} else {
|
||||
early_error(
|
||||
error_format,
|
||||
"the `noprelude` --extern option requires a file path",
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => early_error(error_format, &format!("unknown --extern option `{}`", opt)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Crates start out being not private, and go to being private `priv`
|
||||
// is specified.
|
||||
entry.is_private_dep |= is_private_dep;
|
||||
// If any flag is missing `noprelude`, then add to the prelude.
|
||||
entry.add_prelude |= add_prelude;
|
||||
}
|
||||
Externs(externs)
|
||||
}
|
||||
|
@ -802,6 +802,14 @@ impl Abi {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` is this is a scalar type
|
||||
pub fn is_scalar(&self) -> bool {
|
||||
match *self {
|
||||
Abi::Scalar(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
|
@ -7,10 +7,10 @@ use errors;
|
||||
use getopts;
|
||||
use rustc::lint::Level;
|
||||
use rustc::session;
|
||||
use rustc::session::config::{CrateType, parse_crate_types_from_list};
|
||||
use rustc::session::config::{CrateType, parse_crate_types_from_list, parse_externs};
|
||||
use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
|
||||
use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
|
||||
get_cmd_lint_options, host_triple, ExternEntry};
|
||||
get_cmd_lint_options, host_triple};
|
||||
use rustc::session::search_paths::SearchPath;
|
||||
use rustc_driver;
|
||||
use rustc_target::spec::TargetTriple;
|
||||
@ -320,13 +320,7 @@ impl Options {
|
||||
let libs = matches.opt_strs("L").iter()
|
||||
.map(|s| SearchPath::from_cli_opt(s, error_format))
|
||||
.collect();
|
||||
let externs = match parse_externs(&matches) {
|
||||
Ok(ex) => ex,
|
||||
Err(err) => {
|
||||
diag.struct_err(&err).emit();
|
||||
return Err(1);
|
||||
}
|
||||
};
|
||||
let externs = parse_externs(&matches, &debugging_options, error_format);
|
||||
let extern_html_root_urls = match parse_extern_html_roots(&matches) {
|
||||
Ok(ex) => ex,
|
||||
Err(err) => {
|
||||
@ -617,24 +611,3 @@ fn parse_extern_html_roots(
|
||||
|
||||
Ok(externs)
|
||||
}
|
||||
|
||||
/// Extracts `--extern CRATE=PATH` arguments from `matches` and
|
||||
/// returns a map mapping crate names to their paths or else an
|
||||
/// error message.
|
||||
/// Also handles `--extern-private` which for the purposes of rustdoc
|
||||
/// we can treat as `--extern`
|
||||
// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
|
||||
fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
|
||||
let mut externs: BTreeMap<_, ExternEntry> = BTreeMap::new();
|
||||
for arg in matches.opt_strs("extern").iter().chain(matches.opt_strs("extern-private").iter()) {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
|
||||
let location = parts.next().map(|s| s.to_string());
|
||||
let name = name.to_string();
|
||||
// For Rustdoc purposes, we can treat all externs as public
|
||||
externs.entry(name)
|
||||
.or_default()
|
||||
.locations.insert(location.clone());
|
||||
}
|
||||
Ok(Externs::new(externs))
|
||||
}
|
||||
|
@ -248,7 +248,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
|
||||
..
|
||||
} = options;
|
||||
|
||||
let extern_names: Vec<String> = externs.iter().map(|(s,_)| s).cloned().collect();
|
||||
let extern_names: Vec<String> = externs.iter()
|
||||
.filter(|(_, entry)| entry.add_prelude)
|
||||
.map(|(name, _)| name).cloned().collect();
|
||||
|
||||
// Add the doc cfg into the doc build.
|
||||
cfgs.push("doc".to_string());
|
||||
|
@ -145,10 +145,6 @@ fn opts() -> Vec<RustcOptGroup> {
|
||||
stable("extern", |o| {
|
||||
o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")
|
||||
}),
|
||||
unstable("extern-private", |o| {
|
||||
o.optmulti("", "extern-private",
|
||||
"pass an --extern to rustc (compatibility only)", "NAME=PATH")
|
||||
}),
|
||||
unstable("extern-html-root-url", |o| {
|
||||
o.optmulti("", "extern-html-root-url",
|
||||
"base URL to use for dependencies", "NAME=URL")
|
||||
|
17
src/test/codegen/bool-cmp.rs
Normal file
17
src/test/codegen/bool-cmp.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// This is a test for optimal Ord trait implementation for bool.
|
||||
// See <https://github.com/rust-lang/rust/issues/66780> for more info.
|
||||
|
||||
// compile-flags: -C opt-level=3
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
// CHECK-LABEL: @cmp_bool
|
||||
#[no_mangle]
|
||||
pub fn cmp_bool(a: bool, b: bool) -> Ordering {
|
||||
// CHECK: zext i1
|
||||
// CHECK: zext i1
|
||||
// CHECK: sub nsw
|
||||
a.cmp(&b)
|
||||
}
|
38
src/test/mir-opt/const_prop/issue-66971.rs
Normal file
38
src/test/mir-opt/const_prop/issue-66971.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// compile-flags: -Z mir-opt-level=2
|
||||
|
||||
// Due to a bug in propagating scalar pairs the assertion below used to fail. In the expected
|
||||
// outputs below, after ConstProp this is how _2 would look like with the bug:
|
||||
//
|
||||
// _2 = (const Scalar(0x00) : (), const 0u8);
|
||||
//
|
||||
// Which has the wrong type.
|
||||
|
||||
fn encode(this: ((), u8, u8)) {
|
||||
assert!(this.2 == 0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
encode(((), 0, 0));
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = ();
|
||||
// _2 = (move _3, const 0u8, const 0u8);
|
||||
// ...
|
||||
// _1 = const encode(move _2) -> bb1;
|
||||
// ...
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = const Scalar(<ZST>) : ();
|
||||
// _2 = (move _3, const 0u8, const 0u8);
|
||||
// ...
|
||||
// _1 = const encode(move _2) -> bb1;
|
||||
// ...
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
34
src/test/mir-opt/const_prop/issue-67019.rs
Normal file
34
src/test/mir-opt/const_prop/issue-67019.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// compile-flags: -Z mir-opt-level=2
|
||||
|
||||
// This used to ICE in const-prop
|
||||
|
||||
fn test(this: ((u8, u8),)) {
|
||||
assert!((this.0).0 == 1);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test(((1, 2),));
|
||||
}
|
||||
|
||||
// Important bit is parameter passing so we only check that below
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = (const 1u8, const 2u8);
|
||||
// _2 = (move _3,);
|
||||
// ...
|
||||
// _1 = const test(move _2) -> bb1;
|
||||
// ...
|
||||
// }
|
||||
// END rustc.main.ConstProp.before.mir
|
||||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = (const 1u8, const 2u8);
|
||||
// _2 = (move _3,);
|
||||
// ...
|
||||
// _1 = const test(move _2) -> bb1;
|
||||
// ...
|
||||
// }
|
||||
// END rustc.main.ConstProp.after.mir
|
28
src/test/mir-opt/retain-never-const.rs
Normal file
28
src/test/mir-opt/retain-never-const.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// Regression test for #66975 - ensure that we don't keep unevaluated
|
||||
// `!`-typed constants until codegen.
|
||||
|
||||
// Force generation of optimized mir for functions that do not reach codegen.
|
||||
// compile-flags: --emit mir,link
|
||||
|
||||
#![feature(const_panic)]
|
||||
|
||||
struct PrintName<T>(T);
|
||||
|
||||
impl<T> PrintName<T> {
|
||||
const VOID: ! = panic!();
|
||||
}
|
||||
|
||||
fn no_codegen<T>() {
|
||||
let _ = PrintName::<T>::VOID;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.no_codegen.PreCodegen.after.mir
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = const PrintName::<T>::VOID;
|
||||
// unreachable;
|
||||
// }
|
||||
// END rustc.no_codegen.PreCodegen.after.mir
|
@ -1,6 +1,5 @@
|
||||
// aux-build:issue-66159-1.rs
|
||||
// aux-crate:priv:issue_66159_1=issue-66159-1.rs
|
||||
// compile-flags:-Z unstable-options
|
||||
// extern-private:issue_66159_1
|
||||
|
||||
// The issue was an ICE which meant that we never actually generated the docs
|
||||
// so if we have generated the docs, we're okay.
|
||||
|
@ -0,0 +1,18 @@
|
||||
// Regression test for #66975
|
||||
#![warn(const_err)]
|
||||
|
||||
struct PrintName<T>(T);
|
||||
|
||||
impl<T> PrintName<T> {
|
||||
const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
|
||||
//~^ WARN any use of this value will cause an error
|
||||
}
|
||||
|
||||
fn f<T>() {
|
||||
let _ = PrintName::<T>::VOID;
|
||||
//~^ ERROR erroneous constant encountered
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
f::<()>();
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/index-out-of-bounds-never-type.rs:7:61
|
||||
|
|
||||
LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
|
||||
| --------------------------------------------------------^^^^^---
|
||||
| |
|
||||
| index out of bounds: the len is 0 but the index is 0
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/index-out-of-bounds-never-type.rs:2:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: erroneous constant encountered
|
||||
--> $DIR/index-out-of-bounds-never-type.rs:12:13
|
||||
|
|
||||
LL | let _ = PrintName::<T>::VOID;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
15
src/test/ui/consts/const-eval/panic-assoc-never-type.rs
Normal file
15
src/test/ui/consts/const-eval/panic-assoc-never-type.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// Regression test for #66975
|
||||
#![warn(const_err)]
|
||||
#![feature(const_panic)]
|
||||
|
||||
struct PrintName;
|
||||
|
||||
impl PrintName {
|
||||
const VOID: ! = panic!();
|
||||
//~^ WARN any use of this value will cause an error
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = PrintName::VOID;
|
||||
//~^ ERROR erroneous constant used
|
||||
}
|
24
src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
Normal file
24
src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/panic-assoc-never-type.rs:8:21
|
||||
|
|
||||
LL | const VOID: ! = panic!();
|
||||
| ----------------^^^^^^^^-
|
||||
| |
|
||||
| the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:8:21
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/panic-assoc-never-type.rs:2:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/panic-assoc-never-type.rs:13:13
|
||||
|
|
||||
LL | let _ = PrintName::VOID;
|
||||
| ^^^^^^^^^^^^^^^ referenced constant has errors
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
11
src/test/ui/consts/const-eval/panic-never-type.rs
Normal file
11
src/test/ui/consts/const-eval/panic-never-type.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// Regression test for #66975
|
||||
#![warn(const_err)]
|
||||
#![feature(const_panic)]
|
||||
|
||||
const VOID: ! = panic!();
|
||||
//~^ WARN any use of this value will cause an error
|
||||
|
||||
fn main() {
|
||||
let _ = VOID;
|
||||
//~^ ERROR erroneous constant used
|
||||
}
|
24
src/test/ui/consts/const-eval/panic-never-type.stderr
Normal file
24
src/test/ui/consts/const-eval/panic-never-type.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
warning: any use of this value will cause an error
|
||||
--> $DIR/panic-never-type.rs:5:17
|
||||
|
|
||||
LL | const VOID: ! = panic!();
|
||||
| ----------------^^^^^^^^-
|
||||
| |
|
||||
| the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:5:17
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/panic-never-type.rs:2:9
|
||||
|
|
||||
LL | #![warn(const_err)]
|
||||
| ^^^^^^^^^
|
||||
= note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error[E0080]: erroneous constant used
|
||||
--> $DIR/panic-never-type.rs:9:13
|
||||
|
|
||||
LL | let _ = VOID;
|
||||
| ^^^^ referenced constant has errors
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
3
src/test/ui/extern-flag/auxiliary/somedep.rs
Normal file
3
src/test/ui/extern-flag/auxiliary/somedep.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub fn somefun() {}
|
||||
|
||||
pub struct S;
|
20
src/test/ui/extern-flag/multiple-opts.rs
Normal file
20
src/test/ui/extern-flag/multiple-opts.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// aux-crate:priv,noprelude:somedep=somedep.rs
|
||||
// compile-flags: -Zunstable-options
|
||||
// edition:2018
|
||||
|
||||
// Test for multiple options to --extern. Can't test for errors from both
|
||||
// options at the same time, so this only checks that noprelude is honored.
|
||||
|
||||
#![warn(exported_private_dependencies)]
|
||||
|
||||
// Module to avoid adding to prelude.
|
||||
pub mod m {
|
||||
extern crate somedep;
|
||||
pub struct PublicType {
|
||||
pub field: somedep::S,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
somedep::somefun(); //~ ERROR failed to resolve
|
||||
}
|
9
src/test/ui/extern-flag/multiple-opts.stderr
Normal file
9
src/test/ui/extern-flag/multiple-opts.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0433]: failed to resolve: use of undeclared type or module `somedep`
|
||||
--> $DIR/multiple-opts.rs:19:5
|
||||
|
|
||||
LL | somedep::somefun();
|
||||
| ^^^^^^^ use of undeclared type or module `somedep`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
10
src/test/ui/extern-flag/noprelude-and-prelude.rs
Normal file
10
src/test/ui/extern-flag/noprelude-and-prelude.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// check-pass
|
||||
// aux-crate:noprelude:somedep=somedep.rs
|
||||
// compile-flags: -Zunstable-options --extern somedep
|
||||
// edition:2018
|
||||
|
||||
// Having a flag with `noprelude` and one without, will add to the prelude.
|
||||
|
||||
fn main() {
|
||||
somedep::somefun();
|
||||
}
|
11
src/test/ui/extern-flag/noprelude-resolves.rs
Normal file
11
src/test/ui/extern-flag/noprelude-resolves.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// check-pass
|
||||
// aux-crate:noprelude:somedep=somedep.rs
|
||||
// compile-flags: -Zunstable-options
|
||||
// edition:2018
|
||||
|
||||
// `extern crate` can be used to add to prelude.
|
||||
extern crate somedep;
|
||||
|
||||
fn main() {
|
||||
somedep::somefun();
|
||||
}
|
7
src/test/ui/extern-flag/noprelude.rs
Normal file
7
src/test/ui/extern-flag/noprelude.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// aux-crate:noprelude:somedep=somedep.rs
|
||||
// compile-flags: -Zunstable-options
|
||||
// edition:2018
|
||||
|
||||
fn main() {
|
||||
somedep::somefun(); //~ ERROR failed to resolve
|
||||
}
|
9
src/test/ui/extern-flag/noprelude.stderr
Normal file
9
src/test/ui/extern-flag/noprelude.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0433]: failed to resolve: use of undeclared type or module `somedep`
|
||||
--> $DIR/noprelude.rs:6:5
|
||||
|
|
||||
LL | somedep::somefun();
|
||||
| ^^^^^^^ use of undeclared type or module `somedep`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
13
src/test/ui/extern-flag/public-and-private.rs
Normal file
13
src/test/ui/extern-flag/public-and-private.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// aux-crate:priv:somedep=somedep.rs
|
||||
// compile-flags: -Zunstable-options --extern somedep
|
||||
// edition:2018
|
||||
|
||||
#![deny(exported_private_dependencies)]
|
||||
|
||||
// Having a flag with `priv` and one without, will remain private (it is sticky).
|
||||
|
||||
pub struct PublicType {
|
||||
pub field: somedep::S, //~ ERROR from private dependency
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/extern-flag/public-and-private.stderr
Normal file
14
src/test/ui/extern-flag/public-and-private.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: type `somedep::S` from private dependency 'somedep' in public interface
|
||||
--> $DIR/public-and-private.rs:10:5
|
||||
|
|
||||
LL | pub field: somedep::S,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/public-and-private.rs:5:9
|
||||
|
|
||||
LL | #![deny(exported_private_dependencies)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
13
src/test/ui/mir/issue66339.rs
Normal file
13
src/test/ui/mir/issue66339.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// compile-flags: -Z mir-opt-level=2
|
||||
// build-pass
|
||||
|
||||
// This used to ICE in const-prop
|
||||
|
||||
fn foo() {
|
||||
let bar = |_| { };
|
||||
let _ = bar("a");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo();
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
// aux-build:priv_dep.rs
|
||||
// aux-crate:priv:priv_dep=priv_dep.rs
|
||||
// aux-build:pub_dep.rs
|
||||
// extern-private:priv_dep
|
||||
#![deny(exported_private_dependencies)]
|
||||
|
||||
// This crate is a private dependency
|
||||
extern crate priv_dep;
|
||||
// This crate is a public dependenct
|
||||
// This crate is a public dependency
|
||||
extern crate pub_dep;
|
||||
|
||||
use priv_dep::{OtherType, OtherTrait};
|
||||
|
@ -1,23 +1,23 @@
|
||||
error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:21:5
|
||||
--> $DIR/pub-priv1.rs:20:5
|
||||
|
|
||||
LL | pub field: OtherType,
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/pub-priv1.rs:4:9
|
||||
--> $DIR/pub-priv1.rs:3:9
|
||||
|
|
||||
LL | #![deny(exported_private_dependencies)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: type `priv_dep::OtherType` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:28:5
|
||||
--> $DIR/pub-priv1.rs:27:5
|
||||
|
|
||||
LL | pub fn pub_fn(param: OtherType) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: trait `priv_dep::OtherTrait` from private dependency 'priv_dep' in public interface
|
||||
--> $DIR/pub-priv1.rs:34:1
|
||||
--> $DIR/pub-priv1.rs:33:1
|
||||
|
|
||||
LL | / pub trait MyPubTrait {
|
||||
LL | | type Foo: OtherTrait;
|
||||
|
@ -71,6 +71,7 @@ pub struct EarlyProps {
|
||||
pub ignore: Ignore,
|
||||
pub should_fail: bool,
|
||||
pub aux: Vec<String>,
|
||||
pub aux_crate: Vec<(String, String)>,
|
||||
pub revisions: Vec<String>,
|
||||
}
|
||||
|
||||
@ -80,6 +81,7 @@ impl EarlyProps {
|
||||
ignore: Ignore::Run,
|
||||
should_fail: false,
|
||||
aux: Vec::new(),
|
||||
aux_crate: Vec::new(),
|
||||
revisions: vec![],
|
||||
};
|
||||
|
||||
@ -157,6 +159,10 @@ impl EarlyProps {
|
||||
props.aux.push(s);
|
||||
}
|
||||
|
||||
if let Some(ac) = config.parse_aux_crate(ln) {
|
||||
props.aux_crate.push(ac);
|
||||
}
|
||||
|
||||
if let Some(r) = config.parse_revisions(ln) {
|
||||
props.revisions.extend(r);
|
||||
}
|
||||
@ -311,10 +317,9 @@ pub struct TestProps {
|
||||
// directory as the test, but for backwards compatibility reasons
|
||||
// we also check the auxiliary directory)
|
||||
pub aux_builds: Vec<String>,
|
||||
// A list of crates to pass '--extern-private name:PATH' flags for
|
||||
// This should be a subset of 'aux_build'
|
||||
// FIXME: Replace this with a better solution: https://github.com/rust-lang/rust/pull/54020
|
||||
pub extern_private: Vec<String>,
|
||||
// Similar to `aux_builds`, but a list of NAME=somelib.rs of dependencies
|
||||
// to build and pass with the `--extern` flag.
|
||||
pub aux_crates: Vec<(String, String)>,
|
||||
// Environment settings to use for compiling
|
||||
pub rustc_env: Vec<(String, String)>,
|
||||
// Environment variables to unset prior to compiling.
|
||||
@ -387,7 +392,7 @@ impl TestProps {
|
||||
run_flags: None,
|
||||
pp_exact: None,
|
||||
aux_builds: vec![],
|
||||
extern_private: vec![],
|
||||
aux_crates: vec![],
|
||||
revisions: vec![],
|
||||
rustc_env: vec![],
|
||||
unset_rustc_env: vec![],
|
||||
@ -514,8 +519,8 @@ impl TestProps {
|
||||
self.aux_builds.push(ab);
|
||||
}
|
||||
|
||||
if let Some(ep) = config.parse_extern_private(ln) {
|
||||
self.extern_private.push(ep);
|
||||
if let Some(ac) = config.parse_aux_crate(ln) {
|
||||
self.aux_crates.push(ac);
|
||||
}
|
||||
|
||||
if let Some(ee) = config.parse_env(ln, "exec-env") {
|
||||
@ -713,8 +718,14 @@ impl Config {
|
||||
.map(|r| r.trim().to_string())
|
||||
}
|
||||
|
||||
fn parse_extern_private(&self, line: &str) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "extern-private")
|
||||
fn parse_aux_crate(&self, line: &str) -> Option<(String, String)> {
|
||||
self.parse_name_value_directive(line, "aux-crate").map(|r| {
|
||||
let mut parts = r.trim().splitn(2, '=');
|
||||
(
|
||||
parts.next().expect("aux-crate name").to_string(),
|
||||
parts.next().expect("aux-crate value").to_string(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_compile_flags(&self, line: &str) -> Option<String> {
|
||||
|
@ -1776,93 +1776,16 @@ impl<'test> TestCx<'test> {
|
||||
create_dir_all(&aux_dir).unwrap();
|
||||
}
|
||||
|
||||
// Use a Vec instead of a HashMap to preserve original order
|
||||
let mut extern_priv = self.props.extern_private.clone();
|
||||
|
||||
let mut add_extern_priv = |priv_dep: &str, dylib: bool| {
|
||||
let lib_name = get_lib_name(priv_dep, dylib);
|
||||
rustc
|
||||
.arg("--extern-private")
|
||||
.arg(format!("{}={}", priv_dep, aux_dir.join(lib_name).to_str().unwrap()));
|
||||
};
|
||||
|
||||
for rel_ab in &self.props.aux_builds {
|
||||
let aux_testpaths = self.compute_aux_test_paths(rel_ab);
|
||||
let aux_props =
|
||||
self.props
|
||||
.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
||||
let aux_output = TargetLocation::ThisDirectory(self.aux_output_dir_name());
|
||||
let aux_cx = TestCx {
|
||||
config: self.config,
|
||||
props: &aux_props,
|
||||
testpaths: &aux_testpaths,
|
||||
revision: self.revision,
|
||||
};
|
||||
// Create the directory for the stdout/stderr files.
|
||||
create_dir_all(aux_cx.output_base_dir()).unwrap();
|
||||
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
|
||||
|
||||
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
|
||||
(true, None)
|
||||
} else if self.config.target.contains("cloudabi")
|
||||
|| self.config.target.contains("emscripten")
|
||||
|| (self.config.target.contains("musl")
|
||||
&& !aux_props.force_host
|
||||
&& !self.config.host.contains("musl"))
|
||||
|| self.config.target.contains("wasm32")
|
||||
|| self.config.target.contains("nvptx")
|
||||
|| self.is_vxworks_pure_static()
|
||||
{
|
||||
// We primarily compile all auxiliary libraries as dynamic libraries
|
||||
// to avoid code size bloat and large binaries as much as possible
|
||||
// for the test suite (otherwise including libstd statically in all
|
||||
// executables takes up quite a bit of space).
|
||||
//
|
||||
// For targets like MUSL or Emscripten, however, there is no support for
|
||||
// dynamic libraries so we just go back to building a normal library. Note,
|
||||
// however, that for MUSL if the library is built with `force_host` then
|
||||
// it's ok to be a dylib as the host should always support dylibs.
|
||||
(false, Some("lib"))
|
||||
} else {
|
||||
(true, Some("dylib"))
|
||||
};
|
||||
|
||||
let trimmed = rel_ab.trim_end_matches(".rs").to_string();
|
||||
|
||||
// Normally, every 'extern-private' has a correspodning 'aux-build'
|
||||
// entry. If so, we remove it from our list of private crates,
|
||||
// and add an '--extern-private' flag to rustc
|
||||
if extern_priv.remove_item(&trimmed).is_some() {
|
||||
add_extern_priv(&trimmed, dylib);
|
||||
}
|
||||
|
||||
if let Some(crate_type) = crate_type {
|
||||
aux_rustc.args(&["--crate-type", crate_type]);
|
||||
}
|
||||
|
||||
aux_rustc.arg("-L").arg(&aux_dir);
|
||||
|
||||
let auxres = aux_cx.compose_and_run(
|
||||
aux_rustc,
|
||||
aux_cx.config.compile_lib_path.to_str().unwrap(),
|
||||
Some(aux_dir.to_str().unwrap()),
|
||||
None,
|
||||
);
|
||||
if !auxres.status.success() {
|
||||
self.fatal_proc_rec(
|
||||
&format!(
|
||||
"auxiliary build of {:?} failed to compile: ",
|
||||
aux_testpaths.file.display()
|
||||
),
|
||||
&auxres,
|
||||
);
|
||||
}
|
||||
self.build_auxiliary(rel_ab, &aux_dir);
|
||||
}
|
||||
|
||||
// Add any '--extern-private' entries without a matching
|
||||
// 'aux-build'
|
||||
for private_lib in extern_priv {
|
||||
add_extern_priv(&private_lib, true);
|
||||
for (aux_name, aux_path) in &self.props.aux_crates {
|
||||
let is_dylib = self.build_auxiliary(&aux_path, &aux_dir);
|
||||
let lib_name = get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"),
|
||||
is_dylib);
|
||||
rustc.arg("--extern")
|
||||
.arg(format!("{}={}/{}", aux_name, aux_dir.display(), lib_name));
|
||||
}
|
||||
|
||||
self.props.unset_rustc_env.clone()
|
||||
@ -1877,6 +1800,74 @@ impl<'test> TestCx<'test> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Builds an aux dependency.
|
||||
///
|
||||
/// Returns whether or not it is a dylib.
|
||||
fn build_auxiliary(&self, source_path: &str, aux_dir: &Path) -> bool {
|
||||
let aux_testpaths = self.compute_aux_test_paths(source_path);
|
||||
let aux_props =
|
||||
self.props
|
||||
.from_aux_file(&aux_testpaths.file, self.revision, self.config);
|
||||
let aux_output = TargetLocation::ThisDirectory(self.aux_output_dir_name());
|
||||
let aux_cx = TestCx {
|
||||
config: self.config,
|
||||
props: &aux_props,
|
||||
testpaths: &aux_testpaths,
|
||||
revision: self.revision,
|
||||
};
|
||||
// Create the directory for the stdout/stderr files.
|
||||
create_dir_all(aux_cx.output_base_dir()).unwrap();
|
||||
let mut aux_rustc = aux_cx.make_compile_args(&aux_testpaths.file, aux_output);
|
||||
|
||||
let (dylib, crate_type) = if aux_props.no_prefer_dynamic {
|
||||
(true, None)
|
||||
} else if self.config.target.contains("cloudabi")
|
||||
|| self.config.target.contains("emscripten")
|
||||
|| (self.config.target.contains("musl")
|
||||
&& !aux_props.force_host
|
||||
&& !self.config.host.contains("musl"))
|
||||
|| self.config.target.contains("wasm32")
|
||||
|| self.config.target.contains("nvptx")
|
||||
|| self.is_vxworks_pure_static()
|
||||
{
|
||||
// We primarily compile all auxiliary libraries as dynamic libraries
|
||||
// to avoid code size bloat and large binaries as much as possible
|
||||
// for the test suite (otherwise including libstd statically in all
|
||||
// executables takes up quite a bit of space).
|
||||
//
|
||||
// For targets like MUSL or Emscripten, however, there is no support for
|
||||
// dynamic libraries so we just go back to building a normal library. Note,
|
||||
// however, that for MUSL if the library is built with `force_host` then
|
||||
// it's ok to be a dylib as the host should always support dylibs.
|
||||
(false, Some("lib"))
|
||||
} else {
|
||||
(true, Some("dylib"))
|
||||
};
|
||||
|
||||
if let Some(crate_type) = crate_type {
|
||||
aux_rustc.args(&["--crate-type", crate_type]);
|
||||
}
|
||||
|
||||
aux_rustc.arg("-L").arg(&aux_dir);
|
||||
|
||||
let auxres = aux_cx.compose_and_run(
|
||||
aux_rustc,
|
||||
aux_cx.config.compile_lib_path.to_str().unwrap(),
|
||||
Some(aux_dir.to_str().unwrap()),
|
||||
None,
|
||||
);
|
||||
if !auxres.status.success() {
|
||||
self.fatal_proc_rec(
|
||||
&format!(
|
||||
"auxiliary build of {:?} failed to compile: ",
|
||||
aux_testpaths.file.display()
|
||||
),
|
||||
&auxres,
|
||||
);
|
||||
}
|
||||
dylib
|
||||
}
|
||||
|
||||
fn compose_and_run(
|
||||
&self,
|
||||
mut command: Command,
|
||||
|
Loading…
Reference in New Issue
Block a user