Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create some minimal HIR for associated opaque types #120943

Merged
merged 1 commit into from
Mar 14, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub(super) fn index_hir<'hir>(
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
};

for (local_id, node) in collector.nodes.iter_enumerated() {
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,11 @@ pub struct OpaqueTy<'hir> {
pub in_trait: bool,
}

#[derive(Copy, Clone, Debug, HashStable_Generic)]
pub struct AssocOpaqueTy {
// Add some data if necessary
}

/// From whence the opaque type came.
#[derive(Copy, Clone, PartialEq, Eq, Debug, HashStable_Generic)]
pub enum OpaqueTyOrigin {
Expand Down Expand Up @@ -3363,6 +3368,7 @@ pub enum OwnerNode<'hir> {
TraitItem(&'hir TraitItem<'hir>),
ImplItem(&'hir ImplItem<'hir>),
Crate(&'hir Mod<'hir>),
AssocOpaqueTy(&'hir AssocOpaqueTy),
}

impl<'hir> OwnerNode<'hir> {
Expand All @@ -3372,7 +3378,7 @@ impl<'hir> OwnerNode<'hir> {
| OwnerNode::ForeignItem(ForeignItem { ident, .. })
| OwnerNode::ImplItem(ImplItem { ident, .. })
| OwnerNode::TraitItem(TraitItem { ident, .. }) => Some(*ident),
OwnerNode::Crate(..) => None,
OwnerNode::Crate(..) | OwnerNode::AssocOpaqueTy(..) => None,
}
}

Expand All @@ -3385,6 +3391,7 @@ impl<'hir> OwnerNode<'hir> {
| OwnerNode::ImplItem(ImplItem { span, .. })
| OwnerNode::TraitItem(TraitItem { span, .. }) => span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
}
}

Expand Down Expand Up @@ -3443,6 +3450,7 @@ impl<'hir> OwnerNode<'hir> {
| OwnerNode::ImplItem(ImplItem { owner_id, .. })
| OwnerNode::ForeignItem(ForeignItem { owner_id, .. }) => *owner_id,
OwnerNode::Crate(..) => crate::CRATE_HIR_ID.owner,
OwnerNode::AssocOpaqueTy(..) => unreachable!(),
}
}

Expand Down Expand Up @@ -3486,6 +3494,7 @@ impl<'hir> Into<Node<'hir>> for OwnerNode<'hir> {
OwnerNode::ImplItem(n) => Node::ImplItem(n),
OwnerNode::TraitItem(n) => Node::TraitItem(n),
OwnerNode::Crate(n) => Node::Crate(n),
OwnerNode::AssocOpaqueTy(n) => Node::AssocOpaqueTy(n),
}
}
}
Expand Down Expand Up @@ -3523,6 +3532,7 @@ pub enum Node<'hir> {
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
// FIXME: Merge into `Node::Infer`.
ArrayLenInfer(&'hir InferArg),
AssocOpaqueTy(&'hir AssocOpaqueTy),
// Span by reference to minimize `Node`'s size
#[allow(rustc::pass_by_value)]
Err(&'hir Span),
Expand Down Expand Up @@ -3573,6 +3583,7 @@ impl<'hir> Node<'hir> {
| Node::Infer(..)
| Node::WhereBoundPredicate(..)
| Node::ArrayLenInfer(..)
| Node::AssocOpaqueTy(..)
| Node::Err(..) => None,
}
}
Expand Down Expand Up @@ -3678,6 +3689,7 @@ impl<'hir> Node<'hir> {
Node::TraitItem(i) => Some(OwnerNode::TraitItem(i)),
Node::ImplItem(i) => Some(OwnerNode::ImplItem(i)),
Node::Crate(i) => Some(OwnerNode::Crate(i)),
Node::AssocOpaqueTy(i) => Some(OwnerNode::AssocOpaqueTy(i)),
_ => None,
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorG
hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
};

if let Some(generics) = node.generics() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
visitor.visit_impl_item(item)
}
hir::OwnerNode::Crate(_) => {}
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
}

