diff options
| author | Ralf Jung <post@ralfj.de> | 2022-11-05 12:35:40 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2022-11-05 15:21:50 +0100 |
| commit | 83239c2c1ebed372dd34016bdd75d02e4429589d (patch) | |
| tree | f76015608b2a3fcdbdc5dc7f50049e089c6666d6 /compiler/rustc_metadata/src | |
| parent | 4492c029eff7b42e91e759576ab0c7ca88f873dc (diff) | |
| parent | 452cf4f7109f58433ac38be7d3da527408571054 (diff) | |
| download | rust-83239c2c1ebed372dd34016bdd75d02e4429589d.tar.gz rust-83239c2c1ebed372dd34016bdd75d02e4429589d.zip | |
Merge from rustc
Diffstat (limited to 'compiler/rustc_metadata/src')
| -rw-r--r-- | compiler/rustc_metadata/src/creader.rs | 97 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/errors.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/encoder.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/mod.rs | 7 |
6 files changed, 136 insertions, 33 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index cfcceecbef4..d4c457975a8 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1,8 +1,10 @@ //! Validates all used crates and extern libraries and loads their metadata use crate::errors::{ - ConflictingGlobalAlloc, CrateNotPanicRuntime, GlobalAllocRequired, NoMultipleGlobalAlloc, - NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore, + AllocFuncRequired, ConflictingAllocErrorHandler, ConflictingGlobalAlloc, CrateNotPanicRuntime, + GlobalAllocRequired, MissingAllocErrorHandler, NoMultipleAllocErrorHandler, + NoMultipleGlobalAlloc, NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, + ProfilerBuiltinsNeedsCore, }; use crate::locator::{CrateError, CrateLocator, CratePaths}; use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob}; @@ -41,8 +43,13 @@ pub struct CStore { /// 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 needs an allocation error handler 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. + alloc_error_handler_kind: Option<AllocatorKind>, /// This crate has a `#[global_allocator]` item. has_global_allocator: bool, + /// This crate has a `#[alloc_error_handler]` item. + has_alloc_error_handler: bool, /// This map is used to verify we get no hash conflicts between /// `StableCrateId` values. @@ -197,10 +204,18 @@ impl CStore { self.allocator_kind } + pub(crate) fn alloc_error_handler_kind(&self) -> Option<AllocatorKind> { + self.alloc_error_handler_kind + } + pub(crate) fn has_global_allocator(&self) -> bool { self.has_global_allocator } + pub(crate) fn has_alloc_error_handler(&self) -> bool { + self.has_alloc_error_handler + } + pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { let json_unused_externs = tcx.sess.opts.json_unused_externs; @@ -247,7 +262,9 @@ impl<'a> CrateLoader<'a> { metas: IndexVec::from_elem_n(None, 1), injected_panic_runtime: None, allocator_kind: None, + alloc_error_handler_kind: None, has_global_allocator: false, + has_alloc_error_handler: false, stable_crate_ids, unused_externs: Vec::new(), }, @@ -792,6 +809,13 @@ impl<'a> CrateLoader<'a> { } spans => !spans.is_empty(), }; + self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(&self.sess, krate) { + [span1, span2, ..] => { + self.sess.emit_err(NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 }); + true + } + spans => !spans.is_empty(), + }; // Check to see if we actually need an allocator. This desire comes // about through the `#![needs_allocator]` attribute and is typically @@ -832,22 +856,48 @@ impl<'a> CrateLoader<'a> { } } } + let mut alloc_error_handler = + self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate")); + for (_, data) in self.cstore.iter_crate_data() { + if data.has_alloc_error_handler() { + match alloc_error_handler { + Some(other_crate) => { + self.sess.emit_err(ConflictingAllocErrorHandler { + crate_name: data.name(), + other_crate_name: other_crate, + }); + } + None => alloc_error_handler = Some(data.name()), + } + } + } if global_allocator.is_some() { self.cstore.allocator_kind = Some(AllocatorKind::Global); - return; + } else { + // Ok we haven't found a global allocator but we still need an + // allocator. At this point our allocator request is typically fulfilled + // by the standard library, denoted by the `#![default_lib_allocator]` + // attribute. + if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator) + && !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator()) + { + self.sess.emit_err(GlobalAllocRequired); + } + self.cstore.allocator_kind = Some(AllocatorKind::Default); } - // Ok we haven't found a global allocator but we still need an - // allocator. At this point our allocator request is typically fulfilled - // by the standard library, denoted by the `#![default_lib_allocator]` - // attribute. - if !self.sess.contains_name(&krate.attrs, sym::default_lib_allocator) - && !self.cstore.iter_crate_data().any(|(_, data)| data.has_default_lib_allocator()) - { - self.sess.emit_err(GlobalAllocRequired); + if alloc_error_handler.is_some() { + self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Global); + } else { + // The alloc crate provides a default allocation error handler if + // one isn't specified. + if !self.sess.features_untracked().default_alloc_error_handler { + self.sess.emit_err(AllocFuncRequired); + self.sess.emit_note(MissingAllocErrorHandler); + } + self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default); } - self.cstore.allocator_kind = Some(AllocatorKind::Default); } fn inject_dependency_if( @@ -1023,3 +1073,26 @@ fn global_allocator_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> { visit::walk_crate(&mut f, krate); f.spans } + +fn alloc_error_handler_spans(sess: &Session, krate: &ast::Crate) -> Vec<Span> { + struct Finder<'a> { + sess: &'a Session, + name: Symbol, + spans: Vec<Span>, + } + impl<'ast, 'a> visit::Visitor<'ast> for Finder<'a> { + fn visit_item(&mut self, item: &'ast ast::Item) { + if item.ident.name == self.name + && self.sess.contains_name(&item.attrs, sym::rustc_std_internal_symbol) + { + self.spans.push(item.span); + } + visit::walk_item(self, item) + } + } + + let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::oom)); + let mut f = Finder { sess, name, spans: Vec::new() }; + visit::walk_crate(&mut f, krate); + f.spans +} diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 7c387b9a9ec..e5b91d566e5 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -344,6 +344,16 @@ pub struct NoMultipleGlobalAlloc { } #[derive(Diagnostic)] +#[diag(metadata_no_multiple_alloc_error_handler)] +pub struct NoMultipleAllocErrorHandler { + #[primary_span] + #[label] + pub span2: Span, + #[label(metadata_prev_alloc_error_handler)] + pub span1: Span, +} + +#[derive(Diagnostic)] #[diag(metadata_conflicting_global_alloc)] pub struct ConflictingGlobalAlloc { pub crate_name: Symbol, @@ -351,10 +361,25 @@ pub struct ConflictingGlobalAlloc { } #[derive(Diagnostic)] +#[diag(metadata_conflicting_alloc_error_handler)] +pub struct ConflictingAllocErrorHandler { + pub crate_name: Symbol, + pub other_crate_name: Symbol, +} + +#[derive(Diagnostic)] #[diag(metadata_global_alloc_required)] pub struct GlobalAllocRequired; #[derive(Diagnostic)] +#[diag(metadata_alloc_func_required)] +pub struct AllocFuncRequired; + +#[derive(Diagnostic)] +#[diag(metadata_missing_alloc_error_handler)] +pub struct MissingAllocErrorHandler; + +#[derive(Diagnostic)] #[diag(metadata_no_transitive_needs_dep)] pub struct NoTransitiveNeedsDep<'a> { pub crate_name: Symbol, @@ -578,6 +603,7 @@ pub struct InvalidMetadataFiles { } impl IntoDiagnostic<'_> for InvalidMetadataFiles { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, @@ -606,6 +632,7 @@ pub struct CannotFindCrate { } impl IntoDiagnostic<'_> for CannotFindCrate { + #[track_caller] fn into_diagnostic( self, handler: &'_ rustc_errors::Handler, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 691e3d0f8f9..8e80d794a13 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -15,7 +15,6 @@ use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::diagnostic_items::DiagnosticItems; -use rustc_hir::lang_items; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; @@ -967,7 +966,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } /// Iterates over the language items in the given crate. - fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { + fn get_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] { tcx.arena.alloc_from_iter( self.root .lang_items @@ -1319,7 +1318,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) } - fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { + fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] { tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self)) } @@ -1765,6 +1764,10 @@ impl CrateMetadata { self.root.has_global_allocator } + pub(crate) fn has_alloc_error_handler(&self) -> bool { + self.root.has_alloc_error_handler + } + pub(crate) fn has_default_lib_allocator(&self) -> bool { self.root.has_default_lib_allocator } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index a0a0855251b..f475b0b3981 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -255,6 +255,7 @@ provide! { tcx, def_id, other, cdata, is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } + has_alloc_error_handler => { cdata.root.has_alloc_error_handler } has_panic_handler => { cdata.root.has_panic_handler } is_profiler_runtime => { cdata.root.profiler_runtime } required_panic_strategy => { cdata.root.required_panic_strategy } @@ -339,6 +340,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { // resolve! Does this work? Unsure! That's what the issue is about *providers = Providers { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), + alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); false @@ -464,6 +466,10 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { assert_eq!(cnum, LOCAL_CRATE); CStore::from_tcx(tcx).has_global_allocator() }, + has_alloc_error_handler: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + CStore::from_tcx(tcx).has_alloc_error_handler() + }, postorder_cnums: |tcx, ()| { tcx.arena .alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE)) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 049514ec7b2..6a73e14e9f5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -17,7 +17,7 @@ use rustc_hir::def_id::{ }; use rustc_hir::definitions::DefPathData; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::lang_items; +use rustc_hir::lang_items::LangItem; use rustc_middle::hir::nested_filter; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::{ @@ -670,6 +670,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(), has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), + has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE), has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), has_default_lib_allocator: tcx .sess @@ -787,8 +788,7 @@ fn should_encode_attr( } else if attr.doc_str().is_some() { // We keep all public doc comments because they might be "imported" into downstream crates // if they use `#[doc(inline)]` to copy an item's documentation into their own. - *is_def_id_public - .get_or_insert_with(|| tcx.effective_visibilities(()).effective_vis(def_id).is_some()) + *is_def_id_public.get_or_insert_with(|| tcx.effective_visibilities(()).is_exported(def_id)) } else if attr.has_name(sym::doc) { // If this is a `doc` attribute, and it's marked `inline` (as in `#[doc(inline)]`), we can // remove it. It won't be inlinable in downstream crates. @@ -1905,22 +1905,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.lazy_array(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index))) } - fn encode_lang_items(&mut self) -> LazyArray<(DefIndex, usize)> { + fn encode_lang_items(&mut self) -> LazyArray<(DefIndex, LangItem)> { empty_proc_macro!(self); - let tcx = self.tcx; - let lang_items = tcx.lang_items(); - let lang_items = lang_items.items().iter(); - self.lazy_array(lang_items.enumerate().filter_map(|(i, &opt_def_id)| { - if let Some(def_id) = opt_def_id { - if def_id.is_local() { - return Some((def_id.index, i)); - } - } - None + let lang_items = self.tcx.lang_items().iter(); + self.lazy_array(lang_items.filter_map(|(lang_item, def_id)| { + def_id.as_local().map(|id| (id.local_def_index, lang_item)) })) } - fn encode_lang_items_missing(&mut self) -> LazyArray<lang_items::LangItem> { + fn encode_lang_items_missing(&mut self) -> LazyArray<LangItem> { empty_proc_macro!(self); let tcx = self.tcx; self.lazy_array(&tcx.lang_items().missing) diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 27dc8ff16ac..aa6d378a43a 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}; use rustc_hir::definitions::DefKey; -use rustc_hir::lang_items; +use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::{BitSet, FiniteBitSet}; use rustc_index::vec::IndexVec; use rustc_middle::metadata::ModChild; @@ -223,6 +223,7 @@ pub(crate) struct CrateRoot { panic_in_drop_strategy: PanicStrategy, edition: Edition, has_global_allocator: bool, + has_alloc_error_handler: bool, has_panic_handler: bool, has_default_lib_allocator: bool, @@ -230,8 +231,8 @@ pub(crate) struct CrateRoot { dylib_dependency_formats: LazyArray<Option<LinkagePreference>>, lib_features: LazyArray<(Symbol, Option<Symbol>)>, stability_implications: LazyArray<(Symbol, Symbol)>, - lang_items: LazyArray<(DefIndex, usize)>, - lang_items_missing: LazyArray<lang_items::LangItem>, + lang_items: LazyArray<(DefIndex, LangItem)>, + lang_items_missing: LazyArray<LangItem>, diagnostic_items: LazyArray<(Symbol, DefIndex)>, native_libraries: LazyArray<NativeLib>, foreign_modules: LazyArray<ForeignModule>, |
