diff --git a/libs/edge-toolkit/src/config.rs b/libs/edge-toolkit/src/config.rs index 1d4bcb3d..9eb75ece 100644 --- a/libs/edge-toolkit/src/config.rs +++ b/libs/edge-toolkit/src/config.rs @@ -219,7 +219,8 @@ impl Language { /// to branch on the returned bool -- they don't repeat the message themselves. #[must_use] pub fn mise_env_includes(language: Language) -> bool { - let Ok(value) = std::env::var("MISE_ENV") else { + const MISE_ENV: &str = "MISE_ENV"; + let Ok(value) = std::env::var(MISE_ENV) else { return true; }; let included = !value.is_empty() && value.split(',').any(|seg| seg.trim() == language.as_str()); diff --git a/libs/et-otlp/src/lib.rs b/libs/et-otlp/src/lib.rs index ea4b3952..547e05fe 100644 --- a/libs/et-otlp/src/lib.rs +++ b/libs/et-otlp/src/lib.rs @@ -41,10 +41,11 @@ pub struct OtelHandles { impl OtelHandles { /// Flush any buffered spans/logs/metrics and tear down the exporters. pub fn shutdown(self) { - // Errors here are non-fatal -- the process is exiting anyway. - drop(self.tracer_provider.shutdown()); - drop(self.logger_provider.shutdown()); - drop(self.meter_provider.shutdown()); + // Errors here are non-fatal -- the process is exiting anyway, and there is no caller to + // propagate to, so each teardown result is intentionally discarded. + let _tracer = self.tracer_provider.shutdown(); + let _logger = self.logger_provider.shutdown(); + let _meter = self.meter_provider.shutdown(); } } @@ -60,8 +61,8 @@ impl OtelHandles { /// invalid, or the global subscriber is already set. pub fn init(config: &OtlpConfig) -> Result> { // tracing_log forwards `log` crate records (used by transitive deps) - // through the tracing subscriber. - drop(tracing_log::LogTracer::init()); + // through the tracing subscriber. A second init (global logger already set) is a real error here. + tracing_log::LogTracer::init()?; let mut headers = std::collections::HashMap::new(); if let Some(auth) = &config.auth { diff --git a/libs/path/src/lib.rs b/libs/path/src/lib.rs index 2ea31e04..2ba26a8d 100644 --- a/libs/path/src/lib.rs +++ b/libs/path/src/lib.rs @@ -34,7 +34,8 @@ pub fn find_project_root(start: &Path) -> PathBuf { /// start, or `edge_toolkit::config::get_project_root`, instead. #[must_use] pub fn find_project_root_from_manifest() -> PathBuf { - let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default(); + const CARGO_MANIFEST_DIR: &str = "CARGO_MANIFEST_DIR"; + let manifest = std::env::var(CARGO_MANIFEST_DIR).unwrap_or_default(); find_project_root(Path::new(&manifest)) } diff --git a/libs/test-helpers/src/lib.rs b/libs/test-helpers/src/lib.rs index 6b45061f..e731056c 100644 --- a/libs/test-helpers/src/lib.rs +++ b/libs/test-helpers/src/lib.rs @@ -52,8 +52,9 @@ impl ChildGuard { /// Kill the child and reap it now (also runs on drop; errors are ignored). pub fn shutdown(&mut self) { - drop(self.child.kill()); - drop(self.child.wait()); + // Best-effort teardown, also invoked from Drop -- no caller to propagate to, so discard. + let _kill = self.child.kill(); + let _wait = self.child.wait(); } } @@ -73,10 +74,13 @@ pub fn drain_stderr(child: &mut Child) -> Arc> { let stderr = child.stderr.take().unwrap(); let log = Arc::new(Mutex::new(String::new())); let sink = Arc::clone(&log); - drop(std::thread::spawn(move || { + // Detached drainer: nothing joins the handle, so neither the read result nor the thread's own + // outcome has a caller to propagate to -- both are intentionally discarded (partial output on a + // read error is still worth keeping for diagnostics). + let _drainer = std::thread::spawn(move || { let mut buffer = String::new(); - drop(std::io::BufReader::new(stderr).read_to_string(&mut buffer)); + let _read = std::io::BufReader::new(stderr).read_to_string(&mut buffer); *sink.lock().unwrap() = buffer; - })); + }); log } diff --git a/services/ws-modules/har1/src/lib.rs b/services/ws-modules/har1/src/lib.rs index 6cfafd8b..d9708108 100644 --- a/services/ws-modules/har1/src/lib.rs +++ b/services/ws-modules/har1/src/lib.rs @@ -157,6 +157,7 @@ impl MotionReading { } #[wasm_bindgen] +#[derive(Default)] pub struct DeviceSensors { active: bool, orientation_state: Rc>>, @@ -165,12 +166,6 @@ pub struct DeviceSensors { motion_listener: Option>, } -impl Default for DeviceSensors { - fn default() -> Self { - Self::new() - } -} - #[wasm_bindgen] impl DeviceSensors { #[must_use] diff --git a/services/ws-modules/sensor1/src/lib.rs b/services/ws-modules/sensor1/src/lib.rs index a723f034..9f1e9af5 100644 --- a/services/ws-modules/sensor1/src/lib.rs +++ b/services/ws-modules/sensor1/src/lib.rs @@ -133,6 +133,7 @@ impl MotionReading { } #[wasm_bindgen] +#[derive(Default)] pub struct DeviceSensors { active: bool, orientation_state: Rc>>, @@ -141,12 +142,6 @@ pub struct DeviceSensors { motion_listener: Option>, } -impl Default for DeviceSensors { - fn default() -> Self { - Self::new() - } -} - #[wasm_bindgen] impl DeviceSensors { #[must_use] diff --git a/services/ws-pyo3-runner/src/agent.rs b/services/ws-pyo3-runner/src/agent.rs index d188c821..fd1c6794 100644 --- a/services/ws-pyo3-runner/src/agent.rs +++ b/services/ws-pyo3-runner/src/agent.rs @@ -156,7 +156,7 @@ pub async fn run(agent: InitializedAgent) -> Result<(), RunnerError> { // Populate the slot before `on_connect` so Python sees a valid // `storage.agent_id` from the first instant it can act. *agent_id_slot.lock().unwrap_or_else(PoisonError::into_inner) = Some(agent_id.clone()); - drop(inbound_tx.send(InboundEvent::Connect(agent_id))); + let _connect_sent = inbound_tx.send(InboundEvent::Connect(agent_id)); let result = drive(&mut socket, &inbound_tx, &mut outbound_rx).await; @@ -164,10 +164,10 @@ pub async fn run(agent: InitializedAgent) -> Result<(), RunnerError> { // then drop our sender so the worker's recv loop ends. Join before aborting // the storage task so an `on_shutdown` that persists state can still reach // it; only then close the socket and stop storage. - drop(inbound_tx.send(InboundEvent::Shutdown)); + let _shutdown_sent = inbound_tx.send(InboundEvent::Shutdown); drop(inbound_tx); - drop(worker.join()); - drop(socket.send(tungstenite::Message::Close(None)).await); + let _joined = worker.join(); + let _close_sent = socket.send(tungstenite::Message::Close(None)).await; storage_task.abort(); result } @@ -195,12 +195,16 @@ fn python_worker( } } InboundEvent::Text(text) => match dispatcher.on_text_frame(&text) { - Ok(Some(reply)) => drop(outbound_tx.send(OutboundFrame::Text(reply))), + Ok(Some(reply)) => { + let _sent = outbound_tx.send(OutboundFrame::Text(reply)); + } Ok(None) => {} Err(err) => warn!("on_text_frame raised: {err}"), }, InboundEvent::Binary(bytes) => match dispatcher.on_binary_frame(&bytes) { - Ok(Some(reply)) => drop(outbound_tx.send(OutboundFrame::Binary(reply))), + Ok(Some(reply)) => { + let _sent = outbound_tx.send(OutboundFrame::Binary(reply)); + } Ok(None) => {} Err(err) => warn!("on_binary_frame raised: {err}"), }, @@ -233,7 +237,7 @@ async fn storage_worker(http_base: String, mut rx: mpsc::UnboundedReceiver Ok(None), Err(source) => Err(StorageError::get(&agent_id, &key, source.to_string())), }; - drop(reply.send(outcome)); + let _reply_sent = reply.send(outcome); } StorageOp::Put { agent_id, @@ -245,7 +249,7 @@ async fn storage_worker(http_base: String, mut rx: mpsc::UnboundedReceiver Ok(()), Err(source) => Err(StorageError::put(&agent_id, &key, source.to_string())), }; - drop(reply.send(outcome)); + let _reply_sent = reply.send(outcome); } } } @@ -273,10 +277,10 @@ async fn drive( // pushes to via WsSender, so multi-send + reply compose in order. frame = socket.next() => match frame { Some(Ok(tungstenite::Message::Binary(bytes))) => { - drop(inbound_tx.send(InboundEvent::Binary(bytes))); + let _forwarded = inbound_tx.send(InboundEvent::Binary(bytes)); } Some(Ok(tungstenite::Message::Text(text))) => { - drop(inbound_tx.send(InboundEvent::Text(text))); + let _forwarded = inbound_tx.send(InboundEvent::Text(text)); } Some(Ok(tungstenite::Message::Close(_))) => { info!("server closed connection"); diff --git a/services/ws-pyo3-runner/tests/modules.rs b/services/ws-pyo3-runner/tests/modules.rs index 57c7c9be..7f8fd7b6 100644 --- a/services/ws-pyo3-runner/tests/modules.rs +++ b/services/ws-pyo3-runner/tests/modules.rs @@ -116,8 +116,8 @@ async fn module_behaves( }; let outcome = tokio::time::timeout(budget, run_exchange(&mut control, &control_id, &exchange)).await; - drop(runner.kill()); - drop(runner.wait()); + runner.kill().unwrap(); + let _status = runner.wait().unwrap(); match outcome { Ok(result) => result, diff --git a/services/ws-test-server/tests/helpers.rs b/services/ws-test-server/tests/helpers.rs index 98f51dc3..ac69605b 100644 --- a/services/ws-test-server/tests/helpers.rs +++ b/services/ws-test-server/tests/helpers.rs @@ -16,7 +16,8 @@ use tokio_tungstenite::{accept_async, connect_async}; async fn scripted_server(frames: Vec) -> String { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let port = listener.local_addr().unwrap().port(); - drop(tokio::spawn(async move { + // Detached scripted server; the handle is intentionally not joined (the task runs until the test ends). + let _server = tokio::spawn(async move { let Ok((stream, _)) = listener.accept().await else { return; }; @@ -30,7 +31,7 @@ async fn scripted_server(frames: Vec) -> String { } // Keep the connection open so the client can finish reading rather than seeing an early close. std::future::pending::<()>().await; - })); + }); format!("ws://127.0.0.1:{port}") } diff --git a/services/ws-wasi-runner/src/host/ws.rs b/services/ws-wasi-runner/src/host/ws.rs index a13bbbc9..b803a404 100644 --- a/services/ws-wasi-runner/src/host/ws.rs +++ b/services/ws-wasi-runner/src/host/ws.rs @@ -71,10 +71,11 @@ impl WsBackend { let (tx, rx) = mpsc::unbounded_channel::(); // The handshake consumed the et-connect-ack frame; re-surface it to the // guest's `recv()` so guests that read it still see it as the first message. - drop(tx.send(ServerMessage::ConnectAck { + // Cannot fail: `rx` (created just above) is still alive, so the channel is open. + let _seeded = tx.send(ServerMessage::ConnectAck { agent_id: assigned_id.clone(), status, - })); + }); let agent_id = Arc::new(Mutex::new(Some(assigned_id))); let connection_state = Arc::new(Mutex::new(State::Connected)); diff --git a/services/ws-wasm-agent/tests/web.rs b/services/ws-wasm-agent/tests/web.rs index 2d6426e7..f9335ba0 100644 --- a/services/ws-wasm-agent/tests/web.rs +++ b/services/ws-wasm-agent/tests/web.rs @@ -24,7 +24,7 @@ async fn test_websocket_connection() { .set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 1000) .unwrap(); }); - drop(JsFuture::from(promise).await); + let _resolved = JsFuture::from(promise).await.unwrap(); // Assert connection state is successfully connected or at least it didn't fail let state = client.get_state(); diff --git a/services/ws/src/lib.rs b/services/ws/src/lib.rs index 961e4701..1691ad5c 100644 --- a/services/ws/src/lib.rs +++ b/services/ws/src/lib.rs @@ -328,13 +328,13 @@ impl Connection { "Direct message {} delivered from {} to {}", message_id, from_agent_id, to_agent_id ); - drop(recipient.send(SessionMessage::Json(ServerMessage::AgentMessage { + let _sent = recipient.send(SessionMessage::Json(ServerMessage::AgentMessage { message_id: message_id.clone(), from_agent_id, scope: MessageScope::Direct, server_received_at: pending.server_received_at, message: pending.message, - }))); + })); self.send_status( Some(message_id), MessageDeliveryStatus::Delivered, @@ -367,7 +367,7 @@ impl Connection { recipients.len() ); for (_, recipient) in recipients { - drop(recipient.send(SessionMessage::Text(text.to_string()))); + let _sent = recipient.send(SessionMessage::Text(text.to_string())); } } @@ -381,7 +381,7 @@ impl Connection { recipients.len() ); for (_, recipient) in recipients { - drop(recipient.send(SessionMessage::Binary(bytes.clone()))); + let _sent = recipient.send(SessionMessage::Binary(bytes.clone())); } } @@ -509,13 +509,13 @@ impl Connection { recipients.len() ); for (_, recipient) in &recipients { - drop(recipient.send(SessionMessage::Json(ServerMessage::AgentMessage { + let _sent = recipient.send(SessionMessage::Json(ServerMessage::AgentMessage { message_id: message_id.clone(), from_agent_id: from_agent_id.clone(), scope: MessageScope::Broadcast, server_received_at: server_received_at.clone(), message: message.clone(), - }))); + })); } self.send_status( Some(message_id), @@ -545,11 +545,11 @@ impl Connection { ) .await; if let Some(sender) = sender_session { - drop(sender.send(SessionMessage::Json(ServerMessage::MessageStatus { + let _sent = sender.send(SessionMessage::Json(ServerMessage::MessageStatus { message_id: Some(message_id), status: MessageDeliveryStatus::Acknowledged, detail: format!("agent {recipient_agent_id} acknowledged receipt"), - }))); + })); } } Err(error) => {