Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #63653

Closed
wants to merge 11 commits into from
Closed
3 changes: 3 additions & 0 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,9 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
if builder.config.llvm_use_libcxx {
cargo.env("LLVM_USE_LIBCXX", "1");
}
if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
cargo.env("LLVM_NDEBUG", "1");
}
}
_ => panic!("unknown backend: {}", backend),
}
Expand Down
30 changes: 30 additions & 0 deletions src/libcore/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,36 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
_ => (usize::MAX, None)
}
}

#[inline]
fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
where
F: FnMut(Acc, Self::Item) -> R,
R: Try<Ok = Acc>,
{
// fully iterate the current iterator. this is necessary because
// `self.iter` may be empty even when `self.orig` isn't
acc = self.iter.try_fold(acc, &mut f)?;
self.iter = self.orig.clone();

// complete a full cycle, keeping track of whether the cycled
// iterator is empty or not. we need to return early in case
// of an empty iterator to prevent an infinite loop
let mut is_empty = true;
acc = self.iter.try_fold(acc, |acc, x| {
is_empty = false;
f(acc, x)
})?;

if is_empty {
return Try::from_ok(acc);
}

loop {
self.iter = self.orig.clone();
acc = self.iter.try_fold(acc, &mut f)?;
}
}
}

#[stable(feature = "fused", since = "1.26.0")]
Expand Down
12 changes: 12 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,18 @@ fn test_cycle() {
assert_eq!(empty::<i32>().cycle().fold(0, |acc, x| acc + x), 0);

assert_eq!(once(1).cycle().skip(1).take(4).fold(0, |acc, x| acc + x), 4);

assert_eq!((0..10).cycle().take(5).sum::<i32>(), 10);
assert_eq!((0..10).cycle().take(15).sum::<i32>(), 55);
assert_eq!((0..10).cycle().take(25).sum::<i32>(), 100);

let mut iter = (0..10).cycle();
iter.nth(14);
assert_eq!(iter.take(8).sum::<i32>(), 38);

let mut iter = (0..10).cycle();
iter.nth(9);
assert_eq!(iter.take(3).sum::<i32>(), 3);
}

#[test]
Expand Down
8 changes: 8 additions & 0 deletions src/libproc_macro/bridge/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,14 @@ pub enum ProcMacro {
}

impl ProcMacro {
pub fn name(&self) -> &'static str {
match self {
ProcMacro::CustomDerive { trait_name, .. } => trait_name,
ProcMacro::Attr { name, .. } => name,
ProcMacro::Bang { name, ..} => name
}
}

pub const fn custom_derive(
trait_name: &'static str,
attributes: &'static [&'static str],
Expand Down
26 changes: 0 additions & 26 deletions src/librustc/hir/def_id.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::ty::{self, TyCtxt};
use crate::hir::map::definitions::FIRST_FREE_DEF_INDEX;
use rustc_data_structures::indexed_vec::Idx;
use std::fmt;
use std::u32;
Expand Down Expand Up @@ -102,31 +101,6 @@ newtype_index! {
}
}

impl DefIndex {
// Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
// function maps the index of the macro within the crate (which is also the
// index of the macro in the CrateMetadata::proc_macros array) to the
// corresponding DefIndex.
pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
// DefIndex for proc macros start from FIRST_FREE_DEF_INDEX,
// because the first FIRST_FREE_DEF_INDEX indexes are reserved
// for internal use.
let def_index = DefIndex::from(
proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX)
.expect("integer overflow adding `proc_macro_index`"));
assert!(def_index != CRATE_DEF_INDEX);
def_index
}

// This function is the reverse of from_proc_macro_index() above.
pub fn to_proc_macro_index(self: DefIndex) -> usize {
self.index().checked_sub(FIRST_FREE_DEF_INDEX)
.unwrap_or_else(|| {
bug!("using local index {:?} as proc-macro index", self)
})
}
}

impl rustc_serialize::UseSpecializedEncodable for DefIndex {}
impl rustc_serialize::UseSpecializedDecodable for DefIndex {}

Expand Down
19 changes: 0 additions & 19 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,6 @@ impl Definitions {
}

/// Adds a root definition (no parent) and a few other reserved definitions.
///
/// After the initial definitions are created the first `FIRST_FREE_DEF_INDEX` indexes
/// are taken, so the "user" indexes will be allocated starting with `FIRST_FREE_DEF_INDEX`
/// in ascending order.
pub fn create_root_def(&mut self,
crate_name: &str,
crate_disambiguator: CrateDisambiguator)
Expand Down Expand Up @@ -589,19 +585,6 @@ impl DefPathData {
}
}

/// Evaluates to the number of tokens passed to it.
///
/// Logarithmic counting: every one or two recursive expansions, the number of
/// tokens to count is divided by two, instead of being reduced by one.
/// Therefore, the recursion depth is the binary logarithm of the number of
/// tokens to count, and the expanded tree is likewise very small.
macro_rules! count {
() => (0usize);
($one:tt) => (1usize);
($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
}

// We define the GlobalMetaDataKind enum with this macro because we want to
// make sure that we exhaustively iterate over all variants when registering
// the corresponding DefIndices in the DefTable.
Expand All @@ -614,8 +597,6 @@ macro_rules! define_global_metadata_kind {
$($variant),*
}

pub const FIRST_FREE_DEF_INDEX: usize = 1 + count!($($variant)*);

impl GlobalMetaDataKind {
fn allocate_def_indices(definitions: &mut Definitions) {
$({
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ top_level_options!(
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
maybe_sysroot: Option<PathBuf> [TRACKED],
maybe_sysroot: Option<PathBuf> [UNTRACKED],

target_triple: TargetTriple [TRACKED],

Expand Down
12 changes: 10 additions & 2 deletions src/librustc_codegen_utils/symbol_names/v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,14 @@ impl SymbolMangler<'tcx> {

let lifetimes = regions.into_iter().map(|br| {
match br {
ty::BrAnon(i) => i + 1,
ty::BrAnon(i) => {
// FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
assert_ne!(i, 0);
i - 1
},
_ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value),
}
}).max().unwrap_or(0);
}).max().map_or(0, |max| max + 1);

self.push_opt_integer_62("G", lifetimes as u64);
lifetime_depths.end += lifetimes;
Expand Down Expand Up @@ -297,6 +301,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
// Late-bound lifetimes use indices starting at 1,
// see `BinderLevel` for more details.
ty::ReLateBound(debruijn, ty::BrAnon(i)) => {
// FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
assert_ne!(i, 0);
let i = i - 1;

let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
let depth = binder.lifetime_depths.start + i;

Expand Down
4 changes: 4 additions & 0 deletions src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ fn main() {
cfg.define("LLVM_RUSTLLVM", None);
}

if env::var_os("LLVM_NDEBUG").is_some() {
cfg.define("NDEBUG", None);
}

build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm"));
cfg.file("../rustllvm/PassWrapper.cpp")
.file("../rustllvm/RustWrapper.cpp")
Expand Down
91 changes: 25 additions & 66 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
use crate::locator::{self, CratePaths};
use crate::decoder::proc_macro_def_path_table;
use crate::schema::CrateRoot;
use crate::schema::{CrateRoot};
use rustc_data_structures::sync::{Lrc, RwLock, Lock};

use rustc::hir::def_id::CrateNum;
Expand All @@ -26,11 +25,11 @@ use std::{cmp, fs};
use syntax::ast;
use syntax::attr;
use syntax::ext::allocator::{global_allocator_spans, AllocatorKind};
use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
use syntax::symbol::{Symbol, sym};
use syntax::{span_err, span_fatal};
use syntax_pos::{Span, DUMMY_SP};
use log::{debug, info, log_enabled};
use proc_macro::bridge::client::ProcMacro;

pub struct Library {
pub dylib: Option<(PathBuf, PathKind)>,
Expand Down Expand Up @@ -230,24 +229,13 @@ impl<'a> CrateLoader<'a> {

let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();

let proc_macros = crate_root.proc_macro_decls_static.map(|_| {
let raw_proc_macros = crate_root.proc_macro_data.map(|_| {
if self.sess.opts.debugging_opts.dual_proc_macros {
let host_lib = host_lib.unwrap();
self.load_derive_macros(
&host_lib.metadata.get_root(),
host_lib.dylib.map(|p| p.0),
span
)
let host_lib = host_lib.as_ref().unwrap();
self.dlsym_proc_macros(host_lib.dylib.as_ref().map(|p| p.0.clone()),
&host_lib.metadata.get_root(), span)
} else {
self.load_derive_macros(&crate_root, dylib.clone().map(|p| p.0), span)
}
});

let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
if let Some(proc_macros) = &proc_macros {
proc_macro_def_path_table(&crate_root, proc_macros)
} else {
crate_root.def_path_table.decode((&metadata, self.sess))
self.dlsym_proc_macros(dylib.clone().map(|p| p.0), &crate_root, span)
}
});

Expand All @@ -260,13 +248,16 @@ impl<'a> CrateLoader<'a> {
.map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
.collect();

let def_path_table = record_time(&self.sess.perf_stats.decode_def_path_tables_time, || {
crate_root.def_path_table.decode((&metadata, self.sess))
});

let cmeta = cstore::CrateMetadata {
name: crate_root.name,
imported_name: ident,
extern_crate: Lock::new(None),
def_path_table: Lrc::new(def_path_table),
trait_impls,
proc_macros,
root: crate_root,
blob: metadata,
cnum_map,
Expand All @@ -280,7 +271,10 @@ impl<'a> CrateLoader<'a> {
rlib,
rmeta,
},
private_dep
private_dep,
span,
host_lib,
raw_proc_macros
};

let cmeta = Lrc::new(cmeta);
Expand All @@ -300,8 +294,6 @@ impl<'a> CrateLoader<'a> {
// message we emit
let mut proc_macro_locator = locate_ctxt.clone();

// Try to load a proc macro
proc_macro_locator.is_proc_macro = Some(true);

// Load the proc macro crate for the target
let (locator, target_result) = if self.sess.opts.debugging_opts.dual_proc_macros {
Expand Down Expand Up @@ -389,7 +381,7 @@ impl<'a> CrateLoader<'a> {
match result {
(LoadResult::Previous(cnum), None) => {
let data = self.cstore.get_crate_data(cnum);
if data.root.proc_macro_decls_static.is_some() {
if data.root.proc_macro_data.is_some() {
dep_kind = DepKind::UnexportedMacrosOnly;
}
data.dep_kind.with_lock(|data_dep_kind| {
Expand Down Expand Up @@ -482,7 +474,7 @@ impl<'a> CrateLoader<'a> {
dep_kind: DepKind)
-> cstore::CrateNumMap {
debug!("resolving deps of external crate");
if crate_root.proc_macro_decls_static.is_some() {
if crate_root.proc_macro_data.is_some() {
return cstore::CrateNumMap::new();
}

Expand Down Expand Up @@ -574,19 +566,13 @@ impl<'a> CrateLoader<'a> {
}
}

/// Loads custom derive macros.
///
/// Note that this is intentionally similar to how we load plugins today,
/// but also intentionally separate. Plugins are likely always going to be
/// implemented as dynamic libraries, but we have a possible future where
/// custom derive (and other macro-1.1 style features) are implemented via
/// executables and custom IPC.
fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, span: Span)
-> Vec<(ast::Name, Lrc<SyntaxExtension>)> {
use std::{env, mem};
fn dlsym_proc_macros(&self,
dylib: Option<PathBuf>,
root: &CrateRoot<'_>,
span: Span
) -> &'static [ProcMacro] {
use std::env;
use crate::dynamic_lib::DynamicLibrary;
use proc_macro::bridge::client::ProcMacro;
use syntax::ext::proc_macro::{BangProcMacro, AttrProcMacro, ProcMacroDerive};

let path = match dylib {
Some(dylib) => dylib,
Expand All @@ -608,38 +594,11 @@ impl<'a> CrateLoader<'a> {
*(sym as *const &[ProcMacro])
};

let extensions = decls.iter().map(|&decl| {
let (name, kind, helper_attrs) = match decl {
ProcMacro::CustomDerive { trait_name, attributes, client } => {
let helper_attrs =
attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
(
trait_name,
SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
client, attrs: helper_attrs.clone()
})),
helper_attrs,
)
}
ProcMacro::Attr { name, client } => (
name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new()
),
ProcMacro::Bang { name, client } => (
name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
)
};

(Symbol::intern(name), Lrc::new(SyntaxExtension {
helper_attrs,
..SyntaxExtension::default(kind, root.edition)
}))
}).collect();

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
mem::forget(lib);
std::mem::forget(lib);

extensions
decls
}

/// Look for a plugin registrar. Returns library path, crate
Expand Down
Loading