Rollup merge of #115294 - compiler-errors:cycle-err, r=oli-obk
More precisely detect cycle errors from type_of on opaque Not sure if this still needs work. Just putting it up for initial impressions, since it seems that a few people are frustrated with the increased error verbosity due to #113320. Essentially we introduce a new sub-query for `type_of` specifically for opaques which returns a value that is able to distinguish "has errors" from "due to cycle recovery". Fixes #115188 r? `@oli-obk`
This commit is contained in:
commit
b4c63f06e8
26 changed files with 297 additions and 309 deletions
|
@ -56,6 +56,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
resolve_bound_vars::provide(providers);
|
||||
*providers = Providers {
|
||||
type_of: type_of::type_of,
|
||||
type_of_opaque: type_of::type_of_opaque,
|
||||
item_bounds: item_bounds::item_bounds,
|
||||
explicit_item_bounds: item_bounds::explicit_item_bounds,
|
||||
generics_of: generics_of::generics_of,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_errors::{Applicability, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::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, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
|
@ -388,86 +389,62 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
}
|
||||
},
|
||||
|
||||
Node::Item(item) => {
|
||||
match item.kind {
|
||||
ItemKind::Static(ty, .., body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id,
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
"static variable",
|
||||
)
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
}
|
||||
ItemKind::Const(ty, _, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(
|
||||
tcx, def_id, body_id, ty.span, item.ident, "constant",
|
||||
)
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
}
|
||||
ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
|
||||
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
|
||||
spans if spans.len() > 0 => {
|
||||
let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf {
|
||||
span: spans.into(),
|
||||
note: (),
|
||||
});
|
||||
Ty::new_error(tcx, guar)
|
||||
}
|
||||
_ => icx.to_ty(*self_ty),
|
||||
},
|
||||
ItemKind::Fn(..) => {
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
let def = tcx.adt_def(def_id);
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_adt(tcx, def, args)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(&OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
|
||||
in_trait,
|
||||
..
|
||||
}) => {
|
||||
if in_trait && !tcx.defaultness(owner).has_value() {
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"tried to get type of this RPITIT with no definition"
|
||||
);
|
||||
}
|
||||
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
|
||||
}
|
||||
ItemKind::Trait(..)
|
||||
| ItemKind::TraitAlias(..)
|
||||
| ItemKind::Macro(..)
|
||||
| ItemKind::Mod(..)
|
||||
| ItemKind::ForeignMod { .. }
|
||||
| ItemKind::GlobalAsm(..)
|
||||
| ItemKind::ExternCrate(..)
|
||||
| ItemKind::Use(..) => {
|
||||
span_bug!(
|
||||
item.span,
|
||||
"compute_type_of_item: unexpected item type: {:?}",
|
||||
item.kind
|
||||
);
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::Static(ty, .., body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(
|
||||
tcx,
|
||||
def_id,
|
||||
body_id,
|
||||
ty.span,
|
||||
item.ident,
|
||||
"static variable",
|
||||
)
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemKind::Const(ty, _, body_id) => {
|
||||
if is_suggestable_infer_ty(ty) {
|
||||
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
|
||||
} else {
|
||||
icx.to_ty(ty)
|
||||
}
|
||||
}
|
||||
ItemKind::TyAlias(self_ty, _) => icx.to_ty(self_ty),
|
||||
ItemKind::Impl(hir::Impl { self_ty, .. }) => match self_ty.find_self_aliases() {
|
||||
spans if spans.len() > 0 => {
|
||||
let guar = tcx
|
||||
.sess
|
||||
.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () });
|
||||
Ty::new_error(tcx, guar)
|
||||
}
|
||||
_ => icx.to_ty(*self_ty),
|
||||
},
|
||||
ItemKind::Fn(..) => {
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_fn_def(tcx, def_id.to_def_id(), args)
|
||||
}
|
||||
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) => {
|
||||
let def = tcx.adt_def(def_id);
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
Ty::new_adt(tcx, def, args)
|
||||
}
|
||||
ItemKind::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|
||||
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|
||||
|ty| ty.instantiate_identity(),
|
||||
),
|
||||
ItemKind::Trait(..)
|
||||
| ItemKind::TraitAlias(..)
|
||||
| ItemKind::Macro(..)
|
||||
| ItemKind::Mod(..)
|
||||
| ItemKind::ForeignMod { .. }
|
||||
| ItemKind::GlobalAsm(..)
|
||||
| ItemKind::ExternCrate(..)
|
||||
| ItemKind::Use(..) => {
|
||||
span_bug!(item.span, "compute_type_of_item: unexpected item type: {:?}", item.kind);
|
||||
}
|
||||
},
|
||||
|
||||
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
|
@ -514,6 +491,51 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
ty::EarlyBinder::bind(output)
|
||||
}
|
||||
|
||||
pub(super) fn type_of_opaque(
|
||||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
use rustc_hir::*;
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
Ok(ty::EarlyBinder::bind(match tcx.hir().get(hir_id) {
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(&OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner),
|
||||
in_trait,
|
||||
..
|
||||
}) => {
|
||||
if in_trait && !tcx.defaultness(owner).has_value() {
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"tried to get type of this RPITIT with no definition"
|
||||
);
|
||||
}
|
||||
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
|
||||
}
|
||||
_ => {
|
||||
span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind);
|
||||
}
|
||||
},
|
||||
|
||||
x => {
|
||||
bug!("unexpected sort of node in type_of_opaque(): {:?}", x);
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
// Foreign opaque type will go through the foreign provider
|
||||
// and load the type from metadata.
|
||||
Ok(tcx.type_of(def_id))
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_placeholder_type<'a>(
|
||||
tcx: TyCtxt<'a>,
|
||||
def_id: LocalDefId,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::mir;
|
||||
use crate::query::CyclePlaceholder;
|
||||
use crate::traits;
|
||||
use crate::ty::{self, Ty};
|
||||
use std::mem::{size_of, transmute_copy, MaybeUninit};
|
||||
|
@ -142,6 +143,10 @@ impl EraseType for Result<&'_ ty::List<Ty<'_>>, ty::util::AlwaysRequiresDrop> {
|
|||
[u8; size_of::<Result<&'static ty::List<Ty<'static>>, ty::util::AlwaysRequiresDrop>>()];
|
||||
}
|
||||
|
||||
impl EraseType for Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
||||
type Result = [u8; size_of::<Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder>>()];
|
||||
}
|
||||
|
||||
impl<T> EraseType for Option<&'_ T> {
|
||||
type Result = [u8; size_of::<Option<&'static ()>>()];
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::mir::interpret::{
|
|||
use crate::mir::interpret::{LitToConstError, LitToConstInput};
|
||||
use crate::mir::mono::CodegenUnit;
|
||||
use crate::query::erase::{erase, restore, Erase};
|
||||
use crate::query::plumbing::{query_ensure, query_get_at, DynamicQuery};
|
||||
use crate::query::plumbing::{query_ensure, query_get_at, CyclePlaceholder, DynamicQuery};
|
||||
use crate::thir;
|
||||
use crate::traits::query::{
|
||||
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
|
||||
|
@ -243,6 +243,16 @@ rustc_queries! {
|
|||
feedable
|
||||
}
|
||||
|
||||
/// Specialized instance of `type_of` that detects cycles that are due to
|
||||
/// revealing opaque because of an auto trait bound. Unless `CyclePlaceholder` needs
|
||||
/// to be handled separately, call `type_of` instead.
|
||||
query type_of_opaque(key: DefId) -> Result<ty::EarlyBinder<Ty<'tcx>>, CyclePlaceholder> {
|
||||
desc { |tcx|
|
||||
"computing type of opaque `{path}`",
|
||||
path = tcx.def_path_str(key),
|
||||
}
|
||||
}
|
||||
|
||||
query collect_return_position_impl_trait_in_trait_tys(key: DefId)
|
||||
-> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@ use rustc_query_system::dep_graph::SerializedDepNodeIndex;
|
|||
pub(crate) use rustc_query_system::query::QueryJobId;
|
||||
use rustc_query_system::query::*;
|
||||
use rustc_query_system::HandleCycleError;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||
use std::ops::Deref;
|
||||
|
||||
pub struct QueryKeyStringCache {
|
||||
|
@ -52,7 +52,8 @@ pub struct DynamicQuery<'tcx, C: QueryCache> {
|
|||
pub loadable_from_disk:
|
||||
fn(tcx: TyCtxt<'tcx>, key: &C::Key, index: SerializedDepNodeIndex) -> bool,
|
||||
pub hash_result: HashResult<C::Value>,
|
||||
pub value_from_cycle_error: fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> C::Value,
|
||||
pub value_from_cycle_error:
|
||||
fn(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>], guar: ErrorGuaranteed) -> C::Value,
|
||||
pub format_value: fn(&C::Value) -> String,
|
||||
}
|
||||
|
||||
|
@ -629,3 +630,6 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
|||
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct CyclePlaceholder(pub ErrorGuaranteed);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::dep_graph::DepKind;
|
||||
use crate::query::plumbing::CyclePlaceholder;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
|
@ -8,20 +9,38 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
|
|||
use rustc_query_system::query::QueryInfo;
|
||||
use rustc_query_system::Value;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Ty<'_> {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo<DepKind>]) -> Self {
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
_: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
// SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
|
||||
// FIXME: Represent the above fact in the trait system somehow.
|
||||
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(Ty::new_misc_error(tcx)) }
|
||||
unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(Ty::new_error(tcx, guar)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Result<ty::EarlyBinder<Ty<'_>>, CyclePlaceholder> {
|
||||
fn from_cycle_error(
|
||||
_tcx: TyCtxt<'tcx>,
|
||||
_: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
Err(CyclePlaceholder(guar))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::SymbolName<'_> {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo<DepKind>]) -> Self {
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
_: &[QueryInfo<DepKind>],
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
// SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
|
||||
// FIXME: Represent the above fact in the trait system somehow.
|
||||
unsafe {
|
||||
|
@ -33,8 +52,12 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::SymbolName<'_> {
|
|||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::Binder<'_, ty::FnSig<'_>> {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo<DepKind>]) -> Self {
|
||||
let err = Ty::new_misc_error(tcx);
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
stack: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
let err = Ty::new_error(tcx, guar);
|
||||
|
||||
let arity = if let Some(frame) = stack.get(0)
|
||||
&& frame.query.dep_kind == DepKind::fn_sig
|
||||
|
@ -63,7 +86,11 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::Binder<'_, ty::FnSig<'_>> {
|
|||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Representability {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle: &[QueryInfo<DepKind>],
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
let mut item_and_field_ids = Vec::new();
|
||||
let mut representable_ids = FxHashSet::default();
|
||||
for info in cycle {
|
||||
|
@ -95,22 +122,35 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Representability {
|
|||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<Ty<'_>> {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
|
||||
ty::EarlyBinder::bind(Ty::from_cycle_error(tcx, cycle))
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
ty::EarlyBinder::bind(Ty::from_cycle_error(tcx, cycle, guar))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::EarlyBinder<ty::Binder<'_, ty::FnSig<'_>>> {
|
||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle: &[QueryInfo<DepKind>]) -> Self {
|
||||
ty::EarlyBinder::bind(ty::Binder::from_cycle_error(tcx, cycle))
|
||||
fn from_cycle_error(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
ty::EarlyBinder::bind(ty::Binder::from_cycle_error(tcx, cycle, guar))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Value<TyCtxt<'tcx>, DepKind> for Result<T, &'_ ty::layout::LayoutError<'_>> {
|
||||
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _cycle: &[QueryInfo<DepKind>]) -> Self {
|
||||
fn from_cycle_error(
|
||||
_tcx: TyCtxt<'tcx>,
|
||||
_cycle: &[QueryInfo<DepKind>],
|
||||
_guar: ErrorGuaranteed,
|
||||
) -> Self {
|
||||
// tcx.arena.alloc cannot be used because we are not allowed to use &'tcx LayoutError under
|
||||
// min_specialization. Since this is an error path anyways, leaking doesn't matter (and really,
|
||||
// tcx.arena.alloc is pretty much equal to leaking).
|
||||
// FIXME: `Cycle` should carry the ErrorGuaranteed
|
||||
Err(Box::leak(Box::new(ty::layout::LayoutError::Cycle)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ use rustc_query_system::query::{
|
|||
};
|
||||
use rustc_query_system::HandleCycleError;
|
||||
use rustc_query_system::Value;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
||||
#[macro_use]
|
||||
mod plumbing;
|
||||
|
@ -146,8 +146,9 @@ where
|
|||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cycle: &[QueryInfo<DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self::Value {
|
||||
(self.dynamic.value_from_cycle_error)(tcx, cycle)
|
||||
(self.dynamic.value_from_cycle_error)(tcx, cycle, guar)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -605,8 +605,8 @@ macro_rules! define_queries {
|
|||
} {
|
||||
|_tcx, _key, _prev_index, _index| None
|
||||
}),
|
||||
value_from_cycle_error: |tcx, cycle| {
|
||||
let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle);
|
||||
value_from_cycle_error: |tcx, cycle, guar| {
|
||||
let result: queries::$name::Value<'tcx> = Value::from_cycle_error(tcx, cycle, guar);
|
||||
erase(result)
|
||||
},
|
||||
loadable_from_disk: |_tcx, _key, _index| {
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::query::DepNodeIndex;
|
|||
use crate::query::{QueryContext, QueryInfo, QueryState};
|
||||
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
@ -57,6 +58,7 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy {
|
|||
self,
|
||||
tcx: Qcx::DepContext,
|
||||
cycle: &[QueryInfo<Qcx::DepKind>],
|
||||
guar: ErrorGuaranteed,
|
||||
) -> Self::Value;
|
||||
|
||||
fn anon(self) -> bool;
|
||||
|
|
|
@ -148,8 +148,8 @@ where
|
|||
use HandleCycleError::*;
|
||||
match query.handle_cycle_error() {
|
||||
Error => {
|
||||
error.emit();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle)
|
||||
let guar = error.emit();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
|
||||
}
|
||||
Fatal => {
|
||||
error.emit();
|
||||
|
@ -157,8 +157,8 @@ where
|
|||
unreachable!()
|
||||
}
|
||||
DelayBug => {
|
||||
error.delay_as_bug();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle)
|
||||
let guar = error.delay_as_bug();
|
||||
query.value_from_cycle_error(*qcx.dep_context(), &cycle_error.cycle, guar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use rustc_span::ErrorGuaranteed;
|
||||
|
||||
use crate::dep_graph::{DepContext, DepKind};
|
||||
use crate::query::QueryInfo;
|
||||
|
||||
pub trait Value<Tcx: DepContext, D: DepKind>: Sized {
|
||||
fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo<D>]) -> Self;
|
||||
fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo<D>], guar: ErrorGuaranteed) -> Self;
|
||||
}
|
||||
|
||||
impl<Tcx: DepContext, T, D: DepKind> Value<Tcx, D> for T {
|
||||
default fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo<D>]) -> T {
|
||||
default fn from_cycle_error(tcx: Tcx, cycle: &[QueryInfo<D>], _guar: ErrorGuaranteed) -> T {
|
||||
tcx.sess().abort_if_errors();
|
||||
// Ideally we would use `bug!` here. But bug! is only defined in rustc_middle, and it's
|
||||
// non-trivial to define it earlier.
|
||||
|
|
|
@ -2346,14 +2346,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
|
||||
let ty = self.tcx().type_of(def_id);
|
||||
if ty.skip_binder().references_error() {
|
||||
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
|
||||
}
|
||||
// We can resolve the `impl Trait` to its concrete type,
|
||||
// which enforces a DAG between the functions requiring
|
||||
// the auto trait bounds in question.
|
||||
t.rebind(vec![ty.instantiate(self.tcx(), args)])
|
||||
match self.tcx().type_of_opaque(def_id) {
|
||||
Ok(ty) => t.rebind(vec![ty.instantiate(self.tcx(), args)]),
|
||||
Err(_) => {
|
||||
return Err(SelectionError::OpaqueTypeAutoTraitLeakageUnknown(def_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue