From 7953a11d0c9466103344c15a56569a0aa7f45c9d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 2 Nov 2020 12:57:57 -0800 Subject: Implement improper ctypes check without infinite loop on cyclic structs --- syntax/improper.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 syntax/improper.rs (limited to 'syntax/improper.rs') diff --git a/syntax/improper.rs b/syntax/improper.rs new file mode 100644 index 00000000..6fd31629 --- /dev/null +++ b/syntax/improper.rs @@ -0,0 +1,36 @@ +use self::ImproperCtype::*; +use crate::syntax::atom::Atom::{self, *}; +use crate::syntax::{Type, Types}; +use proc_macro2::Ident; + +pub enum ImproperCtype<'a> { + Definite(bool), + Depends(&'a Ident), +} + +impl<'a> Types<'a> { + // yes, no, maybe + pub fn determine_improper_ctype(&self, ty: &Type) -> ImproperCtype<'a> { + match ty { + Type::Ident(ident) => { + let ident = &ident.rust; + if let Some(atom) = Atom::from(ident) { + Definite(atom == RustString) + } else if let Some(strct) = self.structs.get(ident) { + Depends(&strct.name.rust) // iterate to fixed-point + } else { + Definite(self.rust.contains(ident)) + } + } + Type::RustBox(_) + | Type::RustVec(_) + | Type::Str(_) + | Type::Fn(_) + | Type::Void(_) + | Type::Slice(_) + | Type::SliceRefU8(_) => Definite(true), + Type::UniquePtr(_) | Type::CxxVector(_) => Definite(false), + Type::Ref(ty) => self.determine_improper_ctype(&ty.inner), + } + } +} -- cgit v1.2.3