let mut rl = ResolveBoundVars::default();
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ impl<'a> State<'a> {
self.print_bounds(":", pred.bounds);
}
Node::ArrayLenInfer(_) => self.word("_"),
Node::AssocOpaqueTy(..) => unreachable!(),
Node::Err(_) => self.word("/*ERROR*/"),
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2174,7 +2174,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut call_finder = FindClosureArg { tcx: self.tcx, calls: vec![] };
let node = self
.tcx
.opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
.opt_local_def_id_to_hir_id(
self.tcx.hir().get_parent_item(call_expr.hir_id).def_id,
)
.map(|hir_id| self.tcx.hir_node(hir_id));
match node {
Some(hir::Node::Item(item)) => call_finder.visit_item(item),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2554,6 +2554,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
hir::OwnerNode::ImplItem(i) => visitor.visit_impl_item(i),
hir::OwnerNode::TraitItem(i) => visitor.visit_trait_item(i),
hir::OwnerNode::Crate(_) => bug!("OwnerNode::Crate doesn't not have generics"),
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
}

let ast_generics = self.tcx.hir().get_generics(lifetime_scope).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
cached_typeck_results: Cell::new(None),
param_env: ty::ParamEnv::empty(),
effective_visibilities: tcx.effective_visibilities(()),
last_node_with_lint_attrs: tcx.local_def_id_to_hir_id(module_def_id.into()),
last_node_with_lint_attrs: tcx.local_def_id_to_hir_id(module_def_id),
generics: None,
only_module: true,
};
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
levels.add_id(hir::CRATE_HIR_ID);
levels.visit_mod(mod_, mod_.spans.inner_span, hir::CRATE_HIR_ID)
}
hir::OwnerNode::AssocOpaqueTy(..) => unreachable!(),
},
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ macro_rules! arena_types {
[] features: rustc_feature::Features,
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
[] crate_inherent_impls: rustc_middle::ty::CrateInherentImpls,
[] hir_owner_nodes: rustc_hir::OwnerNodes<'tcx>,
]);
)
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,20 +161,18 @@ impl<'tcx> TyCtxt<'tcx> {
/// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
#[inline]
pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
Some(self.hir_node(self.opt_local_def_id_to_hir_id(id)?))
Some(self.hir_node_by_def_id(id))
}

/// Retrieves the `hir::Node` corresponding to `id`.
pub fn hir_node(self, id: HirId) -> Node<'tcx> {
self.hir_owner_nodes(id.owner).nodes[id.local_id].node
}

/// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
/// Retrieves the `hir::Node` corresponding to `id`.
#[inline]
#[track_caller]
pub fn hir_node_by_def_id(self, id: LocalDefId) -> Node<'tcx> {
self.opt_hir_node_by_def_id(id)
.unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}"))
self.hir_node(self.local_def_id_to_hir_id(id))
}

/// Returns `HirId` of the parent HIR node of node with this `hir_id`.
Expand Down Expand Up @@ -963,6 +961,7 @@ impl<'hir> Map<'hir> {
Node::Crate(item) => item.spans.inner_span,
Node::WhereBoundPredicate(pred) => pred.span,
Node::ArrayLenInfer(inf) => inf.span,
Node::AssocOpaqueTy(..) => unreachable!(),
Node::Err(span) => *span,
}
}
Expand Down Expand Up @@ -1227,6 +1226,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
Node::Crate(..) => String::from("(root_crate)"),
Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
Node::ArrayLenInfer(_) => node_str("array len infer"),
Node::AssocOpaqueTy(..) => unreachable!(),
Node::Err(_) => node_str("error"),
}
}
Expand Down
10 changes: 4 additions & 6 deletions compiler/rustc_middle/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,10 @@ pub fn provide(providers: &mut Providers) {
providers.hir_crate_items = map::hir_crate_items;
providers.crate_hash = map::crate_hash;
providers.hir_module_items = map::hir_module_items;
providers.opt_local_def_id_to_hir_id = |tcx, def_id| {
Some(match tcx.hir_crate(()).owners[def_id] {
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
MaybeOwner::NonOwner(hir_id) => hir_id,
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
})
providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owners[def_id] {
MaybeOwner::Owner(_) => HirId::make_owner(def_id),
MaybeOwner::NonOwner(hir_id) => hir_id,
MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id),
};
providers.opt_hir_owner_nodes =
|tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,8 @@ rustc_queries! {
cache_on_disk_if { true }
}

/// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any.
///
/// Definitions that were generated with no HIR, would be fed to return `None`.
query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{
/// Returns HIR ID for the given `LocalDefId`.
query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId {
desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) }
feedable
}
Expand All @@ -196,6 +194,7 @@ rustc_queries! {
/// Avoid calling this query directly.
query opt_hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> {
desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) }
feedable
}

