Skip to content
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
2 changes: 0 additions & 2 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,6 @@ pub enum StashKey {
MaybeFruTypo,
CallAssocMethod,
AssociatedTypeSuggestion,
/// Query cycle detected, stashing in favor of a better error.
Cycle,
UndeterminedMacroResolution,
/// Used by `Parser::maybe_recover_trailing_expr`
ExprInPat,
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_hir_analysis/src/check/compare_eii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::iter;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, E0806, struct_span_code_err};
use rustc_hir::attrs::EiiImplResolution;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, FnSig, HirId, ItemKind, find_attr};
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
Expand Down Expand Up @@ -37,6 +38,14 @@ pub(crate) fn compare_eii_function_types<'tcx>(
eii_name: Symbol,
eii_attr_span: Span,
) -> Result<(), ErrorGuaranteed> {
// Error recovery can resolve the EII target to another value item with the same name,
// such as a tuple-struct constructor. Skip the comparison in that case and rely on the
// earlier name-resolution error instead of ICEing while building EII diagnostics.
// See <https://github.com/rust-lang/rust/issues/153502>.
if !is_foreign_function(tcx, foreign_item) {
return Ok(());
}

check_is_structurally_compatible(tcx, external_impl, foreign_item, eii_name, eii_attr_span)?;

let external_impl_span = tcx.def_span(external_impl);
Expand Down Expand Up @@ -442,3 +451,7 @@ fn get_declaration_sig<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Option<&'
let hir_id: HirId = tcx.local_def_id_to_hir_id(def_id);
tcx.hir_fn_sig_by_hir_id(hir_id)
}

fn is_foreign_function(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
tcx.is_foreign_item(def_id) && matches!(tcx.def_kind(def_id), DefKind::Fn)
}
17 changes: 5 additions & 12 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use rustc_errors::{Applicability, StashKey, Suggestions};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
Expand Down Expand Up @@ -183,10 +182,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}
},

Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|ty| ty.instantiate_identity(),
),
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).instantiate_identity(),

Node::ForeignItem(foreign_item) => match foreign_item.kind {
ForeignItemKind::Fn(..) => {
Expand Down Expand Up @@ -249,12 +245,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}
}

