Skip to content
Permalink
Browse files

rustc_metadata: Move `has_global_allocator` from session to cstore

  • Loading branch information
petrochenkov committed Nov 24, 2019
1 parent 4c8105e commit 9be526e8ebfd318ecc5c6d5a6c40886dffb1be95
@@ -237,6 +237,7 @@ pub trait CrateStore {
fn metadata_encoding_version(&self) -> &[u8];
fn injected_panic_runtime(&self) -> Option<CrateNum>;
fn allocator_kind(&self) -> Option<AllocatorKind>;
fn has_global_allocator(&self) -> bool;
}

pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
@@ -133,9 +133,6 @@ pub struct Session {
/// false positives about a job server in our environment.
pub jobserver: Client,

/// Metadata about the allocators for the current crate being compiled.
pub has_global_allocator: Once<bool>,

/// Cap lint level specified by a driver specifically.
pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,

@@ -1180,7 +1177,6 @@ fn build_session_(
print_fuel_crate,
print_fuel,
jobserver: jobserver::client(),
has_global_allocator: Once::new(),
driver_lint_caps,
trait_methods_not_found: Lock::new(Default::default()),
confused_type_with_std_module: Lock::new(Default::default()),
@@ -3028,4 +3028,8 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
// We want to check if the panic handler was defined in this crate
tcx.lang_items().panic_impl().map_or(false, |did| did.is_local())
};
providers.has_global_allocator = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
tcx.cstore.has_global_allocator()
};
}
@@ -37,7 +37,11 @@ use rustc_error_codes::*;
pub struct CStore {
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
injected_panic_runtime: Option<CrateNum>,
/// This crate needs an allocator and either provides it itself, or finds it in a dependency.
/// If the above is true, then this field denotes the kind of the found allocator.
allocator_kind: Option<AllocatorKind>,
/// This crate has a `#[global_allocator]` item.
has_global_allocator: bool,
}

pub struct CrateLoader<'a> {
@@ -150,6 +154,10 @@ impl CStore {
crate fn allocator_kind(&self) -> Option<AllocatorKind> {
self.allocator_kind
}

crate fn has_global_allocator(&self) -> bool {
self.has_global_allocator
}
}

impl<'a> CrateLoader<'a> {
@@ -170,6 +178,7 @@ impl<'a> CrateLoader<'a> {
metas: IndexVec::from_elem_n(None, 1),
injected_panic_runtime: None,
allocator_kind: None,
has_global_allocator: false,
}
}
}
@@ -562,7 +571,6 @@ impl<'a> CrateLoader<'a> {
});
if !any_non_rlib {
info!("panic runtime injection skipped, only generating rlib");
self.cstore.injected_panic_runtime = None;
return
}

@@ -593,7 +601,6 @@ impl<'a> CrateLoader<'a> {
// we just don't need one at all, then we're done here and there's
// nothing else to do.
if !needs_panic_runtime || runtime_found {
self.cstore.injected_panic_runtime = None;
return
}

@@ -753,7 +760,7 @@ impl<'a> CrateLoader<'a> {
}

fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
let has_global_allocator = match &*global_allocator_spans(krate) {
self.cstore.has_global_allocator = match &*global_allocator_spans(krate) {
[span1, span2, ..] => {
self.sess.struct_span_err(*span2, "cannot define multiple global allocators")
.span_label(*span2, "cannot define a new global allocator")
@@ -763,7 +770,6 @@ impl<'a> CrateLoader<'a> {
}
spans => !spans.is_empty()
};
self.sess.has_global_allocator.set(has_global_allocator);

// Check to see if we actually need an allocator. This desire comes
// about through the `#![needs_allocator]` attribute and is typically
@@ -774,7 +780,6 @@ impl<'a> CrateLoader<'a> {
needs_allocator = needs_allocator || data.needs_allocator();
});
if !needs_allocator {
self.cstore.allocator_kind = None;
return
}

@@ -790,7 +795,6 @@ impl<'a> CrateLoader<'a> {
}
});
if all_rlib {
self.cstore.allocator_kind = None;
return
}

@@ -801,8 +805,8 @@ impl<'a> CrateLoader<'a> {
// First up we check for global allocators. Look at the crate graph here
// and see what's a global allocator, including if we ourselves are a
// global allocator.
let mut global_allocator = if has_global_allocator {
Some(None)
let mut global_allocator = if self.cstore.has_global_allocator {
Some(Symbol::intern("this crate"))
} else {
None
};
@@ -811,19 +815,14 @@ impl<'a> CrateLoader<'a> {
return
}
match global_allocator {
Some(Some(other_crate)) => {
Some(other_crate) => {
self.sess.err(&format!("the `#[global_allocator]` in {} \
conflicts with this global \
conflicts with global \
allocator in: {}",
other_crate,
data.name()));
}
Some(None) => {
self.sess.err(&format!("the `#[global_allocator]` in this \
crate conflicts with global \
allocator in: {}", data.name()));
}
None => global_allocator = Some(Some(data.name())),
None => global_allocator = Some(data.name()),
}
});
if global_allocator.is_some() {
@@ -848,7 +847,7 @@ impl<'a> CrateLoader<'a> {
add `#[global_allocator]` to a static item \
that implements the GlobalAlloc trait.");
}
self.cstore.allocator_kind = Some(AllocatorKind::DefaultLib);
self.cstore.allocator_kind = Some(AllocatorKind::Default);
}

fn inject_dependency_if(&self,
@@ -536,4 +536,8 @@ impl CrateStore for CStore {
fn allocator_kind(&self) -> Option<AllocatorKind> {
self.allocator_kind()
}

fn has_global_allocator(&self) -> bool {
self.has_global_allocator()
}
}
@@ -496,7 +496,6 @@ impl<'tcx> EncodeContext<'tcx> {

let attrs = tcx.hir().krate_attrs();
let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
let has_global_allocator = *tcx.sess.has_global_allocator.get();

let root = self.lazy(CrateRoot {
name: tcx.crate_name(LOCAL_CRATE),
@@ -506,7 +505,7 @@ impl<'tcx> EncodeContext<'tcx> {
disambiguator: tcx.sess.local_crate_disambiguator(),
panic_strategy: tcx.sess.panic_strategy(),
edition: tcx.sess.edition(),
has_global_allocator: has_global_allocator,
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
has_default_lib_allocator: has_default_lib_allocator,
plugin_registrar_fn: tcx.plugin_registrar_fn(LOCAL_CRATE).map(|id| id.index),
@@ -5,16 +5,14 @@ use syntax_pos::Span;
#[derive(Clone, Copy)]
pub enum AllocatorKind {
Global,
DefaultLib,
DefaultExe,
Default,
}

impl AllocatorKind {
pub fn fn_name(&self, base: &str) -> String {
match *self {
AllocatorKind::Global => format!("__rg_{}", base),
AllocatorKind::DefaultLib => format!("__rdl_{}", base),
AllocatorKind::DefaultExe => format!("__rde_{}", base),
AllocatorKind::Default => format!("__rdl_{}", base),
}
}
}
@@ -1,4 +1,4 @@
error: the `#[global_allocator]` in system_allocator conflicts with this global allocator in: system_allocator2
error: the `#[global_allocator]` in system_allocator conflicts with global allocator in: system_allocator2

error: aborting due to previous error

0 comments on commit 9be526e

Please sign in to comment.
You can’t perform that action at this time.