Repository: biomejs/biome (language: rust)

Issue:
📎 Update project to Rust 2024 edition
### Description

Upgrading Rust versions is always fun :) 

@siketyan wanna give it a shot?? 


Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 632702e3d3d2..5c43b1b76867 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,13 +12,6 @@ unused_import_braces                   = "warn"
 unused_lifetimes                       = "warn"
 unused_macro_rules                     = "warn"
 
-# Rust 2024 upgrade
-deprecated_safe_2024       = "warn"
-impl_trait_overcaptures    = "warn"
-keyword_idents_2024        = "warn"
-missing_unsafe_on_extern   = "warn"
-unsafe_attr_outside_unsafe = "warn"
-
 [workspace.lints.clippy]
 allow_attributes        = "deny"
 cargo_common_metadata   = "allow"
@@ -93,7 +86,7 @@ verbose_file_reads                = "warn"
 [workspace.package]
 authors    = ["Biome Developers and Contributors"]
 categories = ["development-tools", "web-programming"]
-edition    = "2021"
+edition    = "2024"
 homepage   = "https://biomejs.dev/"
 keywords   = ["parser", "linter", "formatter"]
 license    = "MIT OR Apache-2.0"
diff --git a/crates/biome_css_semantic/src/semantic_model/model.rs b/crates/biome_css_semantic/src/semantic_model/model.rs
index 30d6b17e6df2..9d4fe6204063 100644
--- a/crates/biome_css_semantic/src/semantic_model/model.rs
+++ b/crates/biome_css_semantic/src/semantic_model/model.rs
@@ -53,14 +53,14 @@ impl SemanticModel {
                 .range_to_rule
                 .iter()
                 .rev()
-                .find(|(&range, _)| range.contains_range(target_range))
+                .find(|&(&range, _)| range.contains_range(target_range))
                 .map(|(_, rule)| rule)
         } else {
             self.data
                 .range_to_rule
                 .range(..=target_range)
                 .rev()
-                .find(|(&range, _)| range.contains_range(target_range))
+                .find(|&(&range, _)| range.contains_range(target_range))
                 .map(|(_, rule)| rule)
         }
     }
