rm ItemKind::OpaqueTy
This introduce an additional collection of opaques on HIR, as they can no longer be listed using the free item list.
This commit is contained in:
parent
4ec7839afa
commit
d6f247f3d5
45 changed files with 306 additions and 368 deletions
|
@ -252,10 +252,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
|
||||
/// projections that would result in "inheriting lifetimes".
|
||||
fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
let item = tcx.hir().expect_item(def_id);
|
||||
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
|
||||
tcx.dcx().span_bug(item.span, "expected opaque item");
|
||||
};
|
||||
let hir::OpaqueTy { origin, .. } = tcx.hir().expect_opaque_ty(def_id);
|
||||
|
||||
// HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
|
||||
// `async-std` (and `pub async fn` in general).
|
||||
|
@ -265,16 +262,16 @@ fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
return;
|
||||
}
|
||||
|
||||
let span = tcx.def_span(item.owner_id.def_id);
|
||||
let span = tcx.def_span(def_id);
|
||||
|
||||
if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
|
||||
if tcx.type_of(def_id).instantiate_identity().references_error() {
|
||||
return;
|
||||
}
|
||||
if check_opaque_for_cycles(tcx, item.owner_id.def_id, span).is_err() {
|
||||
if check_opaque_for_cycles(tcx, def_id, span).is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
|
||||
let _ = check_opaque_meets_bounds(tcx, def_id, span, origin);
|
||||
}
|
||||
|
||||
/// Checks that an opaque type does not contain cycles.
|
||||
|
@ -481,8 +478,7 @@ fn sanity_check_found_hidden_type<'tcx>(
|
|||
/// 2. Checking that all lifetimes that are implicitly captured are mentioned.
|
||||
/// 3. Asserting that all parameters mentioned in the captures list are invariant.
|
||||
fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
|
||||
let hir::OpaqueTy { bounds, .. } =
|
||||
*tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
|
||||
let hir::OpaqueTy { bounds, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
|
||||
let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
|
||||
hir::GenericBound::Use(bounds, ..) => Some(bounds),
|
||||
_ => None,
|
||||
|
|
|
@ -93,7 +93,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
|||
// it's a refinement to a TAIT.
|
||||
if !tcx.hir().get_if_local(impl_opaque.def_id).is_some_and(|node| {
|
||||
matches!(
|
||||
node.expect_item().expect_opaque_ty().origin,
|
||||
node.expect_opaque_ty().origin,
|
||||
hir::OpaqueTyOrigin::AsyncFn { parent, .. } | hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||
if parent == impl_m.def_id.expect_local()
|
||||
)
|
||||
|
|
|
@ -260,8 +260,8 @@ fn reject_placeholder_type_signatures_in_item<'tcx>(
|
|||
| hir::ItemKind::Trait(_, _, generics, ..)
|
||||
| hir::ItemKind::Impl(hir::Impl { generics, .. })
|
||||
| hir::ItemKind::Struct(_, generics) => (generics, true),
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
|
||||
| hir::ItemKind::TyAlias(_, generics) => (generics, false),
|
||||
// FIXME: how to handle opaque types since no longer items
|
||||
hir::ItemKind::TyAlias(_, generics) => (generics, false),
|
||||
// `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
|
||||
_ => return,
|
||||
};
|
||||
|
@ -731,18 +731,8 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||
}
|
||||
}
|
||||
|
||||
// Don't call `type_of` on opaque types, since that depends on type
|
||||
// checking function bodies. `check_item_type` ensures that it's called
|
||||
// instead.
|
||||
hir::ItemKind::OpaqueTy(..) => {
|
||||
tcx.ensure().generics_of(def_id);
|
||||
tcx.ensure().predicates_of(def_id);
|
||||
tcx.ensure().explicit_item_bounds(def_id);
|
||||
tcx.ensure().explicit_item_super_predicates(def_id);
|
||||
tcx.ensure().item_bounds(def_id);
|
||||
tcx.ensure().item_super_predicates(def_id);
|
||||
}
|
||||
|
||||
// FIXME: ok to ignore opaque tys in collection?
|
||||
//
|
||||
hir::ItemKind::TyAlias(..) => {
|
||||
tcx.ensure().generics_of(def_id);
|
||||
tcx.ensure().type_of(def_id);
|
||||
|
@ -1852,12 +1842,8 @@ fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
|
|||
}
|
||||
|
||||
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
|
||||
match tcx.hir_node_by_def_id(def_id) {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
|
||||
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
|
||||
}
|
||||
_ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id),
|
||||
}
|
||||
let opaque = tcx.hir().expect_opaque_ty(def_id);
|
||||
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
|
||||
}
|
||||
|
||||
fn rendered_precise_capturing_args<'tcx>(
|
||||
|
@ -1870,12 +1856,10 @@ fn rendered_precise_capturing_args<'tcx>(
|
|||
return tcx.rendered_precise_capturing_args(opaque_def_id);
|
||||
}
|
||||
|
||||
tcx.hir_node_by_def_id(def_id).expect_item().expect_opaque_ty().bounds.iter().find_map(
|
||||
|bound| match bound {
|
||||
hir::GenericBound::Use(args, ..) => {
|
||||
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
|
||||
hir::GenericBound::Use(args, ..) => {
|
||||
Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| arg.name())))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||
|
@ -10,12 +9,10 @@ pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) {
|
|||
return;
|
||||
}
|
||||
|
||||
for id in tcx.hir().items() {
|
||||
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
|
||||
|
||||
let ty = tcx.type_of(id.owner_id).instantiate_identity();
|
||||
|
||||
tcx.dcx().emit_err(crate::errors::TypeOf { span: tcx.def_span(id.owner_id), ty });
|
||||
for id in tcx.hir_crate_items(()).opaques() {
|
||||
let ty = tcx.type_of(id).instantiate_identity();
|
||||
let span = tcx.def_span(id);
|
||||
tcx.dcx().emit_err(crate::errors::TypeOf { span, ty });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
debug!("RPITIT fn_def_id={fn_def_id:?} opaque_def_id={opaque_def_id:?}");
|
||||
let trait_def_id = tcx.parent(fn_def_id);
|
||||
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
|
||||
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
|
||||
|
@ -207,36 +208,33 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
| Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
|
||||
Some(tcx.typeck_root_def_id(def_id.to_def_id()))
|
||||
}
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
|
||||
..
|
||||
}) => {
|
||||
if in_trait_or_impl.is_some() {
|
||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
|
||||
} else {
|
||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
|
||||
}
|
||||
Some(fn_def_id.to_def_id())
|
||||
Node::OpaqueTy(&hir::OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, in_trait_or_impl }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },
|
||||
..
|
||||
}) => {
|
||||
if in_trait_or_impl.is_some() {
|
||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn);
|
||||
} else {
|
||||
assert_matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn);
|
||||
}
|
||||
ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
|
||||
..
|
||||
}) => {
|
||||
if in_assoc_ty {
|
||||
assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
|
||||
} else {
|
||||
assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
|
||||
}
|
||||
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
|
||||
// Opaque types are always nested within another item, and
|
||||
// inherit the generics of the item.
|
||||
Some(parent.to_def_id())
|
||||
Some(fn_def_id.to_def_id())
|
||||
}
|
||||
Node::OpaqueTy(&hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty },
|
||||
..
|
||||
}) => {
|
||||
if in_assoc_ty {
|
||||
assert_matches!(tcx.def_kind(parent), DefKind::AssocTy);
|
||||
} else {
|
||||
assert_matches!(tcx.def_kind(parent), DefKind::TyAlias);
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent);
|
||||
// Opaque types are always nested within another item, and
|
||||
// inherit the generics of the item.
|
||||
Some(parent.to_def_id())
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -272,13 +270,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
|||
ItemKind::TyAlias(..)
|
||||
| ItemKind::Enum(..)
|
||||
| ItemKind::Struct(..)
|
||||
| ItemKind::OpaqueTy(..)
|
||||
| ItemKind::Union(..) => (None, Defaults::Allowed),
|
||||
ItemKind::Const(..) => (None, Defaults::Deny),
|
||||
_ => (None, Defaults::FutureCompatDisallowed),
|
||||
}
|
||||
}
|
||||
|
||||
Node::OpaqueTy(..) => (None, Defaults::Allowed),
|
||||
|
||||
// GATs
|
||||
Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => {
|
||||
(None, Defaults::Deny)
|
||||
|
|
|
@ -335,8 +335,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
// RPITIT's bounds are the same as opaque type bounds, but with
|
||||
// a projection self type.
|
||||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
let item = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_item();
|
||||
let opaque_ty = item.expect_opaque_ty();
|
||||
let opaque_ty = tcx.hir_node_by_def_id(opaque_def_id.expect_local()).expect_opaque_ty();
|
||||
let item_ty = Ty::new_projection_from_args(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
|
@ -347,7 +346,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
opaque_def_id.expect_local(),
|
||||
opaque_ty.bounds,
|
||||
item_ty,
|
||||
item.span,
|
||||
opaque_ty.span,
|
||||
filter,
|
||||
);
|
||||
assert_only_contains_predicates_from(filter, bounds, item_ty);
|
||||
|
@ -369,11 +368,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
span,
|
||||
..
|
||||
}) => associated_type_bounds(tcx, def_id, bounds, *span, filter),
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, origin, .. }),
|
||||
span,
|
||||
..
|
||||
}) => match origin {
|
||||
hir::Node::OpaqueTy(hir::OpaqueTy { bounds, origin, span, .. }) => match origin {
|
||||
// Since RPITITs are lowered as projections in `<dyn HirTyLowerer>::lower_ty`,
|
||||
// when we're asking for the item bounds of the *opaques* in a trait's default
|
||||
// method signature, we need to map these projections back to opaques.
|
||||
|
@ -412,7 +407,7 @@ pub(super) fn explicit_item_bounds_with_filter(
|
|||
}
|
||||
},
|
||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::TyAlias(..), .. }) => &[],
|
||||
_ => bug!("item_bounds called on {:?}", def_id),
|
||||
node => bug!("item_bounds called on {def_id:?} => {node:?}"),
|
||||
};
|
||||
|
||||
ty::EarlyBinder::bind(bounds)
|
||||
|
|
|
@ -330,7 +330,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||
// Opaque types duplicate some of their generic parameters.
|
||||
// We create bi-directional Outlives predicates between the original
|
||||
// and the duplicated parameter, to ensure that they do not get out of sync.
|
||||
if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
|
||||
if let Node::OpaqueTy(..) = node {
|
||||
let opaque_ty_node = tcx.parent_hir_node(hir_id);
|
||||
let Node::Ty(&hir::Ty { kind: TyKind::OpaqueDef(_, lifetimes), .. }) = opaque_ty_node
|
||||
else {
|
||||
|
|
|
@ -486,6 +486,31 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_opaque_ty(&mut self, opaque: &'tcx rustc_hir::OpaqueTy<'tcx>) {
|
||||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
// not including any parent `impl Trait`s.
|
||||
let mut bound_vars = FxIndexMap::default();
|
||||
debug!(?opaque.generics.params);
|
||||
for param in opaque.generics.params {
|
||||
let (def_id, reg) = ResolvedArg::early(param);
|
||||
bound_vars.insert(def_id, reg);
|
||||
}
|
||||
|
||||
let hir_id = self.tcx.local_def_id_to_hir_id(opaque.def_id);
|
||||
let scope = Scope::Binder {
|
||||
hir_id,
|
||||
bound_vars,
|
||||
s: self.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
self.with(scope, |this| {
|
||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||
this.with(scope, |this| intravisit::walk_opaque_ty(this, opaque))
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
|
||||
match &item.kind {
|
||||
|
@ -513,38 +538,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
// These sorts of items have no lifetime parameters at all.
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent, .. }
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
|
||||
generics,
|
||||
..
|
||||
}) => {
|
||||
// We want to start our early-bound indices at the end of the parent scope,
|
||||
// not including any parent `impl Trait`s.
|
||||
let mut bound_vars = FxIndexMap::default();
|
||||
debug!(?generics.params);
|
||||
for param in generics.params {
|
||||
let (def_id, reg) = ResolvedArg::early(param);
|
||||
bound_vars.insert(def_id, reg);
|
||||
}
|
||||
|
||||
let scope = Scope::Root { opt_parent_item: Some(parent) };
|
||||
self.with(scope, |this| {
|
||||
let scope = Scope::Binder {
|
||||
hir_id: item.hir_id(),
|
||||
bound_vars,
|
||||
s: this.scope,
|
||||
scope_type: BinderScopeType::Normal,
|
||||
where_bound_origin: None,
|
||||
};
|
||||
this.with(scope, |this| {
|
||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||
this.with(scope, |this| intravisit::walk_item(this, item))
|
||||
});
|
||||
})
|
||||
}
|
||||
hir::ItemKind::TyAlias(_, generics)
|
||||
| hir::ItemKind::Const(_, generics, _)
|
||||
| hir::ItemKind::Enum(_, generics)
|
||||
|
@ -689,17 +682,14 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
};
|
||||
self.with(scope, |this| this.visit_ty(mt.ty));
|
||||
}
|
||||
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||
hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
|
||||
self.visit_opaque_ty(opaque_ty);
|
||||
|
||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||
// `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
|
||||
// `type MyAnonTy<'b> = impl MyTrait<'b>;`
|
||||
// ^ ^ this gets resolved in the scope of
|
||||
// the opaque_ty generics
|
||||
let opaque_ty = self.tcx.hir().item(item_id);
|
||||
match &opaque_ty.kind {
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
|
||||
i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||
};
|
||||
|
||||
// Resolve the lifetimes that are applied to the opaque type.
|
||||
// These are resolved in the current scope.
|
||||
|
@ -722,9 +712,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
{
|
||||
// Opaques do not declare their own lifetimes, so if a lifetime comes from an opaque
|
||||
// it must be a reified late-bound lifetime from a trait goal.
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::OpaqueTy { .. }, ..
|
||||
}) => "higher-ranked lifetime from outer `impl Trait`",
|
||||
hir::Node::OpaqueTy(_) => "higher-ranked lifetime from outer `impl Trait`",
|
||||
// Other items are fine.
|
||||
hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => {
|
||||
continue;
|
||||
|
@ -740,8 +728,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||
|
||||
let (span, label) = if lifetime.ident.span == self.tcx.def_span(lifetime_def_id)
|
||||
{
|
||||
let opaque_span = self.tcx.def_span(item_id.owner_id);
|
||||
(opaque_span, Some(opaque_span))
|
||||
(opaque_ty.span, Some(opaque_ty.span))
|
||||
} else {
|
||||
(lifetime.ident.span, None)
|
||||
};
|
||||
|
|
|
@ -529,10 +529,6 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
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(..)
|
||||
|
@ -545,6 +541,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
|||
}
|
||||
},
|
||||
|
||||
Node::OpaqueTy(..) => tcx.type_of_opaque(def_id).map_or_else(
|
||||
|CyclePlaceholder(guar)| Ty::new_error(tcx, guar),
|
||||
|ty| ty.instantiate_identity(),
|
||||
),
|
||||
|
||||
Node::ForeignItem(foreign_item) => match foreign_item.kind {
|
||||
ForeignItemKind::Fn(..) => {
|
||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id);
|
||||
|
@ -603,42 +604,25 @@ pub(super) fn type_of_opaque(
|
|||
def_id: DefId,
|
||||
) -> Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
use rustc_hir::*;
|
||||
|
||||
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(&OpaqueTy {
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl },
|
||||
..
|
||||
}) => {
|
||||
if in_trait_or_impl == Some(hir::RpitContext::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)
|
||||
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
|
||||
opaque::find_opaque_ty_constraints_for_tait(tcx, def_id)
|
||||
}
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
|
||||
opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id)
|
||||
}
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
|
||||
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => {
|
||||
if in_trait_or_impl == Some(hir::RpitContext::Trait)
|
||||
&& !tcx.defaultness(owner).has_value()
|
||||
{
|
||||
span_bug!(
|
||||
tcx.def_span(def_id),
|
||||
"tried to get type of this RPITIT with no definition"
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
span_bug!(item.span, "type_of_opaque: unexpected item type: {:?}", item.kind);
|
||||
}
|
||||
},
|
||||
|
||||
x => {
|
||||
bug!("unexpected sort of node in type_of_opaque(): {:?}", x);
|
||||
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
|
|
|
@ -2087,43 +2087,36 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
|
||||
self.lower_path(opt_self_ty, path, hir_ty.hir_id, false)
|
||||
}
|
||||
&hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||
let opaque_ty = tcx.hir().item(item_id);
|
||||
&hir::TyKind::OpaqueDef(opaque_ty, lifetimes) => {
|
||||
let local_def_id = opaque_ty.def_id;
|
||||
|
||||
match opaque_ty.kind {
|
||||
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
|
||||
let local_def_id = item_id.owner_id.def_id;
|
||||
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
|
||||
// generate the def_id of an associated type for the trait and return as
|
||||
// type a projection.
|
||||
match origin {
|
||||
hir::OpaqueTyOrigin::FnReturn {
|
||||
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::AsyncFn {
|
||||
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||
..
|
||||
} => self.lower_opaque_ty(
|
||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id)
|
||||
.to_def_id(),
|
||||
lifetimes,
|
||||
true,
|
||||
),
|
||||
hir::OpaqueTyOrigin::FnReturn {
|
||||
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::AsyncFn {
|
||||
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
|
||||
}
|
||||
}
|
||||
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
|
||||
// generate the def_id of an associated type for the trait and return as
|
||||
// type a projection.
|
||||
match opaque_ty.origin {
|
||||
hir::OpaqueTyOrigin::FnReturn {
|
||||
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::AsyncFn {
|
||||
in_trait_or_impl: Some(hir::RpitContext::Trait),
|
||||
..
|
||||
} => self.lower_opaque_ty(
|
||||
tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id(),
|
||||
lifetimes,
|
||||
true,
|
||||
),
|
||||
hir::OpaqueTyOrigin::FnReturn {
|
||||
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::AsyncFn {
|
||||
in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
|
||||
..
|
||||
}
|
||||
| hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
self.lower_opaque_ty(local_def_id.to_def_id(), lifetimes, false)
|
||||
}
|
||||
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||
}
|
||||
}
|
||||
// If we encounter a type relative path with RTN generics, then it must have
|
||||
|
@ -2289,7 +2282,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
span_bug!(
|
||||
tcx.def_span(param.def_id),
|
||||
"only expected lifetime for opaque's own generics, got {:?}",
|
||||
param.kind
|
||||
param
|
||||
);
|
||||
};
|
||||
let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::fmt::Write;
|
||||
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
use rustc_middle::ty::{GenericArgs, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -24,18 +23,18 @@ fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
|
|||
}
|
||||
|
||||
pub(crate) fn variances(tcx: TyCtxt<'_>) {
|
||||
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
|
||||
for id in tcx.hir().items() {
|
||||
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
|
||||
let crate_items = tcx.hir_crate_items(());
|
||||
|
||||
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
|
||||
for id in crate_items.opaques() {
|
||||
tcx.dcx().emit_err(crate::errors::VariancesOf {
|
||||
span: tcx.def_span(id.owner_id),
|
||||
variances: format_variances(tcx, id.owner_id.def_id),
|
||||
span: tcx.def_span(id),
|
||||
variances: format_variances(tcx, id),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for id in tcx.hir().items() {
|
||||
for id in crate_items.free_items() {
|
||||
if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue