Skip to content

Commit

Permalink
New type GenericArguments represents actual arguments to generics.
Browse files Browse the repository at this point in the history
  • Loading branch information
jorendorff authored and emilio committed May 9, 2022
1 parent 798cfab commit 13c0a4a
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 93 deletions.
4 changes: 2 additions & 2 deletions src/bindgen/cdecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::io::Write;

use crate::bindgen::declarationtyperesolver::DeclarationType;
use crate::bindgen::ir::{ArrayLength, Function, Type};
use crate::bindgen::ir::{ArrayLength, Function, GenericArgument, Type};
use crate::bindgen::writer::{ListType, SourceWriter};
use crate::bindgen::{Config, Language};

Expand Down Expand Up @@ -35,7 +35,7 @@ impl CDeclarator {
struct CDecl {
type_qualifers: String,
type_name: String,
type_generic_args: Vec<Type>,
type_generic_args: Vec<GenericArgument>,
declarators: Vec<CDeclarator>,
type_ctype: Option<DeclarationType>,
}
Expand Down
15 changes: 8 additions & 7 deletions src/bindgen/ir/enumeration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use crate::bindgen::config::{Config, Language};
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
AnnotationSet, AnnotationValue, Cfg, ConditionWrite, Documentation, Field, GenericParams,
GenericPath, Item, ItemContainer, Literal, Path, Repr, ReprStyle, Struct, ToCondition, Type,
AnnotationSet, AnnotationValue, Cfg, ConditionWrite, Documentation, Field, GenericArgument,
GenericParams, GenericPath, Item, ItemContainer, Literal, Path, Repr, ReprStyle, Struct,
ToCondition, Type,
};
use crate::bindgen::library::Library;
use crate::bindgen::mangle;
Expand Down Expand Up @@ -61,8 +62,8 @@ impl VariantBody {

fn specialize(
&self,
generic_values: &[Type],
mappings: &[(&Path, &Type)],
generic_values: &[GenericArgument],
mappings: &[(&Path, &GenericArgument)],
config: &Config,
) -> Self {
match *self {
Expand Down Expand Up @@ -265,8 +266,8 @@ impl EnumVariant {

fn specialize(
&self,
generic_values: &[Type],
mappings: &[(&Path, &Type)],
generic_values: &[GenericArgument],
mappings: &[(&Path, &GenericArgument)],
config: &Config,
) -> Self {
Self::new(
Expand Down Expand Up @@ -611,7 +612,7 @@ impl Item for Enum {

fn instantiate_monomorph(
&self,
generic_values: &[Type],
generic_values: &[GenericArgument],
library: &Library,
out: &mut Monomorphs,
) {
Expand Down
58 changes: 51 additions & 7 deletions src/bindgen/ir/generic_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use syn::ext::IdentExt;

use crate::bindgen::config::{Config, Language};
use crate::bindgen::declarationtyperesolver::{DeclarationType, DeclarationTypeResolver};
use crate::bindgen::ir::{Path, Type};
use crate::bindgen::ir::{ArrayLength, Path, Type};
use crate::bindgen::utilities::IterHelpers;
use crate::bindgen::writer::{Source, SourceWriter};

Expand All @@ -19,7 +19,8 @@ impl GenericParams {
.params
.iter()
.filter_map(|x| match *x {
syn::GenericParam::Type(syn::TypeParam { ref ident, .. }) => {
syn::GenericParam::Type(syn::TypeParam { ref ident, .. })
| syn::GenericParam::Const(syn::ConstParam { ref ident, .. }) => {
Some(Path::new(ident.unraw().to_string()))
}
_ => None,
Expand Down Expand Up @@ -69,16 +70,52 @@ impl Source for GenericParams {
}
}

/// A (non-lifetime) argument passed to a generic, either a type or a constant expression.
///
/// Note: Both arguments in a type like `Array<T, N>` are represented as
/// `GenericArgument::Type`s, even if `N` is actually the name of a const. This
/// is a consequence of `syn::GenericArgument` doing the same thing.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum GenericArgument {
Type(Type),
Const(ArrayLength),
}

impl GenericArgument {
pub fn specialize(&self, mappings: &[(&Path, &GenericArgument)]) -> GenericArgument {
match *self {
GenericArgument::Type(ref ty) => GenericArgument::Type(ty.specialize(mappings)),
GenericArgument::Const(ref expr) => GenericArgument::Const(expr.clone()),
}
}

pub fn rename_for_config(&mut self, config: &Config, generic_params: &GenericParams) {
match *self {
GenericArgument::Type(ref mut ty) => ty.rename_for_config(config, generic_params),
GenericArgument::Const(ref mut expr) => expr.rename_for_config(config),
}
}
}

impl Source for GenericArgument {
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
match *self {
GenericArgument::Type(ref ty) => ty.write(config, out),
GenericArgument::Const(ref expr) => expr.write(config, out),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct GenericPath {
path: Path,
export_name: String,
generics: Vec<Type>,
generics: Vec<GenericArgument>,
ctype: Option<DeclarationType>,
}

impl GenericPath {
pub fn new(path: Path, generics: Vec<Type>) -> Self {
pub fn new(path: Path, generics: Vec<GenericArgument>) -> Self {
let export_name = path.name().to_owned();
Self {
path,
Expand All @@ -103,11 +140,11 @@ impl GenericPath {
&self.path
}

pub fn generics(&self) -> &[Type] {
pub fn generics(&self) -> &[GenericArgument] {
&self.generics
}

pub fn generics_mut(&mut self) -> &mut [Type] {
pub fn generics_mut(&mut self) -> &mut [GenericArgument] {
&mut self.generics
}

Expand All @@ -123,6 +160,10 @@ impl GenericPath {
&self.export_name
}

pub fn is_single_identifier(&self) -> bool {
self.generics.is_empty()
}

pub fn rename_for_config(&mut self, config: &Config, generic_params: &GenericParams) {
for generic in &mut self.generics {
generic.rename_for_config(config, generic_params);
Expand Down Expand Up @@ -156,8 +197,11 @@ impl GenericPath {
ref args,
..
}) => args.iter().try_skip_map(|x| match *x {
syn::GenericArgument::Type(ref x) => Type::load(x),
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)?)))
}
_ => Err(format!("can't handle generic argument {:?}", x)),
})?,
syn::PathArguments::Parenthesized(_) => {
Expand Down
10 changes: 8 additions & 2 deletions src/bindgen/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::bindgen::config::Config;
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Path, Static, Struct, Type, Typedef, Union,
AnnotationSet, Cfg, Constant, Enum, GenericArgument, OpaqueItem, Path, Static, Struct, Typedef,
Union,
};
use crate::bindgen::library::Library;
use crate::bindgen::monomorph::Monomorphs;
Expand Down Expand Up @@ -37,7 +38,12 @@ pub trait Item {
}
fn rename_for_config(&mut self, _config: &Config) {}
fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) {}
fn instantiate_monomorph(&self, _generics: &[Type], _library: &Library, _out: &mut Monomorphs) {
fn instantiate_monomorph(
&self,
_generics: &[GenericArgument],
_library: &Library,
_out: &mut Monomorphs,
) {
unreachable!("Cannot instantiate {} as a generic.", self.name())
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/bindgen/ir/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::bindgen::config::{Config, Language};
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericParams, Item, ItemContainer, Path,
ToCondition, Type,
AnnotationSet, Cfg, ConditionWrite, Documentation, GenericArgument, GenericParams, Item,
ItemContainer, Path, ToCondition,
};
use crate::bindgen::library::Library;
use crate::bindgen::mangle;
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Item for OpaqueItem {

fn instantiate_monomorph(
&self,
generic_values: &[Type],
generic_values: &[GenericArgument],
library: &Library,
out: &mut Monomorphs,
) {
Expand Down
11 changes: 6 additions & 5 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ use crate::bindgen::config::{Config, Language, LayoutConfig};
use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
use crate::bindgen::dependencies::Dependencies;
use crate::bindgen::ir::{
AnnotationSet, Cfg, ConditionWrite, Constant, Documentation, Field, GenericParams, Item,
ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition, Type, Typedef,
AnnotationSet, Cfg, ConditionWrite, Constant, Documentation, Field, GenericArgument,
GenericParams, Item, ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition, Type,
Typedef,
};
use crate::bindgen::library::Library;
use crate::bindgen::mangle;
Expand Down Expand Up @@ -174,8 +175,8 @@ impl Struct {

pub fn specialize(
&self,
generic_values: &[Type],
mappings: &[(&Path, &Type)],
generic_values: &[GenericArgument],
mappings: &[(&Path, &GenericArgument)],
config: &Config,
) -> Self {
let mangled_path = mangle::mangle_path(&self.path, generic_values, &config.export.mangle);
Expand Down Expand Up @@ -365,7 +366,7 @@ impl Item for Struct {

fn instantiate_monomorph(
&self,
generic_values: &[Type],
generic_values: &[GenericArgument],
library: &Library,
out: &mut Monomorphs,
) {
Expand Down
Loading

0 comments on commit 13c0a4a

Please sign in to comment.