diff --git a/crates/biome_formatter/src/macros.rs b/crates/biome_formatter/src/macros.rs
index 591a4cd93c31..95d87cbc38e9 100644
--- a/crates/biome_formatter/src/macros.rs
+++ b/crates/biome_formatter/src/macros.rs
@@ -328,12 +328,22 @@ macro_rules! format {
 /// [`MostExpanded`]: crate::format_element::BestFittingElement::most_expanded
 #[macro_export]
 macro_rules! best_fitting {
-    ($least_expanded:expr, $($tail:expr),+ $(,)?) => {{
-        #[expect(clippy::macro_metavars_in_unsafe)]
-        unsafe {
-            $crate::BestFitting::from_arguments_unchecked($crate::format_args!($least_expanded, $($tail),+))
-        }
-    }}
+    ($least_expanded:expr, $($tail:expr),+ $(,)?) => {
+        // FIXME: Using any block in this macro causes a "temporary value dropped while borrowed"
+        //        (E0716) error since Rust 2024 edition. It seems temporary lifetime extension is
+        //        not working correctly, so it is a compiler bug?
+        $crate::macros::__macro_helper::best_fitting($crate::format_args!($least_expanded, $($tail),+))
+    };
+}
+
+#[doc(hidden)]
+pub mod __macro_helper {
+    #[inline(always)]
+    pub fn best_fitting<Context>(
+        arguments: crate::Arguments<Context>,
+    ) -> crate::BestFitting<Context> {
+        unsafe { crate::BestFitting::from_arguments_unchecked(arguments) }
+    }
 }
 
 #[cfg(test)]
diff --git a/crates/biome_js_analyze/src/lint/suspicious/no_misleading_character_class.rs b/crates/biome_js_analyze/src/lint/suspicious/no_misleading_character_class.rs
index ed206455195d..3de0e2a79682 100644
--- a/crates/biome_js_analyze/src/lint/suspicious/no_misleading_character_class.rs
+++ b/crates/biome_js_analyze/src/lint/suspicious/no_misleading_character_class.rs
@@ -73,21 +73,29 @@ pub enum Message {
 impl Message {
     fn diagnostic(&self) -> &str {
         match self {
-            Self::CombiningClassOrVs16 => "A character class cannot match a character and a combining character.",
+            Self::CombiningClassOrVs16 => {
+                "A character class cannot match a character and a combining character."
+            }
             Self::SurrogatePairWithoutUFlag => {
                 "A character class cannot match a surrogate pair. Add the 'u' unicode flag to match against them."
             }
-            Self::EmojiModifier => "A character class cannot match an emoji with a skin tone modifier.",
+            Self::EmojiModifier => {
+                "A character class cannot match an emoji with a skin tone modifier."
+            }
             Self::RegionalIndicatorSymbol => {
                 "A character class cannot match a pair of regional indicator symbols."
             }
-            Self::JoinedCharSequence => "A character class cannot match a joined character sequence.",
+            Self::JoinedCharSequence => {
+                "A character class cannot match a joined character sequence."
+            }
         }
     }
 
     fn note(&self) -> &str {
         match self {
-            Self::CombiningClassOrVs16 => "A character and a combining character forms a new character. Replace the character class with an alternation.",
+            Self::CombiningClassOrVs16 => {
+                "A character and a combining character forms a new character. Replace the character class with an alternation."
+            }
             Self::SurrogatePairWithoutUFlag => {
                 "A surrogate pair forms a single codepoint, but is encoded as a pair of two characters. Without the unicode flag, the regex matches a single surrogate character."
             }
@@ -95,7 +103,9 @@ impl Message {
             Self::RegionalIndicatorSymbol => {
                 "A pair of regional indicator symbols encodes a country code. Replace the character class with an alternation."
             }
-            Self::JoinedCharSequence => "A zero width joiner composes several emojis into a new one. Replace the character class with an alternation.",
+            Self::JoinedCharSequence => {
+                "A zero width joiner composes several emojis into a new one. Replace the character class with an alternation."
+            }
         }
     }
 }
@@ -397,7 +407,7 @@ fn decode_unicode_escape_sequence(s: &str, is_in_string: bool) -> Option<Unicode
             .iter()
             .enumerate()
             .skip(offset + 3)
-            .find(|(_, &c)| c == b'}')?;
+            .find(|&(_, &c)| c == b'}')?;
         Some(UnicodeEscape {
             // SAFETY: slicing is safe because `{` is at `offset + 2` and `}` is at `end`.
             codepoint: u32::from_str_radix(&s[offset + 3..end], 16).ok()?,
diff --git a/crates/biome_wasm/Cargo.toml b/crates/biome_wasm/Cargo.toml
index c54b8ad0f841..354373f3b19c 100644
--- a/crates/biome_wasm/Cargo.toml
+++ b/crates/biome_wasm/Cargo.toml
@@ -2,7 +2,7 @@
 authors     = ["Biome Developers and Contributors"]
 categories  = ["development-tools", "web-programming"]
 description = "WebAssembly bindings to the Biome workspace API"
-edition     = "2021"
+edition     = "2024"
 homepage    = "https://biomejs.dev/"
 keywords    = ["parser", "linter", "formatter", "wasm"]
 license     = "MIT OR Apache-2.0"
diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml
index 18f00a11f500..715aa00f800d 100644
--- a/fuzz/Cargo.toml
+++ b/fuzz/Cargo.toml
@@ -3,7 +3,7 @@ name = "rome_fuzz"
 version = "0.0.0"
 authors = ["Addison Crump <research@addisoncrump.info>"]
 publish = false
-edition = "2021"
+edition = "2024"
 
 [features]
 default = ["libfuzzer"]
diff --git a/rustfmt.toml b/rustfmt.toml
index 43d4840c7995..953a33a39b86 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,1 +1,4 @@
 newline_style = "Unix"
+
+# TODO(siketyan): Re-format all files and upgrade to 2024 in a separated PR.
+style_edition = "2021"
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 595ef5c188fc..62f1a3b53118 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2021"
+edition = "2024"
 name    = "xtask"
 publish = false
 version = "0.0.0"
diff --git a/xtask/bench/Cargo.toml b/xtask/bench/Cargo.toml
index d2878477d631..dc189f773aeb 100644
--- a/xtask/bench/Cargo.toml
+++ b/xtask/bench/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2021"
+edition = "2024"
 name    = "xtask_bench"
 publish = false
 version = "0.0.0"
diff --git a/xtask/codegen/Cargo.toml b/xtask/codegen/Cargo.toml
index 88cbb1da120a..ee3b3cf59cc3 100644
--- a/xtask/codegen/Cargo.toml
+++ b/xtask/codegen/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2021"
+edition = "2024"
 name    = "xtask_codegen"
 publish = false
 version = "0.0.0"
diff --git a/xtask/coverage/Cargo.toml b/xtask/coverage/Cargo.toml
index 0c679b1a3a46..23bc1b48b28c 100644
--- a/xtask/coverage/Cargo.toml
+++ b/xtask/coverage/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2021"
+edition = "2024"
 name    = "xtask_coverage"
 publish = false
 version = "0.0.0"
diff --git a/xtask/libs_bench/Cargo.toml b/xtask/libs_bench/Cargo.toml
index e11513f5da65..729157ba329e 100644
--- a/xtask/libs_bench/Cargo.toml
+++ b/xtask/libs_bench/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-edition = "2021"
+edition = "2024"
 name    = "xtask_libs_bench"
 publish = false
 version = "0.0.0"
diff --git a/xtask/rules_check/Cargo.toml b/xtask/rules_check/Cargo.toml
index 7d5561c4ae74..943b7597c241 100644
--- a/xtask/rules_check/Cargo.toml
+++ b/xtask/rules_check/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 description = "Internal script to make sure that the metadata or the rules are correct"
-edition     = "2021"
+edition     = "2024"
 name        = "rules_check"
 publish     = false
 version     = "0.0.0"


Test patch: