Skip to content

Commit

Permalink
Return Vec on TemplateParameters
Browse files Browse the repository at this point in the history
The Option<T> returned in this trait was removed to return Vec.

Fixes #960.
  • Loading branch information
ericho committed Feb 4, 2018
1 parent 92b86c5 commit 6fbb0be
Show file tree
Hide file tree
Showing 17 changed files with 507 additions and 226 deletions.
100 changes: 44 additions & 56 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,20 +300,20 @@ impl AppendImplicitTemplateParams for quote::Tokens {
_ => {},
}

if let Some(params) = item.used_template_params(ctx) {
if params.is_empty() {
return;
}
let params = item.used_template_params(ctx);

let params = params.into_iter().map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("template params cannot fail to be a rust type")
});

self.append_all(quote! {
< #( #params ),* >
});
if params.is_empty() {
return;
}

let params = params.into_iter().map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("template params cannot fail to be a rust type")
});

self.append_all(quote! {
< #( #params ),* >
});
}
}

Expand Down Expand Up @@ -481,10 +481,8 @@ impl CodeGenerator for Var {
// number of actual variables for a single declaration are open ended
// and we don't know what instantiations do or don't exist.
let type_params = item.all_template_params(ctx);
if let Some(params) = type_params {
if !params.is_empty() {
return;
}
if !type_params.is_empty() {
return;
}

let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
Expand Down Expand Up @@ -637,12 +635,8 @@ impl CodeGenerator for Type {
return;
}

let mut outer_params = item.used_template_params(ctx)
.and_then(|ps| if ps.is_empty() {
None
} else {
Some(ps)
});
let used_params = item.used_template_params(ctx);
let mut outer_params = if used_params.is_empty() { None } else { Some(used_params) };

let inner_rust_type = if item.is_opaque(ctx, &()) {
outer_params = None;
Expand Down Expand Up @@ -1598,21 +1592,20 @@ impl CodeGenerator for CompInfo {

let mut generic_param_names = vec![];

if let Some(ref params) = used_template_params {
for (idx, ty) in params.iter().enumerate() {
let param = ctx.resolve_type(*ty);
let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generic_param_names.push(ident.clone());

let prefix = ctx.trait_prefix();
let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
fields.push(quote! {
pub #field_name : ::#prefix::marker::PhantomData<
::#prefix::cell::UnsafeCell<#ident>
> ,
});
}
for (idx, ty) in used_template_params.iter().enumerate() {
let param = ctx.resolve_type(*ty);
let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generic_param_names.push(ident.clone());

let prefix = ctx.trait_prefix();
let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
fields.push(quote! {
pub #field_name : ::#prefix::marker::PhantomData<
::#prefix::cell::UnsafeCell<#ident>
> ,
});
}

let generics = if !generic_param_names.is_empty() {
Expand Down Expand Up @@ -1657,7 +1650,7 @@ impl CodeGenerator for CompInfo {
derives.push("Copy");

if ctx.options().rust_features().builtin_clone_impls() ||
used_template_params.is_some()
!used_template_params.is_empty()
{
// FIXME: This requires extra logic if you have a big array in a
// templated struct. The reason for this is that the magic:
Expand Down Expand Up @@ -1739,7 +1732,7 @@ impl CodeGenerator for CompInfo {
);
}

if used_template_params.is_none() {
if used_template_params.is_empty() {
if !is_opaque {
for var in self.inner_vars() {
ctx.resolve_item(*var).codegen(ctx, result, &());
Expand Down Expand Up @@ -2951,7 +2944,6 @@ impl TryToRustTy for Type {
TypeKind::TemplateAlias(..) |
TypeKind::Alias(..) => {
let template_params = item.used_template_params(ctx)
.unwrap_or(vec![])
.into_iter()
.filter(|param| param.is_template_param(ctx, &()))
.collect::<Vec<_>>();
Expand All @@ -2972,7 +2964,7 @@ impl TryToRustTy for Type {
TypeKind::Comp(ref info) => {
let template_params = item.used_template_params(ctx);
if info.has_non_type_template_params() ||
(item.is_opaque(ctx, &()) && template_params.is_some())
(item.is_opaque(ctx, &()) && !template_params.is_empty())
{
return self.try_to_opaque(ctx, item);
}
Expand Down Expand Up @@ -3066,18 +3058,16 @@ impl TryToRustTy for TemplateInstantiation {
let def_path = def.namespace_aware_canonical_path(ctx);
ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), proc_macro2::Term::intern("::"));

let def_params = match def.self_template_params(ctx) {
Some(params) => params,
None => {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
extra_assert!(
def.is_opaque(ctx, &())
);
return Err(error::Error::InstantiationOfOpaqueType);
}
};
let def_params = def.self_template_params(ctx);
if def_params.is_empty() {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
extra_assert!(
def.is_opaque(ctx, &())
);
return Err(error::Error::InstantiationOfOpaqueType);
}

// TODO: If the definition type is a template class/struct
// definition's member template definition, it could rely on
Expand Down Expand Up @@ -3171,10 +3161,8 @@ impl CodeGenerator for Function {
// instantiations is open ended and we have no way of knowing which
// monomorphizations actually exist.
let type_params = item.all_template_params(ctx);
if let Some(params) = type_params {
if !params.is_empty() {
return;
}
if !type_params.is_empty() {
return;
}

let name = self.name();
Expand Down
4 changes: 2 additions & 2 deletions src/ir/analysis/derive_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
}

// https://github.com/rust-lang/rust/issues/36640
if info.self_template_params(self.ctx).is_some() ||
item.used_template_params(self.ctx).is_some()
if !info.self_template_params(self.ctx).is_empty() ||
!item.used_template_params(self.ctx).is_empty()
{
trace!(
" comp cannot derive copy because issue 36640"
Expand Down
5 changes: 2 additions & 3 deletions src/ir/analysis/template_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
let decl = self.ctx.resolve_type(instantiation.template_definition());
let args = instantiation.template_arguments();

let params = decl.self_template_params(self.ctx).unwrap_or(vec![]);
let params = decl.self_template_params(self.ctx);

debug_assert!(this_id != instantiation.template_definition());
let used_by_def = self.used
Expand Down Expand Up @@ -418,8 +418,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
// Although template definitions should always have
// template parameters, there is a single exception:
// opaque templates. Hence the unwrap_or.
let params =
decl.self_template_params(ctx).unwrap_or(vec![]);
let params = decl.self_template_params(ctx);

for (arg, param) in args.iter().zip(params.iter()) {
let arg = arg.into_resolver()
Expand Down
10 changes: 3 additions & 7 deletions src/ir/comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1668,12 +1668,8 @@ impl TemplateParameters for CompInfo {
fn self_template_params(
&self,
_ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
if self.template_params.is_empty() {
None
} else {
Some(self.template_params.clone())
}
) -> Vec<TypeId> {
self.template_params.clone()
}
}

Expand All @@ -1684,7 +1680,7 @@ impl Trace for CompInfo {
where
T: Tracer,
{
let params = item.all_template_params(context).unwrap_or(vec![]);
let params = item.all_template_params(context);
for p in params {
tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
}
Expand Down
59 changes: 30 additions & 29 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,10 +1342,8 @@ impl BindgenContext {
let mut used_params = HashMap::new();
for &id in self.whitelisted_items() {
used_params.entry(id).or_insert(
id.self_template_params(self).map_or(
Default::default(),
|params| params.into_iter().map(|p| p.into()).collect(),
),
id.self_template_params(self)
.into_iter().map(|p| p.into()).collect()
);
}
self.used_template_parameters = Some(used_params);
Expand Down Expand Up @@ -1528,15 +1526,17 @@ impl BindgenContext {
.and_then(|canon_decl| {
self.get_resolved_type(&canon_decl).and_then(
|template_decl_id| {
template_decl_id.num_self_template_params(self).map(
|num_params| {
(
*canon_decl.cursor(),
template_decl_id.into(),
num_params,
)
},
)
let num_template_params = template_decl_id
.num_self_template_params(self);
if num_template_params == 0 {
None
} else {
Some((
*canon_decl.cursor(),
template_decl_id.into(),
num_template_params,
))
}
},
)
})
Expand All @@ -1557,15 +1557,16 @@ impl BindgenContext {
.cloned()
})
.and_then(|template_decl| {
template_decl.num_self_template_params(self).map(
|num_template_params| {
(
*template_decl.decl(),
template_decl.id(),
num_template_params,
)
},
)
let num_template_params = template_decl.num_self_template_params(self);
if num_template_params == 0 {
None
} else {
Some((
*template_decl.decl(),
template_decl.id(),
num_template_params,
))
}
})
})
}
Expand Down Expand Up @@ -1614,8 +1615,8 @@ impl BindgenContext {

let num_expected_args = match self.resolve_type(template)
.num_self_template_params(self) {
Some(n) => n,
None => {
n if n > 0 => n,
_ => {
warn!(
"Tried to instantiate a template for which we could not \
determine any template parameters"
Expand Down Expand Up @@ -2622,13 +2623,13 @@ impl TemplateParameters for PartialType {
fn self_template_params(
&self,
_ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
// Maybe at some point we will eagerly parse named types, but for now we
// don't and this information is unavailable.
None
vec![]
}

fn num_self_template_params(&self, _ctx: &BindgenContext) -> Option<usize> {
fn num_self_template_params(&self, _ctx: &BindgenContext) -> usize {
// Wouldn't it be nice if libclang would reliably give us this
// information‽
match self.decl().kind() {
Expand All @@ -2647,9 +2648,9 @@ impl TemplateParameters for PartialType {
};
clang_sys::CXChildVisit_Continue
});
Some(num_params)
num_params
}
_ => None,
_ => 0,
}
}
}
13 changes: 6 additions & 7 deletions src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,18 +1112,17 @@ where
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
ctx.resolve_item_fallible(*self).and_then(|item| {
item.self_template_params(ctx)
})
) -> Vec<TypeId> {
ctx.resolve_item_fallible(*self)
.map_or(vec![], |item| item.self_template_params(ctx))
}
}

impl TemplateParameters for Item {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
self.kind.self_template_params(ctx)
}
}
Expand All @@ -1132,15 +1131,15 @@ impl TemplateParameters for ItemKind {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
match *self {
ItemKind::Type(ref ty) => ty.self_template_params(ctx),
// If we start emitting bindings to explicitly instantiated
// functions, then we'll need to check ItemKind::Function for
// template params.
ItemKind::Function(_) |
ItemKind::Module(_) |
ItemKind::Var(_) => None,
ItemKind::Var(_) => vec![],
}
}
}
Expand Down
Loading

0 comments on commit 6fbb0be

Please sign in to comment.