Allow Vec as well as slice

This commit is contained in:
Richard Dodd 2018-08-21 13:47:00 +01:00
parent 496d8cadd8
commit e92536f300
2 changed files with 37 additions and 4 deletions

View File

@ -1111,14 +1111,47 @@ fn assert_last_param_is_slice(decl: &syn::FnDecl) -> Result<(), Diagnostic> {
#[inline]
fn not_slice_error(tok: &dyn ToTokens) -> Diagnostic {
Diagnostic::span_error(tok, "for variadic extern functions, the last argument must be a \
slice, to hold the arguments of unknown length")
slice or `::std::vec::Vec`, to hold the arguments of unknown length")
}
let arg = decl.inputs.last().ok_or_else(|| not_slice_error(&decl))?;
/// Is this path `::std::vec::Vec`.
///
/// I could add `Vec`, but this would break in wierd ways if the user does
/// `use SomethingElse as Vec;`.
#[inline]
fn path_is_vec(path: &syn::Path) -> bool {
#[inline]
fn is_path_segment(path: Option<&syn::PathSegment>,
name: Option<&str>,
plain: bool) -> bool {
match (path, name) {
(Some(ref path), Some(ref name)) =>
(path.arguments.is_empty() || ! plain) && path.ident == name,
(None, None) => true,
_ => false
}
}
let mut iter = (&path.segments).into_iter();
path.leading_colon.is_some()
&& is_path_segment(iter.next(), Some("std"), true)
&& is_path_segment(iter.next(), Some("vec"), true)
&& is_path_segment(iter.next(), Some("Vec"), false)
&& is_path_segment(iter.next(), None, true)
}
let arg = decl.inputs.last().ok_or_else(|| not_slice_error(&decl.inputs))?;
if let syn::FnArg::Captured(ref arg_cap) = arg.value() {
// check for slice reference
if let syn::Type::Reference(ref ref_ty) = arg_cap.ty {
if let syn::Type::Slice(_) = *ref_ty.elem {
return Ok(())
return Ok(());
}
}
// check for `Vec`
if let syn::Type::Path(ref path) = arg_cap.ty {
if path_is_vec(&path.path) {
return Ok(());
}
}
}

View File

@ -32,7 +32,7 @@ extern {
#[wasm_bindgen(variadic)]
fn variadic_concat_str(first: &str, second: &str, rest: &[&str]) -> String;
#[wasm_bindgen(variadic)]
fn variadic_concat_string(first: String, second: String, rest: Vec<String>) -> String;
fn variadic_concat_string(first: String, second: String, rest: ::std::vec::Vec<String>) -> String;
}
// ints