@@ -895,22 +895,33 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { |
|
|
895 |
895 |
} |
896 |
896 |
|
897 |
897 |
fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { |
898 |
|
-struct ProhibitOpaqueTypes<'tcx> { |
|
898 |
+struct ProhibitOpaqueTypes<'a, 'tcx> { |
|
899 |
+cx: &'a LateContext<'a, 'tcx>, |
899 |
900 |
ty: Option<Ty<'tcx>>, |
900 |
901 |
}; |
901 |
902 |
|
902 |
|
-impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'tcx> { |
|
903 |
+impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> { |
903 |
904 |
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { |
904 |
|
-if let ty::Opaque(..) = ty.kind { |
905 |
|
-self.ty = Some(ty); |
906 |
|
-true |
907 |
|
-} else { |
908 |
|
- ty.super_visit_with(self) |
|
905 |
+match ty.kind { |
|
906 |
+ ty::Opaque(..) => { |
|
907 |
+self.ty = Some(ty); |
|
908 |
+true |
|
909 |
+} |
|
910 |
+// Consider opaque types within projections FFI-safe if they do not normalize |
|
911 |
+// to more opaque types. |
|
912 |
+ ty::Projection(..) => { |
|
913 |
+let ty = self.cx.tcx.normalize_erasing_regions(self.cx.param_env, ty); |
|
914 |
+ |
|
915 |
+// If `ty` is a opaque type directly then `super_visit_with` won't invoke |
|
916 |
+// this function again. |
|
917 |
+if ty.has_opaque_types() { self.visit_ty(ty) } else { false } |
|
918 |
+} |
|
919 |
+ _ => ty.super_visit_with(self), |
909 |
920 |
} |
910 |
921 |
} |
911 |
922 |
} |
912 |
923 |
|
913 |
|
-let mut visitor = ProhibitOpaqueTypes { ty: None }; |
|
924 |
+let mut visitor = ProhibitOpaqueTypes { cx: self.cx, ty: None }; |
914 |
925 |
ty.visit_with(&mut visitor); |
915 |
926 |
if let Some(ty) = visitor.ty { |
916 |
927 |
self.emit_ffi_unsafe_type_lint(ty, sp, "opaque types have no C equivalent", None); |