diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 750f1fe121f6d..ed91cea4ae26a 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -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()?)) diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs index bfb04ba8a73f4..d61bb55be6836 100644 --- a/compiler/rustc_data_structures/src/sync/worker_local.rs +++ b/compiler/rustc_data_structures/src/sync/worker_local.rs @@ -154,13 +154,6 @@ impl WorkerLocal { } } -impl WorkerLocal> { - /// Joins the elements of all the worker locals into one Vec - pub fn join(self) -> Vec { - self.into_inner().into_iter().flat_map(|v| v).collect() - } -} - impl Deref for WorkerLocal { type Target = T; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9f00dc418eee9..22502bd4fdb98 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -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, @@ -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 { match tcx.hir().get_by_def_id(def_id) { Node::Expr(&rustc_hir::Expr { diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index 001d53b1099ec..d0d41c614d608 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -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 } } @@ -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 } } @@ -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) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 699e1f49ed6ca..deafad394b821 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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 diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index fe880b939ef46..364269095e011 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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))); @@ -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) } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 61c9e72db2cf5..ac0b2844177f3 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -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; @@ -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) -> bool { + self.opt_parent(def_id.into()) + .map_or(false, |parent| matches!(self.def_kind(parent), DefKind::ForeignMod)) + } } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 21c69662b9ead..12c94dc46760d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -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 { desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) } diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 647f4826876da..8d088b68e5927 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -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)*]) @@ -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(...) -> as QueryConfig>>::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 `::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 `::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> { + value: ProvidedValue<'tcx>, + ) -> Erase> { erase(query_if_arena!([$($modifiers)*] { - if mem::needs_drop::>() { + if mem::needs_drop::>() { &*_tcx.query_system.arenas.$name.alloc(value) } else { &*_tcx.arena.dropless.alloc(value) @@ -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::>() > 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::>() > 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::>() > 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::>() > 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::Target>>) @@ -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> { @@ -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>>, )* } @@ -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 { @@ -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>,)* } @@ -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; @@ -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), diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 03279124177e3..54f9fc5d2b999 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -40,7 +40,8 @@ impl<'a> Parser<'a> { /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of whether /// or not we have attributes - pub(crate) fn parse_stmt_without_recovery( + // Public for `cfg_eval` macro expansion. + pub fn parse_stmt_without_recovery( &mut self, capture_semi: bool, force_collect: ForceCollect, diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index b76734dd07294..7afcbebe274b3 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -15,7 +15,7 @@ #[macro_use] extern crate rustc_middle; -use crate::plumbing::{encode_all_query_results, try_mark_green}; +use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green}; use field_offset::offset_of; use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::sync::AtomicU64; @@ -27,8 +27,7 @@ use rustc_middle::query::on_disk_cache::OnDiskCache; use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns}; use rustc_middle::query::AsLocalKey; use rustc_middle::query::{ - query_keys, query_provided, query_provided_to_value, query_storage, query_values, - DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, + queries, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 2839c4d77035a..ebbf69a100714 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -518,11 +518,11 @@ macro_rules! define_queries { pub fn __rust_end_short_backtrace<'tcx>( tcx: TyCtxt<'tcx>, span: Span, - key: query_keys::$name<'tcx>, + key: queries::$name::Key<'tcx>, mode: QueryMode, - ) -> Option>> { + ) -> Option>> { get_query_incr( - queries::$name::config(tcx), + query_config::$name::config(tcx), QueryCtxt::new(tcx), span, key, @@ -543,11 +543,11 @@ macro_rules! define_queries { pub fn __rust_end_short_backtrace<'tcx>( tcx: TyCtxt<'tcx>, span: Span, - key: query_keys::$name<'tcx>, + key: queries::$name::Key<'tcx>, __mode: QueryMode, - ) -> Option>> { + ) -> Option>> { Some(get_query_non_incr( - queries::$name::config(tcx), + query_config::$name::config(tcx), QueryCtxt::new(tcx), span, key, @@ -570,7 +570,7 @@ macro_rules! define_queries { } #[allow(nonstandard_style)] - mod queries { + mod query_config { use std::marker::PhantomData; $( @@ -586,7 +586,7 @@ macro_rules! define_queries { use super::*; $( - pub(super) fn $name<'tcx>() -> DynamicQuery<'tcx, query_storage::$name<'tcx>> { + pub(super) fn $name<'tcx>() -> DynamicQuery<'tcx, queries::$name::Storage<'tcx>> { DynamicQuery { name: stringify!($name), eval_always: is_eval_always!([$($modifiers)*]), @@ -597,9 +597,8 @@ macro_rules! define_queries { cache_on_disk: |tcx, key| ::rustc_middle::query::cached::$name(tcx, key), execute_query: |tcx, key| erase(tcx.$name(key)), compute: |tcx, key| { - use crate::plumbing::__rust_begin_short_backtrace; __rust_begin_short_backtrace(|| - query_provided_to_value::$name( + queries::$name::provided_to_erased( tcx, call_provider!([$($modifiers)*][tcx, $name, key]) ) @@ -609,12 +608,14 @@ macro_rules! define_queries { try_load_from_disk: should_ever_cache_on_disk!([$($modifiers)*] { |tcx, key, prev_index, index| { if ::rustc_middle::query::cached::$name(tcx, key) { - let value = $crate::plumbing::try_load_from_disk::>( + let value = $crate::plumbing::try_load_from_disk::< + queries::$name::ProvidedValue<'tcx> + >( tcx, prev_index, index, ); - value.map(|value| query_provided_to_value::$name(tcx, value)) + value.map(|value| queries::$name::provided_to_erased(tcx, value)) } else { None } @@ -623,7 +624,7 @@ macro_rules! define_queries { |_tcx, _key, _prev_index, _index| None }), value_from_cycle_error: |tcx, cycle| { - let result: query_values::$name<'tcx> = Value::from_cycle_error(tcx, cycle); + let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle); erase(result) }, loadable_from_disk: |_tcx, _key, _index| { @@ -634,18 +635,18 @@ macro_rules! define_queries { false }) }, - hash_result: hash_result!([$($modifiers)*][query_values::$name<'tcx>]), - format_value: |value| format!("{:?}", restore::>(*value)), + hash_result: hash_result!([$($modifiers)*][queries::$name::Value<'tcx>]), + format_value: |value| format!("{:?}", restore::>(*value)), } } )* } - $(impl<'tcx> QueryConfigRestored<'tcx> for queries::$name<'tcx> { - type RestoredValue = query_values::$name<'tcx>; + $(impl<'tcx> QueryConfigRestored<'tcx> for query_config::$name<'tcx> { + type RestoredValue = queries::$name::Value<'tcx>; type Config = DynamicConfig< 'tcx, - query_storage::$name<'tcx>, + queries::$name::Storage<'tcx>, { is_anon!([$($modifiers)*]) }, { depth_limit!([$($modifiers)*]) }, { feedable!([$($modifiers)*]) }, @@ -660,7 +661,7 @@ macro_rules! define_queries { #[inline(always)] fn restore(value: >>::Value) -> Self::RestoredValue { - restore::>(value) + restore::>(value) } })* @@ -730,7 +731,7 @@ macro_rules! define_queries { } $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> { - $crate::plumbing::query_callback::>( + $crate::plumbing::query_callback::>( is_anon!([$($modifiers)*]), is_eval_always!([$($modifiers)*]), ) @@ -785,8 +786,8 @@ macro_rules! define_queries { ) }, encode_query_results: expand_if_cached!([$($modifiers)*], |tcx, encoder, query_result_index| - $crate::plumbing::encode_query_results::>( - super::queries::$name::config(tcx), + $crate::plumbing::encode_query_results::>( + super::query_config::$name::config(tcx), QueryCtxt::new(tcx), encoder, query_result_index, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index dbfe62ae6e943..730e4c8d30db3 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -433,16 +433,22 @@ where (hasher(&mut hcx, &cached_result), hasher(&mut hcx, &result)) }); let formatter = query.format_value(); - debug_assert_eq!( - old_hash, - new_hash, - "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ - computed={:#?}\nfed={:#?}", - query.dep_kind(), - key, - formatter(&result), - formatter(&cached_result), - ); + if old_hash != new_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. + qcx.dep_context().sess().delay_span_bug( + DUMMY_SP, + format!( + "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ + computed={:#?}\nfed={:#?}", + query.dep_kind(), + key, + formatter(&result), + formatter(&cached_result), + ), + ); + } } } job_owner.complete(cache, result, dep_node_index); diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 25cc82f01d553..d14e6244f7d07 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -506,10 +506,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { | ty::Param(_) | ty::Placeholder(..) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) + | ty::Alias(ty::Inherent, _) | ty::Error(_) => return, ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"), - ty::Alias(_, alias_ty) => alias_ty, + // Excluding IATs here as they don't have meaningful item bounds. + ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty, }; for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 445ab99b28fb3..51069897120af 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1543,7 +1543,10 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( // Check whether the self-type is itself a projection. // If so, extract what we know from the trait and try to come up with a good answer. let bounds = match *obligation.predicate.self_ty().kind() { - ty::Alias(_, ref data) => tcx.item_bounds(data.def_id).subst(tcx, data.substs), + // Excluding IATs here as they don't have meaningful item bounds. + ty::Alias(ty::Projection | ty::Opaque, ref data) => { + tcx.item_bounds(data.def_id).subst(tcx, data.substs) + } ty::Infer(ty::TyVar(_)) => { // If the self-type is an inference variable, then it MAY wind up // being a projected type, so induce an ambiguity. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a8fb55df2d302..aa230936903f1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -143,7 +143,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Before we go into the whole placeholder thing, just // quickly check if the self-type is a projection at all. match obligation.predicate.skip_binder().trait_ref.self_ty().kind() { - ty::Alias(..) => {} + // Excluding IATs here as they don't have meaningful item bounds. + ty::Alias(ty::Projection | ty::Opaque, _) => {} ty::Infer(ty::TyVar(_)) => { span_bug!( obligation.cause.span, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 6a648294efd98..de023501f9e85 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -156,7 +156,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let placeholder_self_ty = placeholder_trait_predicate.self_ty(); let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); let (def_id, substs) = match *placeholder_self_ty.kind() { - ty::Alias(_, ty::AliasTy { def_id, substs, .. }) => (def_id, substs), + // Excluding IATs here as they don't have meaningful item bounds. + ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { + (def_id, substs) + } _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), }; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b72ff5b78e418..f1bd9f5bbf8fa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1645,7 +1645,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.infcx.tcx; let (def_id, substs) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() { - ty::Alias(_, ty::AliasTy { def_id, substs, .. }) => (def_id, substs), + ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { + (def_id, substs) + } _ => { span_bug!( obligation.cause.span, diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 6e0c0e01af863..d8b298b59a3f8 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -365,7 +365,7 @@ pub enum Subcommand { #[arg(long)] all: bool, }, - /// Duild distribution artifacts + /// Build distribution artifacts Dist, /// Install distribution artifacts Install, diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 089c03a0d64ba..4eddd5cedf18e 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -36,7 +36,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "doc" -d 'Build documentation' complete -c x.py -n "__fish_use_subcommand" -f -a "test" -d 'Build and run some test suites' complete -c x.py -n "__fish_use_subcommand" -f -a "bench" -d 'Build and run some benchmarks' complete -c x.py -n "__fish_use_subcommand" -f -a "clean" -d 'Clean out build directories' -complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Duild distribution artifacts' +complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Build distribution artifacts' complete -c x.py -n "__fish_use_subcommand" -f -a "install" -d 'Install distribution artifacts' complete -c x.py -n "__fish_use_subcommand" -f -a "run" -d 'Run tools contained in this repository' complete -c x.py -n "__fish_use_subcommand" -f -a "setup" -d 'Set up the environment for development' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index fad2391e61f08..59fabf53f984b 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -63,7 +63,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Build and run some test suites') [CompletionResult]::new('bench', 'bench', [CompletionResultType]::ParameterValue, 'Build and run some benchmarks') [CompletionResult]::new('clean', 'clean', [CompletionResultType]::ParameterValue, 'Clean out build directories') - [CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Duild distribution artifacts') + [CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Build distribution artifacts') [CompletionResult]::new('install', 'install', [CompletionResultType]::ParameterValue, 'Install distribution artifacts') [CompletionResult]::new('run', 'run', [CompletionResultType]::ParameterValue, 'Run tools contained in this repository') [CompletionResult]::new('setup', 'setup', [CompletionResultType]::ParameterValue, 'Set up the environment for development') diff --git a/src/tools/clippy/tests/ui/issue-111399.rs b/src/tools/clippy/tests/ui/issue-111399.rs new file mode 100644 index 0000000000000..b65e6c7261a57 --- /dev/null +++ b/src/tools/clippy/tests/ui/issue-111399.rs @@ -0,0 +1,13 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +// Check that rustc doesn't crash on the trait bound `Self::Ty: std::marker::Freeze`. + +pub struct Struct; + +impl Struct { + pub type Ty = usize; + pub const CT: Self::Ty = 42; +} + +fn main() {} diff --git a/tests/incremental/const-generic-type-cycle.rs b/tests/incremental/const-generic-type-cycle.rs new file mode 100644 index 0000000000000..ca7b12e9e627b --- /dev/null +++ b/tests/incremental/const-generic-type-cycle.rs @@ -0,0 +1,17 @@ +// Verify that we do not ICE when we try to overwrite an anon-const's type because of a trait +// cycle. +// +// compile-flags: -Zincremental-ignore-spans +// revisions: cpass cfail +// error-pattern: cycle detected when computing type of `Bar::N` + +#![feature(trait_alias)] +#![crate_type="lib"] + +#[cfg(cpass)] +trait Bar {} + +#[cfg(cfail)] +trait Bar {} + +trait BB = Bar<{ 2 + 1 }>; diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 12cbb5a5f1240..d342b2ff6d91b 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -24,7 +24,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_interface::interface::Compiler; use rustc_interface::{Config, Queries}; -use rustc_middle::query::query_values::mir_borrowck; +use rustc_middle::query::queries::mir_borrowck::ProvidedValue; use rustc_middle::query::{ExternProviders, Providers}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; @@ -126,7 +126,7 @@ thread_local! { RefCell::new(HashMap::new()); } -fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> mir_borrowck<'tcx> { +fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> ProvidedValue<'tcx> { let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts(tcx, def_id); // SAFETY: The reader casts the 'static lifetime to 'tcx before using it. let body_with_facts: BodyWithBorrowckFacts<'static> = diff --git a/tests/ui/cfg/cfg-stmt-recovery.rs b/tests/ui/cfg/cfg-stmt-recovery.rs new file mode 100644 index 0000000000000..2e0839d2a1535 --- /dev/null +++ b/tests/ui/cfg/cfg-stmt-recovery.rs @@ -0,0 +1,13 @@ +// Verify that we do not ICE when failing to parse a statement in `cfg_eval`. + +#![feature(cfg_eval)] +#![feature(stmt_expr_attributes)] + +#[cfg_eval] +fn main() { + #[cfg_eval] + let _ = #[cfg(FALSE)] 0; + //~^ ERROR removing an expression is not supported in this position + //~| ERROR expected expression, found `;` + //~| ERROR removing an expression is not supported in this position +} diff --git a/tests/ui/cfg/cfg-stmt-recovery.stderr b/tests/ui/cfg/cfg-stmt-recovery.stderr new file mode 100644 index 0000000000000..cb15e21fac698 --- /dev/null +++ b/tests/ui/cfg/cfg-stmt-recovery.stderr @@ -0,0 +1,20 @@ +error: removing an expression is not supported in this position + --> $DIR/cfg-stmt-recovery.rs:9:13 + | +LL | let _ = #[cfg(FALSE)] 0; + | ^^^^^^^^^^^^^ + +error: expected expression, found `;` + --> $DIR/cfg-stmt-recovery.rs:9:28 + | +LL | let _ = #[cfg(FALSE)] 0; + | ^ expected expression + +error: removing an expression is not supported in this position + --> $DIR/cfg-stmt-recovery.rs:9:13 + | +LL | let _ = #[cfg(FALSE)] 0; + | ^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors +