2019-11-24 01:10:12 +03:00
|
|
|
use crate::creader::{CStore, LoadedMacro};
|
2019-02-08 20:50:17 +09:00
|
|
|
use crate::foreign_modules;
|
|
|
|
|
use crate::native_libs;
|
2015-11-25 00:00:26 +02:00
|
|
|
|
2020-04-27 23:26:11 +05:30
|
|
|
use rustc_ast as ast;
|
2022-05-22 11:16:14 -07:00
|
|
|
use rustc_attr::Deprecation;
|
2021-12-18 20:07:58 +08:00
|
|
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
2022-04-15 19:27:53 +02:00
|
|
|
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
|
2020-03-21 04:39:48 +01:00
|
|
|
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
|
2022-05-22 11:16:14 -07:00
|
|
|
use rustc_middle::arena::ArenaAllocatable;
|
2021-12-21 11:24:43 +08:00
|
|
|
use rustc_middle::metadata::ModChild;
|
2020-03-29 17:19:48 +02:00
|
|
|
use rustc_middle::middle::exported_symbols::ExportedSymbol;
|
2022-05-22 11:16:14 -07:00
|
|
|
use rustc_middle::middle::stability::DeprecationEntry;
|
2021-08-29 21:41:46 +03:00
|
|
|
use rustc_middle::ty::fast_reject::SimplifiedType;
|
2021-05-30 17:24:54 +02:00
|
|
|
use rustc_middle::ty::query::{ExternProviders, Providers};
|
2021-05-07 22:42:12 -07:00
|
|
|
use rustc_middle::ty::{self, TyCtxt, Visibility};
|
2022-01-31 19:55:34 +01:00
|
|
|
use rustc_session::cstore::{CrateSource, CrateStore};
|
2021-06-08 18:36:30 +02:00
|
|
|
use rustc_session::{Session, StableCrateId};
|
2021-06-27 15:51:25 +02:00
|
|
|
use rustc_span::hygiene::{ExpnHash, ExpnId};
|
2020-08-21 19:11:00 -04:00
|
|
|
use rustc_span::source_map::{Span, Spanned};
|
2021-11-30 17:18:48 -08:00
|
|
|
use rustc_span::symbol::{kw, Symbol};
|
2015-11-25 00:00:26 +02:00
|
|
|
|
2018-02-27 17:11:14 +01:00
|
|
|
use rustc_data_structures::sync::Lrc;
|
2016-09-29 02:30:53 +03:00
|
|
|
use std::any::Any;
|
|
|
|
|
|
2022-05-22 11:16:14 -07:00
|
|
|
use super::{Decodable, DecodeContext, DecodeIterator};
|
|
|
|
|
|
|
|
|
|
trait ProcessQueryValue<'tcx, T> {
|
|
|
|
|
fn process_decoded(self, _tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> T;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T> ProcessQueryValue<'_, Option<T>> for Option<T> {
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Option<T> {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T> ProcessQueryValue<'_, T> for Option<T> {
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, _tcx: TyCtxt<'_>, err: impl Fn() -> !) -> T {
|
|
|
|
|
if let Some(value) = self { value } else { err() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'tcx, T: ArenaAllocatable<'tcx>> ProcessQueryValue<'tcx, &'tcx T> for Option<T> {
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx T {
|
|
|
|
|
if let Some(value) = self { tcx.arena.alloc(value) } else { err() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T, E> ProcessQueryValue<'_, Result<Option<T>, E>> for Option<T> {
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Result<Option<T>, E> {
|
|
|
|
|
Ok(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'tcx, &'tcx [T]>
|
|
|
|
|
for Option<DecodeIterator<'a, 'tcx, T>>
|
|
|
|
|
{
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> &'tcx [T] {
|
|
|
|
|
if let Some(iter) = self { tcx.arena.alloc_from_iter(iter) } else { &[] }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ProcessQueryValue<'_, Option<DeprecationEntry>> for Option<Deprecation> {
|
2022-05-23 19:50:29 -07:00
|
|
|
#[inline(always)]
|
2022-05-22 11:16:14 -07:00
|
|
|
fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Option<DeprecationEntry> {
|
|
|
|
|
self.map(DeprecationEntry::external)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-17 21:33:23 +01:00
|
|
|
macro_rules! provide_one {
|
2022-08-11 21:35:33 -05:00
|
|
|
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table }) => {
|
2022-02-17 21:33:23 +01:00
|
|
|
provide_one! {
|
2022-08-11 21:35:33 -05:00
|
|
|
$tcx, $def_id, $other, $cdata, $name => {
|
2022-05-22 11:16:14 -07:00
|
|
|
$cdata
|
|
|
|
|
.root
|
|
|
|
|
.tables
|
|
|
|
|
.$name
|
|
|
|
|
.get($cdata, $def_id.index)
|
|
|
|
|
.map(|lazy| lazy.decode(($cdata, $tcx)))
|
|
|
|
|
.process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-08-11 21:35:33 -05:00
|
|
|
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_direct }) => {
|
2022-05-22 11:16:14 -07:00
|
|
|
provide_one! {
|
2022-08-11 21:35:33 -05:00
|
|
|
$tcx, $def_id, $other, $cdata, $name => {
|
2022-05-22 11:16:14 -07:00
|
|
|
// We don't decode `table_direct`, since it's not a Lazy, but an actual value
|
|
|
|
|
$cdata
|
|
|
|
|
.root
|
|
|
|
|
.tables
|
|
|
|
|
.$name
|
|
|
|
|
.get($cdata, $def_id.index)
|
|
|
|
|
.process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name)))
|
2022-02-17 21:33:23 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2022-08-11 21:35:33 -05:00
|
|
|
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => {
|
|
|
|
|
fn $name<'tcx>(
|
|
|
|
|
$tcx: TyCtxt<'tcx>,
|
|
|
|
|
def_id_arg: ty::query::query_keys::$name<'tcx>,
|
|
|
|
|
) -> ty::query::query_values::$name<'tcx> {
|
2022-02-17 21:33:23 +01:00
|
|
|
let _prof_timer =
|
|
|
|
|
$tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));
|
|
|
|
|
|
|
|
|
|
#[allow(unused_variables)]
|
|
|
|
|
let ($def_id, $other) = def_id_arg.into_args();
|
|
|
|
|
assert!(!$def_id.is_local());
|
|
|
|
|
|
|
|
|
|
// External query providers call `crate_hash` in order to register a dependency
|
|
|
|
|
// on the crate metadata. The exception is `crate_hash` itself, which obviously
|
|
|
|
|
// doesn't need to do this (and can't, as it would cause a query cycle).
|
|
|
|
|
use rustc_middle::dep_graph::DepKind;
|
|
|
|
|
if DepKind::$name != DepKind::crate_hash && $tcx.dep_graph.is_fully_enabled() {
|
|
|
|
|
$tcx.ensure().crate_hash($def_id.krate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let $cdata = CStore::from_tcx($tcx).get_crate_data($def_id.krate);
|
|
|
|
|
|
|
|
|
|
$compute
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-29 02:30:53 +03:00
|
|
|
macro_rules! provide {
|
2022-08-11 21:35:33 -05:00
|
|
|
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident,
|
2022-02-17 21:33:23 +01:00
|
|
|
$($name:ident => { $($compute:tt)* })*) => {
|
2021-05-30 17:24:54 +02:00
|
|
|
pub fn provide_extern(providers: &mut ExternProviders) {
|
2022-02-17 21:33:23 +01:00
|
|
|
$(provide_one! {
|
2022-08-11 21:35:33 -05:00
|
|
|
$tcx, $def_id, $other, $cdata, $name => { $($compute)* }
|
2016-09-29 02:30:53 +03:00
|
|
|
})*
|
|
|
|
|
|
2021-05-30 17:24:54 +02:00
|
|
|
*providers = ExternProviders {
|
2016-09-29 02:30:53 +03:00
|
|
|
$($name,)*
|
|
|
|
|
..*providers
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:40:02 -07:00
|
|
|
// small trait to work around different signature queries all being defined via
|
|
|
|
|
// the macro above.
|
|
|
|
|
trait IntoArgs {
|
2022-03-15 16:30:30 +01:00
|
|
|
type Other;
|
|
|
|
|
fn into_args(self) -> (DefId, Self::Other);
|
2017-08-28 15:55:32 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:40:02 -07:00
|
|
|
impl IntoArgs for DefId {
|
2022-03-15 16:30:30 +01:00
|
|
|
type Other = ();
|
|
|
|
|
fn into_args(self) -> (DefId, ()) {
|
|
|
|
|
(self, ())
|
2017-08-30 11:40:02 -07:00
|
|
|
}
|
2017-08-28 15:55:32 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:40:02 -07:00
|
|
|
impl IntoArgs for CrateNum {
|
2022-03-15 16:30:30 +01:00
|
|
|
type Other = ();
|
|
|
|
|
fn into_args(self) -> (DefId, ()) {
|
|
|
|
|
(self.as_def_id(), ())
|
2017-08-30 11:40:02 -07:00
|
|
|
}
|
2017-08-28 15:55:32 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-30 11:40:02 -07:00
|
|
|
impl IntoArgs for (CrateNum, DefId) {
|
2022-03-15 16:30:30 +01:00
|
|
|
type Other = DefId;
|
2017-08-30 11:40:02 -07:00
|
|
|
fn into_args(self) -> (DefId, DefId) {
|
|
|
|
|
(self.0.as_def_id(), self.1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 17:35:27 +00:00
|
|
|
impl<'tcx> IntoArgs for ty::InstanceDef<'tcx> {
|
2022-03-15 16:30:30 +01:00
|
|
|
type Other = ();
|
|
|
|
|
fn into_args(self) -> (DefId, ()) {
|
|
|
|
|
(self.def_id(), ())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl IntoArgs for (CrateNum, SimplifiedType) {
|
|
|
|
|
type Other = SimplifiedType;
|
|
|
|
|
fn into_args(self) -> (DefId, SimplifiedType) {
|
|
|
|
|
(self.0.as_def_id(), self.1)
|
2021-10-01 17:08:06 +00:00
|
|
|
}
|
2017-08-30 11:40:02 -07:00
|
|
|
}
|
|
|
|
|
|
2022-08-11 21:35:33 -05:00
|
|
|
provide! { tcx, def_id, other, cdata,
|
2022-02-17 21:33:23 +01:00
|
|
|
explicit_item_bounds => { table }
|
|
|
|
|
explicit_predicates_of => { table }
|
|
|
|
|
generics_of => { table }
|
|
|
|
|
inferred_outlives_of => { table }
|
|
|
|
|
super_predicates_of => { table }
|
|
|
|
|
type_of => { table }
|
|
|
|
|
variances_of => { table }
|
|
|
|
|
fn_sig => { table }
|
2022-04-27 10:22:08 +02:00
|
|
|
codegen_fn_attrs => { table }
|
2022-02-17 21:33:23 +01:00
|
|
|
impl_trait_ref => { table }
|
|
|
|
|
const_param_default => { table }
|
2022-05-29 20:15:34 +02:00
|
|
|
object_lifetime_default => { table }
|
2022-02-17 21:33:23 +01:00
|
|
|
thir_abstract_const => { table }
|
|
|
|
|
optimized_mir => { table }
|
|
|
|
|
mir_for_ctfe => { table }
|
|
|
|
|
promoted_mir => { table }
|
|
|
|
|
def_span => { table }
|
|
|
|
|
def_ident_span => { table }
|
|
|
|
|
lookup_stability => { table }
|
|
|
|
|
lookup_const_stability => { table }
|
2022-04-27 18:14:19 +04:00
|
|
|
lookup_default_body_stability => { table }
|
2022-02-17 21:33:23 +01:00
|
|
|
lookup_deprecation_entry => { table }
|
2022-08-15 14:11:11 -05:00
|
|
|
params_in_repr => { table }
|
2022-02-17 21:33:23 +01:00
|
|
|
unused_generic_params => { table }
|
2022-05-22 11:16:14 -07:00
|
|
|
opt_def_kind => { table_direct }
|
2022-02-17 22:00:03 +01:00
|
|
|
impl_parent => { table }
|
2022-05-22 11:16:14 -07:00
|
|
|
impl_polarity => { table_direct }
|
|
|
|
|
impl_defaultness => { table_direct }
|
2022-06-15 20:54:43 +10:00
|
|
|
constness => { table_direct }
|
2022-02-17 22:00:03 +01:00
|
|
|
coerce_unsized_info => { table }
|
2022-02-18 18:53:47 +01:00
|
|
|
mir_const_qualif => { table }
|
2022-02-18 19:09:02 +01:00
|
|
|
rendered_const => { table }
|
2022-05-22 11:16:14 -07:00
|
|
|
asyncness => { table_direct }
|
2022-02-18 19:23:58 +01:00
|
|
|
fn_arg_names => { table }
|
2022-02-18 19:34:24 +01:00
|
|
|
generator_kind => { table }
|
2022-03-10 19:07:27 +01:00
|
|
|
trait_def => { table }
|
Introduce deduced parameter attributes, and use them for deducing `readonly` on
indirect immutable freeze by-value function parameters.
Right now, `rustc` only examines function signatures and the platform ABI when
determining the LLVM attributes to apply to parameters. This results in missed
optimizations, because there are some attributes that can be determined via
analysis of the MIR making up the function body. In particular, `readonly`
could be applied to most indirectly-passed by-value function arguments
(specifically, those that are freeze and are observed not to be mutated), but
it currently is not.
This patch introduces the machinery that allows `rustc` to determine those
attributes. It consists of a query, `deduced_param_attrs`, that, when
evaluated, analyzes the MIR of the function to determine supplementary
attributes. The results of this query for each function are written into the
crate metadata so that the deduced parameter attributes can be applied to
cross-crate functions. In this patch, we simply check the parameter for
mutations to determine whether the `readonly` attribute should be applied to
parameters that are indirect immutable freeze by-value. More attributes could
conceivably be deduced in the future: `nocapture` and `noalias` come to mind.
Adding `readonly` to indirect function parameters where applicable enables some
potential optimizations in LLVM that are discussed in [issue 103103] and [PR
103070] around avoiding stack-to-stack memory copies that appear in functions
like `core::fmt::Write::write_fmt` and `core::panicking::assert_failed`. These
functions pass a large structure unchanged by value to a subfunction that also
doesn't mutate it. Since the structure in this case is passed as an indirect
parameter, it's a pointer from LLVM's perspective. As a result, the
intermediate copy of the structure that our codegen emits could be optimized
away by LLVM's MemCpyOptimizer if it knew that the pointer is `readonly
nocapture noalias` in both the caller and callee. We already pass `nocapture
noalias`, but we're missing `readonly`, as we can't determine whether a
by-value parameter is mutated by examining the signature in Rust. I didn't have
much success with having LLVM infer the `readonly` attribute, even with fat
LTO; it seems that deducing it at the MIR level is necessary.
No large benefits should be expected from this optimization *now*; LLVM needs
some changes (discussed in [PR 103070]) to more aggressively use the `noalias
nocapture readonly` combination in its alias analysis. I have some LLVM patches
for these optimizations and have had them looked over. With all the patches
applied locally, I enabled LLVM to remove all the `memcpy`s from the following
code:
```rust
fn main() {
println!("Hello {}", 3);
}
```
which is a significant codegen improvement over the status quo. I expect that
if this optimization kicks in in multiple places even for such a simple
program, then it will apply to Rust code all over the place.
[issue 103103]: https://github.com/rust-lang/rust/issues/103103
[PR 103070]: https://github.com/rust-lang/rust/pull/103070
2022-10-17 19:42:15 -07:00
|
|
|
deduced_param_attrs => { table }
|
2022-09-23 00:56:55 +00:00
|
|
|
collect_trait_impl_trait_tys => {
|
|
|
|
|
Ok(cdata
|
|
|
|
|
.root
|
|
|
|
|
.tables
|
|
|
|
|
.trait_impl_trait_tys
|
|
|
|
|
.get(cdata, def_id.index)
|
|
|
|
|
.map(|lazy| lazy.decode((cdata, tcx)))
|
|
|
|
|
.process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id)))
|
|
|
|
|
}
|
2022-02-17 21:33:23 +01:00
|
|
|
|
2022-08-28 00:10:06 +03:00
|
|
|
visibility => { cdata.get_visibility(def_id.index) }
|
2016-09-29 02:30:53 +03:00
|
|
|
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
|
2017-03-01 18:42:26 +02:00
|
|
|
adt_destructor => {
|
|
|
|
|
let _ = cdata;
|
2020-10-09 17:22:25 +02:00
|
|
|
tcx.calculate_dtor(def_id, |_,_| Ok(()))
|
2017-03-01 18:42:26 +02:00
|
|
|
}
|
2022-04-05 23:46:44 +03:00
|
|
|
associated_item_def_ids => {
|
|
|
|
|
tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess))
|
|
|
|
|
}
|
2022-08-04 22:03:16 +02:00
|
|
|
associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
|
2018-11-30 15:19:12 +01:00
|
|
|
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
|
2017-04-14 10:51:22 -04:00
|
|
|
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
|
2022-01-06 12:13:41 +08:00
|
|
|
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
|
2017-05-04 12:45:56 -05:00
|
|
|
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
|
2020-10-28 13:12:49 +00:00
|
|
|
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
|
2017-06-14 22:49:07 -07:00
|
|
|
|
2018-12-01 17:27:12 +01:00
|
|
|
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
|
2021-05-11 22:06:07 +02:00
|
|
|
is_private_dep => { cdata.private_dep }
|
2018-05-12 16:36:53 -07:00
|
|
|
is_panic_runtime => { cdata.root.panic_runtime }
|
|
|
|
|
is_compiler_builtins => { cdata.root.compiler_builtins }
|
|
|
|
|
has_global_allocator => { cdata.root.has_global_allocator }
|
2022-10-14 02:24:58 +01:00
|
|
|
has_alloc_error_handler => { cdata.root.has_alloc_error_handler }
|
2018-09-06 21:24:33 +02:00
|
|
|
has_panic_handler => { cdata.root.has_panic_handler }
|
2018-05-12 16:36:53 -07:00
|
|
|
is_profiler_runtime => { cdata.root.profiler_runtime }
|
2022-06-08 21:32:17 +01:00
|
|
|
required_panic_strategy => { cdata.root.required_panic_strategy }
|
2021-09-09 13:31:19 +01:00
|
|
|
panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
|
2018-02-15 10:52:26 +01:00
|
|
|
extern_crate => {
|
2018-12-01 17:27:12 +01:00
|
|
|
let r = *cdata.extern_crate.lock();
|
|
|
|
|
r.map(|c| &*tcx.arena.alloc(c))
|
2018-02-15 10:52:26 +01:00
|
|
|
}
|
2018-05-12 16:36:53 -07:00
|
|
|
is_no_builtins => { cdata.root.no_builtins }
|
2019-01-29 07:24:32 +02:00
|
|
|
symbol_mangling_version => { cdata.root.symbol_mangling_version }
|
2018-02-27 19:28:21 +01:00
|
|
|
reachable_non_generics => {
|
|
|
|
|
let reachable_non_generics = tcx
|
|
|
|
|
.exported_symbols(cdata.cnum)
|
|
|
|
|
.iter()
|
2022-04-02 22:27:33 +01:00
|
|
|
.filter_map(|&(exported_symbol, export_info)| {
|
2018-02-27 19:28:21 +01:00
|
|
|
if let ExportedSymbol::NonGeneric(def_id) = exported_symbol {
|
2022-04-02 22:27:33 +01:00
|
|
|
Some((def_id, export_info))
|
2018-02-27 19:28:21 +01:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
|
2020-03-27 20:26:20 +01:00
|
|
|
reachable_non_generics
|
2018-02-27 19:28:21 +01:00
|
|
|
}
|
2022-01-31 19:55:34 +01:00
|
|
|
native_libraries => { cdata.get_native_libraries(tcx.sess).collect() }
|
|
|
|
|
foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() }
|
2018-05-12 16:36:53 -07:00
|
|
|
crate_hash => { cdata.root.hash }
|
2019-11-24 18:12:02 +03:00
|
|
|
crate_host_hash => { cdata.host_hash }
|
2021-05-10 18:23:32 +02:00
|
|
|
crate_name => { cdata.root.name }
|
2017-08-30 11:40:02 -07:00
|
|
|
|
2018-03-13 11:58:53 -07:00
|
|
|
extra_filename => { cdata.root.extra_filename.clone() }
|
|
|
|
|
|
2021-12-24 11:09:32 +08:00
|
|
|
traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
|
2022-01-06 15:13:22 +08:00
|
|
|
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
|
2022-03-15 16:30:30 +01:00
|
|
|
crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
|
2017-08-30 14:48:57 -07:00
|
|
|
|
2018-02-15 10:52:26 +01:00
|
|
|
dep_kind => {
|
|
|
|
|
let r = *cdata.dep_kind.lock();
|
|
|
|
|
r
|
|
|
|
|
}
|
2021-12-23 16:12:34 +08:00
|
|
|
module_children => {
|
2022-11-22 20:01:44 +03:00
|
|
|
tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess))
|
2017-08-31 08:07:39 -07:00
|
|
|
}
|
2018-12-01 16:57:29 +01:00
|
|
|
defined_lib_features => { cdata.get_lib_features(tcx) }
|
2022-07-13 15:10:19 +01:00
|
|
|
stability_implications => {
|
|
|
|
|
cdata.get_stability_implications(tcx).iter().copied().collect()
|
|
|
|
|
}
|
2022-05-13 13:50:21 +00:00
|
|
|
is_intrinsic => { cdata.get_is_intrinsic(def_id.index) }
|
2022-03-18 17:02:32 +01:00
|
|
|
defined_lang_items => { cdata.get_lang_items(tcx) }
|
2020-03-27 20:26:20 +01:00
|
|
|
diagnostic_items => { cdata.get_diagnostic_items() }
|
2018-12-01 16:57:29 +01:00
|
|
|
missing_lang_items => { cdata.get_missing_lang_items(tcx) }
|
2017-08-31 11:12:05 -07:00
|
|
|
|
2017-08-31 11:30:22 -07:00
|
|
|
missing_extern_crate_item => {
|
2020-10-26 20:02:06 -04:00
|
|
|
let r = matches!(*cdata.extern_crate.borrow(), Some(extern_crate) if !extern_crate.is_direct());
|
2018-02-15 10:52:26 +01:00
|
|
|
r
|
2017-08-31 11:30:22 -07:00
|
|
|
}
|
2017-08-31 12:08:29 -07:00
|
|
|
|
2022-01-31 19:55:34 +01:00
|
|
|
used_crate_source => { Lrc::clone(&cdata.source) }
|
2022-04-25 18:02:43 -07:00
|
|
|
debugger_visualizers => { cdata.get_debugger_visualizers() }
|
2017-09-20 20:42:49 +02:00
|
|
|
|
rustc: Fix mixing crates with different `share_generics`
This commit addresses #64319 by removing the `dylib` crate type from the
list of crate type that exports generic symbols. The bug in #64319
arises because a `dylib` crate type was trying to export a symbol in an
uptream crate but it miscalculated the symbol name of the uptream
symbol. This isn't really necessary, though, since `dylib` crates aren't
that heavily used, so we can just conservatively say that the `dylib`
crate type never exports generic symbols, forcibly removing them from
the exported symbol lists if were to otherwise find them.
The fix here happens in two places:
* First is in the `local_crate_exports_generics` method, indicating that
it's now `false` for the `Dylib` crate type. Only rlibs actually
export generics at this point.
* Next is when we load exported symbols from upstream crate. If, for our
compilation session, the crate may be included from a dynamic library,
then its generic symbols are removed. When the crate was linked into a
dynamic library its symbols weren't exported, so we can't consider
them a candidate to link against.
Overally this should avoid situations where we incorrectly calculate the
upstream symbol names in the face of differnet `share_generics` options,
ultimately...
Closes #64319
2019-09-11 08:08:04 -07:00
|
|
|
exported_symbols => {
|
2019-11-01 13:46:05 +01:00
|
|
|
let syms = cdata.exported_symbols(tcx);
|
rustc: Fix mixing crates with different `share_generics`
This commit addresses #64319 by removing the `dylib` crate type from the
list of crate type that exports generic symbols. The bug in #64319
arises because a `dylib` crate type was trying to export a symbol in an
uptream crate but it miscalculated the symbol name of the uptream
symbol. This isn't really necessary, though, since `dylib` crates aren't
that heavily used, so we can just conservatively say that the `dylib`
crate type never exports generic symbols, forcibly removing them from
the exported symbol lists if were to otherwise find them.
The fix here happens in two places:
* First is in the `local_crate_exports_generics` method, indicating that
it's now `false` for the `Dylib` crate type. Only rlibs actually
export generics at this point.
* Next is when we load exported symbols from upstream crate. If, for our
compilation session, the crate may be included from a dynamic library,
then its generic symbols are removed. When the crate was linked into a
dynamic library its symbols weren't exported, so we can't consider
them a candidate to link against.
Overally this should avoid situations where we incorrectly calculate the
upstream symbol names in the face of differnet `share_generics` options,
ultimately...
Closes #64319
2019-09-11 08:08:04 -07:00
|
|
|
|
2019-11-01 13:46:05 +01:00
|
|
|
// FIXME rust-lang/rust#64319, rust-lang/rust#64872: We want
|
|
|
|
|
// to block export of generics from dylibs, but we must fix
|
|
|
|
|
// rust-lang/rust#65890 before we can do that robustly.
|
rustc: Fix mixing crates with different `share_generics`
This commit addresses #64319 by removing the `dylib` crate type from the
list of crate type that exports generic symbols. The bug in #64319
arises because a `dylib` crate type was trying to export a symbol in an
uptream crate but it miscalculated the symbol name of the uptream
symbol. This isn't really necessary, though, since `dylib` crates aren't
that heavily used, so we can just conservatively say that the `dylib`
crate type never exports generic symbols, forcibly removing them from
the exported symbol lists if were to otherwise find them.
The fix here happens in two places:
* First is in the `local_crate_exports_generics` method, indicating that
it's now `false` for the `Dylib` crate type. Only rlibs actually
export generics at this point.
* Next is when we load exported symbols from upstream crate. If, for our
compilation session, the crate may be included from a dynamic library,
then its generic symbols are removed. When the crate was linked into a
dynamic library its symbols weren't exported, so we can't consider
them a candidate to link against.
Overally this should avoid situations where we incorrectly calculate the
upstream symbol names in the face of differnet `share_generics` options,
ultimately...
Closes #64319
2019-09-11 08:08:04 -07:00
|
|
|
|
2020-03-14 12:41:32 +01:00
|
|
|
syms
|
rustc: Fix mixing crates with different `share_generics`
This commit addresses #64319 by removing the `dylib` crate type from the
list of crate type that exports generic symbols. The bug in #64319
arises because a `dylib` crate type was trying to export a symbol in an
uptream crate but it miscalculated the symbol name of the uptream
symbol. This isn't really necessary, though, since `dylib` crates aren't
that heavily used, so we can just conservatively say that the `dylib`
crate type never exports generic symbols, forcibly removing them from
the exported symbol lists if were to otherwise find them.
The fix here happens in two places:
* First is in the `local_crate_exports_generics` method, indicating that
it's now `false` for the `Dylib` crate type. Only rlibs actually
export generics at this point.
* Next is when we load exported symbols from upstream crate. If, for our
compilation session, the crate may be included from a dynamic library,
then its generic symbols are removed. When the crate was linked into a
dynamic library its symbols weren't exported, so we can't consider
them a candidate to link against.
Overally this should avoid situations where we incorrectly calculate the
upstream symbol names in the face of differnet `share_generics` options,
ultimately...
Closes #64319
2019-09-11 08:08:04 -07:00
|
|
|
}
|
2020-06-27 14:54:19 -07:00
|
|
|
|
|
|
|
|
crate_extern_paths => { cdata.source().paths().cloned().collect() }
|
2020-10-05 15:32:25 -04:00
|
|
|
expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
|
2022-03-05 12:04:32 +02:00
|
|
|
generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) }
|
2016-09-29 02:30:53 +03:00
|
|
|
}
|
|
|
|
|
|
2021-12-31 18:15:52 +08:00
|
|
|
pub(in crate::rmeta) fn provide(providers: &mut Providers) {
|
2017-08-31 15:08:34 -07:00
|
|
|
// 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
|
2017-06-11 21:16:26 -07:00
|
|
|
*providers = Providers {
|
2021-06-06 11:30:08 +02:00
|
|
|
allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(),
|
2022-10-14 02:24:58 +01:00
|
|
|
alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(),
|
2021-05-11 22:06:07 +02:00
|
|
|
is_private_dep: |_tcx, cnum| {
|
|
|
|
|
assert_eq!(cnum, LOCAL_CRATE);
|
|
|
|
|
false
|
|
|
|
|
},
|
2022-07-12 13:52:35 -07:00
|
|
|
native_library: |tcx, id| {
|
2017-08-30 14:48:57 -07:00
|
|
|
tcx.native_libraries(id.krate)
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|lib| native_libs::relevant_lib(&tcx.sess, lib))
|
2018-02-10 14:28:17 -08:00
|
|
|
.find(|lib| {
|
2022-02-19 00:48:49 +01:00
|
|
|
let Some(fm_id) = lib.foreign_module else {
|
|
|
|
|
return false;
|
2018-02-10 14:28:17 -08:00
|
|
|
};
|
2020-10-27 15:01:03 +01:00
|
|
|
let map = tcx.foreign_modules(id.krate);
|
2020-10-27 20:17:48 +01:00
|
|
|
map.get(&fm_id)
|
2018-02-10 14:28:17 -08:00
|
|
|
.expect("failed to find foreign module")
|
|
|
|
|
.foreign_items
|
|
|
|
|
.contains(&id)
|
|
|
|
|
})
|
2017-08-30 14:48:57 -07:00
|
|
|
},
|
|
|
|
|
native_libraries: |tcx, cnum| {
|
|
|
|
|
assert_eq!(cnum, LOCAL_CRATE);
|
2022-01-31 19:55:34 +01:00
|
|
|
native_libs::collect(tcx)
|
2017-08-30 14:48:57 -07:00
|
|
|
},
|
2018-02-10 14:28:17 -08:00
|
|
|
foreign_modules: |tcx, cnum| {
|
|
|
|
|
assert_eq!(cnum, LOCAL_CRATE);
|
2022-01-31 19:55:34 +01:00
|
|
|
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect()
|
2018-02-10 14:28:17 -08:00
|
|
|
},
|
2017-09-07 08:13:41 -07:00
|
|
|
|
2018-11-27 02:59:49 +00:00
|
|
|
// Returns a map from a sufficiently visible external item (i.e., an
|
2017-08-31 11:30:22 -07:00
|
|
|
// external item that is visible from at least one local module) to a
|
|
|
|
|
// sufficiently visible parent (considering modules that re-export the
|
|
|
|
|
// external item to be parents).
|
2021-05-11 14:16:48 +02:00
|
|
|
visible_parent_map: |tcx, ()| {
|
2017-08-31 11:30:22 -07:00
|
|
|
use std::collections::hash_map::Entry;
|
|
|
|
|
use std::collections::vec_deque::VecDeque;
|
|
|
|
|
|
2018-07-21 22:15:11 +03:00
|
|
|
let mut visible_parent_map: DefIdMap<DefId> = Default::default();
|
2022-07-24 21:25:35 +00:00
|
|
|
// This is a secondary visible_parent_map, storing the DefId of
|
|
|
|
|
// parents that re-export the child as `_` or module parents
|
|
|
|
|
// which are `#[doc(hidden)]`. Since we prefer paths that don't
|
|
|
|
|
// do this, merge this map at the end, only if we're missing
|
|
|
|
|
// keys from the former.
|
|
|
|
|
// This is a rudimentary check that does not catch all cases,
|
|
|
|
|
// just the easiest.
|
2021-11-30 17:18:48 -08:00
|
|
|
let mut fallback_map: DefIdMap<DefId> = Default::default();
|
2017-08-31 11:30:22 -07:00
|
|
|
|
2017-12-12 19:05:12 -06:00
|
|
|
// Issue 46112: We want the map to prefer the shortest
|
|
|
|
|
// paths when reporting the path to an item. Therefore we
|
|
|
|
|
// build up the map via a breadth-first search (BFS),
|
|
|
|
|
// which naturally yields minimal-length paths.
|
|
|
|
|
//
|
|
|
|
|
// Note that it needs to be a BFS over the whole forest of
|
|
|
|
|
// crates, not just each individual crate; otherwise you
|
|
|
|
|
// only get paths that are locally minimal with respect to
|
|
|
|
|
// whatever crate we happened to encounter first in this
|
|
|
|
|
// traversal, but not globally minimal across all crates.
|
|
|
|
|
let bfs_queue = &mut VecDeque::new();
|
2017-12-19 15:04:02 +01:00
|
|
|
|
2021-09-17 09:13:16 +02:00
|
|
|
for &cnum in tcx.crates(()) {
|
2017-08-31 11:30:22 -07:00
|
|
|
// Ignore crates without a corresponding local `extern crate` item.
|
|
|
|
|
if tcx.missing_extern_crate_item(cnum) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-15 19:27:53 +02:00
|
|
|
bfs_queue.push_back(cnum.as_def_id());
|
2017-12-12 19:05:12 -06:00
|
|
|
}
|
|
|
|
|
|
2021-12-21 11:24:43 +08:00
|
|
|
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| {
|
2021-12-18 20:07:58 +08:00
|
|
|
if !child.vis.is_public() {
|
2021-09-17 09:13:16 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2017-08-31 11:30:22 -07:00
|
|
|
|
2021-12-18 20:07:58 +08:00
|
|
|
if let Some(def_id) = child.res.opt_def_id() {
|
|
|
|
|
if child.ident.name == kw::Underscore {
|
|
|
|
|
fallback_map.insert(def_id, parent);
|
2021-11-30 17:18:48 -08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-24 21:25:35 +00:00
|
|
|
if ty::util::is_doc_hidden(tcx, parent) {
|
|
|
|
|
fallback_map.insert(def_id, parent);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-18 20:07:58 +08:00
|
|
|
match visible_parent_map.entry(def_id) {
|
2021-09-17 09:13:16 +02:00
|
|
|
Entry::Occupied(mut entry) => {
|
|
|
|
|
// If `child` is defined in crate `cnum`, ensure
|
|
|
|
|
// that it is mapped to a parent in `cnum`.
|
2021-12-18 20:07:58 +08:00
|
|
|
if def_id.is_local() && entry.get().is_local() {
|
2021-09-05 23:37:15 +03:00
|
|
|
entry.insert(parent);
|
|
|
|
|
}
|
2017-08-31 11:30:22 -07:00
|
|
|
}
|
2021-09-17 09:13:16 +02:00
|
|
|
Entry::Vacant(entry) => {
|
|
|
|
|
entry.insert(parent);
|
2021-12-18 20:07:58 +08:00
|
|
|
if matches!(
|
|
|
|
|
child.res,
|
|
|
|
|
Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, _)
|
|
|
|
|
) {
|
|
|
|
|
bfs_queue.push_back(def_id);
|
|
|
|
|
}
|
2021-09-17 09:13:16 +02:00
|
|
|
}
|
2021-09-05 23:37:15 +03:00
|
|
|
}
|
2021-09-17 09:13:16 +02:00
|
|
|
}
|
|
|
|
|
};
|
2017-08-31 11:30:22 -07:00
|
|
|
|
2021-09-17 09:13:16 +02:00
|
|
|
while let Some(def) = bfs_queue.pop_front() {
|
2021-12-23 16:12:34 +08:00
|
|
|
for child in tcx.module_children(def).iter() {
|
2021-09-17 09:13:16 +02:00
|
|
|
add_child(bfs_queue, child, def);
|
2017-08-31 11:30:22 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-24 21:25:35 +00:00
|
|
|
// Fill in any missing entries with the less preferable path.
|
|
|
|
|
// If this path re-exports the child as `_`, we still use this
|
|
|
|
|
// path in a diagnostic that suggests importing `::*`.
|
2021-11-30 17:18:48 -08:00
|
|
|
for (child, parent) in fallback_map {
|
|
|
|
|
visible_parent_map.entry(child).or_insert(parent);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-31 19:55:34 +01:00
|
|
|
visible_parent_map
|
2017-08-31 11:30:22 -07:00
|
|
|
},
|
|
|
|
|
|
2021-05-11 11:26:52 +02:00
|
|
|
dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)),
|
2019-11-24 18:12:02 +03:00
|
|
|
has_global_allocator: |tcx, cnum| {
|
|
|
|
|
assert_eq!(cnum, LOCAL_CRATE);
|
|
|
|
|
CStore::from_tcx(tcx).has_global_allocator()
|
|
|
|
|
},
|
2022-10-14 02:24:58 +01:00
|
|
|
has_alloc_error_handler: |tcx, cnum| {
|
|
|
|
|
assert_eq!(cnum, LOCAL_CRATE);
|
|
|
|
|
CStore::from_tcx(tcx).has_alloc_error_handler()
|
|
|
|
|
},
|
2021-05-11 14:50:54 +02:00
|
|
|
postorder_cnums: |tcx, ()| {
|
|
|
|
|
tcx.arena
|
|
|
|
|
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
|
2019-11-24 18:12:02 +03:00
|
|
|
},
|
2021-12-21 19:40:11 +08:00
|
|
|
crates: |tcx, ()| tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).crates_untracked()),
|
2017-06-11 21:16:26 -07:00
|
|
|
..*providers
|
|
|
|
|
};
|
2016-09-29 02:30:53 +03:00
|
|
|
}
|
|
|
|
|
|
2019-11-24 01:10:12 +03:00
|
|
|
impl CStore {
|
2021-12-24 14:57:21 +08:00
|
|
|
pub fn struct_field_names_untracked<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
def: DefId,
|
|
|
|
|
sess: &'a Session,
|
|
|
|
|
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
|
2019-10-09 17:37:28 +03:00
|
|
|
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
|
2015-11-20 17:46:39 +02:00
|
|
|
}
|
|
|
|
|
|
2021-12-24 14:57:21 +08:00
|
|
|
pub fn struct_field_visibilities_untracked(
|
|
|
|
|
&self,
|
|
|
|
|
def: DefId,
|
2022-08-28 00:10:06 +03:00
|
|
|
) -> impl Iterator<Item = Visibility<DefId>> + '_ {
|
2021-05-07 22:42:12 -07:00
|
|
|
self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-25 20:15:15 +04:00
|
|
|
pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
|
|
|
|
|
self.get_crate_data(def.krate).get_ctor(def.index)
|
2021-05-07 22:42:12 -07:00
|
|
|
}
|
|
|
|
|
|
2022-08-28 00:10:06 +03:00
|
|
|
pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> {
|
2021-05-07 22:42:12 -07:00
|
|
|
self.get_crate_data(def.krate).get_visibility(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 20:01:44 +03:00
|
|
|
pub fn module_children_untracked<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
def_id: DefId,
|
|
|
|
|
sess: &'a Session,
|
|
|
|
|
) -> impl Iterator<Item = ModChild> + 'a {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_module_children(def_id.index, sess)
|
2015-11-20 17:46:39 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-31 17:23:29 -06:00
|
|
|
pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
|
2019-10-09 16:43:47 +02:00
|
|
|
let _prof_timer = sess.prof.generic_activity("metadata_load_macro");
|
|
|
|
|
|
2016-11-05 20:30:40 +00:00
|
|
|
let data = self.get_crate_data(id.krate);
|
2019-11-17 18:54:22 +03:00
|
|
|
if data.root.is_proc_macro_crate() {
|
2021-07-10 23:15:30 +03:00
|
|
|
return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
|
2016-11-05 20:30:40 +00:00
|
|
|
}
|
|
|
|
|
|
2019-11-13 13:01:43 +01:00
|
|
|
let span = data.get_span(id.index, sess);
|
2016-10-28 06:52:45 +00:00
|
|
|
|
2017-03-05 05:15:58 +00:00
|
|
|
LoadedMacro::MacroDef(
|
|
|
|
|
ast::Item {
|
2021-12-21 20:11:36 +08:00
|
|
|
ident: data.item_ident(id.index, sess),
|
2016-10-28 06:52:45 +00:00
|
|
|
id: ast::DUMMY_NODE_ID,
|
2019-11-13 13:01:43 +01:00
|
|
|
span,
|
2021-12-21 20:11:36 +08:00
|
|
|
attrs: data.get_item_attrs(id.index, sess).collect(),
|
2020-03-14 00:00:35 +03:00
|
|
|
kind: ast::ItemKind::MacroDef(data.get_macro(id.index, sess)),
|
2020-08-21 19:11:00 -04:00
|
|
|
vis: ast::Visibility {
|
|
|
|
|
span: span.shrink_to_lo(),
|
|
|
|
|
kind: ast::VisibilityKind::Inherited,
|
|
|
|
|
tokens: None,
|
|
|
|
|
},
|
2017-07-10 17:44:46 -07:00
|
|
|
tokens: None,
|
2019-10-20 03:28:36 +03:00
|
|
|
},
|
|
|
|
|
data.root.edition,
|
|
|
|
|
)
|
2016-10-28 06:52:45 +00:00
|
|
|
}
|
|
|
|
|
|
2022-08-04 22:03:16 +02:00
|
|
|
pub fn fn_has_self_parameter_untracked(&self, def: DefId, sess: &Session) -> bool {
|
|
|
|
|
self.get_crate_data(def.krate).get_fn_has_self_parameter(def.index, sess)
|
2018-07-31 17:23:29 -06:00
|
|
|
}
|
2019-10-06 14:30:46 +03:00
|
|
|
|
2022-01-31 19:55:34 +01:00
|
|
|
pub fn crate_source_untracked(&self, cnum: CrateNum) -> Lrc<CrateSource> {
|
2019-10-06 14:30:46 +03:00
|
|
|
self.get_crate_data(cnum).source.clone()
|
|
|
|
|
}
|
2020-01-09 09:23:44 +01:00
|
|
|
|
2019-10-14 17:20:50 -07:00
|
|
|
pub fn get_span_untracked(&self, def_id: DefId, sess: &Session) -> Span {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_span(def_id.index, sess)
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-12 21:20:16 +02:00
|
|
|
pub fn def_kind(&self, def: DefId) -> DefKind {
|
|
|
|
|
self.get_crate_data(def.krate).def_kind(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 19:40:11 +08:00
|
|
|
pub fn crates_untracked(&self) -> impl Iterator<Item = CrateNum> + '_ {
|
|
|
|
|
self.iter_crate_data().map(|(cnum, _)| cnum)
|
2021-07-12 21:20:16 +02:00
|
|
|
}
|
|
|
|
|
|
2020-01-09 09:23:44 +01:00
|
|
|
pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes
|
|
|
|
|
}
|
2020-03-17 11:45:02 -04:00
|
|
|
|
|
|
|
|
pub fn module_expansion_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
|
|
|
|
|
self.get_crate_data(def_id.krate).module_expansion(def_id.index, sess)
|
|
|
|
|
}
|
2020-12-02 23:39:05 +03:00
|
|
|
|
2021-06-01 14:10:14 +02:00
|
|
|
/// Only public-facing way to traverse all the definitions in a non-local crate.
|
|
|
|
|
/// Critically useful for this third-party project: <https://github.com/hacspec/hacspec>.
|
|
|
|
|
/// See <https://github.com/rust-lang/rust/pull/85889> for context.
|
|
|
|
|
pub fn num_def_ids_untracked(&self, cnum: CrateNum) -> usize {
|
|
|
|
|
self.get_crate_data(cnum).num_def_ids()
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-24 14:57:21 +08:00
|
|
|
pub fn item_attrs_untracked<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
def_id: DefId,
|
|
|
|
|
sess: &'a Session,
|
|
|
|
|
) -> impl Iterator<Item = ast::Attribute> + 'a {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess)
|
2021-02-23 15:12:28 +00:00
|
|
|
}
|
Implement span quoting for proc-macros
This PR implements span quoting, allowing proc-macros to produce spans
pointing *into their own crate*. This is used by the unstable
`proc_macro::quote!` macro, allowing us to get error messages like this:
```
error[E0412]: cannot find type `MissingType` in this scope
--> $DIR/auxiliary/span-from-proc-macro.rs:37:20
|
LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> TokenStream {
| ----------------------------------------------------------------------------------- in this expansion of procedural macro `#[error_from_attribute]`
...
LL | field: MissingType
| ^^^^^^^^^^^ not found in this scope
|
::: $DIR/span-from-proc-macro.rs:8:1
|
LL | #[error_from_attribute]
| ----------------------- in this macro invocation
```
Here, `MissingType` occurs inside the implementation of the proc-macro
`#[error_from_attribute]`. Previosuly, this would always result in a
span pointing at `#[error_from_attribute]`
This will make many proc-macro-related error message much more useful -
when a proc-macro generates code containing an error, users will get an
error message pointing directly at that code (within the macro
definition), instead of always getting a span pointing at the macro
invocation site.
This is implemented as follows:
* When a proc-macro crate is being *compiled*, it causes the `quote!`
macro to get run. This saves all of the sapns in the input to `quote!`
into the metadata of *the proc-macro-crate* (which we are currently
compiling). The `quote!` macro then expands to a call to
`proc_macro::Span::recover_proc_macro_span(id)`, where `id` is an
opaque identifier for the span in the crate metadata.
* When the same proc-macro crate is *run* (e.g. it is loaded from disk
and invoked by some consumer crate), the call to
`proc_macro::Span::recover_proc_macro_span` causes us to load the span
from the proc-macro crate's metadata. The proc-macro then produces a
`TokenStream` containing a `Span` pointing into the proc-macro crate
itself.
The recursive nature of 'quote!' can be difficult to understand at
first. The file `src/test/ui/proc-macro/quote-debug.stdout` shows
the output of the `quote!` macro, which should make this eaier to
understand.
This PR also supports custom quoting spans in custom quote macros (e.g.
the `quote` crate). All span quoting goes through the
`proc_macro::quote_span` method, which can be called by a custom quote
macro to perform span quoting. An example of this usage is provided in
`src/test/ui/proc-macro/auxiliary/custom-quote.rs`
Custom quoting currently has a few limitations:
In order to quote a span, we need to generate a call to
`proc_macro::Span::recover_proc_macro_span`. However, proc-macros
support renaming the `proc_macro` crate, so we can't simply hardcode
this path. Previously, the `quote_span` method used the path
`crate::Span` - however, this only works when it is called by the
builtin `quote!` macro in the same crate. To support being called from
arbitrary crates, we need access to the name of the `proc_macro` crate
to generate a path. This PR adds an additional argument to `quote_span`
to specify the name of the `proc_macro` crate. Howver, this feels kind
of hacky, and we may want to change this before stabilizing anything
quote-related.
Additionally, using `quote_span` currently requires enabling the
`proc_macro_internals` feature. The builtin `quote!` macro
has an `#[allow_internal_unstable]` attribute, but this won't work for
custom quote implementations. This will likely require some additional
tricks to apply `allow_internal_unstable` to the span of
`proc_macro::Span::recover_proc_macro_span`.
2020-08-02 19:52:16 -04:00
|
|
|
|
|
|
|
|
pub fn get_proc_macro_quoted_span_untracked(
|
|
|
|
|
&self,
|
|
|
|
|
cnum: CrateNum,
|
|
|
|
|
id: usize,
|
|
|
|
|
sess: &Session,
|
|
|
|
|
) -> Span {
|
|
|
|
|
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
|
|
|
|
|
}
|
2021-08-29 21:41:46 +03:00
|
|
|
|
2022-02-01 15:37:30 +08:00
|
|
|
/// Decodes all trait impls in the crate (for rustdoc).
|
2021-08-29 21:41:46 +03:00
|
|
|
pub fn trait_impls_in_crate_untracked(
|
|
|
|
|
&self,
|
|
|
|
|
cnum: CrateNum,
|
2021-08-29 21:41:46 +03:00
|
|
|
) -> impl Iterator<Item = (DefId, DefId, Option<SimplifiedType>)> + '_ {
|
2021-12-24 14:57:21 +08:00
|
|
|
self.get_crate_data(cnum).get_trait_impls()
|
2021-08-29 21:41:46 +03:00
|
|
|
}
|
2022-02-01 15:37:30 +08:00
|
|
|
|
|
|
|
|
/// Decodes all inherent impls in the crate (for rustdoc).
|
|
|
|
|
pub fn inherent_impls_in_crate_untracked(
|
|
|
|
|
&self,
|
|
|
|
|
cnum: CrateNum,
|
|
|
|
|
) -> impl Iterator<Item = (DefId, DefId)> + '_ {
|
|
|
|
|
self.get_crate_data(cnum).get_inherent_impls()
|
|
|
|
|
}
|
2022-02-08 17:42:22 +08:00
|
|
|
|
2022-03-18 17:02:32 +01:00
|
|
|
/// Decodes all incoherent inherent impls in the crate (for rustdoc).
|
|
|
|
|
pub fn incoherent_impls_in_crate_untracked(
|
|
|
|
|
&self,
|
|
|
|
|
cnum: CrateNum,
|
|
|
|
|
) -> impl Iterator<Item = DefId> + '_ {
|
|
|
|
|
self.get_crate_data(cnum).get_all_incoherent_impls()
|
2022-02-08 17:42:22 +08:00
|
|
|
}
|
2022-04-16 23:49:37 +03:00
|
|
|
|
2022-04-21 01:09:48 +03:00
|
|
|
pub fn associated_item_def_ids_untracked<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
def_id: DefId,
|
|
|
|
|
sess: &'a Session,
|
|
|
|
|
) -> impl Iterator<Item = DefId> + 'a {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_associated_item_def_ids(def_id.index, sess)
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-16 23:49:37 +03:00
|
|
|
pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool {
|
|
|
|
|
self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index)
|
|
|
|
|
}
|
2018-07-31 17:23:29 -06:00
|
|
|
}
|
|
|
|
|
|
2019-11-24 01:10:12 +03:00
|
|
|
impl CrateStore for CStore {
|
2019-11-24 18:12:02 +03:00
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
|
|
|
self
|
2018-07-31 17:23:29 -06:00
|
|
|
}
|
2022-12-07 14:31:50 +00:00
|
|
|
fn untracked_as_any(&mut self) -> &mut dyn Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
2018-07-31 17:23:29 -06:00
|
|
|
|
2021-07-12 21:20:16 +02:00
|
|
|
fn crate_name(&self, cnum: CrateNum) -> Symbol {
|
2019-10-02 03:15:38 +03:00
|
|
|
self.get_crate_data(cnum).root.name
|
2018-07-31 17:23:29 -06:00
|
|
|
}
|
|
|
|
|
|
2021-07-12 21:20:16 +02:00
|
|
|
fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId {
|
2021-06-08 18:36:30 +02:00
|
|
|
self.get_crate_data(cnum).root.stable_crate_id
|
2018-07-31 17:23:29 -06:00
|
|
|
}
|
|
|
|
|
|
2021-07-20 13:59:12 +02:00
|
|
|
fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum {
|
|
|
|
|
self.stable_crate_ids[&stable_crate_id]
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-31 17:23:29 -06:00
|
|
|
/// Returns the `DefKey` for a given `DefId`. This indicates the
|
|
|
|
|
/// parent `DefId` as well as some idea of what kind of data the
|
|
|
|
|
/// `DefId` refers to.
|
|
|
|
|
fn def_key(&self, def: DefId) -> DefKey {
|
|
|
|
|
self.get_crate_data(def.krate).def_key(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn def_path(&self, def: DefId) -> DefPath {
|
|
|
|
|
self.get_crate_data(def.krate).def_path(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn def_path_hash(&self, def: DefId) -> DefPathHash {
|
|
|
|
|
self.get_crate_data(def.krate).def_path_hash(def.index)
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-20 14:18:37 +02:00
|
|
|
fn def_path_hash_to_def_id(&self, cnum: CrateNum, hash: DefPathHash) -> DefId {
|
|
|
|
|
let def_index = self.get_crate_data(cnum).def_path_hash_to_def_index(hash);
|
|
|
|
|
DefId { krate: cnum, index: def_index }
|
2020-07-29 12:26:15 -04:00
|
|
|
}
|
|
|
|
|
|
2021-10-02 17:35:27 +02:00
|
|
|
fn expn_hash_to_expn_id(
|
|
|
|
|
&self,
|
|
|
|
|
sess: &Session,
|
|
|
|
|
cnum: CrateNum,
|
|
|
|
|
index_guess: u32,
|
|
|
|
|
hash: ExpnHash,
|
|
|
|
|
) -> ExpnId {
|
|
|
|
|
self.get_crate_data(cnum).expn_hash_to_expn_id(sess, index_guess, hash)
|
2021-06-27 15:51:25 +02:00
|
|
|
}
|
2021-12-21 14:01:10 -05:00
|
|
|
|
|
|
|
|
fn import_source_files(&self, sess: &Session, cnum: CrateNum) {
|
2022-08-06 23:00:49 +02:00
|
|
|
let cdata = self.get_crate_data(cnum);
|
|
|
|
|
for file_index in 0..cdata.root.source_map.size() {
|
|
|
|
|
cdata.imported_source_file(file_index as u32, sess);
|
|
|
|
|
}
|
2021-12-21 14:01:10 -05:00
|
|
|
}
|
2017-05-18 20:56:25 +03:00
|
|
|
}
|