diff --git a/Cargo.toml b/Cargo.toml index b406358b..893fc828 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,8 @@ unused_qualifications = "warn" pedantic = { level = "warn", priority = -1 } # Lints. Keep alphabetically sorted +allow_attributes = "warn" +allow_attributes_without_reason = "warn" as_conversions = "warn" assertions_on_result_states = "warn" dbg_macro = "warn" diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index d660c6ba..e267bac4 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -85,7 +85,7 @@ pub(crate) async fn get_register_available_route( /// - Creates a new account and populates it with default account data /// - If `inhibit_login` is false: Creates a device and returns `device_id` and /// `access_token` -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn register_route( body: Ar, ) -> Result> { diff --git a/src/api/client_server/context.rs b/src/api/client_server/context.rs index ba803454..97ea7f17 100644 --- a/src/api/client_server/context.rs +++ b/src/api/client_server/context.rs @@ -17,7 +17,7 @@ use crate::{services, Ar, Error, Ra, Result}; /// /// - Only works if the user is joined (TODO: always allow, but only show events /// if the user was joined, depending on `history_visibility`) -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn get_context_route( body: Ar, ) -> Result> { diff --git a/src/api/client_server/directory.rs b/src/api/client_server/directory.rs index 3d4e1e06..148dfbf0 100644 --- a/src/api/client_server/directory.rs +++ b/src/api/client_server/directory.rs @@ -137,7 +137,7 @@ pub(crate) async fn get_room_visibility_route( })) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn get_public_rooms_filtered_helper( server: Option<&ServerName>, limit: Option, @@ -267,7 +267,6 @@ pub(crate) async fn get_public_rooms_filtered_helper( }) } -#[allow(clippy::too_many_lines)] #[tracing::instrument] fn room_id_to_chunk(room_id: ruma::OwnedRoomId) -> Result { let canonical_alias = services() diff --git a/src/api/client_server/keys.rs b/src/api/client_server/keys.rs index 0e423e72..4fcc36c1 100644 --- a/src/api/client_server/keys.rs +++ b/src/api/client_server/keys.rs @@ -284,7 +284,7 @@ pub(crate) async fn get_key_changes_route( })) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn get_keys_helper bool>( sender_user: Option<&UserId>, device_keys_input: &BTreeMap>, diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index ab11894c..deb4380d 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -124,7 +124,7 @@ fn set_header_or_panic( /// # `GET /_matrix/media/r0/config` /// /// Returns max upload size. -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] pub(crate) async fn get_media_config_legacy_route( _body: Ar, ) -> Result> { @@ -196,7 +196,7 @@ impl From for AllowRemote { } struct RemoteResponse { - #[allow(unused)] + #[expect(unused, reason = "placeholder for future spec changes")] metadata: authenticated_media_fed::ContentMetadata, content: authenticated_media_fed::Content, } @@ -290,7 +290,7 @@ async fn get_remote_content_via_federation_api( }) } -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] #[tracing::instrument(skip_all)] async fn get_remote_content_via_legacy_api( mxc: &MxcData<'_>, @@ -365,7 +365,7 @@ pub(crate) async fn get_remote_content( /// Load media from our server or over federation. /// /// - Only allows federation if `allow_remote` is true -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] pub(crate) async fn get_content_legacy_route( body: Ar, ) -> Result { @@ -487,7 +487,7 @@ async fn get_content_route_ruma( /// Load media from our server or over federation, permitting desired filename. /// /// - Only allows federation if `allow_remote` is true -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] pub(crate) async fn get_content_as_filename_legacy_route( body: Ar, ) -> Result { @@ -632,7 +632,7 @@ fn fix_thumbnail_headers(r: &mut axum::response::Response) { /// Load media thumbnail from our server or over federation. /// /// - Only allows federation if `allow_remote` is true -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] pub(crate) async fn get_content_thumbnail_legacy_route( body: Ar, ) -> Result { @@ -741,7 +741,7 @@ async fn get_remote_thumbnail_via_federation_api( }) } -#[allow(deprecated)] // unauthenticated media +#[expect(deprecated, reason = "legacy media APIs")] #[tracing::instrument(skip_all)] async fn get_remote_thumbnail_via_legacy_api( server_name: &ruma::ServerName, diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 95aefcf4..f05fdbef 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -499,7 +499,6 @@ pub(crate) async fn joined_members_route( })) } -#[allow(clippy::too_many_lines)] #[tracing::instrument(skip(reason, _third_party_signed))] async fn join_room_by_id_helper( sender_user: Option<&UserId>, @@ -1265,7 +1264,7 @@ async fn validate_and_add_event_id( Ok((event_id, value)) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn invite_helper( sender_user: &UserId, user_id: &UserId, @@ -1571,7 +1570,7 @@ pub(crate) async fn leave_room( Ok(()) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { let mut make_leave_response_and_server = Err(Error::BadServerResponse( "No server available to assist in leaving.", diff --git a/src/api/client_server/message.rs b/src/api/client_server/message.rs index df723d07..0cad991c 100644 --- a/src/api/client_server/message.rs +++ b/src/api/client_server/message.rs @@ -118,7 +118,7 @@ pub(crate) async fn send_message_event_route( /// /// - Only works if the user is joined (TODO: always allow, but only show events /// where the user was joined, depending on `history_visibility`) -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn get_message_events_route( body: Ar, ) -> Result> { diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index c2488464..79f26418 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -50,7 +50,7 @@ use crate::{ /// - Send events listed in initial state /// - Send events implied by `name` and `topic` /// - Send invite events -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn create_room_route( body: Ar, ) -> Result> { @@ -570,7 +570,7 @@ pub(crate) async fn get_room_aliases_route( /// - Transfers some state events /// - Moves local aliases /// - Modifies old room power levels to prevent users from speaking -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn upgrade_room_route( body: Ar, ) -> Result> { diff --git a/src/api/client_server/search.rs b/src/api/client_server/search.rs index cd36a13b..f1de73b4 100644 --- a/src/api/client_server/search.rs +++ b/src/api/client_server/search.rs @@ -22,7 +22,7 @@ use crate::{services, Ar, Error, Ra, Result}; /// /// - Only works if the user is currently joined to the room (TODO: Respect /// history visibility) -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn search_events_route( body: Ar, ) -> Result> { diff --git a/src/api/client_server/session.rs b/src/api/client_server/session.rs index 188397cf..3b8a9aee 100644 --- a/src/api/client_server/session.rs +++ b/src/api/client_server/session.rs @@ -51,11 +51,8 @@ pub(crate) async fn get_login_types_route( /// /// Note: You can use [`GET /_matrix/client/r0/login`](get_login_types_route) to /// see supported login types. -#[allow( - // To allow deprecated login methods - deprecated, - clippy::too_many_lines, -)] +#[expect(deprecated, reason = "To allow deprecated login methods")] +#[expect(clippy::too_many_lines)] pub(crate) async fn login_route( body: Ar, ) -> Result> { @@ -252,8 +249,6 @@ pub(crate) async fn login_route( info!(%user_id, %device_id, "User logged in"); - // Homeservers are still required to send the `home_server` field - #[allow(deprecated)] Ok(Ra(login::v3::Response { user_id, access_token: token, diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 252036a5..35cf3f0b 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -67,7 +67,7 @@ use crate::{ /// For left rooms: /// - If the user left after `since`: `prev_batch` token, empty state (TODO: /// subset of the state at the point of the leave) -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn sync_events_route( body: Ar, ) -> Result, Ra> { @@ -449,7 +449,7 @@ pub(crate) async fn sync_events_route( } #[tracing::instrument(skip_all, fields(room_id = %room_id))] -#[allow(clippy::too_many_arguments, clippy::too_many_lines)] +#[expect(clippy::too_many_arguments)] async fn load_joined_room( sender_user: &UserId, sender_device: &DeviceId, @@ -1121,7 +1121,7 @@ fn share_encrypted_room( .any(|encrypted| encrypted)) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn sync_events_v4_route( body: Ar, ) -> Result, Ra> { diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index 712386d9..5dbf6734 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -50,7 +50,7 @@ struct ArPieces { /// Non-generic part of [`Ar::from_request()`]. Splitting this out reduces /// binary size by ~10%. -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] async fn ar_from_request_inner( req: axum::extract::Request, metadata: Metadata, diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 9030bf99..9a23ef15 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -372,7 +372,6 @@ fn add_port_to_hostname(destination_str: &str) -> FedDest { /// Implemented according to the specification at /// Numbers in comments below refer to bullet points in linked section of /// specification -#[allow(clippy::too_many_lines)] #[tracing::instrument(ret(level = "debug"))] async fn find_actual_destination( destination: &'_ ServerName, @@ -729,7 +728,7 @@ pub(crate) fn parse_incoming_pdu( /// # `PUT /_matrix/federation/v1/send/{txnId}` /// /// Push EDUs and PDUs to this server. -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn send_transaction_message_route( body: Ar, ) -> Result> { @@ -1561,7 +1560,7 @@ pub(crate) async fn create_join_event_template_route( })) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] async fn create_join_event( sender_servername: &ServerName, room_id: &RoomId, @@ -1706,7 +1705,7 @@ async fn create_join_event( /// # `PUT /_matrix/federation/v1/send_join/{roomId}/{eventId}` /// /// Submits a signed join event. -#[allow(deprecated)] +#[expect(deprecated, reason = "support for deprecated API")] pub(crate) async fn create_join_event_v1_route( body: Ar, ) -> Result> { @@ -1750,7 +1749,7 @@ pub(crate) async fn create_join_event_v2_route( /// # `PUT /_matrix/federation/v2/invite/{roomId}/{eventId}` /// /// Invites a remote user to a room. -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] pub(crate) async fn create_invite_route( body: Ar, ) -> Result> { diff --git a/src/cli/serve.rs b/src/cli/serve.rs index 0991066b..f6908110 100644 --- a/src/cli/serve.rs +++ b/src/cli/serve.rs @@ -124,7 +124,7 @@ async fn federation_self_test() -> Result<()> { Ok(()) } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] async fn run_server() -> Result<(), error::Serve> { use error::Serve as Error; @@ -337,7 +337,7 @@ fn legacy_media_routes(config: &Config) -> Router { } } -#[allow(clippy::too_many_lines)] +#[expect(clippy::too_many_lines, reason = "there's a lot of routes")] fn client_routes() -> Router { use client_server as c2s; @@ -705,7 +705,6 @@ pub(crate) trait RumaHandler { macro_rules! impl_ruma_handler { ( $($ty:ident),* $(,)? ) => { #[axum::async_trait] - #[allow(non_snake_case)] impl RumaHandler<($($ty,)* Ar,)> for F where @@ -728,7 +727,10 @@ macro_rules! impl_ruma_handler { path, on( method_filter, - |$( $ty: $ty, )* req: Ar| async move { + |$(#[expect( + non_snake_case, + reason = "reuse of macro fragments", + )] $ty: $ty, )* req: Ar| async move { let span = info_span!( "run_ruma_handler", auth.user = ?req.sender_user, diff --git a/src/config.rs b/src/config.rs index c980c26b..44af76ec 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,7 +27,7 @@ use proxy::ProxyConfig; pub(crate) static DEFAULT_PATH: Lazy = Lazy::new(|| [env!("CARGO_PKG_NAME"), "config.toml"].iter().collect()); -#[allow(clippy::struct_excessive_bools)] +#[expect(clippy::struct_excessive_bools, reason = "config schema struct")] #[derive(Debug, Deserialize)] pub(crate) struct Config { #[serde(default = "false_fn")] diff --git a/src/database.rs b/src/database.rs index abfad85a..1435247d 100644 --- a/src/database.rs +++ b/src/database.rs @@ -95,13 +95,17 @@ pub(crate) struct KeyValueDatabase { pub(super) roomuserid_lastprivatereadupdate: Arc, // PresenceId = RoomId + Count + UserId - // This exists in the database already but is currently unused - #[allow(dead_code)] + #[expect( + dead_code, + reason = "This exists in the database already but is currently unused" + )] pub(super) presenceid_presence: Arc, // LastPresenceUpdate = Count - // This exists in the database already but is currently unused - #[allow(dead_code)] + #[expect( + dead_code, + reason = "This exists in the database already but is currently unused" + )] pub(super) userid_lastpresenceupdate: Arc, // Trees "owned" by `self::key_value::rooms` @@ -317,7 +321,7 @@ impl KeyValueDatabase { not(any(feature = "rocksdb", feature = "sqlite")), allow(unreachable_code) )] - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] pub(crate) fn load_or_create(config: &Config) -> Result { Self::check_db_setup(config)?; @@ -478,7 +482,7 @@ impl KeyValueDatabase { .try_into() .expect("pdu cache capacity fits into usize"), )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -486,7 +490,7 @@ impl KeyValueDatabase { auth_chain_cache: Mutex::new(LruCache::new( (100_000.0 * config.cache_capacity_modifier) as usize, )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -494,7 +498,7 @@ impl KeyValueDatabase { shorteventid_cache: Mutex::new(LruCache::new( (100_000.0 * config.cache_capacity_modifier) as usize, )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -502,7 +506,7 @@ impl KeyValueDatabase { eventidshort_cache: Mutex::new(LruCache::new( (100_000.0 * config.cache_capacity_modifier) as usize, )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -510,7 +514,7 @@ impl KeyValueDatabase { shortstatekey_cache: Mutex::new(LruCache::new( (100_000.0 * config.cache_capacity_modifier) as usize, )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -531,7 +535,7 @@ impl KeyValueDatabase { /// /// If it is not possible to migrate the database to the current version, /// returns an error. - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] pub(crate) async fn apply_migrations(&self) -> Result<()> { // If the database has any data, perform data migrations before starting let latest_database_version = 13; diff --git a/src/database/abstraction/rocksdb.rs b/src/database/abstraction/rocksdb.rs index 72e676a1..8fcb6421 100644 --- a/src/database/abstraction/rocksdb.rs +++ b/src/database/abstraction/rocksdb.rs @@ -72,10 +72,11 @@ fn db_options(max_open_files: i32, rocksdb_cache: &Cache) -> Options { impl KeyValueDatabaseEngine for Arc { fn open(config: &Config) -> Result { - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, - clippy::cast_possible_truncation + clippy::cast_possible_truncation, + reason = "saturating to usize is fine" )] let cache_capacity_bytes = (config.database.cache_capacity_mb * 1024.0 * 1024.0) as usize; @@ -144,7 +145,11 @@ impl KeyValueDatabaseEngine for Arc { })) } - #[allow(clippy::as_conversions, clippy::cast_precision_loss)] + #[expect( + clippy::as_conversions, + clippy::cast_precision_loss, + reason = "these are just informational" + )] fn memory_usage(&self) -> Result { let stats = get_memory_usage_stats(Some(&[&self.rocks]), Some(&[&self.cache]))?; diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs index 7b41fc79..27062710 100644 --- a/src/database/abstraction/sqlite.rs +++ b/src/database/abstraction/sqlite.rs @@ -124,11 +124,12 @@ impl KeyValueDatabaseEngine for Arc { // 2. divide by permanent connections + permanent iter connections + // write connection // 3. round down to nearest integer - #[allow( + #[expect( clippy::as_conversions, clippy::cast_possible_truncation, clippy::cast_precision_loss, - clippy::cast_sign_loss + clippy::cast_sign_loss, + reason = "saturating to u32 is fine" )] let cache_size_per_thread = ((config.database.cache_capacity_mb * 1024.0) diff --git a/src/database/abstraction/watchers.rs b/src/database/abstraction/watchers.rs index b31bd082..2bab1d74 100644 --- a/src/database/abstraction/watchers.rs +++ b/src/database/abstraction/watchers.rs @@ -9,7 +9,10 @@ use tokio::sync::watch; #[derive(Default)] pub(super) struct Watchers { - #[allow(clippy::type_complexity)] + #[expect( + clippy::type_complexity, + reason = "not actually all that complex" + )] watchers: RwLock, (watch::Sender<()>, watch::Receiver<()>)>>, } diff --git a/src/database/key_value/rooms/edus/read_receipt.rs b/src/database/key_value/rooms/edus/read_receipt.rs index f8e1470f..ae4ddc57 100644 --- a/src/database/key_value/rooms/edus/read_receipt.rs +++ b/src/database/key_value/rooms/edus/read_receipt.rs @@ -53,7 +53,7 @@ impl service::rooms::edus::read_receipt::Data for KeyValueDatabase { } #[tracing::instrument(skip(self))] - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn readreceipts_since<'a>( &'a self, room_id: &RoomId, diff --git a/src/database/key_value/rooms/search.rs b/src/database/key_value/rooms/search.rs index 510feca5..f39b82e7 100644 --- a/src/database/key_value/rooms/search.rs +++ b/src/database/key_value/rooms/search.rs @@ -64,7 +64,7 @@ impl service::rooms::search::Data for KeyValueDatabase { } #[tracing::instrument(skip(self))] - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn search_pdus<'a>( &'a self, room_id: &RoomId, diff --git a/src/database/key_value/rooms/state_cache.rs b/src/database/key_value/rooms/state_cache.rs index 115511eb..4c195363 100644 --- a/src/database/key_value/rooms/state_cache.rs +++ b/src/database/key_value/rooms/state_cache.rs @@ -482,7 +482,7 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { } /// Returns an iterator over all rooms a user was invited to. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] #[tracing::instrument(skip(self))] fn rooms_invited<'a>( &'a self, @@ -575,7 +575,7 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { } /// Returns an iterator over all rooms a user left. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] #[tracing::instrument(skip(self))] fn rooms_left<'a>( &'a self, diff --git a/src/error.rs b/src/error.rs index 72bcd337..996a1e19 100644 --- a/src/error.rs +++ b/src/error.rs @@ -35,9 +35,6 @@ impl fmt::Display for DisplayWithSources<'_> { } /// Top-level errors -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum Main { #[error(transparent)] @@ -45,9 +42,6 @@ pub(crate) enum Main { } /// Errors returned from the `serve` CLI subcommand. -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum ServeCommand { #[error("failed to load configuration")] @@ -70,9 +64,6 @@ pub(crate) enum ServeCommand { } /// Error generated if `server_name` has changed or if checking this failed -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum ServerNameChanged { #[error("failed to check if there are any users")] @@ -86,9 +77,6 @@ pub(crate) enum ServerNameChanged { } /// Observability initialization errors -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum Observability { // Upstream's documentation on what this error means is very sparse @@ -104,9 +92,6 @@ pub(crate) enum Observability { } /// Configuration errors -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum Config { #[error("failed to find configuration file")] @@ -123,9 +108,6 @@ pub(crate) enum Config { } /// Errors that can occur while searching for a config file -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum ConfigSearch { #[error("XDG Base Directory error")] @@ -136,9 +118,6 @@ pub(crate) enum ConfigSearch { } /// Errors serving traffic -// Missing docs are allowed here since that kind of information should be -// encoded in the error messages themselves anyway. -#[allow(missing_docs)] #[derive(Error, Debug)] pub(crate) enum Serve { #[error("no listeners were specified in the configuration file")] diff --git a/src/observability.rs b/src/observability.rs index 059ed436..b04065d7 100644 --- a/src/observability.rs +++ b/src/observability.rs @@ -39,7 +39,7 @@ pub(crate) static METRICS: Lazy = Lazy::new(Metrics::new); /// Cleans up resources relating to observability when [`Drop`]ped pub(crate) struct Guard { /// Drop guard used to flush [`tracing_flame`] data on exit - #[allow(dead_code)] + #[expect(dead_code, reason = "only exists to be dropped")] flame_guard: Option>>, } @@ -80,7 +80,10 @@ pub(crate) type FilterReloadHandle = Box + Sync>; /// Collection of [`FilterReloadHandle`]s, allowing the filters for tracing /// backends to be changed dynamically. Handles may be [`None`] if the backend /// is disabled in the config. -#[allow(clippy::missing_docs_in_private_items)] +#[expect( + clippy::missing_docs_in_private_items, + reason = "mirrors config struct layout" +)] pub(crate) struct FilterReloadHandles { pub(crate) traces: Option, pub(crate) flame: Option, @@ -91,7 +94,7 @@ pub(crate) struct FilterReloadHandles { /// /// See also [`Metrics::record_lookup`]. // Keep variants sorted -#[allow(clippy::missing_docs_in_private_items)] +#[expect(clippy::missing_docs_in_private_items)] #[derive(Clone, Copy, AsRefStr, IntoStaticStr)] pub(crate) enum Lookup { AppserviceInRoom, @@ -208,7 +211,7 @@ pub(crate) fn init( let (log_layer, log_filter, _) = make_backend(true, &config.observability.logs.filter, || { /// Time format selection for `tracing_subscriber` at runtime - #[allow(clippy::missing_docs_in_private_items)] + #[expect(clippy::missing_docs_in_private_items, reason = "trivial")] enum TimeFormat { SystemTime, NoTime, diff --git a/src/service.rs b/src/service.rs index c2dcb0f8..06b4ce61 100644 --- a/src/service.rs +++ b/src/service.rs @@ -99,7 +99,7 @@ impl Services { }, state_accessor: rooms::state_accessor::Service { db, - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -107,7 +107,7 @@ impl Services { server_visibility_cache: StdMutex::new(LruCache::new( (100.0 * config.cache_capacity_modifier) as usize, )), - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation @@ -121,7 +121,7 @@ impl Services { }, state_compressor: rooms::state_compressor::Service { db, - #[allow( + #[expect( clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation diff --git a/src/service/admin.rs b/src/service/admin.rs index e46368ed..4fc84203 100644 --- a/src/service/admin.rs +++ b/src/service/admin.rs @@ -55,8 +55,10 @@ enum AdminCommand { /// # ``` /// # yaml content here /// # ``` - // Allowed because the doc comment gets parsed by our code later - #[allow(clippy::doc_markdown)] + #[expect( + clippy::doc_markdown, + reason = "the doc comment gets parsed by our code later" + )] RegisterAppservice, /// Unregister an appservice using its ID @@ -104,8 +106,10 @@ enum AdminCommand { /// # ``` /// # User list here /// # ``` - // Allowed because the doc comment gets parsed by our code later - #[allow(clippy::doc_markdown)] + #[expect( + clippy::doc_markdown, + reason = "the doc comment gets parsed by our code later" + )] DeactivateAll { #[arg(short, long)] /// Remove users from their joined rooms @@ -131,8 +135,10 @@ enum AdminCommand { /// # ``` /// # PDU json content here /// # ``` - // Allowed because the doc comment gets parsed by our code later - #[allow(clippy::doc_markdown)] + #[expect( + clippy::doc_markdown, + reason = "the doc comment gets parsed by our code later" + )] ParsePdu, /// Retrieve and print a PDU by ID from the Grapevine database @@ -206,8 +212,10 @@ enum AdminCommand { /// # ``` /// # json here /// # ``` - // Allowed because the doc comment gets parsed by our code later - #[allow(clippy::doc_markdown)] + #[expect( + clippy::doc_markdown, + reason = "the doc comment gets parsed by our code later" + )] SignJson, /// Verify json signatures @@ -215,8 +223,10 @@ enum AdminCommand { /// # ``` /// # json here /// # ``` - // Allowed because the doc comment gets parsed by our code later - #[allow(clippy::doc_markdown)] + #[expect( + clippy::doc_markdown, + reason = "the doc comment gets parsed by our code later" + )] VerifyJson, /// Dynamically change a tracing backend's filter string @@ -411,7 +421,6 @@ impl Service { AdminCommand::try_parse_from(argv).map_err(|error| error.to_string()) } - #[allow(clippy::too_many_lines)] #[tracing::instrument(skip(self, body))] async fn process_admin_command( &self, @@ -1286,7 +1295,6 @@ impl Service { /// Users in this room are considered admins by grapevine, and the room can /// be used to issue admin commands by talking to the server user inside /// it. - #[allow(clippy::too_many_lines)] #[tracing::instrument(skip(self))] pub(crate) async fn create_admin_room(&self) -> Result<()> { let room_id = RoomId::new(services().globals.server_name()); @@ -1527,8 +1535,7 @@ impl Service { /// /// Errors are propagated from the database, and will have None if there is /// no admin room - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] pub(crate) fn get_admin_room(&self) -> Result> { services() .rooms diff --git a/src/service/globals.rs b/src/service/globals.rs index a1662c9e..0a02ffe0 100644 --- a/src/service/globals.rs +++ b/src/service/globals.rs @@ -110,7 +110,7 @@ pub(crate) struct RotationHandler( // TODO: Determine if it's safe to delete this field. I'm not deleting it // right now because I'm unsure what implications that would have for how // the sender expects to work. - #[allow(dead_code)] broadcast::Receiver<()>, + #[expect(dead_code, reason = "see comment")] broadcast::Receiver<()>, ); impl RotationHandler { @@ -310,8 +310,6 @@ impl Service { /// Matrix resource ownership is based on the server name; changing it /// requires recreating the database from scratch. This check needs to be /// done before background tasks are started to avoid data races. - // Allowed because this function calls `services()` - #[allow(clippy::unused_self)] pub(crate) fn err_if_server_name_changed( &self, ) -> Result<(), crate::error::ServerNameChanged> { @@ -544,7 +542,6 @@ impl Service { /// Filters the key map of multiple servers down to keys that should be /// accepted given the expiry time, room version, and timestamp of the /// paramters - #[allow(clippy::unused_self)] pub(crate) fn filter_keys_server_map( &self, keys: BTreeMap, @@ -561,7 +558,7 @@ impl Service { /// Filters the keys of a single server down to keys that should be accepted /// given the expiry time, room version, and timestamp of the paramters - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self)] pub(crate) fn filter_keys_single_server( &self, keys: SigningKeys, diff --git a/src/service/media.rs b/src/service/media.rs index 03109004..6b616185 100644 --- a/src/service/media.rs +++ b/src/service/media.rs @@ -19,7 +19,6 @@ pub(crate) struct FileMeta { // // TODO: Write a database migration to get rid of this and instead store // only the filename instead of the entire `Content-Disposition` header. - #[allow(dead_code)] pub(crate) content_disposition: Option, pub(crate) content_type: Option, } diff --git a/src/service/rooms/auth_chain.rs b/src/service/rooms/auth_chain.rs index 5dcf9275..4eff5a83 100644 --- a/src/service/rooms/auth_chain.rs +++ b/src/service/rooms/auth_chain.rs @@ -49,9 +49,13 @@ impl Service { for id in starting_events { let short = services().rooms.short.get_or_create_shorteventid(&id)?; - // I'm afraid to change this in case there is accidental reliance on - // the truncation - #[allow(clippy::as_conversions, clippy::cast_possible_truncation)] + #[expect( + clippy::as_conversions, + clippy::cast_possible_truncation, + reason = "I'm afraid to change this in case there is \ + accidental + reliance on the truncation" + )] let bucket_id = (short.get() % NUM_BUCKETS as u64) as usize; buckets[bucket_id].insert((short, id.clone())); i += 1; diff --git a/src/service/rooms/edus/read_receipt/data.rs b/src/service/rooms/edus/read_receipt/data.rs index b48ec9e2..2b4bfe9d 100644 --- a/src/service/rooms/edus/read_receipt/data.rs +++ b/src/service/rooms/edus/read_receipt/data.rs @@ -15,7 +15,7 @@ pub(crate) trait Data: Send + Sync { /// Returns an iterator over the most recent read receipts in a room that /// happened after the event with id `since`. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn readreceipts_since<'a>( &'a self, room_id: &RoomId, @@ -40,7 +40,7 @@ pub(crate) trait Data: Send + Sync { /// Returns the private read marker. // TODO: Implement MSC2285 - #[allow(dead_code)] + #[expect(dead_code, reason = "private read receipts are unimplemented")] fn private_read_get( &self, room_id: &RoomId, @@ -49,7 +49,7 @@ pub(crate) trait Data: Send + Sync { /// Returns the count of the last typing update in this room. // TODO: Implement MSC2285 - #[allow(dead_code)] + #[expect(dead_code, reason = "private read receipts are unimplemented")] fn last_privateread_update( &self, user_id: &UserId, diff --git a/src/service/rooms/event_handler.rs b/src/service/rooms/event_handler.rs index d5e7a6a4..7b327540 100644 --- a/src/service/rooms/event_handler.rs +++ b/src/service/rooms/event_handler.rs @@ -312,7 +312,7 @@ impl Service { r } - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] #[tracing::instrument(skip(self, origin, room_id, value, pub_key_map))] fn handle_outlier_pdu<'a>( &'a self, @@ -1433,7 +1433,7 @@ impl Service { } #[tracing::instrument(skip_all)] - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] async fn fetch_unknown_prev_events( &self, origin: &ServerName, @@ -1709,7 +1709,7 @@ impl Service { Ok(()) } - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] pub(crate) async fn fetch_join_signing_keys( &self, event: &create_join_event::v2::Response, @@ -1840,8 +1840,6 @@ impl Service { } /// Returns Ok if the acl allows the server - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] #[tracing::instrument(skip_all)] pub(crate) fn acl_check( &self, diff --git a/src/service/rooms/lazy_loading.rs b/src/service/rooms/lazy_loading.rs index 10e0fff1..ffb8e34f 100644 --- a/src/service/rooms/lazy_loading.rs +++ b/src/service/rooms/lazy_loading.rs @@ -11,7 +11,7 @@ use crate::Result; pub(crate) struct Service { pub(crate) db: &'static dyn Data, - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] pub(crate) lazy_load_waiting: Mutex< HashMap< (OwnedUserId, OwnedDeviceId, OwnedRoomId, PduCount), diff --git a/src/service/rooms/pdu_metadata.rs b/src/service/rooms/pdu_metadata.rs index 767ada39..0aabf407 100644 --- a/src/service/rooms/pdu_metadata.rs +++ b/src/service/rooms/pdu_metadata.rs @@ -45,7 +45,7 @@ impl Service { } } - #[allow(clippy::too_many_arguments, clippy::too_many_lines)] + #[expect(clippy::too_many_arguments)] #[tracing::instrument(skip(self))] pub(crate) fn paginate_relations_with_filter( &self, diff --git a/src/service/rooms/pdu_metadata/data.rs b/src/service/rooms/pdu_metadata/data.rs index baab44a4..e56ff6bd 100644 --- a/src/service/rooms/pdu_metadata/data.rs +++ b/src/service/rooms/pdu_metadata/data.rs @@ -9,7 +9,7 @@ use crate::{ pub(crate) trait Data: Send + Sync { fn add_relation(&self, from: u64, to: u64) -> Result<()>; - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn relations_until<'a>( &'a self, user_id: &'a UserId, diff --git a/src/service/rooms/search/data.rs b/src/service/rooms/search/data.rs index 2372a9aa..dcc0b06c 100644 --- a/src/service/rooms/search/data.rs +++ b/src/service/rooms/search/data.rs @@ -20,7 +20,7 @@ pub(crate) trait Data: Send + Sync { message_body: &str, ) -> Result<()>; - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn search_pdus<'a>( &'a self, room_id: &RoomId, diff --git a/src/service/rooms/spaces.rs b/src/service/rooms/spaces.rs index 57655564..42b1438d 100644 --- a/src/service/rooms/spaces.rs +++ b/src/service/rooms/spaces.rs @@ -50,7 +50,6 @@ pub(crate) struct Service { } impl Service { - #[allow(clippy::too_many_lines)] #[tracing::instrument(skip(self))] pub(crate) async fn get_hierarchy( &self, @@ -326,7 +325,6 @@ impl Service { }) } - #[allow(clippy::too_many_lines)] #[tracing::instrument(skip(self, children))] fn get_room_chunk( &self, @@ -532,8 +530,7 @@ impl Service { } } - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] fn handle_simplified_join_rule( &self, join_rule: &SpaceRoomJoinRule, diff --git a/src/service/rooms/state_accessor.rs b/src/service/rooms/state_accessor.rs index f27a69ee..91a4be13 100644 --- a/src/service/rooms/state_accessor.rs +++ b/src/service/rooms/state_accessor.rs @@ -396,8 +396,6 @@ impl Service { ) } - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] #[tracing::instrument(skip(self), ret(level = "trace"))] pub(crate) fn user_can_invite( &self, diff --git a/src/service/rooms/state_cache.rs b/src/service/rooms/state_cache.rs index a2b1aab2..f9986aa6 100644 --- a/src/service/rooms/state_cache.rs +++ b/src/service/rooms/state_cache.rs @@ -175,8 +175,7 @@ impl Service { } /// Copy `m.tag` account data to an upgraded room. - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] fn copy_upgraded_account_data_tag( &self, user_id: &UserId, @@ -206,8 +205,7 @@ impl Service { } /// Copy references in `m.direct` account data events to an upgraded room. - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] fn copy_upgraded_account_data_direct( &self, user_id: &UserId, diff --git a/src/service/rooms/state_cache/data.rs b/src/service/rooms/state_cache/data.rs index 5369e42f..a140cea9 100644 --- a/src/service/rooms/state_cache/data.rs +++ b/src/service/rooms/state_cache/data.rs @@ -93,7 +93,7 @@ pub(crate) trait Data: Send + Sync { ) -> Box> + 'a>; /// Returns an iterator over all rooms a user was invited to. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn rooms_invited<'a>( &'a self, user_id: &UserId, @@ -116,7 +116,7 @@ pub(crate) trait Data: Send + Sync { ) -> Result>>>; /// Returns an iterator over all rooms a user left. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn rooms_left<'a>( &'a self, user_id: &UserId, @@ -132,6 +132,6 @@ pub(crate) trait Data: Send + Sync { fn is_invited(&self, user_id: &UserId, room_id: &RoomId) -> Result; // TODO: Use this when implementing sync filtering - #[allow(dead_code)] + #[expect(dead_code, reason = "sync filtering is unimplemented")] fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result; } diff --git a/src/service/rooms/state_compressor.rs b/src/service/rooms/state_compressor.rs index 42dc8878..ac8f791e 100644 --- a/src/service/rooms/state_compressor.rs +++ b/src/service/rooms/state_compressor.rs @@ -31,7 +31,6 @@ pub(crate) struct CompressedStateLayer { pub(crate) struct Service { pub(crate) db: &'static dyn Data, - #[allow(clippy::type_complexity)] pub(crate) stateinfo_cache: Mutex>>, } @@ -75,7 +74,6 @@ impl CompressedStateEvent { impl Service { /// Returns a stack with info on shortstatehash, full state, added diff and /// removed diff for the selected shortstatehash and each parent layer. - #[allow(clippy::type_complexity)] #[tracing::instrument(skip(self))] pub(crate) fn load_shortstatehash_info( &self, @@ -130,8 +128,7 @@ impl Service { Ok(response) } - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] pub(crate) fn compress_state_event( &self, shortstatekey: ShortStateKey, @@ -147,8 +144,7 @@ impl Service { } /// Returns shortstatekey, event id - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect(clippy::unused_self, reason = "uses services()")] pub(crate) fn parse_compressed_state_event( &self, compressed_event: &CompressedStateEvent, @@ -180,7 +176,6 @@ impl Service { /// for this layer /// * `parent_states` - A stack with info on shortstatehash, full state, /// added diff and removed diff for each parent layer - #[allow(clippy::type_complexity)] #[tracing::instrument(skip( self, statediffnew, @@ -303,7 +298,7 @@ impl Service { /// Returns the new shortstatehash, and the state diff from the previous /// room state - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] #[tracing::instrument(skip(self, new_state_ids_compressed))] pub(crate) fn save_state( &self, diff --git a/src/service/rooms/threads/data.rs b/src/service/rooms/threads/data.rs index 384c23c8..3f2bfcdb 100644 --- a/src/service/rooms/threads/data.rs +++ b/src/service/rooms/threads/data.rs @@ -6,7 +6,7 @@ use ruma::{ use crate::{service::rooms::timeline::PduId, PduEvent, Result}; pub(crate) trait Data: Send + Sync { - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn threads_until<'a>( &'a self, user_id: &'a UserId, diff --git a/src/service/rooms/timeline.rs b/src/service/rooms/timeline.rs index 53802841..d91828c2 100644 --- a/src/service/rooms/timeline.rs +++ b/src/service/rooms/timeline.rs @@ -683,7 +683,7 @@ impl Service { Ok(pdu_id) } - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] pub(crate) fn create_hash_and_sign_event( &self, pdu_builder: PduBuilder, diff --git a/src/service/rooms/timeline/data.rs b/src/service/rooms/timeline/data.rs index acd0b33c..7f7750f2 100644 --- a/src/service/rooms/timeline/data.rs +++ b/src/service/rooms/timeline/data.rs @@ -82,7 +82,7 @@ pub(crate) trait Data: Send + Sync { /// Returns an iterator over all events and their tokens in a room that /// happened before the event with id `until` in reverse-chronological /// order. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn pdus_until<'a>( &'a self, user_id: &UserId, @@ -92,7 +92,7 @@ pub(crate) trait Data: Send + Sync { /// Returns an iterator over all events in a room that happened after the /// event with id `from` in chronological order. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn pdus_after<'a>( &'a self, user_id: &UserId, diff --git a/src/service/sending/data.rs b/src/service/sending/data.rs index 00795faf..649f711f 100644 --- a/src/service/sending/data.rs +++ b/src/service/sending/data.rs @@ -4,7 +4,6 @@ use super::{Destination, RequestKey, SendingEventType}; use crate::Result; pub(crate) trait Data: Send + Sync { - #[allow(clippy::type_complexity)] fn active_requests<'a>( &'a self, ) -> Box< diff --git a/src/service/users.rs b/src/service/users.rs index 47277600..9fd40b66 100644 --- a/src/service/users.rs +++ b/src/service/users.rs @@ -34,7 +34,7 @@ pub(crate) struct SlidingSyncCache { pub(crate) struct Service { pub(crate) db: &'static dyn Data, - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] pub(crate) connections: Mutex< BTreeMap< (OwnedUserId, OwnedDeviceId, String), @@ -58,7 +58,7 @@ impl Service { self.connections.lock().unwrap().remove(&(user_id, device_id, conn_id)); } - #[allow(clippy::too_many_lines)] + #[expect(clippy::too_many_lines)] pub(crate) fn update_sync_request_with_cache( &self, user_id: OwnedUserId, @@ -255,8 +255,10 @@ impl Service { } /// Check if a user is an admin - // Allowed because this function uses `services()` - #[allow(clippy::unused_self)] + #[expect( + clippy::unused_self, + reason = "Allowed because this function uses `services()`" + )] pub(crate) fn is_admin(&self, user_id: &UserId) -> Result { services().admin.get_admin_room()?.map_or(Ok(false), |admin_room_id| { services().rooms.state_cache.is_joined(user_id, &admin_room_id) diff --git a/src/utils.rs b/src/utils.rs index c9cafa56..386cb8a6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -21,8 +21,11 @@ use ruma::{ use crate::{Error, Result}; -// Hopefully we have a better chat protocol in 530 years -#[allow(clippy::as_conversions, clippy::cast_possible_truncation)] +#[expect( + clippy::as_conversions, + clippy::cast_possible_truncation, + reason = "Hopefully we have a better chat protocol in 530 years" +)] pub(crate) fn millis_since_unix_epoch() -> u64 { SystemTime::now() .duration_since(UNIX_EPOCH) @@ -252,7 +255,10 @@ pub(crate) fn dbg_truncate_str(s: &str, mut max_len: usize) -> Cow<'_, str> { if s.len() <= max_len { s.into() } else { - #[allow(clippy::string_slice)] // we checked it's at a char boundary + #[expect( + clippy::string_slice, + reason = "we checked it's at a char boundary" + )] format!("{}...", &s[..max_len]).into() } } diff --git a/src/utils/error.rs b/src/utils/error.rs index 49b5ab15..deacc557 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -16,7 +16,10 @@ use crate::Ra; pub(crate) type Result = std::result::Result; #[derive(Error, Debug)] -#[allow(clippy::error_impl_error)] +#[expect( + clippy::error_impl_error, + reason = "This is our one and only Error struct" +)] pub(crate) enum Error { #[cfg(feature = "sqlite")] #[error( diff --git a/src/utils/room_version.rs b/src/utils/room_version.rs index 389dc367..423e04d2 100644 --- a/src/utils/room_version.rs +++ b/src/utils/room_version.rs @@ -35,9 +35,11 @@ pub(crate) struct RoomVersion { pub(crate) redaction_event_redacts_in_content: bool, } -// Allowed so that we can use struct-update syntax for incremental changes -// between versions even when all fields change. -#[allow(clippy::needless_update)] +#[expect( + clippy::needless_update, + reason = "so that we can use struct-update syntax for incremental changes \ + between versions even when all fields change" +)] mod known_versions { use super::RoomVersion;