msg_socket_on_derive: use fully qualified types

The types from msg_socket were assumed to be in scope for the custom
derive implementation, which would cause mysterious compiler errors if
the custom derive was invoked in a module without msg_socket types in
scope.

This CL uses fully qualified types in the generated output to avoid
these errors.

This change also uses `extern crate msg_socket` in case the call site
doesn't have it in scope.

BUG=None
TEST=cargo test -p msg_on_socket_derive

Change-Id: Ie6443cd4ffc070d27e71de123090a58f19846472
Reviewed-on: https://chromium-review.googlesource.com/1314208
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Jingkui Wang <jkwang@google.com>
This commit is contained in:
Zach Reizner 2018-11-01 18:15:16 -07:00 committed by chrome-bot
parent 60f55da937
commit 3c71bb953e
5 changed files with 174 additions and 135 deletions

View file

@ -22,7 +22,23 @@ use syn::{Data, DataEnum, DataStruct, DeriveInput, Fields, Ident};
/// The function that derives the recursive implementation for struct or enum.
#[proc_macro_derive(MsgOnSocket)]
pub fn msg_on_socket_derive(input: TokenStream) -> TokenStream {
socket_msg_impl(syn::parse(input).unwrap()).into()
let ast: DeriveInput = syn::parse(input).unwrap();
let const_namespace = Ident::new(
&format!("__MSG_ON_SOCKET_IMPL_{}", ast.ident),
Span::call_site(),
);
let impl_for_input = socket_msg_impl(ast);
let wrapped_impl = quote! {
const #const_namespace: () = {
extern crate msg_socket as _msg_socket;
#impl_for_input
};
};
wrapped_impl.into()
}
fn socket_msg_impl(ast: DeriveInput) -> Tokens {
@ -62,7 +78,7 @@ fn impl_for_named_struct(name: Ident, ds: DataStruct) -> Tokens {
let read_buffer = define_read_buffer_for_struct(&name, &fields);
let write_buffer = define_write_buffer_for_struct(&name, &fields);
quote!(
impl MsgOnSocket for #name {
impl _msg_socket::MsgOnSocket for #name {
#buffer_sizes_impls
#read_buffer
#write_buffer
@ -121,8 +137,8 @@ fn define_read_buffer_for_struct(_name: &Ident, fields: &[(Ident, syn::Type)]) -
init_fields.push(quote!( #name ));
}
quote!{
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd])
-> MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<(Self, usize)> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
#(#read_fields)*
@ -143,8 +159,8 @@ fn define_write_buffer_for_struct(_name: &Ident, fields: &[(Ident, syn::Type)])
write_fields.push(write_field);
}
quote!{
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd])
-> MsgResult<usize> {
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
#(#write_fields)*
@ -161,7 +177,7 @@ fn impl_for_enum(name: Ident, de: DataEnum) -> Tokens {
let read_buffer = define_read_buffer_for_enum(&name, &de);
let write_buffer = define_write_buffer_for_enum(&name, &de);
quote!(
impl MsgOnSocket for #name {
impl _msg_socket::MsgOnSocket for #name {
#buffer_sizes_impls
#read_buffer
#write_buffer
@ -278,13 +294,13 @@ fn define_read_buffer_for_enum(name: &Ident, de: &DataEnum) -> Tokens {
i += 1;
}
quote!(
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd])
-> MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<(Self, usize)> {
let v = buffer[0];
match v {
#(#match_variants)*
_ => {
Err(MsgError::InvalidType)
Err(_msg_socket::MsgError::InvalidType)
}
}
}
@ -356,7 +372,8 @@ fn define_write_buffer_for_enum(name: &Ident, de: &DataEnum) -> Tokens {
}
quote!(
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd]) -> MsgResult<usize> {
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
match self {
#(#match_variants)*
}
@ -381,7 +398,7 @@ fn impl_for_tuple_struct(name: Ident, ds: DataStruct) -> Tokens {
let read_buffer = define_read_buffer_for_tuples(&name, &types);
let write_buffer = define_write_buffer_for_tuples(&name, &types);
quote!(
impl MsgOnSocket for #name {
impl _msg_socket::MsgOnSocket for #name {
#buffer_sizes_impls
#read_buffer
#write_buffer
@ -416,8 +433,8 @@ fn define_read_buffer_for_tuples(name: &Ident, fields: &[syn::Type]) -> Tokens {
}
quote!{
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd])
-> MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<(Self, usize)> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
#(#read_fields)*
@ -442,8 +459,8 @@ fn define_write_buffer_for_tuples(name: &Ident, fields: &[syn::Type]) -> Tokens
tmp_names.push(tmp_name);
}
quote!{
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd])
-> MsgResult<usize> {
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
let #name( #(#tmp_names),* ) = self;
@ -487,7 +504,8 @@ fn write_to_buffer_and_move_offset(name: &Ident, ty: &syn::Type) -> Tokens {
#[cfg(test)]
mod tests {
use super::*;
use syn::DeriveInput;
use socket_msg_impl;
#[test]
fn end_to_end_struct_test() {
@ -500,7 +518,7 @@ mod tests {
};
let expected = quote! {
impl MsgOnSocket for MyMsg {
impl _msg_socket::MsgOnSocket for MyMsg {
fn msg_size() -> usize {
<u8>::msg_size() as usize
+ <RawFd>::msg_size() as usize
@ -511,8 +529,8 @@ mod tests {
+ <RawFd>::max_fd_count() as usize
+ <u32>::max_fd_count() as usize
}
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd])
-> MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<(Self, usize)> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
let t = <u8>::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?;
@ -529,8 +547,8 @@ mod tests {
let c = t.0;
Ok((Self { a, b, c }, __fd_offset))
}
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd])
-> MsgResult<usize> {
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
let o = self.a.write_to_buffer(&mut buffer[__offset..],
@ -560,7 +578,7 @@ mod tests {
};
let expected = quote! {
impl MsgOnSocket for MyMsg {
impl _msg_socket::MsgOnSocket for MyMsg {
fn msg_size() -> usize {
<u8>::msg_size() as usize +
<u32>::msg_size() as usize + <File>::msg_size() as usize
@ -570,8 +588,8 @@ mod tests {
+ <u32>::max_fd_count() as usize
+ <File>::max_fd_count() as usize
}
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd])
-> MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<(Self, usize)> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
let t = <u8>::read_from_buffer(&buffer[__offset..], &fds[__fd_offset..])?;
@ -588,8 +606,8 @@ mod tests {
let tuple_tmp2 = t.0;
Ok((MyMsg(tuple_tmp0, tuple_tmp1, tuple_tmp2), __fd_offset))
}
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd])
-> MsgResult<usize> {
fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
let mut __offset = 0usize;
let mut __fd_offset = 0usize;
let MyMsg(tuple_tmp0, tuple_tmp1, tuple_tmp2) = self;
@ -624,7 +642,7 @@ mod tests {
};
let expected = quote! {
impl MsgOnSocket for MyMsg {
impl _msg_socket::MsgOnSocket for MyMsg {
fn msg_size() -> usize {
[
<u8>::msg_size() as usize,
@ -641,8 +659,8 @@ mod tests {
].iter()
.max().unwrap().clone() as usize
}
unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd]) ->
MsgResult<(Self, usize)> {
unsafe fn read_from_buffer(buffer: &[u8], fds: &[std::os::unix::io::RawFd]) ->
_msg_socket::MsgResult<(Self, usize)> {
let v = buffer[0];
match v {
0u8 => {
@ -672,13 +690,14 @@ mod tests {
Ok((MyMsg::C{f0, f1}, __fd_offset))
}
_ => {
Err(MsgError::InvalidType)
Err(_msg_socket::MsgError::InvalidType)
}
}
}
fn write_to_buffer(&self,
buffer: &mut [u8],
fds: &mut [RawFd]) -> MsgResult<usize> {
fds: &mut [std::os::unix::io::RawFd])
-> _msg_socket::MsgResult<usize> {
match self {
MyMsg::A(enum_variant_tmp0) => {
buffer[0] = 0u8;

View file

@ -199,106 +199,3 @@ impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for UnlinkMsgSocket<I, O> {}
impl<M: MsgOnSocket> MsgSender<M> for Sender<M> {}
impl<M: MsgOnSocket> MsgReceiver<M> for Receiver<M> {}
#[cfg(test)]
mod tests {
use super::*;
use sys_util::EventFd;
#[derive(MsgOnSocket)]
struct Request {
field0: u8,
field1: EventFd,
field2: u32,
}
#[derive(MsgOnSocket)]
enum Response {
A(u8),
B,
C(u32, EventFd),
D([u8; 4]),
E { f0: u8, f1: u32 },
}
#[derive(MsgOnSocket)]
struct Message(u8, u16, EventFd);
#[test]
fn sock_send_recv_struct() {
let (req, res) = pair::<Request, Response>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
req.send(&Request {
field0: 2,
field1: e0,
field2: 0xf0f0,
}).unwrap();
let r = res.recv().unwrap();
assert_eq!(r.field0, 2);
assert_eq!(r.field2, 0xf0f0);
r.field1.write(0x0f0f).unwrap();
assert_eq!(e1.read().unwrap(), 0x0f0f);
}
#[test]
fn sock_send_recv_enum() {
let (req, res) = pair::<Request, Response>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
res.send(&Response::C(0xf0f0, e0)).unwrap();
let r = req.recv().unwrap();
match r {
Response::C(v, efd) => {
assert_eq!(v, 0xf0f0);
efd.write(0x0f0f).unwrap();
}
_ => panic!("wrong type"),
};
assert_eq!(e1.read().unwrap(), 0x0f0f);
res.send(&Response::B).unwrap();
match req.recv().unwrap() {
Response::B => {}
_ => panic!("Wrong enum type"),
};
res.send(&Response::A(0x3)).unwrap();
match req.recv().unwrap() {
Response::A(v) => assert_eq!(v, 0x3),
_ => panic!("Wrong enum type"),
};
res.send(&Response::D([0, 1, 2, 3])).unwrap();
match req.recv().unwrap() {
Response::D(v) => assert_eq!(v, [0, 1, 2, 3]),
_ => panic!("Wrong enum type"),
};
res.send(&Response::E {
f0: 0x12,
f1: 0x0f0f,
}).unwrap();
match req.recv().unwrap() {
Response::E { f0, f1 } => {
assert_eq!(f0, 0x12);
assert_eq!(f1, 0x0f0f);
}
_ => panic!("Wrong enum type"),
};
}
#[test]
fn sock_send_recv_tuple() {
let (req, res) = pair::<Message, Message>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
req.send(&Message(1, 0x12, e0)).unwrap();
let r = res.recv().unwrap();
assert_eq!(r.0, 1);
assert_eq!(r.1, 0x12);
r.2.write(0x0f0f).unwrap();
assert_eq!(e1.read().unwrap(), 0x0f0f);
}
}

66
msg_socket/tests/enum.rs Normal file
View file

@ -0,0 +1,66 @@
extern crate msg_on_socket_derive;
extern crate msg_socket;
extern crate sys_util;
use sys_util::EventFd;
use msg_socket::*;
#[derive(MsgOnSocket)]
struct DummyRequest {}
#[derive(MsgOnSocket)]
enum Response {
A(u8),
B,
C(u32, EventFd),
D([u8; 4]),
E { f0: u8, f1: u32 },
}
#[test]
fn sock_send_recv_enum() {
let (req, res) = pair::<DummyRequest, Response>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
res.send(&Response::C(0xf0f0, e0)).unwrap();
let r = req.recv().unwrap();
match r {
Response::C(v, efd) => {
assert_eq!(v, 0xf0f0);
efd.write(0x0f0f).unwrap();
}
_ => panic!("wrong type"),
};
assert_eq!(e1.read().unwrap(), 0x0f0f);
res.send(&Response::B).unwrap();
match req.recv().unwrap() {
Response::B => {}
_ => panic!("Wrong enum type"),
};
res.send(&Response::A(0x3)).unwrap();
match req.recv().unwrap() {
Response::A(v) => assert_eq!(v, 0x3),
_ => panic!("Wrong enum type"),
};
res.send(&Response::D([0, 1, 2, 3])).unwrap();
match req.recv().unwrap() {
Response::D(v) => assert_eq!(v, [0, 1, 2, 3]),
_ => panic!("Wrong enum type"),
};
res.send(&Response::E {
f0: 0x12,
f1: 0x0f0f,
}).unwrap();
match req.recv().unwrap() {
Response::E { f0, f1 } => {
assert_eq!(f0, 0x12);
assert_eq!(f1, 0x0f0f);
}
_ => panic!("Wrong enum type"),
};
}

View file

@ -0,0 +1,34 @@
extern crate msg_on_socket_derive;
extern crate msg_socket;
extern crate sys_util;
use sys_util::EventFd;
use msg_socket::*;
#[derive(MsgOnSocket)]
struct Request {
field0: u8,
field1: EventFd,
field2: u32,
}
#[derive(MsgOnSocket)]
struct DummyResponse {}
#[test]
fn sock_send_recv_struct() {
let (req, res) = pair::<Request, DummyResponse>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
req.send(&Request {
field0: 2,
field1: e0,
field2: 0xf0f0,
}).unwrap();
let r = res.recv().unwrap();
assert_eq!(r.field0, 2);
assert_eq!(r.field2, 0xf0f0);
r.field1.write(0x0f0f).unwrap();
assert_eq!(e1.read().unwrap(), 0x0f0f);
}

23
msg_socket/tests/tuple.rs Normal file
View file

@ -0,0 +1,23 @@
extern crate msg_on_socket_derive;
extern crate msg_socket;
extern crate sys_util;
use sys_util::EventFd;
use msg_socket::*;
#[derive(MsgOnSocket)]
struct Message(u8, u16, EventFd);
#[test]
fn sock_send_recv_tuple() {
let (req, res) = pair::<Message, Message>().unwrap();
let e0 = EventFd::new().unwrap();
let e1 = e0.try_clone().unwrap();
req.send(&Message(1, 0x12, e0)).unwrap();
let r = res.recv().unwrap();
assert_eq!(r.0, 1);
assert_eq!(r.1, 0x12);
r.2.write(0x0f0f).unwrap();
assert_eq!(e1.read().unwrap(), 0x0f0f);
}