Skip to content

Return Vec on TemplateParameters #1245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 44 additions & 56 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,20 +299,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(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(quote! {
< #( #params ),* >
});
}
}

Expand Down Expand Up @@ -480,10 +480,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 @@ -636,12 +634,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 @@ -1597,21 +1591,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 @@ -1656,7 +1649,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 @@ -1738,7 +1731,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 @@ -2993,7 +2986,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 @@ -3014,7 +3006,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 @@ -3108,18 +3100,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)), "::");

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 @@ -3213,10 +3203,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: 21 additions & 38 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,12 @@ 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_params = template_decl_id.num_self_template_params(self);
Some((
*canon_decl.cursor(),
template_decl_id.into(),
num_params,
))
},
)
})
Expand All @@ -1557,15 +1552,12 @@ 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);
Some((
*template_decl.decl(),
template_decl.id(),
num_template_params,
))
})
})
}
Expand Down Expand Up @@ -1612,17 +1604,8 @@ impl BindgenContext {
) -> Option<TypeId> {
use clang_sys;

let num_expected_args = match self.resolve_type(template)
.num_self_template_params(self) {
Some(n) => n,
None => {
warn!(
"Tried to instantiate a template for which we could not \
determine any template parameters"
);
return None;
}
};
let num_expected_args = self.resolve_type(template)
.num_self_template_params(self);

let mut args = vec![];
let mut found_const_arg = false;
Expand Down Expand Up @@ -2622,13 +2605,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 +2630,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