}
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
- struct ProhibitOpaqueTypes<'a, 'tcx> {
- cx: &'a LateContext<'tcx>,
- }
-
- impl<'a, 'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
+ struct ProhibitOpaqueTypes;
+ impl<'tcx> ty::visit::TypeVisitor<'tcx> for ProhibitOpaqueTypes {
type BreakTy = Ty<'tcx>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
- match ty.kind() {
- ty::Opaque(..) => ControlFlow::Break(ty),
- // Consider opaque types within projections FFI-safe if they do not normalize
- // to more opaque types.
- ty::Projection(..) => {
- let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty);
-
- // If `ty` is an opaque type directly then `super_visit_with` won't invoke
- // this function again.
- if ty.has_opaque_types() {
- self.visit_ty(ty)
- } else {
- ControlFlow::CONTINUE
- }
- }
- _ => ty.super_visit_with(self),
+ if !ty.has_opaque_types() {
+ return ControlFlow::CONTINUE;
+ }
+
+ if let ty::Opaque(..) = ty.kind() {
+ ControlFlow::Break(ty)
+ } else {
+ ty.super_visit_with(self)
}
}
}
- if let Some(ty) = ty.visit_with(&mut ProhibitOpaqueTypes { cx: self.cx }).break_value() {
+ if let Some(ty) = self
+ .cx
+ .tcx
+ .normalize_erasing_regions(self.cx.param_env, ty)
+ .visit_with(&mut ProhibitOpaqueTypes)
+ .break_value()
+ {
self.emit_ffi_unsafe_type_lint(ty, sp, fluent::lint_improper_ctypes_opaque, None);
true
} else {