Skip to content

Commit cb87f98

Browse files
authored
Remove unnecessary casts to raw pointers (#134)
The references automatically coerce to raw pointers. This also improves the signal-to-noise ratio on the `as` keyword, which is often an antipattern (e.g. for many numeric casts).
1 parent 4b2b023 commit cb87f98

File tree

7 files changed

+77
-61
lines changed

7 files changed

+77
-61
lines changed

rclrs/build.rs

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,23 @@ use std::fs::read_dir;
33
use std::path::{Path, PathBuf};
44

55
const AMENT_PREFIX_PATH: &str = "AMENT_PREFIX_PATH";
6+
const ROS_DISTRO: &str = "ROS_DISTRO";
7+
8+
fn get_env_var_or_abort(env_var: &'static str) -> String {
9+
if let Ok(value) = env::var(env_var) {
10+
value
11+
} else {
12+
panic!(
13+
"{} environment variable not set - please source ROS 2 installation first.",
14+
env_var
15+
);
16+
}
17+
}
618

719
fn main() {
20+
let ros_distro = get_env_var_or_abort(ROS_DISTRO);
21+
println!("cargo:rustc-cfg=ros_distro=\"{ros_distro}\"");
22+
823
let mut builder = bindgen::Builder::default()
924
.header("src/rcl_wrapper.h")
1025
.derive_copy(false)
@@ -39,47 +54,41 @@ fn main() {
3954
//
4055
// See REP 122 for more details: https://www.ros.org/reps/rep-0122.html#filesystem-layout
4156

42-
if let Ok(ament_prefix_paths) = env::var(AMENT_PREFIX_PATH) {
43-
for ament_prefix_path in ament_prefix_paths.split(':').map(Path::new) {
44-
// Locate the ament index
45-
let ament_index = ament_prefix_path.join("share/ament_index/resource_index/packages");
46-
if !ament_index.is_dir() {
47-
continue;
48-
}
57+
let ament_prefix_paths = get_env_var_or_abort(AMENT_PREFIX_PATH);
58+
for ament_prefix_path in ament_prefix_paths.split(':').map(Path::new) {
59+
// Locate the ament index
60+
let ament_index = ament_prefix_path.join("share/ament_index/resource_index/packages");
61+
if !ament_index.is_dir() {
62+
continue;
63+
}
4964

50-
// Old-style include directory
51-
let include_dir = ament_prefix_path.join("include");
65+
// Old-style include directory
66+
let include_dir = ament_prefix_path.join("include");
5267

53-
// Including the old-style packages
54-
builder = builder.clang_arg(format!("-isystem{}", include_dir.display()));
68+
// Including the old-style packages
69+
builder = builder.clang_arg(format!("-isystem{}", include_dir.display()));
5570

56-
// Search for and include new-style-converted package paths
57-
for dir_entry in read_dir(&ament_index).unwrap().filter_map(|p| p.ok()) {
58-
let package = dir_entry.file_name();
59-
let package_include_dir = include_dir.join(&package);
71+
// Search for and include new-style-converted package paths
72+
for dir_entry in read_dir(&ament_index).unwrap().filter_map(|p| p.ok()) {
73+
let package = dir_entry.file_name();
74+
let package_include_dir = include_dir.join(&package);
6075

61-
if package_include_dir.is_dir() {
62-
let new_style_include_dir = package_include_dir.join(&package);
76+
if package_include_dir.is_dir() {
77+
let new_style_include_dir = package_include_dir.join(&package);
6378

64-
// CycloneDDS is a special case - it needs to be included as if it were a new-style path, but
65-
// doesn't actually have a secondary folder within it called "CycloneDDS"
66-
// TODO(jhdcs): if this changes in future, remove this check
67-
if package == "CycloneDDS" || new_style_include_dir.is_dir() {
68-
builder =
69-
builder.clang_arg(format!("-isystem{}", package_include_dir.display()));
70-
}
79+
// CycloneDDS is a special case - it needs to be included as if it were a new-style path, but
80+
// doesn't actually have a secondary folder within it called "CycloneDDS"
81+
// TODO(jhdcs): if this changes in future, remove this check
82+
if package == "CycloneDDS" || new_style_include_dir.is_dir() {
83+
builder =
84+
builder.clang_arg(format!("-isystem{}", package_include_dir.display()));
7185
}
7286
}
73-
74-
// Link the native libraries
75-
let library_path = ament_prefix_path.join("lib");
76-
println!("cargo:rustc-link-search=native={}", library_path.display());
7787
}
78-
} else {
79-
panic!(
80-
"{} environment variable not set - please source ROS 2 installation first.",
81-
AMENT_PREFIX_PATH
82-
);
88+
89+
// Link the native libraries
90+
let library_path = ament_prefix_path.join("lib");
91+
println!("cargo:rustc-link-search=native={}", library_path.display());
8392
}
8493

8594
println!("cargo:rustc-link-lib=dylib=rcl");

rclrs/src/context.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ impl Drop for rcl_context_t {
1313
fn drop(&mut self) {
1414
// SAFETY: These functions have no preconditions besides a valid/initialized handle
1515
unsafe {
16-
rcl_shutdown(self as *mut _);
17-
rcl_context_fini(self as *mut _);
16+
rcl_shutdown(self);
17+
rcl_context_fini(self);
1818
}
1919
}
2020
}
@@ -74,7 +74,7 @@ impl Context {
7474
let mut init_options = rcl_get_zero_initialized_init_options();
7575
// SAFETY: Passing in a zero-initialized value is expected.
7676
// In the case where this returns not ok, there's nothing to clean up.
77-
rcl_init_options_init(&mut init_options as *mut _, allocator).ok()?;
77+
rcl_init_options_init(&mut init_options, allocator).ok()?;
7878
// SAFETY: This function does not store the ephemeral init_options and c_args
7979
// pointers. Passing in a zero-initialized handle is expected.
8080
let ret = rcl_init(
@@ -84,12 +84,12 @@ impl Context {
8484
} else {
8585
c_args.as_ptr()
8686
},
87-
&init_options as *const _,
88-
handle as *mut _,
87+
&init_options,
88+
handle,
8989
);
9090
// SAFETY: It's safe to pass in an initialized object.
9191
// Early return will not leak memory, because this is the last fini function.
92-
rcl_init_options_fini(&mut init_options as *mut _).ok()?;
92+
rcl_init_options_fini(&mut init_options).ok()?;
9393
// Move the check after the last fini()
9494
ret.ok()?;
9595
}
@@ -144,6 +144,6 @@ impl Context {
144144
// handler could call `rcl_shutdown()`, hence making the context invalid.
145145
let handle = &mut *self.handle.lock();
146146
// SAFETY: No preconditions for this function.
147-
unsafe { rcl_context_is_valid(handle as *mut _) }
147+
unsafe { rcl_context_is_valid(handle) }
148148
}
149149
}

rclrs/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,15 @@ pub fn spin_once(node: &Node, timeout: Option<Duration>) -> Result<(), RclReturn
5454
///
5555
/// This function additionally checks that the context is still valid.
5656
pub fn spin(node: &Node) -> Result<(), RclReturnCode> {
57+
// The context_is_valid functions exists only to abstract away ROS distro differences
58+
#[cfg(ros_distro = "foxy")]
5759
// SAFETY: No preconditions for this function.
58-
while unsafe { rcl_context_is_valid(&mut *node.context.lock() as *mut _) } {
60+
let context_is_valid = || unsafe { rcl_context_is_valid(&mut *node.context.lock()) };
61+
#[cfg(not(ros_distro = "foxy"))]
62+
// SAFETY: No preconditions for this function.
63+
let context_is_valid = || unsafe { rcl_context_is_valid(&*node.context.lock()) };
64+
65+
while context_is_valid() {
5966
if let Some(error) = spin_once(node, None).err() {
6067
match error {
6168
RclReturnCode::Timeout => continue,

rclrs/src/node/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rosidl_runtime_rs::Message;
2020
impl Drop for rcl_node_t {
2121
fn drop(&mut self) {
2222
// SAFETY: No preconditions for this function
23-
unsafe { rcl_node_fini(self as *mut _).unwrap() };
23+
unsafe { rcl_node_fini(self).unwrap() };
2424
}
2525
}
2626

@@ -71,11 +71,11 @@ impl Node {
7171
// to keep them alive.
7272
// The context handle is kept alive because it is co-owned by the node.
7373
rcl_node_init(
74-
&mut node_handle as *mut _,
74+
&mut node_handle,
7575
raw_node_name.as_ptr(),
7676
raw_node_ns.as_ptr(),
77-
context_handle as *mut _,
78-
&node_options as *const _,
77+
context_handle,
78+
&node_options,
7979
)
8080
.ok()?;
8181
}

rclrs/src/node/publisher.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ where
8181
// afterwards.
8282
// TODO: type support?
8383
rcl_publisher_init(
84-
&mut publisher_handle as *mut _,
85-
node_handle as *mut _,
84+
&mut publisher_handle,
85+
node_handle,
8686
type_support,
8787
topic_c_string.as_ptr(),
88-
&publisher_options as *const _,
88+
&publisher_options,
8989
)
9090
.ok()?;
9191
}
@@ -125,7 +125,7 @@ where
125125
// The message does not need to be valid beyond the duration of this function call.
126126
// The third argument is explictly allowed to be NULL.
127127
rcl_publish(
128-
handle as *mut _,
128+
handle,
129129
rmw_message.as_ref() as *const <T as Message>::RmwMsg as *mut _,
130130
std::ptr::null_mut(),
131131
)

rclrs/src/node/subscription.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl Drop for SubscriptionHandle {
3131
let node_handle = &mut *self.node_handle.lock();
3232
// SAFETY: No preconditions for this function (besides the arguments being valid).
3333
unsafe {
34-
rcl_subscription_fini(handle as *mut _, node_handle as *mut _);
34+
rcl_subscription_fini(handle, node_handle);
3535
}
3636
}
3737
}
@@ -100,11 +100,11 @@ where
100100
// afterwards.
101101
// TODO: type support?
102102
rcl_subscription_init(
103-
&mut subscription_handle as *mut _,
104-
node_handle as *mut _,
103+
&mut subscription_handle,
104+
node_handle,
105105
type_support,
106106
topic_c_string.as_ptr(),
107-
&subscription_options as *const _,
107+
&subscription_options,
108108
)
109109
.ok()?;
110110
}
@@ -152,7 +152,7 @@ where
152152
// beyond the function call.
153153
// The latter two pointers are explicitly allowed to be NULL.
154154
rcl_take(
155-
handle as *const _,
155+
handle,
156156
&mut rmw_message as *mut <T as Message>::RmwMsg as *mut _,
157157
std::ptr::null_mut(),
158158
std::ptr::null_mut(),

rclrs/src/wait.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct ReadyEntities {
4545
impl Drop for rcl_wait_set_t {
4646
fn drop(&mut self) {
4747
// SAFETY: No preconditions for this function (besides passing in a valid wait set).
48-
let rc = unsafe { rcl_wait_set_fini(self as *mut _) };
48+
let rc = unsafe { rcl_wait_set_fini(self) };
4949
if let Err(e) = to_rcl_result(rc) {
5050
panic!("Unable to release WaitSet. {:?}", e)
5151
}
@@ -64,14 +64,14 @@ impl WaitSet {
6464
// SAFETY: We're passing in a zero-initialized wait set and a valid context.
6565
// There are no other preconditions.
6666
rcl_wait_set_init(
67-
&mut rcl_wait_set as *mut _,
67+
&mut rcl_wait_set,
6868
number_of_subscriptions,
6969
0,
7070
0,
7171
0,
7272
0,
7373
0,
74-
&mut *context.handle.lock() as *mut _,
74+
&mut *context.handle.lock(),
7575
rcutils_get_default_allocator(),
7676
)
7777
.ok()?;
@@ -94,7 +94,7 @@ impl WaitSet {
9494
// valid, which it always is in our case. Hence, only debug_assert instead of returning
9595
// Result.
9696
// SAFETY: No preconditions for this function (besides passing in a valid wait set).
97-
let ret = unsafe { rcl_wait_set_clear(&mut self.handle as *mut _) };
97+
let ret = unsafe { rcl_wait_set_clear(&mut self.handle) };
9898
debug_assert_eq!(ret, 0);
9999
}
100100

@@ -116,8 +116,8 @@ impl WaitSet {
116116
// for as long as the wait set exists, because it's stored in self.subscriptions.
117117
// Passing in a null pointer for the third argument is explicitly allowed.
118118
rcl_wait_set_add_subscription(
119-
&mut self.handle as *mut _,
120-
&*subscription.handle().lock() as *const _,
119+
&mut self.handle,
120+
&*subscription.handle().lock(),
121121
std::ptr::null_mut(),
122122
)
123123
}
@@ -162,7 +162,7 @@ impl WaitSet {
162162
// We cannot currently guarantee that the wait sets may not share content, but it is
163163
// mentioned in the doc comment for `add_subscription`.
164164
// Also, the handle is obviously valid.
165-
unsafe { rcl_wait(&mut self.handle as *mut _, timeout_ns) }.ok()?;
165+
unsafe { rcl_wait(&mut self.handle, timeout_ns) }.ok()?;
166166
let mut ready_entities = ReadyEntities {
167167
subscriptions: Vec::new(),
168168
};

0 commit comments

Comments
 (0)