pub(super) fn type_of_opaque(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
pub(super) fn type_of_opaque(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<'_, Ty<'_>> {
if let Some(def_id) = def_id.as_local() {
Ok(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(
tcx,
Expand Down Expand Up @@ -287,11 +280,11 @@ pub(super) fn type_of_opaque(
DefiningScopeKind::MirBorrowck,
)
}
})
}
} else {
// Foreign opaque type will go through the foreign provider
// and load the type from metadata.
Ok(tcx.type_of(def_id))
tcx.type_of(def_id)
}
}

Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_macros/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ struct QueryModifiers {
arena_cache: Option<Ident>,
cache_on_disk_if: Option<CacheOnDiskIf>,
cycle_delay_bug: Option<Ident>,
cycle_stash: Option<Ident>,
depth_limit: Option<Ident>,
desc: Desc,
eval_always: Option<Ident>,
Expand All @@ -159,7 +158,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
let mut cache_on_disk_if = None;
let mut desc = None;
let mut cycle_delay_bug = None;
let mut cycle_stash = None;
let mut no_hash = None;
let mut anon = None;
let mut eval_always = None;
Expand Down Expand Up @@ -195,8 +193,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
try_insert!(arena_cache = modifier);
} else if modifier == "cycle_delay_bug" {
try_insert!(cycle_delay_bug = modifier);
} else if modifier == "cycle_stash" {
try_insert!(cycle_stash = modifier);
} else if modifier == "no_hash" {
try_insert!(no_hash = modifier);
} else if modifier == "anon" {
Expand All @@ -221,7 +217,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> {
cache_on_disk_if,
desc,
cycle_delay_bug,
cycle_stash,
no_hash,
anon,
eval_always,
Expand Down Expand Up @@ -257,7 +252,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {
arena_cache,
cache_on_disk_if,
cycle_delay_bug,
cycle_stash,
depth_limit,
desc: _,
eval_always,
Expand All @@ -273,8 +267,6 @@ fn make_modifiers_stream(query: &Query) -> proc_macro2::TokenStream {

let cycle_error_handling = if cycle_delay_bug.is_some() {
quote! { DelayBug }
} else if cycle_stash.is_some() {
quote! { Stash }
} else {
quote! { Error }
};
Expand Down Expand Up @@ -411,7 +403,6 @@ fn add_to_analyzer_stream(query: &Query, analyzer_stream: &mut proc_macro2::Toke
doc_link!(
arena_cache,
cycle_delay_bug,
cycle_stash,
no_hash,
anon,
eval_always,
Expand Down
12 changes: 2 additions & 10 deletions compiler/rustc_middle/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
//! - `cache_on_disk_if { ... }`: Cache the query result to disk if the provided block evaluates to
//! true. The query key identifier is available for use within the block, as is `tcx`.
//! - `cycle_delay_bug`: If a dependency cycle is detected, emit a delayed bug instead of aborting immediately.
//! - `cycle_stash`: If a dependency cycle is detected, stash the error for later handling.
//! - `no_hash`: Do not hash the query result for incremental compilation; just mark as dirty if recomputed.
//! - `anon`: Make the query anonymous in the dependency graph (no dep node is created).
//! - `eval_always`: Always evaluate the query, ignoring its dependencies and cached results.
Expand Down Expand Up @@ -118,7 +117,6 @@ use crate::mir::mono::{
CodegenUnit, CollectionMode, MonoItem, MonoItemPartitions, NormalizationErrorInMono,
};
use crate::query::describe_as_module;
use crate::query::plumbing::CyclePlaceholder;
use crate::traits::query::{
CanonicalAliasGoal, CanonicalDropckOutlivesGoal, CanonicalImpliedOutlivesBoundsGoal,
CanonicalMethodAutoderefStepsGoal, CanonicalPredicateGoal, CanonicalTypeOpAscribeUserTypeGoal,
Expand Down Expand Up @@ -339,22 +337,16 @@ rustc_queries! {
feedable
}

/// Returns the *hidden type* of the opaque type given by `DefId` unless a cycle occurred.
///
/// This is a specialized instance of [`Self::type_of`] that detects query cycles.
/// Unless `CyclePlaceholder` needs to be handled separately, call [`Self::type_of`] instead.
/// This is used to improve the error message in cases where revealing the hidden type
/// for auto-trait leakage cycles.
/// Returns the *hidden type* of the opaque type given by `DefId`.
///
/// # Panics
///
/// This query will panic if the given definition is not an opaque type.
query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<'tcx, Ty<'tcx>>, CyclePlaceholder> {
query type_of_opaque(key: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
desc {
"computing type of opaque `{path}`",
path = tcx.def_path_str(key),
}
cycle_stash
}
query type_of_opaque_hir_typeck(key: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
desc {
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/query/erase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use rustc_span::{ErrorGuaranteed, Spanned};

use crate::mir::interpret::EvalToValTreeResult;
use crate::mir::mono::{MonoItem, NormalizationErrorInMono};
use crate::query::plumbing::CyclePlaceholder;
use crate::traits::solve;
use crate::ty::adjustment::CoerceUnsizedInfo;
use crate::ty::{self, Ty, TyCtxt};
Expand Down Expand Up @@ -212,10 +211,6 @@ impl Erasable for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
[u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
}

impl Erasable for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
type Storage = [u8; size_of::<Result<ty::EarlyBinder<'static, Ty<'_>>, CyclePlaceholder>>()];
}

impl Erasable
for Result<(&'_ [Spanned<MonoItem<'_>>], &'_ [Spanned<MonoItem<'_>>]), NormalizationErrorInMono>
{
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/query/modifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ pub(crate) struct cache_on_disk_if;
/// A cycle error results in a delay_bug call
pub(crate) struct cycle_delay_bug;

/// # `cycle_stash` query modifier
///
/// A cycle error results in a stashed cycle error that can be unstashed and canceled later
pub(crate) struct cycle_stash;

/// # `depth_limit` query modifier
///
/// Whether the query has a call depth limit
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_data_structures::sharded::Sharded;
use rustc_data_structures::sync::{AtomicU64, WorkerLocal};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::hir_id::OwnerId;
use rustc_macros::HashStable;
use rustc_span::{ErrorGuaranteed, Span};
pub use sealed::IntoQueryParam;

Expand Down Expand Up @@ -58,7 +57,6 @@ pub enum ActiveKeyStatus<'tcx> {
pub enum CycleErrorHandling {
Error,
DelayBug,
Stash,
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -651,9 +649,6 @@ mod sealed {
}
}

#[derive(Copy, Clone, Debug, HashStable)]
pub struct CyclePlaceholder(pub ErrorGuaranteed);

#[cold]
pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! {
bug!(
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,10 +633,6 @@ pub enum SelectionError<'tcx> {
NotConstEvaluatable(NotConstEvaluatable),
/// Exceeded the recursion depth during type projection.
Overflow(OverflowError),
/// Computing an opaque type's hidden type caused an error (e.g. a cycle error).
/// We can thus not know whether the hidden type implements an auto trait, so
/// we should not presume anything about it.
OpaqueTypeAutoTraitLeakageUnknown(DefId),
/// Error for a `ConstArgHasType` goal
ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
}
Expand Down
43 changes: 30 additions & 13 deletions compiler/rustc_query_impl/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_data_structures::hash_table::{Entry, HashTable};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_data_structures::{outline, sharded, sync};
use rustc_errors::{FatalError, StashKey};
use rustc_errors::FatalError;
use rustc_middle::dep_graph::{DepGraphData, DepNodeKey, SerializedDepNodeIndex};
use rustc_middle::query::plumbing::QueryVTable;
use rustc_middle::query::{
Expand All @@ -16,8 +16,8 @@ use rustc_middle::ty::TyCtxt;
use rustc_middle::verify_ich::incremental_verify_ich;
use rustc_span::{DUMMY_SP, Span};

use crate::collect_active_jobs_from_all_queries;
use crate::dep_graph::{DepNode, DepNodeIndex};
use crate::for_each_query_vtable;
use crate::job::{QueryJobInfo, QueryJobMap, find_cycle_in_stack, report_cycle};
use crate::plumbing::{current_query_job, next_job_id, start_query};

Expand All @@ -30,14 +30,41 @@ pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool {
state.active.lock_shards().all(|shard| shard.is_empty())
}

/// Returns a map of currently active query jobs, collected from all queries.
///
/// If `require_complete` is `true`, this function locks all shards of the
/// query results to produce a complete map, which always returns `Ok`.
/// Otherwise, it may return an incomplete map as an error if any shard
/// lock cannot be acquired.
///
/// Prefer passing `false` to `require_complete` to avoid potential deadlocks,
/// especially when called from within a deadlock handler, unless a
/// complete map is needed and no deadlock is possible at this call site.
pub fn collect_active_jobs_from_all_queries<'tcx>(
tcx: TyCtxt<'tcx>,
require_complete: bool,
) -> Result<QueryJobMap<'tcx>, QueryJobMap<'tcx>> {
let mut job_map_out = QueryJobMap::default();
let mut complete = true;

for_each_query_vtable!(ALL, tcx, |query| {
let res = gather_active_jobs(query, tcx, require_complete, &mut job_map_out);
if res.is_none() {
complete = false;
}
});

if complete { Ok(job_map_out) } else { Err(job_map_out) }
}

/// Internal plumbing for collecting the set of active jobs for this query.
///
/// Should only be called from `collect_active_jobs_from_all_queries`.
///
/// (We arbitrarily use the word "gather" when collecting the jobs for
/// each individual query, so that we have distinct function names to
/// grep for.)
pub(crate) fn gather_active_jobs<'tcx, C>(
fn gather_active_jobs<'tcx, C>(
query: &'tcx QueryVTable<'tcx, C>,
tcx: TyCtxt<'tcx>,
require_complete: bool,
Expand Down Expand Up @@ -110,16 +137,6 @@ fn mk_cycle<'tcx, C: QueryCache>(
let guar = error.delay_as_bug();
(query.value_from_cycle_error)(tcx, cycle_error, guar)
}
CycleErrorHandling::Stash => {
let guar = if let Some(root) = cycle_error.cycle.first()
&& let Some(span) = root.frame.info.span
{
error.stash(span, StashKey::Cycle).unwrap()
} else {
error.emit()
};
(query.value_from_cycle_error)(tcx, cycle_error, guar)
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_query_impl/src/from_cycle_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_middle::dep_graph::DepKind;
use rustc_middle::queries::QueryVTables;
use rustc_middle::query::CycleError;
use rustc_middle::query::erase::erase_val;
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
Expand All @@ -31,9 +30,6 @@ pub(crate) fn specialize_query_vtables<'tcx>(vtables: &mut QueryVTables<'tcx>) {
vtables.erase_and_anonymize_regions_ty.value_from_cycle_error =
|tcx, _, guar| erase_val(Ty::new_error(tcx, guar));

vtables.type_of_opaque.value_from_cycle_error =
|_, _, guar| erase_val(Err(CyclePlaceholder(guar)));

vtables.fn_sig.value_from_cycle_error = |tcx, cycle, guar| erase_val(fn_sig(tcx, cycle, guar));

vtables.check_representability.value_from_cycle_error =
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_query_impl/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::{DUMMY_SP, Span};

use crate::collect_active_jobs_from_all_queries;
use crate::execution::collect_active_jobs_from_all_queries;

/// Map from query job IDs to job information collected by
/// `collect_active_jobs_from_all_queries`.
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_query_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
use rustc_data_structures::sync::AtomicU64;
use rustc_middle::dep_graph;
use rustc_middle::queries::{self, ExternProviders, Providers};
use rustc_middle::query::on_disk_cache::{CacheEncoder, EncodedDepNodeIndex, OnDiskCache};
use rustc_middle::query::on_disk_cache::OnDiskCache;
use rustc_middle::query::plumbing::{QuerySystem, QueryVTable};
use rustc_middle::query::{AsLocalQueryKey, QueryCache, QueryMode};
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;

pub use crate::dep_kind_vtables::make_dep_kind_vtables;
pub use crate::execution::collect_active_jobs_from_all_queries;
pub use crate::job::{QueryJobMap, break_query_cycles, print_query_stack};
use crate::profiling_support::QueryKeyStringCache;

#[macro_use]
mod plumbing;
Expand Down Expand Up @@ -66,7 +66,8 @@ pub fn query_system<'tcx>(
rustc_middle::rustc_with_all_queries! { define_queries! }

pub fn provide(providers: &mut rustc_middle::util::Providers) {
providers.hooks.alloc_self_profile_query_strings = alloc_self_profile_query_strings;
providers.hooks.query_key_hash_verify_all = query_key_hash_verify_all;
providers.hooks.encode_all_query_results = encode_all_query_results;
providers.hooks.alloc_self_profile_query_strings =
profiling_support::alloc_self_profile_query_strings;
providers.hooks.query_key_hash_verify_all = plumbing::query_key_hash_verify_all;
providers.hooks.encode_all_query_results = plumbing::encode_all_query_results;
}
Loading
Loading