diff --git a/src/bindgen/cdecl.rs b/src/bindgen/cdecl.rs index 1018e09..a01d817 100644 --- a/src/bindgen/cdecl.rs +++ b/src/bindgen/cdecl.rs @@ -5,7 +5,7 @@ use std::io::Write; use crate::bindgen::declarationtyperesolver::DeclarationType; -use crate::bindgen::ir::{ArrayLength, Function, GenericArgument, Type}; +use crate::bindgen::ir::{ConstExpr, Function, GenericArgument, Type}; use crate::bindgen::writer::{ListType, SourceWriter}; use crate::bindgen::{Config, Language}; @@ -70,7 +70,7 @@ impl CDecl { t ), }; - let ptr_as_array = Type::Array(ty.clone(), ArrayLength::Value(length.to_string())); + let ptr_as_array = Type::Array(ty.clone(), ConstExpr::Value(length.to_string())); cdecl.build_type(&ptr_as_array, *is_const, config); cdecl } diff --git a/src/bindgen/ir/generic_path.rs b/src/bindgen/ir/generic_path.rs index e9f3620..861d51a 100644 --- a/src/bindgen/ir/generic_path.rs +++ b/src/bindgen/ir/generic_path.rs @@ -6,7 +6,7 @@ use syn::ext::IdentExt; use crate::bindgen::cdecl; use crate::bindgen::config::{Config, Language}; use crate::bindgen::declarationtyperesolver::{DeclarationType, DeclarationTypeResolver}; -use crate::bindgen::ir::{ArrayLength, Path, Type}; +use crate::bindgen::ir::{ConstExpr, Path, Type}; use crate::bindgen::utilities::IterHelpers; use crate::bindgen::writer::{Source, SourceWriter}; @@ -153,7 +153,7 @@ impl Source for GenericParams { #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum GenericArgument { Type(Type), - Const(ArrayLength), + Const(ConstExpr), } impl GenericArgument { @@ -275,7 +275,7 @@ impl GenericPath { syn::GenericArgument::Type(ref x) => Ok(Type::load(x)?.map(GenericArgument::Type)), syn::GenericArgument::Lifetime(_) => Ok(None), syn::GenericArgument::Const(ref x) => { - Ok(Some(GenericArgument::Const(ArrayLength::load(x)?))) + Ok(Some(GenericArgument::Const(ConstExpr::load(x)?))) } _ => Err(format!("can't handle generic argument {:?}", x)), })?, diff --git a/src/bindgen/ir/ty.rs b/src/bindgen/ir/ty.rs index cd52fec..0e318e2 100644 --- a/src/bindgen/ir/ty.rs +++ b/src/bindgen/ir/ty.rs @@ -311,22 +311,25 @@ impl PrimitiveType { } } -// The `U` part of `[T; U]` +/// Constant expressions. +/// +/// Used for the `U` part of `[T; U]` and const generics. We support a very +/// limited vocabulary here: only identifiers and literals. #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub enum ArrayLength { +pub enum ConstExpr { Name(String), Value(String), } -impl ArrayLength { +impl ConstExpr { pub fn as_str(&self) -> &str { match *self { - ArrayLength::Name(ref string) | ArrayLength::Value(ref string) => string, + ConstExpr::Name(ref string) | ConstExpr::Value(ref string) => string, } } pub fn rename_for_config(&mut self, config: &Config) { - if let ArrayLength::Name(ref mut name) = self { + if let ConstExpr::Name(ref mut name) = self { config.export.rename(name); } } @@ -336,18 +339,18 @@ impl ArrayLength { syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(ref len), .. - }) => Ok(ArrayLength::Value(len.base10_digits().to_string())), + }) => Ok(ConstExpr::Value(len.base10_digits().to_string())), syn::Expr::Path(ref path) => { let generic_path = GenericPath::load(&path.path)?; - Ok(ArrayLength::Name(generic_path.export_name().to_owned())) + Ok(ConstExpr::Name(generic_path.export_name().to_owned())) } _ => Err(format!("can't handle const expression {:?}", expr)), } } - pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> ArrayLength { + pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> ConstExpr { match *self { - ArrayLength::Name(ref name) => { + ConstExpr::Name(ref name) => { let path = Path::new(name); for &(param, value) in mappings { if path == *param { @@ -356,7 +359,7 @@ impl ArrayLength { if path.is_single_identifier() => { // This happens when the generic argument is a path. - return ArrayLength::Name(path.name().to_string()); + return ConstExpr::Name(path.name().to_string()); } GenericArgument::Const(ref expr) => { return expr.clone(); @@ -368,13 +371,13 @@ impl ArrayLength { } } } - ArrayLength::Value(_) => {} + ConstExpr::Value(_) => {} } self.clone() } } -impl Source for ArrayLength { +impl Source for ConstExpr { fn write(&self, _config: &Config, out: &mut SourceWriter) { write!(out, "{}", self.as_str()); } @@ -393,7 +396,7 @@ pub enum Type { }, Path(GenericPath), Primitive(PrimitiveType), - Array(Box, ArrayLength), + Array(Box, ConstExpr), FuncPtr { ret: Box, args: Vec<(Option, Type)>, @@ -472,7 +475,7 @@ impl Type { None => return Err("Cannot have an array of zero sized types.".to_owned()), }; - let len = ArrayLength::load(len)?; + let len = ConstExpr::load(len)?; Type::Array(Box::new(converted), len) } syn::Type::BareFn(ref function) => { diff --git a/src/bindgen/mangle.rs b/src/bindgen/mangle.rs index c61255e..f20bb3c 100644 --- a/src/bindgen/mangle.rs +++ b/src/bindgen/mangle.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use crate::bindgen::config::MangleConfig; -use crate::bindgen::ir::{ArrayLength, GenericArgument, GenericPath, Path, Type}; +use crate::bindgen::ir::{ConstExpr, GenericArgument, GenericPath, Path, Type}; use crate::bindgen::rename::IdentifierType; pub fn mangle_path(path: &Path, generic_values: &[GenericArgument], config: &MangleConfig) -> Path { @@ -71,14 +71,14 @@ impl<'a> Mangler<'a> { fn append_mangled_argument(&mut self, arg: &GenericArgument, last: bool) { match *arg { GenericArgument::Type(ref ty) => self.append_mangled_type(ty, last), - GenericArgument::Const(ArrayLength::Name(ref name)) => { + GenericArgument::Const(ConstExpr::Name(ref name)) => { // This must behave the same as a GenericArgument::Type, // because const arguments are commonly represented as Types; // see the comment on `enum GenericArgument`. let fake_ty = Type::Path(GenericPath::new(Path::new(name), vec![])); self.append_mangled_type(&fake_ty, last); } - GenericArgument::Const(ArrayLength::Value(ref val)) => self.output.push_str(val), + GenericArgument::Const(ConstExpr::Value(ref val)) => self.output.push_str(val), } } @@ -310,7 +310,7 @@ fn generics() { assert_eq!( mangle_path( &Path::new("Top"), - &[GenericArgument::Const(ArrayLength::Value("40".to_string()))], + &[GenericArgument::Const(ConstExpr::Value("40".to_string()))], &MangleConfig::default(), ), Path::new("Top_40") @@ -319,7 +319,7 @@ fn generics() { assert_eq!( mangle_path( &Path::new("Top"), - &[GenericArgument::Const(ArrayLength::Name("N".to_string()))], + &[GenericArgument::Const(ConstExpr::Name("N".to_string()))], &MangleConfig::default(), ), Path::new("Top_N") @@ -339,7 +339,7 @@ fn generics() { &Path::new("Foo"), &[ float(), - GenericArgument::Const(ArrayLength::Value("40".to_string())) + GenericArgument::Const(ConstExpr::Value("40".to_string())) ], &MangleConfig::default(), ),