diff --git a/.cargo/config.toml b/.cargo/config.toml index 2e7aff007..c261699d2 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -45,9 +45,8 @@ rustflags = [ "-Wclippy::rc_buffer", "-Wclippy::rc_mutex", "-Wclippy::rest_pat_in_fully_bound_structs", - # "-Wclippy::same_name_method", # broke bitflags v2 "-Wclippy::unnecessary_safety_comment", - # TODO "-Wclippy::undocumented_unsafe_blocks", + "-Wclippy::undocumented_unsafe_blocks", # pedantic diff --git a/crates/oxc_allocator/src/arena.rs b/crates/oxc_allocator/src/arena.rs index c8adf7eac..74ee4c1a7 100644 --- a/crates/oxc_allocator/src/arena.rs +++ b/crates/oxc_allocator/src/arena.rs @@ -19,6 +19,7 @@ pub struct Box<'alloc, T: ?Sized>(pub &'alloc mut T); impl<'alloc, T> Box<'alloc, T> { pub fn unbox(self) -> T { + // SAFETY: // This pointer read is safe because the reference `self.0` is // guaranteed to be unique--not just now, but we're guaranteed it's not // borrowed from some other reference. This in turn is because we never diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index bd32ac7e1..d1b474056 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -58,6 +58,9 @@ impl<'a> AstBuilder<'a> { } pub fn copy(&self, src: &T) -> T { + // SAFETY: + // This should be safe as long as `src` is an reference from the allocator. + // But honestly, I'm not really sure if this is safe. unsafe { std::mem::transmute_copy(src) } } diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind.rs index 1e81c7390..5365fd426 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind.rs @@ -150,9 +150,13 @@ pub enum AstKind<'a> { TSPropertySignature(&'a TSPropertySignature<'a>), } -// SAFETY: The AST is part of the bump allocator, +// SAFETY: +// The AST is part of the bump allocator, // it is our responsibility to never simultaneously mutate across threads. unsafe impl<'a> Send for AstKind<'a> {} +// SAFETY: +// The AST is part of the bump allocator, +// it is our responsibility to never simultaneously mutate across threads. unsafe impl<'a> Sync for AstKind<'a> {} impl<'a> AstKind<'a> { diff --git a/crates/oxc_ast/src/visit.rs b/crates/oxc_ast/src/visit.rs index a68dff724..ac0b709e6 100644 --- a/crates/oxc_ast/src/visit.rs +++ b/crates/oxc_ast/src/visit.rs @@ -20,6 +20,9 @@ pub trait Visit<'a>: Sized { fn leave_scope(&mut self) {} fn alloc(&self, t: &T) -> &'a T { + // SAFETY: + // This should be safe as long as `src` is an reference from the allocator. + // But honestly, I'm not really sure if this is safe. unsafe { std::mem::transmute(t) } } diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 098e27523..df617833c 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -959,7 +959,10 @@ fn print_non_negative_float(value: f64, _p: &Codegen<{ MINIF let chars = result.as_bytes(); let len = chars.len(); let dot = chars.iter().position(|&c| c == b'.'); - let u8_to_string = |num: &[u8]| unsafe { String::from_utf8_unchecked(num.to_vec()) }; + let u8_to_string = |num: &[u8]| { + // SAFETY: criterias of `from_utf8_unchecked`.are met. + unsafe { String::from_utf8_unchecked(num.to_vec()) } + }; if dot == Some(1) && chars[0] == b'0' { // Strip off the leading zero when minifying diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index d1f56eb91..0b19265c3 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -98,6 +98,7 @@ impl Codegen { } pub fn into_code(self) -> String { + // SAFETY: criterias of `from_utf8_unchecked`.are met. unsafe { String::from_utf8_unchecked(self.code) } } @@ -153,6 +154,7 @@ impl Codegen { } fn peek_nth(&self, n: usize) -> Option { + // SAFETY: criterias of `from_utf8_unchecked`.are met. unsafe { from_utf8_unchecked(self.code()) }.chars().nth_back(n) } diff --git a/crates/oxc_formatter/src/lib.rs b/crates/oxc_formatter/src/lib.rs index 2abedb88f..7ac33ecda 100644 --- a/crates/oxc_formatter/src/lib.rs +++ b/crates/oxc_formatter/src/lib.rs @@ -127,6 +127,7 @@ impl Formatter { #[inline] pub fn into_code(self) -> String { + // SAFETY: criterias of `from_utf8_unchecked`.are met. unsafe { String::from_utf8_unchecked(self.code) } } diff --git a/crates/oxc_parser/examples/multi-thread.rs b/crates/oxc_parser/examples/multi-thread.rs index a6deb5991..bfe761456 100644 --- a/crates/oxc_parser/examples/multi-thread.rs +++ b/crates/oxc_parser/examples/multi-thread.rs @@ -19,9 +19,10 @@ use std::{sync::Arc, thread}; /// Wrap the AST for unsafe `Send` and `Sync` struct BumpaloProgram<'a>(Program<'a>); -// SAFETY: It is now our responsibility to never simultaneously mutate the AST across threads. #[allow(clippy::non_send_fields_in_send_ty)] +// SAFETY: It is now our responsibility to never simultaneously mutate the AST across threads. unsafe impl<'a> Send for BumpaloProgram<'a> {} +// SAFETY: It is now our responsibility to never simultaneously mutate the AST across threads. unsafe impl<'a> Sync for BumpaloProgram<'a> {} /// `ouroboros` is used to "bind" the allocator and AST together to remove the lifetime. diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index ce108e046..02f377e20 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -41,6 +41,8 @@ impl<'a> Parser<'a> { /// Get current source text pub(crate) fn cur_src(&self) -> &'a str { let range = self.cur_token().span(); + // SAFETY: + // range comes from the parser, which are ensured to meeting the criteria of `get_unchecked`. unsafe { self.source_text.get_unchecked(range.start as usize..range.end as usize) } } diff --git a/crates/oxc_resolver/src/json_comments.rs b/crates/oxc_resolver/src/json_comments.rs index 08625a6ae..b3b27a1de 100644 --- a/crates/oxc_resolver/src/json_comments.rs +++ b/crates/oxc_resolver/src/json_comments.rs @@ -172,6 +172,8 @@ fn strip_buf(state: &mut State, buf: &mut [u8], settings: CommentSettings) -> Re /// /// ``` pub fn strip_comments_in_place(s: &mut str) -> Result<()> { + // SAFETY: + // The content of the slice is valid UTF-8. strip_buf(&mut Top, unsafe { s.as_bytes_mut() }, CommentSettings::all()) }