Skip to content

Commit cc32412

Browse files
committed
Pull opaque type check into a separate method
1 parent fb307f9 commit cc32412

File tree

1 file changed

+64
-61
lines changed

1 file changed

+64
-61
lines changed

compiler/rustc_ty_utils/src/opaque_types.rs

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,69 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
118118
}
119119
TaitInBodyFinder { collector: self }.visit_expr(body);
120120
}
121+
122+
fn visit_opaque_ty(&mut self, alias_ty: &ty::AliasTy<'tcx>) {
123+
if !self.seen.insert(alias_ty.def_id.expect_local()) {
124+
return;
125+
}
126+
127+
// TAITs outside their defining scopes are ignored.
128+
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
129+
trace!(?origin);
130+
match origin {
131+
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
132+
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
133+
if !in_assoc_ty {
134+
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
135+
return;
136+
}
137+
}
138+
}
139+
}
140+
141+
self.opaques.push(alias_ty.def_id.expect_local());
142+
143+
let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
144+
// Only check that the parent generics of the TAIT/RPIT are unique.
145+
// the args owned by the opaque are going to always be duplicate
146+
// lifetime params for RPITs, and empty for TAITs.
147+
match self
148+
.tcx
149+
.uses_unique_generic_params(&alias_ty.args[..parent_count], CheckRegions::FromFunction)
150+
{
151+
Ok(()) => {
152+
// FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
153+
// supported at all, so this is sound to do, but once we want to support them, you'll
154+
// start seeing the error below.
155+
156+
// Collect opaque types nested within the associated type bounds of this opaque type.
157+
// We use identity args here, because we already know that the opaque type uses
158+
// only generic parameters, and thus substituting would not give us more information.
159+
for (pred, span) in self
160+
.tcx
161+
.explicit_item_bounds(alias_ty.def_id)
162+
.instantiate_identity_iter_copied()
163+
{
164+
trace!(?pred);
165+
self.visit_spanned(span, pred);
166+
}
167+
}
168+
Err(NotUniqueParam::NotParam(arg)) => {
169+
self.tcx.dcx().emit_err(NotParam {
170+
arg,
171+
span: self.span(),
172+
opaque_span: self.tcx.def_span(alias_ty.def_id),
173+
});
174+
}
175+
Err(NotUniqueParam::DuplicateParam(arg)) => {
176+
self.tcx.dcx().emit_err(DuplicateArg {
177+
arg,
178+
span: self.span(),
179+
opaque_span: self.tcx.def_span(alias_ty.def_id),
180+
});
181+
}
182+
}
183+
}
121184
}
122185

123186
impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> {
@@ -134,67 +197,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
134197
t.super_visit_with(self)?;
135198
match t.kind() {
136199
ty::Alias(ty::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
137-
if !self.seen.insert(alias_ty.def_id.expect_local()) {
138-
return ControlFlow::Continue(());
139-
}
140-
141-
// TAITs outside their defining scopes are ignored.
142-
let origin = self.tcx.opaque_type_origin(alias_ty.def_id.expect_local());
143-
trace!(?origin);
144-
match origin {
145-
rustc_hir::OpaqueTyOrigin::FnReturn(_)
146-
| rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
147-
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
148-
if !in_assoc_ty {
149-
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
150-
return ControlFlow::Continue(());
151-
}
152-
}
153-
}
154-
}
155-
156-
self.opaques.push(alias_ty.def_id.expect_local());
157-
158-
let parent_count = self.tcx.generics_of(alias_ty.def_id).parent_count;
159-
// Only check that the parent generics of the TAIT/RPIT are unique.
160-
// the args owned by the opaque are going to always be duplicate
161-
// lifetime params for RPITs, and empty for TAITs.
162-
match self.tcx.uses_unique_generic_params(
163-
&alias_ty.args[..parent_count],
164-
CheckRegions::FromFunction,
165-
) {
166-
Ok(()) => {
167-
// FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
168-
// supported at all, so this is sound to do, but once we want to support them, you'll
169-
// start seeing the error below.
170-
171-
// Collect opaque types nested within the associated type bounds of this opaque type.
172-
// We use identity args here, because we already know that the opaque type uses
173-
// only generic parameters, and thus substituting would not give us more information.
174-
for (pred, span) in self
175-
.tcx
176-
.explicit_item_bounds(alias_ty.def_id)
177-
.instantiate_identity_iter_copied()
178-
{
179-
trace!(?pred);
180-
self.visit_spanned(span, pred);
181-
}
182-
}
183-
Err(NotUniqueParam::NotParam(arg)) => {
184-
self.tcx.dcx().emit_err(NotParam {
185-
arg,
186-
span: self.span(),
187-
opaque_span: self.tcx.def_span(alias_ty.def_id),
188-
});
189-
}
190-
Err(NotUniqueParam::DuplicateParam(arg)) => {
191-
self.tcx.dcx().emit_err(DuplicateArg {
192-
arg,
193-
span: self.span(),
194-
opaque_span: self.tcx.def_span(alias_ty.def_id),
195-
});
196-
}
197-
}
200+
self.visit_opaque_ty(alias_ty);
198201
}
199202
ty::Alias(ty::Weak, alias_ty) if alias_ty.def_id.is_local() => {
200203
self.tcx

0 commit comments

Comments
 (0)