add query opaque_types_defined_by
This commit is contained in:
parent
e2daccc4ac
commit
6ae803eedf
3 changed files with 91 additions and 0 deletions
|
@ -236,6 +236,15 @@ rustc_queries! {
|
||||||
cache_on_disk_if { key.is_local() }
|
cache_on_disk_if { key.is_local() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query opaque_types_defined_by(
|
||||||
|
key: LocalDefId
|
||||||
|
) -> &'tcx [LocalDefId] {
|
||||||
|
desc {
|
||||||
|
|tcx| "computing the opaque types defined by `{}`",
|
||||||
|
tcx.def_path_str(key.to_def_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the list of bounds that can be used for
|
/// Returns the list of bounds that can be used for
|
||||||
/// `SelectionCandidate::ProjectionCandidate(_)` and
|
/// `SelectionCandidate::ProjectionCandidate(_)` and
|
||||||
/// `ProjectionTyCandidate::TraitDef`.
|
/// `ProjectionTyCandidate::TraitDef`.
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub mod instance;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod layout_sanity_check;
|
mod layout_sanity_check;
|
||||||
mod needs_drop;
|
mod needs_drop;
|
||||||
|
mod opaque_types;
|
||||||
pub mod representability;
|
pub mod representability;
|
||||||
mod structural_match;
|
mod structural_match;
|
||||||
mod ty;
|
mod ty;
|
||||||
|
@ -47,6 +48,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
implied_bounds::provide(providers);
|
implied_bounds::provide(providers);
|
||||||
layout::provide(providers);
|
layout::provide(providers);
|
||||||
needs_drop::provide(providers);
|
needs_drop::provide(providers);
|
||||||
|
opaque_types::provide(providers);
|
||||||
representability::provide(providers);
|
representability::provide(providers);
|
||||||
ty::provide(providers);
|
ty::provide(providers);
|
||||||
instance::provide(providers);
|
instance::provide(providers);
|
||||||
|
|
80
compiler/rustc_ty_utils/src/opaque_types.rs
Normal file
80
compiler/rustc_ty_utils/src/opaque_types.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use rustc_hir::{def::DefKind, def_id::LocalDefId};
|
||||||
|
use rustc_middle::ty::util::CheckRegions;
|
||||||
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||||
|
use rustc_type_ir::AliasKind;
|
||||||
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
struct OpaqueTypeCollector<'tcx> {
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
opaques: Vec<LocalDefId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
||||||
|
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
|
||||||
|
match t.kind() {
|
||||||
|
ty::Alias(AliasKind::Opaque, alias_ty) => {
|
||||||
|
if let Some(def_id) = alias_ty.def_id.as_local() {
|
||||||
|
if self
|
||||||
|
.tcx
|
||||||
|
.uses_unique_generic_params(alias_ty.substs, CheckRegions::OnlyEarlyBound)
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
self.opaques.push(def_id);
|
||||||
|
return ControlFlow::Continue(());
|
||||||
|
} else {
|
||||||
|
warn!(?t, "opaque types with non-unique params in sig: {t:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
t.super_visit_with(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] {
|
||||||
|
// FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT.
|
||||||
|
match tcx.def_kind(item) {
|
||||||
|
DefKind::Fn | DefKind::AssocFn => {
|
||||||
|
let sig = tcx.fn_sig(item).subst_identity();
|
||||||
|
let mut collector = OpaqueTypeCollector { tcx, opaques: Vec::new() };
|
||||||
|
sig.visit_with(&mut collector);
|
||||||
|
tcx.arena.alloc_from_iter(collector.opaques)
|
||||||
|
}
|
||||||
|
DefKind::Mod
|
||||||
|
| DefKind::Struct
|
||||||
|
| DefKind::Union
|
||||||
|
| DefKind::Enum
|
||||||
|
| DefKind::Variant
|
||||||
|
| DefKind::Trait
|
||||||
|
| DefKind::TyAlias
|
||||||
|
| DefKind::ForeignTy
|
||||||
|
| DefKind::TraitAlias
|
||||||
|
| DefKind::AssocTy
|
||||||
|
| DefKind::TyParam
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::ConstParam
|
||||||
|
| DefKind::Static(_)
|
||||||
|
| DefKind::Ctor(_, _)
|
||||||
|
| DefKind::AssocConst
|
||||||
|
| DefKind::Macro(_)
|
||||||
|
| DefKind::ExternCrate
|
||||||
|
| DefKind::Use
|
||||||
|
| DefKind::ForeignMod
|
||||||
|
| DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::ImplTraitPlaceholder
|
||||||
|
| DefKind::Field
|
||||||
|
| DefKind::LifetimeParam
|
||||||
|
| DefKind::GlobalAsm
|
||||||
|
| DefKind::Impl { .. }
|
||||||
|
| DefKind::Closure
|
||||||
|
| DefKind::Generator => &[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn provide(providers: &mut ty::query::Providers) {
|
||||||
|
*providers = ty::query::Providers { opaque_types_defined_by, ..*providers };
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue