Support defining C compatible variadic functions

Add support for defining C compatible variadic functions in unsafe rust
with extern "C".
This commit is contained in:
Dan Robertson 2018-11-30 15:53:44 +00:00
parent cd56472cc4
commit 58147d486b
No known key found for this signature in database
GPG key ID: 4DE6EEF84B5C9783
48 changed files with 848 additions and 152 deletions

View file

@ -1752,7 +1752,6 @@ impl Clean<Item> for doctree::Function {
pub struct FnDecl {
pub inputs: Arguments,
pub output: FunctionRetTy,
pub variadic: bool,
pub attrs: Attributes,
}
@ -1831,7 +1830,6 @@ impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A)
FnDecl {
inputs: (&self.0.inputs[..], self.1).clean(cx),
output: self.0.output.clean(cx),
variadic: self.0.variadic,
attrs: Attributes::default()
}
}
@ -1849,7 +1847,6 @@ impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
FnDecl {
output: Return(sig.skip_binder().output().clean(cx)),
attrs: Attributes::default(),
variadic: sig.skip_binder().variadic,
inputs: Arguments {
values: sig.skip_binder().inputs().iter().map(|t| {
Argument {
@ -2252,6 +2249,7 @@ pub enum Type {
Slice(Box<Type>),
Array(Box<Type>, String),
Never,
CVarArgs,
Unique(Box<Type>),
RawPointer(Mutability, Box<Type>),
BorrowedRef {
@ -2290,6 +2288,7 @@ pub enum PrimitiveType {
Reference,
Fn,
Never,
CVarArgs,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
@ -2469,6 +2468,7 @@ impl PrimitiveType {
Reference => "reference",
Fn => "fn",
Never => "never",
CVarArgs => "...",
}
}
@ -2518,6 +2518,7 @@ impl Clean<Type> for hir::Ty {
match self.node {
TyKind::Never => Never,
TyKind::CVarArgs(_) => CVarArgs,
TyKind::Ptr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)),
TyKind::Rptr(ref l, ref m) => {
let lifetime = if l.is_elided() {
@ -3654,6 +3655,7 @@ fn build_deref_target_impls(cx: &DocContext<'_, '_, '_>,
Reference => None,
Fn => None,
Never => None,
CVarArgs => tcx.lang_items().va_list(),
};
if let Some(did) = did {
if !did.is_local() {

View file

@ -609,6 +609,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
primitive_link(f, PrimitiveType::Array, &format!("; {}]", n))
}
clean::Never => primitive_link(f, PrimitiveType::Never, "!"),
clean::CVarArgs => primitive_link(f, PrimitiveType::CVarArgs, "..."),
clean::RawPointer(m, ref t) => {
match **t {
clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
@ -834,18 +835,10 @@ impl fmt::Display for clean::FunctionRetTy {
impl fmt::Display for clean::FnDecl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.variadic {
if f.alternate() {
write!(f, "({args:#}, ...){arrow:#}", args = self.inputs, arrow = self.output)
} else {
write!(f, "({args}, ...){arrow}", args = self.inputs, arrow = self.output)
}
if f.alternate() {
write!(f, "({args:#}){arrow:#}", args = self.inputs, arrow = self.output)
} else {
if f.alternate() {
write!(f, "({args:#}){arrow:#}", args = self.inputs, arrow = self.output)
} else {
write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
}
write!(f, "({args}){arrow}", args = self.inputs, arrow = self.output)
}
}
}
@ -907,12 +900,7 @@ impl<'a> fmt::Display for Function<'a> {
}
}
let mut args_plain = format!("({})", args_plain);
if decl.variadic {
args.push_str(",<br> ...");
args_plain.push_str(", ...");
}
let args_plain = format!("({})", args_plain);
let output = if let hir::IsAsync::Async = asyncness {
Cow::Owned(decl.sugared_async_return_type())