Skip to content

Commit 6c1d336

Browse files
committed
mlua_derive: Strip raw-identifier prefix from Lua names
1 parent 529f818 commit 6c1d336

4 files changed

Lines changed: 23 additions & 5 deletions

File tree

mlua_derive/src/from_lua.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use proc_macro::TokenStream;
22
use quote::quote;
3+
use syn::ext::IdentExt;
34
use syn::{DeriveInput, parse_macro_input, parse_quote};
45

56
pub fn from_lua(input: TokenStream) -> TokenStream {
67
let DeriveInput {
78
ident, mut generics, ..
89
} = parse_macro_input!(input as DeriveInput);
910

10-
let ident_str = ident.to_string();
11+
let ident_str = ident.unraw().to_string();
1112
generics
1213
.make_where_clause()
1314
.predicates

mlua_derive/src/userdata/attr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use proc_macro2::Span;
2+
use syn::ext::IdentExt;
23
use syn::meta::ParseNestedMeta;
34
use syn::{Ident, LitStr, Result};
45

@@ -63,7 +64,7 @@ impl LuaAttr {
6364

6465
/// Returns the effective Lua name.
6566
pub(crate) fn name(&self, ident: &Ident) -> String {
66-
self.name.clone().unwrap_or_else(|| ident.to_string())
67+
self.name.clone().unwrap_or_else(|| ident.unraw().to_string())
6768
}
6869

6970
/// Returns the span to use for error reporting.
@@ -79,7 +80,7 @@ impl LuaAttr {
7980
if let Some(ref name) = self.name {
8081
return Ok(name.clone());
8182
}
82-
let fn_name = fn_ident.to_string();
83+
let fn_name = fn_ident.unraw().to_string();
8384
if fn_name.starts_with("__") {
8485
return Ok(fn_name);
8586
}

mlua_derive/src/userdata/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub(crate) mod userdata_impl;
33

44
use proc_macro::TokenStream;
55
use quote::{format_ident, quote};
6+
use syn::ext::IdentExt;
67
use syn::spanned::Spanned;
78
use syn::{Attribute, Data, DeriveInput, Error, Fields, FieldsNamed, Meta, parse_macro_input};
89

@@ -103,7 +104,7 @@ pub fn userdata_type(item: TokenStream) -> TokenStream {
103104
continue;
104105
}
105106

106-
let lua_name = lua_attr.name.unwrap_or_else(|| field_name.to_string());
107+
let lua_name = lua_attr.name.unwrap_or_else(|| field_name.unraw().to_string());
107108

108109
// Assume get/set by default (unless explicitly specified)
109110
let (has_get, has_set) = if lua_attr.get || lua_attr.set {

tests/userdata_macro.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,13 +474,14 @@ fn test_static_metamethods() {
474474
#[derive(Clone, Debug, UserData)]
475475
struct Hygiene {
476476
value: i32,
477+
r#type: i32,
477478
}
478479

479480
#[mlua::userdata_impl]
480481
impl Hygiene {
481482
#[lua(infallible)]
482483
fn new(value: i32) -> Self {
483-
Hygiene { value }
484+
Hygiene { value, r#type: 7 }
484485
}
485486

486487
// `this` must not clash with the generated receiver binding.
@@ -494,6 +495,11 @@ impl Hygiene {
494495
fn add_lua(&self, lua: i32) -> i32 {
495496
self.value + lua
496497
}
498+
499+
#[lua(infallible)]
500+
fn r#double_type(&self) -> i32 {
501+
self.r#type * 2
502+
}
497503
}
498504

499505
#[test]
@@ -505,8 +511,17 @@ fn test_param_name_hygiene() {
505511
lua.load(
506512
r#"
507513
local h = Hygiene.new(10)
514+
515+
-- reserved parameter names must not clash with generated bindings
508516
assert(h:add_this(5) == 15, "add_this should be 10 + 5 = 15")
509517
assert(h:add_lua(3) == 13, "add_lua should be 10 + 3 = 13")
518+
519+
-- the `r#` prefix must not leak into Lua names
520+
assert(h.type == 7, "field r#type should be exposed as 'type'")
521+
h.type = 10
522+
assert(h.type == 10, "field r#type setter should update via 'type'")
523+
assert(h:double_type() == 20, "method r#double_type should be callable as 'double_type'")
524+
assert(h["r#type"] == nil, "the raw prefix must not leak into the Lua name")
510525
"#,
511526
)
512527
.exec()

0 commit comments

Comments
 (0)