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 7 pull requests #111719

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_builtin_macros/src/cfg_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,9 @@ impl CfgEval<'_, '_> {
))
},
Annotatable::Stmt(_) => |parser| {
Ok(Annotatable::Stmt(P(parser.parse_stmt(ForceCollect::Yes)?.unwrap())))
Ok(Annotatable::Stmt(P(parser
.parse_stmt_without_recovery(false, ForceCollect::Yes)?
.unwrap())))
},
Annotatable::Expr(_) => {
|parser| Ok(Annotatable::Expr(parser.parse_expr_force_collect()?))
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_data_structures/src/sync/worker_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,6 @@ impl<T> WorkerLocal<T> {
}
}

impl<T> WorkerLocal<Vec<T>> {
/// Joins the elements of all the worker locals into one Vec
pub fn join(self) -> Vec<T> {
self.into_inner().into_iter().flat_map(|v| v).collect()
}
}

impl<T> Deref for WorkerLocal<T> {
type Target = T;

Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ pub fn provide(providers: &mut Providers) {
fn_sig,
impl_trait_ref,
impl_polarity,
is_foreign_item,
generator_kind,
collect_mod_item_types,
is_type_alias_impl_trait,
Expand Down Expand Up @@ -1466,10 +1465,6 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
fty
}

fn is_foreign_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
matches!(tcx.hir().get_by_def_id(def_id), Node::ForeignItem(..))
}

fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorKind> {
match tcx.hir().get_by_def_id(def_id) {
Node::Expr(&rustc_hir::Expr {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ fn add_query_desc_cached_impl(
quote! {
#[allow(unused_variables, unused_braces, rustc::pass_by_value)]
#[inline]
pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::query_keys::#name<'tcx>) -> bool {
pub fn #name<'tcx>(#tcx: TyCtxt<'tcx>, #key: &crate::query::queries::#name::Key<'tcx>) -> bool {
#expr
}
}
Expand All @@ -262,7 +262,7 @@ fn add_query_desc_cached_impl(
// we're taking `key` by reference, but some rustc types usually prefer being passed by value
#[allow(rustc::pass_by_value)]
#[inline]
pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::query_keys::#name<'tcx>) -> bool {
pub fn #name<'tcx>(_: TyCtxt<'tcx>, _: &crate::query::queries::#name::Key<'tcx>) -> bool {
false
}
}
Expand All @@ -273,7 +273,7 @@ fn add_query_desc_cached_impl(

let desc = quote! {
#[allow(unused_variables)]
pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::query::query_keys::#name<'tcx>) -> String {
pub fn #name<'tcx>(tcx: TyCtxt<'tcx>, key: crate::query::queries::#name::Key<'tcx>) -> String {
let (#tcx, #key) = (tcx, key);
::rustc_middle::ty::print::with_no_trimmed_paths!(
format!(#desc)
Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1251,14 +1251,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}
}

fn is_foreign_item(self, id: DefIndex) -> bool {
if let Some(parent) = self.def_key(id).parent {
matches!(self.def_kind(parent), DefKind::ForeignMod)
} else {
false
}
}

#[inline]
fn def_key(self, index: DefIndex) -> DefKey {
*self
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ macro_rules! provide_one {
($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => $compute:block) => {
fn $name<'tcx>(
$tcx: TyCtxt<'tcx>,
def_id_arg: rustc_middle::query::query_keys::$name<'tcx>,
) -> rustc_middle::query::query_provided::$name<'tcx> {
def_id_arg: rustc_middle::query::queries::$name::Key<'tcx>,
) -> rustc_middle::query::queries::$name::ProvidedValue<'tcx> {
let _prof_timer =
$tcx.prof.generic_activity(concat!("metadata_decode_entry_", stringify!($name)));

Expand Down Expand Up @@ -280,7 +280,6 @@ provide! { tcx, def_id, other, cdata,
}
associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
is_mir_available => { cdata.is_item_mir_available(def_id.index) }
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::query::Providers;
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::*;
use rustc_query_system::ich::StableHashingContext;
Expand Down Expand Up @@ -110,6 +111,12 @@ impl<'tcx> TyCtxt<'tcx> {
None => self.type_of(def_id).map_bound(ImplSubject::Inherent),
}
}

/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
pub fn is_foreign_item(self, def_id: impl Into<DefId>) -> bool {
self.opt_parent(def_id.into())
.map_or(false, |parent| matches!(self.def_kind(parent), DefKind::ForeignMod))
}
}

pub fn provide(providers: &mut Providers) {
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,12 +726,6 @@ rustc_queries! {
desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) }
}

/// Returns `true` if this is a foreign item (i.e., linked via `extern { ... }`).
query is_foreign_item(key: DefId) -> bool {
desc { |tcx| "checking if `{}` is a foreign item", tcx.def_path_str(key) }
separate_provide_extern
}

/// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator.
query generator_kind(def_id: DefId) -> Option<hir::GeneratorKind> {
desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) }
Expand Down
175 changes: 77 additions & 98 deletions compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ macro_rules! separate_provide_extern_decl {
([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
for<'tcx> fn(
TyCtxt<'tcx>,
query_keys::$name<'tcx>,
) -> query_provided::$name<'tcx>
queries::$name::Key<'tcx>,
) -> queries::$name::ProvidedValue<'tcx>
};
([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
separate_provide_extern_decl!([$($modifiers)*][$($args)*])
Expand Down Expand Up @@ -252,60 +252,37 @@ macro_rules! define_callbacks {
$($(#[$attr:meta])*
[$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {

// HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
// below, but using type aliases instead of associated types, to bypass
// the limitations around normalizing under HRTB - for example, this:
// `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
// doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
// This is primarily used by the `provide!` macro in `rustc_metadata`.
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_keys {
use super::*;

$(pub type $name<'tcx> = $($K)*;)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_keys_local {
use super::*;

$(pub type $name<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_values {
use super::*;
#[allow(unused_lifetimes)]
pub mod queries {
$(pub mod $name {
use super::super::*;

$(pub type $name<'tcx> = $V;)*
}
pub type Key<'tcx> = $($K)*;
pub type Value<'tcx> = $V;

/// This module specifies the type returned from query providers and the type used for
/// decoding. For regular queries this is the declared returned type `V`, but
/// `arena_cache` will use `<V as Deref>::Target` instead.
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_provided {
use super::*;
pub type LocalKey<'tcx> = local_key_if_separate_extern!([$($modifiers)*] $($K)*);

$(
pub type $name<'tcx> = query_if_arena!([$($modifiers)*] (<$V as Deref>::Target) ($V));
)*
}

/// This module has a function per query which takes a `query_provided` value and coverts
/// it to a regular `V` value by allocating it on an arena if the query has the
/// `arena_cache` modifier. This will happen when computing the query using a provider or
/// decoding a stored result.
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_provided_to_value {
use super::*;
/// This type alias specifies the type returned from query providers and the type
/// used for decoding. For regular queries this is the declared returned type `V`,
/// but `arena_cache` will use `<V as Deref>::Target` instead.
pub type ProvidedValue<'tcx> = query_if_arena!(
[$($modifiers)*]
(<$V as Deref>::Target)
($V)
);

$(
/// This function takes `ProvidedValue` and coverts it to an erased `Value` by
/// allocating it on an arena if the query has the `arena_cache` modifier. The
/// value is then erased and returned. This will happen when computing the query
/// using a provider or decoding a stored result.
#[inline(always)]
pub fn $name<'tcx>(
pub fn provided_to_erased<'tcx>(
_tcx: TyCtxt<'tcx>,
value: query_provided::$name<'tcx>,
) -> Erase<query_values::$name<'tcx>> {
value: ProvidedValue<'tcx>,
) -> Erase<Value<'tcx>> {
erase(query_if_arena!([$($modifiers)*]
{
if mem::needs_drop::<query_provided::$name<'tcx>>() {
if mem::needs_drop::<ProvidedValue<'tcx>>() {
&*_tcx.query_system.arenas.$name.alloc(value)
} else {
&*_tcx.arena.dropless.alloc(value)
Expand All @@ -314,47 +291,41 @@ macro_rules! define_callbacks {
(value)
))
}
)*
}
#[allow(nonstandard_style, unused_lifetimes)]
pub mod query_storage {
use super::*;

$(
pub type $name<'tcx> = <<$($K)* as Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>>>::Cache;
)*
pub type Storage<'tcx> = <
<$($K)* as keys::Key>::CacheSelector as CacheSelector<'tcx, Erase<$V>>
>::Cache;

// Ensure that keys grow no larger than 64 bytes
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
const _: () = {
if mem::size_of::<Key<'static>>() > 64 {
panic!("{}", concat!(
"the query `",
stringify!($name),
"` has a key type `",
stringify!($($K)*),
"` that is too large"
));
}
};

// Ensure that values grow no larger than 64 bytes
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
const _: () = {
if mem::size_of::<Value<'static>>() > 64 {
panic!("{}", concat!(
"the query `",
stringify!($name),
"` has a value type `",
stringify!($V),
"` that is too large"
));
}
};
})*
}

$(
// Ensure that keys grow no larger than 64 bytes
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
const _: () = {
if mem::size_of::<query_keys::$name<'static>>() > 64 {
panic!("{}", concat!(
"the query `",
stringify!($name),
"` has a key type `",
stringify!($($K)*),
"` that is too large"
));
}
};

// Ensure that values grow no larger than 64 bytes
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
const _: () = {
if mem::size_of::<query_values::$name<'static>>() > 64 {
panic!("{}", concat!(
"the query `",
stringify!($name),
"` has a value type `",
stringify!($V),
"` that is too large"
));
}
};
)*

pub struct QueryArenas<'tcx> {
$($(#[$attr])* pub $name: query_if_arena!([$($modifiers)*]
(WorkerLocal<TypedArena<<$V as Deref>::Target>>)
Expand All @@ -375,7 +346,7 @@ macro_rules! define_callbacks {

#[derive(Default)]
pub struct QueryCaches<'tcx> {
$($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
$($(#[$attr])* pub $name: queries::$name::Storage<'tcx>,)*
}

impl<'tcx> TyCtxtEnsure<'tcx> {
Expand Down Expand Up @@ -433,7 +404,7 @@ macro_rules! define_callbacks {

pub struct DynamicQueries<'tcx> {
$(
pub $name: DynamicQuery<'tcx, query_storage::$name<'tcx>>,
pub $name: DynamicQuery<'tcx, queries::$name::Storage<'tcx>>,
)*
}

Expand All @@ -447,8 +418,8 @@ macro_rules! define_callbacks {
pub struct Providers {
$(pub $name: for<'tcx> fn(
TyCtxt<'tcx>,
query_keys_local::$name<'tcx>,
) -> query_provided::$name<'tcx>,)*
queries::$name::LocalKey<'tcx>,
) -> queries::$name::ProvidedValue<'tcx>,)*
}

pub struct ExternProviders {
Expand Down Expand Up @@ -493,7 +464,7 @@ macro_rules! define_callbacks {
$(pub $name: for<'tcx> fn(
TyCtxt<'tcx>,
Span,
query_keys::$name<'tcx>,
queries::$name::Key<'tcx>,
QueryMode,
) -> Option<Erase<$V>>,)*
}
Expand All @@ -517,11 +488,11 @@ macro_rules! define_feedable {
$(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
$(#[$attr])*
#[inline(always)]
pub fn $name(self, value: query_provided::$name<'tcx>) {
pub fn $name(self, value: queries::$name::ProvidedValue<'tcx>) {
let key = self.key().into_query_param();

let tcx = self.tcx;
let erased = query_provided_to_value::$name(tcx, value);
let erased = queries::$name::provided_to_erased(tcx, value);
let value = restore::<$V>(erased);
let cache = &tcx.query_system.caches.$name;

Expand All @@ -533,12 +504,20 @@ macro_rules! define_feedable {
let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx|
(hasher(&mut hcx, &value), hasher(&mut hcx, &old))
);
assert_eq!(
old_hash, value_hash,
"Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
stringify!($name),
)
if old_hash != value_hash {
// We have an inconsistency. This can happen if one of the two
// results is tainted by errors. In this case, delay a bug to
// ensure compilation is doomed, and keep the `old` value.
tcx.sess.delay_span_bug(DUMMY_SP, format!(
"Trying to feed an already recorded value for query {} key={key:?}:\n\
old value: {old:?}\nnew value: {value:?}",
stringify!($name),
));
}
} else {
// The query is `no_hash`, so we have no way to perform a sanity check.
// If feeding the same value multiple times needs to be supported,
// the query should not be marked `no_hash`.
bug!(
"Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
stringify!($name),
Expand Down
Loading