Support "never" return type

This commit is contained in:
mexus
2020-07-24 16:44:19 +03:00
committed by Emilio Cobos Álvarez
parent 9d7516ef1a
commit a94d6e2c9b
19 changed files with 204 additions and 1 deletions
+3
View File
@@ -317,6 +317,8 @@ pub struct FunctionConfig {
pub swift_name_macro: Option<String>,
/// Sort key for function names
pub sort_by: SortKey,
/// Optional text to output after functions which return `!`.
pub no_return: Option<String>,
}
impl Default for FunctionConfig {
@@ -329,6 +331,7 @@ impl Default for FunctionConfig {
rename_args: None,
swift_name_macro: None,
sort_by: SortKey::Name,
no_return: None,
}
}
}
+21 -1
View File
@@ -33,6 +33,7 @@ pub struct Function {
pub cfg: Option<Cfg>,
pub annotations: AnnotationSet,
pub documentation: Documentation,
pub never_return: bool,
}
impl Function {
@@ -46,10 +47,16 @@ impl Function {
) -> Result<Function, String> {
let mut args = sig.inputs.iter().try_skip_map(|x| x.as_ident_and_type())?;
let mut never_return = false;
let mut ret = match sig.output {
syn::ReturnType::Default => Type::Primitive(PrimitiveType::Void),
syn::ReturnType::Type(_, ref ty) => {
Type::load(ty)?.unwrap_or_else(|| Type::Primitive(PrimitiveType::Void))
if let syn::Type::Never(_) = ty.as_ref() {
never_return = true;
Type::Primitive(PrimitiveType::Void)
} else {
Type::load(ty)?.unwrap_or_else(|| Type::Primitive(PrimitiveType::Void))
}
}
};
@@ -69,6 +76,7 @@ impl Function {
cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
annotations: AnnotationSet::load(attrs)?,
documentation: Documentation::load(attrs),
never_return,
})
}
@@ -205,6 +213,12 @@ impl Source for Function {
write!(out, " {}({})", swift_name_macro, func.swift_name());
}
if func.never_return {
if let Some(ref no_return_attr) = config.function.no_return {
out.write_fmt(format_args!(" {}", no_return_attr));
}
}
out.write(";");
condition.write_after(config, out);
@@ -246,6 +260,12 @@ impl Source for Function {
write!(out, " {}({})", swift_name_macro, func.swift_name());
}
if func.never_return {
if let Some(ref no_return_attr) = config.function.no_return {
out.write_fmt(format_args!(" {}", no_return_attr));
}
}
out.write(";");
condition.write_after(config, out);
+2
View File
@@ -11,4 +11,6 @@ typedef struct Fns {
int8_t (*namedArgsWildcards)(int32_t _, int16_t named, int64_t _1);
} Fns;
void no_return(void);
void root(Fns _fns);
+2
View File
@@ -15,6 +15,8 @@ typedef struct Fns {
extern "C" {
#endif // __cplusplus
void no_return(void);
void root(Fns _fns);
#ifdef __cplusplus
@@ -0,0 +1,16 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
@@ -0,0 +1,24 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+2
View File
@@ -11,4 +11,6 @@ typedef struct {
int8_t (*namedArgsWildcards)(int32_t _, int16_t named, int64_t _1);
} Fns;
void no_return(void);
void root(Fns _fns);
+2
View File
@@ -15,6 +15,8 @@ typedef struct {
extern "C" {
#endif // __cplusplus
void no_return(void);
void root(Fns _fns);
#ifdef __cplusplus
+2
View File
@@ -13,6 +13,8 @@ struct Fns {
extern "C" {
void no_return();
void root(Fns _fns);
} // extern "C"
+16
View File
@@ -0,0 +1,16 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
@@ -0,0 +1,24 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+20
View File
@@ -0,0 +1,20 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <new>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
extern "C" {
void loop_forever() NO_RETURN_ATTR;
uint8_t normal_return();
} // extern "C"
+2
View File
@@ -11,4 +11,6 @@ struct Fns {
int8_t (*namedArgsWildcards)(int32_t _, int16_t named, int64_t _1);
};
void no_return(void);
void root(struct Fns _fns);
+2
View File
@@ -15,6 +15,8 @@ struct Fns {
extern "C" {
#endif // __cplusplus
void no_return(void);
void root(struct Fns _fns);
#ifdef __cplusplus
@@ -0,0 +1,16 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
@@ -0,0 +1,24 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void loop_forever(void) NO_RETURN_ATTR;
uint8_t normal_return(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
+5
View File
@@ -9,3 +9,8 @@ pub struct Fns {
#[no_mangle]
pub extern "C" fn root(_fns: Fns) {}
#[no_mangle]
pub extern "C" fn no_return() -> ! {
loop {}
}
+9
View File
@@ -0,0 +1,9 @@
#[no_mangle]
pub extern fn loop_forever() -> ! {
loop {}
}
#[no_mangle]
pub extern fn normal_return() -> u8 {
0
}
+12
View File
@@ -0,0 +1,12 @@
after_includes = """
#ifndef NO_RETURN_ATTR
#ifdef __GNUC__
#define NO_RETURN_ATTR __attribute__ ((noreturn))
#else // __GNUC__
#define NO_RETURN_ATTR
#endif // __GNUC__
#endif // NO_RETURN_ATTR
"""
[fn]
no_return = "NO_RETURN_ATTR"