/// Gives access to the HIR attributes inside the HIR owner `key`.
Expand All @@ -204,6 +203,7 @@ rustc_queries! {
/// Avoid calling this query directly.
query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> {
desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) }
feedable
}

/// Given the def_id of a const-generic parameter, computes the associated default const
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,11 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
pub fn def_id(&self) -> LocalDefId {
self.key
}

// Caller must ensure that `self.key` ID is indeed an owner.
pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> {
TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } }
}
}

/// The central data structure of the compiler. It stores references
Expand Down Expand Up @@ -2350,8 +2355,8 @@ impl<'tcx> TyCtxt<'tcx> {
self.intrinsic_raw(def_id)
}

pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId {
self.opt_local_def_id_to_hir_id(local_def_id).unwrap()
pub fn opt_local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> Option<HirId> {
Some(self.local_def_id_to_hir_id(local_def_id))
}

pub fn next_trait_solver_globally(self) -> bool {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_passes/src/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ impl<'tcx> ReachableContext<'tcx> {
| Node::Ctor(..)
| Node::Field(_)
| Node::Ty(_)
| Node::Crate(_) => {}
| Node::Crate(_)
| Node::AssocOpaqueTy(..) => {}
_ => {
bug!(
"found unexpected node kind in worklist: {} ({:?})",
Expand Down
29 changes: 21 additions & 8 deletions compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{self as hir, HirId};
use rustc_index::IndexVec;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt, TyCtxtFeed};
use rustc_span::symbol::kw;

pub(crate) fn provide(providers: &mut Providers) {
Expand Down Expand Up @@ -237,6 +238,22 @@ fn associated_types_for_impl_traits_in_associated_fn(
}
}

fn feed_hir(feed: &TyCtxtFeed<'_, LocalDefId>) {
feed.local_def_id_to_hir_id(HirId::make_owner(feed.def_id()));
feed.opt_hir_owner_nodes(Some(feed.tcx.arena.alloc(hir::OwnerNodes {
opt_hash_including_bodies: None,
nodes: IndexVec::from_elem_n(
hir::ParentedNode {
parent: hir::ItemLocalId::INVALID,
node: hir::Node::AssocOpaqueTy(&hir::AssocOpaqueTy {}),
},
1,
),
bodies: Default::default(),
})));
feed.feed_owner_id().hir_attrs(hir::AttributeMap::EMPTY);
}

/// Given an `opaque_ty_def_id` corresponding to an `impl Trait` in an associated
/// function from a trait, synthesize an associated type for that `impl Trait`
/// that inherits properties that we infer from the method and the opaque type.
Expand All @@ -258,9 +275,7 @@ fn associated_type_for_impl_trait_in_trait(
let local_def_id = trait_assoc_ty.def_id();
let def_id = local_def_id.to_def_id();

// There's no HIR associated with this new synthesized `def_id`, so feed
// `opt_local_def_id_to_hir_id` with `None`.
trait_assoc_ty.opt_local_def_id_to_hir_id(None);
feed_hir(&trait_assoc_ty);

// Copy span of the opaque.
trait_assoc_ty.def_ident_span(Some(span));
Expand Down Expand Up @@ -318,9 +333,7 @@ fn associated_type_for_impl_trait_in_impl(
let local_def_id = impl_assoc_ty.def_id();
let def_id = local_def_id.to_def_id();

// There's no HIR associated with this new synthesized `def_id`, so feed
// `opt_local_def_id_to_hir_id` with `None`.
impl_assoc_ty.opt_local_def_id_to_hir_id(None);
feed_hir(&impl_assoc_ty);

// Copy span of the opaque.
impl_assoc_ty.def_ident_span(Some(span));
Expand Down