Auto merge of #129244 - cjgillot:opaque-hir, r=compiler-errors
Make opaque types regular HIR nodes Having opaque types as HIR owner introduces all sorts of complications. This PR proposes to make them regular HIR nodes instead. I haven't gone through all the test changes yet, so there may be a few surprises. Many thanks to `@camelid` for the first draft. Fixes https://github.com/rust-lang/rust/issues/129023 Fixes #129099 Fixes #125843 Fixes #119716 Fixes #121422
This commit is contained in:
commit
5a4ee43c38
105 changed files with 1056 additions and 1112 deletions
|
@ -732,6 +732,19 @@ impl<'hir> Map<'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn expect_opaque_ty(self, id: LocalDefId) -> &'hir OpaqueTy<'hir> {
|
||||
match self.tcx.hir_node_by_def_id(id) {
|
||||
Node::OpaqueTy(opaq) => opaq,
|
||||
_ => {
|
||||
bug!(
|
||||
"expected opaque type definition, found {}",
|
||||
self.node_to_string(self.tcx.local_def_id_to_hir_id(id))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
|
||||
match self.tcx.hir_node(id) {
|
||||
Node::Expr(expr) => expr,
|
||||
|
@ -923,6 +936,7 @@ impl<'hir> Map<'hir> {
|
|||
Node::Ty(ty) => ty.span,
|
||||
Node::AssocItemConstraint(constraint) => constraint.span,
|
||||
Node::TraitRef(tr) => tr.path.span,
|
||||
Node::OpaqueTy(op) => op.span,
|
||||
Node::Pat(pat) => pat.span,
|
||||
Node::PatField(field) => field.span,
|
||||
Node::Arm(arm) => arm.span,
|
||||
|
@ -1006,6 +1020,10 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
|
|||
self.tcx.hir_node(hir_id)
|
||||
}
|
||||
|
||||
fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir> {
|
||||
self.tcx.hir_node_by_def_id(def_id)
|
||||
}
|
||||
|
||||
fn body(&self, id: BodyId) -> &'hir Body<'hir> {
|
||||
(*self).body(id)
|
||||
}
|
||||
|
@ -1139,7 +1157,6 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
|||
ItemKind::ForeignMod { .. } => "foreign mod",
|
||||
ItemKind::GlobalAsm(..) => "global asm",
|
||||
ItemKind::TyAlias(..) => "ty",
|
||||
ItemKind::OpaqueTy(..) => "opaque type",
|
||||
ItemKind::Enum(..) => "enum",
|
||||
ItemKind::Struct(..) => "struct",
|
||||
ItemKind::Union(..) => "union",
|
||||
|
@ -1191,6 +1208,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
|||
Node::Ty(_) => node_str("type"),
|
||||
Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
|
||||
Node::TraitRef(_) => node_str("trait ref"),
|
||||
Node::OpaqueTy(_) => node_str("opaque type"),
|
||||
Node::Pat(_) => node_str("pat"),
|
||||
Node::PatField(_) => node_str("pattern field"),
|
||||
Node::Param(_) => node_str("param"),
|
||||
|
@ -1228,6 +1246,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
|
|||
impl_items,
|
||||
foreign_items,
|
||||
body_owners,
|
||||
opaques,
|
||||
..
|
||||
} = collector;
|
||||
ModuleItems {
|
||||
|
@ -1237,6 +1256,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod
|
|||
impl_items: impl_items.into_boxed_slice(),
|
||||
foreign_items: foreign_items.into_boxed_slice(),
|
||||
body_owners: body_owners.into_boxed_slice(),
|
||||
opaques: opaques.into_boxed_slice(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1256,6 +1276,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
|||
impl_items,
|
||||
foreign_items,
|
||||
body_owners,
|
||||
opaques,
|
||||
..
|
||||
} = collector;
|
||||
|
||||
|
@ -1266,6 +1287,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems {
|
|||
impl_items: impl_items.into_boxed_slice(),
|
||||
foreign_items: foreign_items.into_boxed_slice(),
|
||||
body_owners: body_owners.into_boxed_slice(),
|
||||
opaques: opaques.into_boxed_slice(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1280,6 +1302,7 @@ struct ItemCollector<'tcx> {
|
|||
impl_items: Vec<ImplItemId>,
|
||||
foreign_items: Vec<ForeignItemId>,
|
||||
body_owners: Vec<LocalDefId>,
|
||||
opaques: Vec<LocalDefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> ItemCollector<'tcx> {
|
||||
|
@ -1293,6 +1316,7 @@ impl<'tcx> ItemCollector<'tcx> {
|
|||
impl_items: Vec::default(),
|
||||
foreign_items: Vec::default(),
|
||||
body_owners: Vec::default(),
|
||||
opaques: Vec::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1338,6 +1362,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
|
|||
intravisit::walk_inline_const(self, c)
|
||||
}
|
||||
|
||||
fn visit_opaque_ty(&mut self, o: &'hir OpaqueTy<'hir>) {
|
||||
self.opaques.push(o.def_id);
|
||||
intravisit::walk_opaque_ty(self, o)
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
|
||||
if let ExprKind::Closure(closure) = ex.kind {
|
||||
self.body_owners.push(closure.def_id);
|
||||
|
|
|
@ -28,6 +28,7 @@ pub struct ModuleItems {
|
|||
trait_items: Box<[TraitItemId]>,
|
||||
impl_items: Box<[ImplItemId]>,
|
||||
foreign_items: Box<[ForeignItemId]>,
|
||||
opaques: Box<[LocalDefId]>,
|
||||
body_owners: Box<[LocalDefId]>,
|
||||
}
|
||||
|
||||
|
@ -65,6 +66,10 @@ impl ModuleItems {
|
|||
.chain(self.foreign_items.iter().map(|id| id.owner_id))
|
||||
}
|
||||
|
||||
pub fn opaques(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
||||
self.opaques.iter().copied()
|
||||
}
|
||||
|
||||
pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
||||
self.owners().map(|id| id.def_id)
|
||||
}
|
||||
|
@ -96,6 +101,13 @@ impl ModuleItems {
|
|||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_opaques(
|
||||
&self,
|
||||
f: impl Fn(LocalDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.opaques[..], |&id| f(id))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//! Name resolution for lifetimes and late-bound type and const variables: type declarations.
|
||||
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::ItemLocalId;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{ItemLocalId, OwnerId};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable, TyDecodable, TyEncodable};
|
||||
|
||||
use crate::ty;
|
||||
|
@ -47,11 +47,11 @@ pub enum ObjectLifetimeDefault {
|
|||
|
||||
/// Maps the id of each lifetime reference to the lifetime decl
|
||||
/// that it corresponds to.
|
||||
#[derive(Default, HashStable, Debug)]
|
||||
#[derive(HashStable, Debug)]
|
||||
pub struct ResolveBoundVars {
|
||||
/// Maps from every use of a named (not anonymous) lifetime to a
|
||||
/// `Region` describing how that region is bound
|
||||
pub defs: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, ResolvedArg>>,
|
||||
pub defs: SortedMap<ItemLocalId, ResolvedArg>,
|
||||
|
||||
pub late_bound_vars: FxIndexMap<OwnerId, FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>>,
|
||||
pub late_bound_vars: SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>>,
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use rustc_ast::expand::StrippedCfgItem;
|
|||
use rustc_ast::expand::allocator::AllocatorKind;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
|
@ -1552,7 +1553,7 @@ rustc_queries! {
|
|||
feedable
|
||||
}
|
||||
|
||||
query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
|
||||
query check_well_formed(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
|
||||
ensure_forwards_result_if_red
|
||||
}
|
||||
|
@ -1738,29 +1739,28 @@ rustc_queries! {
|
|||
/// Does lifetime resolution on items. Importantly, we can't resolve
|
||||
/// lifetimes directly on things like trait methods, because of trait params.
|
||||
/// See `rustc_resolve::late::lifetimes` for details.
|
||||
query resolve_bound_vars(_: hir::OwnerId) -> &'tcx ResolveBoundVars {
|
||||
query resolve_bound_vars(owner_id: hir::OwnerId) -> &'tcx ResolveBoundVars {
|
||||
arena_cache
|
||||
desc { "resolving lifetimes" }
|
||||
desc { |tcx| "resolving lifetimes for `{}`", tcx.def_path_str(owner_id) }
|
||||
}
|
||||
query named_variable_map(_: hir::OwnerId) ->
|
||||
Option<&'tcx FxIndexMap<ItemLocalId, ResolvedArg>> {
|
||||
desc { "looking up a named region" }
|
||||
query named_variable_map(owner_id: hir::OwnerId) -> &'tcx SortedMap<ItemLocalId, ResolvedArg> {
|
||||
desc { |tcx| "looking up a named region inside `{}`", tcx.def_path_str(owner_id) }
|
||||
}
|
||||
query is_late_bound_map(_: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
|
||||
desc { "testing if a region is late bound" }
|
||||
query is_late_bound_map(owner_id: hir::OwnerId) -> Option<&'tcx FxIndexSet<ItemLocalId>> {
|
||||
desc { |tcx| "testing if a region is late bound inside `{}`", tcx.def_path_str(owner_id) }
|
||||
}
|
||||
/// For a given item's generic parameter, gets the default lifetimes to be used
|
||||
/// for each parameter if a trait object were to be passed for that parameter.
|
||||
/// For example, for `T` in `struct Foo<'a, T>`, this would be `'static`.
|
||||
/// For `T` in `struct Foo<'a, T: 'a>`, this would instead be `'a`.
|
||||
/// This query will panic if passed something that is not a type parameter.
|
||||
query object_lifetime_default(key: DefId) -> ObjectLifetimeDefault {
|
||||
desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(key) }
|
||||
query object_lifetime_default(def_id: DefId) -> ObjectLifetimeDefault {
|
||||
desc { "looking up lifetime defaults for generic parameter `{}`", tcx.def_path_str(def_id) }
|
||||
separate_provide_extern
|
||||
}
|
||||
query late_bound_vars_map(_: hir::OwnerId)
|
||||
-> Option<&'tcx FxIndexMap<ItemLocalId, Vec<ty::BoundVariableKind>>> {
|
||||
desc { "looking up late bound vars" }
|
||||
query late_bound_vars_map(owner_id: hir::OwnerId)
|
||||
-> &'tcx SortedMap<ItemLocalId, Vec<ty::BoundVariableKind>> {
|
||||
desc { |tcx| "looking up late bound vars inside `{}`", tcx.def_path_str(owner_id) }
|
||||
}
|
||||
|
||||
/// Computes the visibility of the provided `def_id`.
|
||||
|
|
|
@ -56,7 +56,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
|
|||
pub use rustc_type_ir::lift::Lift;
|
||||
use rustc_type_ir::solve::SolverMode;
|
||||
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags, WithCachedTypeInfo, search_graph};
|
||||
use tracing::{debug, instrument};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::arena::Arena;
|
||||
use crate::dep_graph::{DepGraph, DepKindStruct};
|
||||
|
@ -2073,9 +2073,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Returns the origin of the opaque type `def_id`.
|
||||
#[instrument(skip(self), level = "trace", ret)]
|
||||
#[track_caller]
|
||||
pub fn opaque_type_origin(self, def_id: LocalDefId) -> hir::OpaqueTyOrigin {
|
||||
self.hir().expect_item(def_id).expect_opaque_ty().origin
|
||||
let origin = self.hir().expect_opaque_ty(def_id).origin;
|
||||
trace!("opaque_type_origin({def_id:?}) => {origin:?}");
|
||||
origin
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2994,7 +2996,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
pub fn named_bound_var(self, id: HirId) -> Option<resolve_bound_vars::ResolvedArg> {
|
||||
debug!(?id, "named_region");
|
||||
self.named_variable_map(id.owner).and_then(|map| map.get(&id.local_id).cloned())
|
||||
self.named_variable_map(id.owner).get(&id.local_id).cloned()
|
||||
}
|
||||
|
||||
pub fn is_late_bound(self, id: HirId) -> bool {
|
||||
|
@ -3003,12 +3005,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
|
||||
self.mk_bound_variable_kinds(
|
||||
&self
|
||||
.late_bound_vars_map(id.owner)
|
||||
.and_then(|map| map.get(&id.local_id).cloned())
|
||||
.unwrap_or_else(|| {
|
||||
bug!("No bound vars found for {}", self.hir().node_to_string(id))
|
||||
}),
|
||||
&self.late_bound_vars_map(id.owner).get(&id.local_id).cloned().unwrap_or_else(|| {
|
||||
bug!("No bound vars found for {}", self.hir().node_to_string(id))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -3031,8 +3030,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
loop {
|
||||
let parent = self.local_parent(opaque_lifetime_param_def_id);
|
||||
let hir::OpaqueTy { lifetime_mapping, .. } =
|
||||
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
|
||||
let hir::OpaqueTy { lifetime_mapping, .. } = self.hir().expect_opaque_ty(parent);
|
||||
|
||||
let Some((lifetime, _)) = lifetime_mapping
|
||||
.iter()
|
||||
|
|
|
@ -507,14 +507,8 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
|
|||
..
|
||||
},
|
||||
_,
|
||||
) => {
|
||||
self.0.push(ty);
|
||||
}
|
||||
hir::TyKind::OpaqueDef(item_id, _) => {
|
||||
self.0.push(ty);
|
||||
let item = self.1.item(item_id);
|
||||
hir::intravisit::walk_item(self, item);
|
||||
}
|
||||
)
|
||||
| hir::TyKind::OpaqueDef(..) => self.0.push(ty),
|
||||
_ => {}
|
||||
}
|
||||
hir::intravisit::walk_ty(self, ty);
|
||||
|
|
|
@ -21,6 +21,7 @@ use rustc_target::spec::abi;
|
|||
use rustc_type_ir::TyKind::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
|
||||
use tracing::instrument;
|
||||
use ty::util::{AsyncDropGlueMorphology, IntTypeExt};
|
||||
|
||||
use super::GenericParamDefKind;
|
||||
|
@ -500,6 +501,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
pub fn new_opaque(tcx: TyCtxt<'tcx>, def_id: DefId, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
||||
Ty::new_alias(tcx, ty::Opaque, AliasTy::new_from_args(tcx, def_id, args))
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue