Use assert for type checking

This commit is contained in:
lumi 2025-06-19 21:38:34 +10:00
parent 1c821d8804
commit 1ebeaa9e95
Signed by: luaneko
GPG Key ID: 406809B8763FF07A
4 changed files with 23 additions and 31 deletions

View File

@ -434,7 +434,7 @@ impl<'r, 'm> MetatypeMethodBuilder<'r, 'm> {
write!(self.prelude, "local __{name}_len = 0; ").unwrap();
write!(
self.prelude,
r#"if {name} ~= nil then assert(type({name}) == "string", "expected string in argument '{name}', got " .. type({name})); __{name}_len = #{name}; end; "#
r#"if {name} ~= nil then assert(type({name}) == "string", "string expected in argument '{name}', got " .. type({name})); __{name}_len = #{name}; end; "#
)
.unwrap();
self
@ -520,7 +520,7 @@ macro_rules! impl_copy_primitive {
type FromValue = $rtype;
fn prelude(arg: &str) -> impl Display {
display!(r#"assert(type({arg}) == "{0}", "expected {0} in argument '{arg}', got " .. type({arg})); "#, $ltype)
display!(r#"assert(type({arg}) == "{0}", "{0} expected in argument '{arg}', got " .. type({arg})); "#, $ltype)
}
fn convert(from: Self::From) -> Self {

View File

@ -24,7 +24,7 @@ unsafe impl FromFfi for *const [u8] {
let ct = lua_buf::name();
write!(
f,
r#"if {arg} ~= nil then assert(type({arg}) == "string", "expected string in argument '{arg}', got " .. type({arg})); "#
r#"if {arg} ~= nil then assert(type({arg}) == "string", "string expected in argument '{arg}', got " .. type({arg})); "#
)?;
write!(f, "{arg} = {ct}({arg}, #{arg}); end; ")
})
@ -55,7 +55,7 @@ unsafe impl FromFfi for &str {
let ct = lua_buf::name();
write!(
f,
r#"assert(type({arg}) == "string", "expected string in argument '{arg}', got " .. type({arg})); "#
r#"assert(type({arg}) == "string", "string expected in argument '{arg}', got " .. type({arg})); "#
)?;
write!(
f,

View File

@ -146,14 +146,14 @@ impl Visitor {
//
if let Expr::Cast(cast) = expr {
let arg = (*cast.expr).clone();
let mut init: Option<Stmt> = None;
let mut prelude: Option<Stmt> = None;
let ty: LuaType = (&*cast.ty).try_into()?;
let ty_str = format!("{ty}");
let (ident, msg) = match unwrap_expr_ident(&arg).ok() {
Some(ident) => (ident.clone(), format!("{ty} expected in '{ident}', got ")),
None => {
let ident = Ident::new("_", arg.span());
init = Some(parse_quote! { let #ident = #arg; });
prelude = Some(parse_quote! { let #ident = #arg; });
(ident, format!("{ty} expected, got "))
}
};
@ -163,40 +163,32 @@ impl Visitor {
*expr = match ty {
LuaType::Any => parse_quote_spanned!(span => {}),
LuaType::Nil => parse_quote_spanned!(span => {
#init
if #ident != () {
return error(concat!(#msg, r#type(#ident)));
}
#prelude
assert(#ident == (), concat!(#msg, r#type(#ident)));
}),
LuaType::Number => parse_quote_spanned!(span => {
#init
#prelude
let #tmp = #ident;
#ident = tonumber(#ident);
if #ident == () {
return error(concat!(#msg, r#type(#tmp)));
}
assert(#ident != (), concat!(#msg, r#type(#tmp)));
}),
LuaType::Integer => parse_quote_spanned!(span => {
#init
#prelude
let #tmp = #ident;
#ident = tonumber(#ident);
if #ident == () || math::floor(#ident) != #ident {
return error(concat!(#msg, r#type(#tmp)));
}
assert(#ident != () && math::floor(#ident) == #ident, concat!(#msg, r#type(#tmp)));
}),
LuaType::String => parse_quote_spanned!(span => {
#init
#prelude
if r#type(#ident) == "number" {
#ident = tostring(#ident);
} else if r#type(#ident) != "string" {
return error(concat!(#msg, r#type(#ident)));
} else {
assert(r#type(#ident) == "string", concat!(#msg, r#type(#ident)));
}
}),
_ => parse_quote_spanned!(span => {
#init
if r#type(#ident) != #ty_str {
return error(concat!(#msg, r#type(#ident)));
}
#prelude
assert(r#type(#ident) == #ty_str, concat!(#msg, r#type(#ident)));
}),
}
}

View File

@ -81,7 +81,7 @@ fn local_fn() {
fn check(self: string, arg: number) {}
inner
}),
r#"function()local function check(self,arg)do if type(self)=="number"then self=tostring(self);elseif type(self)~="string"then return error("string expected in \'self\', got "..type(self));end;end;do local _arg=arg;arg=tonumber(arg);if arg==nil then return error("number expected in \'arg\', got "..type(_arg));end;end;end;return inner;end"#
r#"function()local function check(self,arg)do if type(self)=="number"then self=tostring(self);else assert(type(self)=="string","string expected in \'self\', got "..type(self));end;end;do local _arg=arg;arg=tonumber(arg);assert(arg~=nil,"number expected in \'arg\', got "..type(_arg));end;end;return inner;end"#
);
}
@ -212,19 +212,19 @@ fn type_checks() {
assert_eq!(luaify!(|s| {}), r#"function(s)end"#);
assert_eq!(
luaify!(|s: table| {}),
r#"function(s)do if type(s)~="table"then return error("table expected in \'s\', got "..type(s));end;end;end"#
r#"function(s)do assert(type(s)=="table","table expected in \'s\', got "..type(s));end;end"#
);
assert_eq!(
luaify!(|s| { s as string }),
r#"function(s)do if type(s)=="number"then s=tostring(s);elseif type(s)~="string"then return error("string expected in \'s\', got "..type(s));end;end;end"#
r#"function(s)do if type(s)=="number"then s=tostring(s);else assert(type(s)=="string","string expected in \'s\', got "..type(s));end;end;end"#
);
assert_eq!(
luaify!(|s| { s as number }),
r#"function(s)do local _s=s;s=tonumber(s);if s==nil then return error("number expected in \'s\', got "..type(_s));end;end;end"#
r#"function(s)do local _s=s;s=tonumber(s);assert(s~=nil,"number expected in \'s\', got "..type(_s));end;end"#
);
assert_eq!(
luaify!(|s| { s as nil }),
r#"function(s)do if s~=nil then return error("nil expected in \'s\', got "..type(s));end;end;end"#
r#"function(s)do assert(s==nil,"nil expected in \'s\', got "..type(s));end;end"#
);
assert_eq!(luaify!(|s| { s as any }), r#"function(s)do end;end"#);
@ -234,7 +234,7 @@ fn type_checks() {
ok as boolean;
res as nil;
}),
r#"function(s)local ok,res=coroutine.yield(thread);do if type(ok)~="boolean"then return error("boolean expected in \'ok\', got "..type(ok));end;end;do if res~=nil then return error("nil expected in \'res\', got "..type(res));end;end;end"#
r#"function(s)local ok,res=coroutine.yield(thread);do assert(type(ok)=="boolean","boolean expected in \'ok\', got "..type(ok));end;do assert(res==nil,"nil expected in \'res\', got "..type(res));end;end"#
);
}