Pull opaque type check into a separate method

This commit is contained in:
Oli Scherer 2024-01-09 11:16:32 +00:00
parent f58af9ba28
commit ac332bd916

View File

@ -118,36 +118,21 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
} }
TaitInBodyFinder { collector: self }.visit_expr(body); TaitInBodyFinder { collector: self }.visit_expr(body);
} }
}
impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> { fn visit_opaque_ty(&mut self, alias_ty: &ty::AliasTy<'tcx>) {
#[instrument(skip(self), ret, level = "trace")]
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
self.visit_spanned(span, value);
ControlFlow::Continue(())
}
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
#[instrument(skip(self), ret, level = "trace")]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
t.super_visit_with(self)?;
match t.kind() {
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
if !self.seen.insert(alias_ty.def_id.expect_local()) { if !self.seen.insert(alias_ty.def_id.expect_local()) {
return ControlFlow::Continue(()); return;
} }
// TAITs outside their defining scopes are ignored. // TAITs outside their defining scopes are ignored.
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local()); let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
trace!(?origin); trace!(?origin);
match origin { match origin {
rustc_hir::OpaqueTyOrigin::FnReturn(_) rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
| rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => { rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
if !in_assoc_ty { if !in_assoc_ty {
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) { if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
return ControlFlow::Continue(()); return;
} }
} }
} }
@ -159,10 +144,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
// Only check that the parent generics of the TAIT/RPIT are unique. // Only check that the parent generics of the TAIT/RPIT are unique.
// the args owned by the opaque are going to always be duplicate // the args owned by the opaque are going to always be duplicate
// lifetime params for RPITs, and empty for TAITs. // lifetime params for RPITs, and empty for TAITs.
match self.tcx.uses_unique_generic_params( match self
&alias_ty.args[..parent_count], .tcx
CheckRegions::FromFunction, .uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::FromFunction)
) { {
Ok(()) => { Ok(()) => {
// FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not // FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
// supported at all, so this is sound to do, but once we want to support them, you'll // supported at all, so this is sound to do, but once we want to support them, you'll
@ -196,6 +181,24 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
} }
} }
} }
}
impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
#[instrument(skip(self), ret, level = "trace")]
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
self.visit_spanned(span, value);
ControlFlow::Continue(())
}
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
#[instrument(skip(self), ret, level = "trace")]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<!> {
t.super_visit_with(self)?;
match t.kind() {
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
self.visit_opaque_ty(alias_ty);
}
ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => { ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => {
self.tcx self.tcx
.type_of(alias_ty.def_id) .type_of(alias_ty.def_id)