Skip to content
Merged
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
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<'_>> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it makes sense to move it back into type_of now, but that can be experimented with in a separate PR

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
12 changes: 1 addition & 11 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 Down Expand Up @@ -110,16 +110,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
Original file line number Diff line number Diff line change
Expand Up @@ -756,11 +756,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id) => return self.report_opaque_type_auto_trait_leakage(
&obligation,
def_id,
),

SelectionError::TraitDynIncompatible(did) => {
let violations = self.tcx.dyn_compatibility_violations(did);
report_dyn_incompatibility(self.tcx, span, None, did, violations)
Expand Down Expand Up @@ -3330,34 +3325,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
)
}

fn report_opaque_type_auto_trait_leakage(
&self,
obligation: &PredicateObligation<'tcx>,
def_id: DefId,
) -> ErrorGuaranteed {
let name = match self.tcx.local_opaque_ty_origin(def_id.expect_local()) {
hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } => {
"opaque type".to_string()
}
hir::OpaqueTyOrigin::TyAlias { .. } => {
format!("`{}`", self.tcx.def_path_debug_str(def_id))
}
};
let mut err = self.dcx().struct_span_err(
obligation.cause.span,
format!("cannot check whether the hidden type of {name} satisfies auto traits"),
);

err.note(
"fetching the hidden types of an opaque inside of the defining scope is not supported. \
You can try moving the opaque type and the item that actually registers a hidden type into a new submodule",
);
err.span_note(self.tcx.def_span(def_id), "opaque type is declared here");

self.note_obligation_cause(&mut err, &obligation);
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
}

fn report_signature_mismatch_error(
&self,
obligation: &PredicateObligation<'tcx>,
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2404,15 +2404,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// We can resolve the opaque type to its hidden type,
// which enforces a DAG between the functions requiring
// the auto trait bounds in question.
match self.tcx().type_of_opaque(def_id) {
Ok(ty) => ty::Binder::dummy(AutoImplConstituents {
types: vec![ty.instantiate(self.tcx(), args)],
assumptions: vec![],
}),
Err(_) => {
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
}
}
let ty = self.tcx().type_of_opaque(def_id);
ty::Binder::dummy(AutoImplConstituents {
types: vec![ty.instantiate(self.tcx(), args)],
assumptions: vec![],
})
}
}
})
Expand Down
3 changes: 1 addition & 2 deletions tests/ui/impl-trait/auto-trait-leakage/auto-trait-leak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ fn main() {}
// Cycles should work as the deferred obligations are
// independently resolved and only require the concrete
// return type, which can't depend on the obligation.
fn cycle1() -> impl Clone {
fn cycle1() -> impl Clone { //~ ERROR: cycle detected
send(cycle2().clone());

Rc::new(Cell::new(5))
}

fn cycle2() -> impl Clone {
send(cycle1().clone());
//~^ ERROR: cannot check whether the hidden type of opaque type satisfies auto traits

Rc::new(String::from("foo"))
}
Loading
Loading