Opaque types should not be HIR items (and thus not be HIR owners) #129023
Description
Summary
- Delete
hir::ItemKind::OpaqueTy
, addhir::Node::OpaqueTy
- Replace the
ItemId
inhir::TyKind::OpaqueDef
with&'hir OpaqueTy
- Fix the fallout
A WIP version of much of this can be seen in 79a3e7a...dcb9e9a, but it's incomplete. The reason is that many parts of the compiler assume that opaques are items and handle them through implicit codepaths.
Background
Currently, opaque types (e.g., return-position impl Trait
) are lowered into a hir::ItemKind::OpaqueTy
and then a hir::TyKind::OpaqueDef
that references that item's ID. However, because opaques' DefId
s are created in rustc_ast_lowering
, yet opaques can contain nodes whose DefId
s are created in DefCollector
(such as anon consts, which may in turn contain arbitrary nested items), this causes an incorrect parenting structure. This issue was uncovered in #128844, and it impeded that change, which delayed creation of defs for all expression-like nodes (anon consts, closures, etc.) until ast_lowering
to fix other issues relating to def parents. @BoxyUwU summarized the issue in that PR's thread, reproduced here:
Context for why the
Item::OpaqueTy
changes since @cjgillot has started looking at this PR:note: "this PR" indicates "this PR before the changes to opaques" as this was written from before those changes were made
Given the code example:
trait Trait<const N: usize> {} #[rustfmt::skip] fn foo() -> impl Trait<{ struct Bar; 1 }> {} impl Trait<1> for () {}The
free_items
for this module are:free_items: [ ItemId { owner_id: DefId(0:1 ~ playground_1[9aa8]::{use#0}) }, ItemId { owner_id: DefId(0:2 ~ playground_1[9aa8]::std) }, ItemId { owner_id: DefId(0:3 ~ playground_1[9aa8]::Trait) }, ItemId { owner_id: DefId(0:7 ~ playground_1[9aa8]::foo) }, ItemId { owner_id: DefId(0:11 ~ playground_1[9aa8]::foo::{opaque#0}) }, ItemId { owner_id: DefId(0:9 ~ playground_1[9aa8]::foo::{constant#0}::Bar) }, ItemId { owner_id: DefId(0:5 ~ playground_1[9aa8]::{impl#0}) } ]
so,
HirIdValidator
gets used onfoo,
opaque#0
andBar,
but not the anon const* `foo` it will recurse and call `visit_nested_item` on the opaque which doesn't recurse, and just checks that the parent `DefId`'s hir's owner is `foo` * `opaque#0`it will recurse and... check the `HirId` of the anon const is right (for some definition of right, unrelated to any of this), then recurse inside it, then visit `Bar` as a nested item and check that: `Bar`'s def parent's hir's owner is `opaque#0`, * On nightly that def parent is the anon const, and the anon consts hir is indeed owned by opaque#0 * On this PR where items (that arent nested bodies) that are in anon consts are not parented to the anon const, `Bar`'s def parent is `foo`, so we attempt to check that `foo`'s hir's owner is `opaque#0` which it is not so we ICE
On nightly: The def parent setup for
Bar
isfoo::{constant}::Bar
,foo
andopaque#0
are hir owners. When we validateopaque
's HirId's, it succeeds as we ignore anon consts, and the fact thatconstant
exists means thatBar
's parent's hir is ownedopaque
. On this PR: The def parent setup forbar
isfoo::Bar
,foo
andopaque#0
are hir owners. When we validateopaque
s HirIds, it fails asconstant#0
is no longer the parent ofBar
so it correctly detects that we have a nested thing inopaque#0
with a parent that is "outside" ofopaque
in a different hir owner's hirConclusion: Opaque types either need to have their
DefId
created inDefCollector
or needs to stop being a hir owner. Or, generally, if something is to be a hir owner node, theDefId
for it should be created before all childrenDefId
s or else you cannot create the parent structure correctly.
As mentioned above, the alternative is to create DefId
s for opaques ahead-of-time, in DefCollector
, but that is unsatisfactory because lowering of opaque types is quite complicated and that logic exists in rustc_ast_lowering
. IMO it also makes more intuitive sense to create defs for things that don't themselves participate in resolution, such as anon consts and opaque types, during ast_lowering
rather than def collection.
Activity