diff --git a/Cargo.lock b/Cargo.lock
index 486f78c5ab7..e786563c399 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -521,7 +521,6 @@ dependencies = [
  "limit",
  "mbe",
  "once_cell",
- "parser",
  "profile",
  "ra-ap-rustc_abi",
  "ra-ap-rustc_parse_format",
diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml
index 1076cab544e..523ff6fc404 100644
--- a/crates/hir-def/Cargo.toml
+++ b/crates/hir-def/Cargo.toml
@@ -44,7 +44,6 @@ cfg.workspace = true
 tt.workspace = true
 limit.workspace = true
 span.workspace = true
-parser.workspace = true
 
 
 [dev-dependencies]
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 67a9d541bcc..8904aca9f28 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -319,7 +319,7 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
         let (parse, _) = ::mbe::token_tree_to_syntax_node(
             subtree,
             ::mbe::TopEntryPoint::MacroItems,
-            parser::Edition::Edition2021,
+            span::Edition::CURRENT,
         );
         if parse.errors().is_empty() {
             Ok(subtree.clone())
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index ae8f028e488..0a74123abbc 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -534,8 +534,7 @@ impl DefCollector<'_> {
             Edition::Edition2015 => name![rust_2015],
             Edition::Edition2018 => name![rust_2018],
             Edition::Edition2021 => name![rust_2021],
-            // FIXME: update this when rust_2024 exists
-            Edition::Edition2024 => name![rust_2021],
+            Edition::Edition2024 => name![rust_2024],
         };
 
         let path_kind = match self.def_map.data.edition {
diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs
index f9fafa9c72b..94681b42a9b 100644
--- a/crates/hir-expand/src/builtin_derive_macro.rs
+++ b/crates/hir-expand/src/builtin_derive_macro.rs
@@ -207,7 +207,7 @@ fn parse_adt(tt: &tt::Subtree, call_site: Span) -> Result<BasicAdtInfo, ExpandEr
     let (parsed, tm) = &mbe::token_tree_to_syntax_node(
         tt,
         mbe::TopEntryPoint::MacroItems,
-        parser::Edition::Edition2021,
+        parser::Edition::CURRENT,
     );
     let macro_items = ast::MacroItems::cast(parsed.syntax_node())
         .ok_or_else(|| ExpandError::other("invalid item definition"))?;
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index 8fe7a04209e..0923aeb8597 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -676,7 +676,7 @@ fn token_tree_to_syntax_node(
         ExpandTo::Type => mbe::TopEntryPoint::Type,
         ExpandTo::Expr => mbe::TopEntryPoint::Expr,
     };
-    mbe::token_tree_to_syntax_node(tt, entry_point, parser::Edition::Edition2021)
+    mbe::token_tree_to_syntax_node(tt, entry_point, parser::Edition::CURRENT)
 }
 
 fn check_tt_count(tt: &tt::Subtree) -> Result<(), ExpandResult<()>> {
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index eed7d4a78eb..b33ae49a944 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -420,7 +420,7 @@ mod tests {
         let (parse, _) = mbe::token_tree_to_syntax_node(
             &tt,
             ::mbe::TopEntryPoint::MacroItems,
-            parser::Edition::Edition2021,
+            parser::Edition::CURRENT,
         );
         assert!(
             parse.errors().is_empty(),
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 0b69799e6bf..8f74bffc2b9 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -303,6 +303,7 @@ pub mod known {
         rust_2015,
         rust_2018,
         rust_2021,
+        rust_2024,
         v1,
         new_display,
         new_debug,
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index cd723494713..3d1885081f9 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -1157,7 +1157,7 @@ fn iterate_trait_method_candidates(
         {
             // FIXME: this should really be using the edition of the method name's span, in case it
             // comes from a macro
-            if db.crate_graph()[krate].edition < Edition::Edition2021 {
+            if db.crate_graph()[krate].edition < Edition::CURRENT {
                 continue;
             }
         }
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 2faef23ed17..cb6bad6e708 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -744,7 +744,7 @@ fn match_meta_var(
     let fragment = match kind {
         MetaVarKind::Path => {
             return input
-                .expect_fragment(parser::PrefixEntryPoint::Path, parser::Edition::Edition2021)
+                .expect_fragment(parser::PrefixEntryPoint::Path, parser::Edition::CURRENT)
                 .map(|it| {
                     it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
                 });
@@ -773,7 +773,7 @@ fn match_meta_var(
                 _ => {}
             };
             return input
-                .expect_fragment(parser::PrefixEntryPoint::Expr, parser::Edition::Edition2021)
+                .expect_fragment(parser::PrefixEntryPoint::Expr, parser::Edition::CURRENT)
                 .map(|tt| {
                     tt.map(|tt| match tt {
                         tt::TokenTree::Leaf(leaf) => tt::Subtree {
@@ -823,7 +823,7 @@ fn match_meta_var(
             return tt_result.map(|it| Some(Fragment::Tokens(it))).into();
         }
     };
-    input.expect_fragment(fragment, parser::Edition::Edition2021).map(|it| it.map(Fragment::Tokens))
+    input.expect_fragment(fragment, parser::Edition::CURRENT).map(|it| it.map(Fragment::Tokens))
 }
 
 fn collect_vars(collector_fun: &mut impl FnMut(SmolStr), pattern: &MetaTemplate) {
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index 7d1ac242da9..d2c42dcacc3 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -196,7 +196,7 @@ where
 
     while iter.peek_n(0).is_some() {
         let expanded =
-            iter.expect_fragment(parser::PrefixEntryPoint::Expr, parser::Edition::Edition2021);
+            iter.expect_fragment(parser::PrefixEntryPoint::Expr, parser::Edition::CURRENT);
 
         res.push(match expanded.value {
             None => break,
diff --git a/crates/parser/src/tests.rs b/crates/parser/src/tests.rs
index 6b5bde7a753..0e040965261 100644
--- a/crates/parser/src/tests.rs
+++ b/crates/parser/src/tests.rs
@@ -88,7 +88,7 @@ fn parse_inline_err() {
 fn parse(entry: TopEntryPoint, text: &str) -> (String, bool) {
     let lexed = LexedStr::new(text);
     let input = lexed.to_input();
-    let output = entry.parse(&input, crate::Edition::Edition2021);
+    let output = entry.parse(&input, crate::Edition::CURRENT);
 
     let mut buf = String::new();
     let mut errors = Vec::new();
diff --git a/crates/parser/src/tests/prefix_entries.rs b/crates/parser/src/tests/prefix_entries.rs
index ee8b2d1f43d..f92b39edb76 100644
--- a/crates/parser/src/tests/prefix_entries.rs
+++ b/crates/parser/src/tests/prefix_entries.rs
@@ -86,7 +86,7 @@ fn check(entry: PrefixEntryPoint, input: &str, prefix: &str) {
     let input = lexed.to_input();
 
     let mut n_tokens = 0;
-    for step in entry.parse(&input, crate::Edition::Edition2021).iter() {
+    for step in entry.parse(&input, crate::Edition::CURRENT).iter() {
         match step {
             Step::Token { n_input_tokens, .. } => n_tokens += n_input_tokens as usize,
             Step::FloatSplit { .. } => n_tokens += 1,
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index a8a91bc412d..a3455435e34 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -172,7 +172,7 @@ pub use crate::ast::SourceFile;
 impl SourceFile {
     pub fn parse(text: &str) -> Parse<SourceFile> {
         let _p = tracing::span!(tracing::Level::INFO, "SourceFile::parse").entered();
-        let (green, errors) = parsing::parse_text(text, parser::Edition::Edition2021);
+        let (green, errors) = parsing::parse_text(text, parser::Edition::CURRENT);
         let root = SyntaxNode::new_root(green.clone());
 
         assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs
index 5186d48c61c..43435056c45 100644
--- a/crates/syntax/src/parsing/reparsing.rs
+++ b/crates/syntax/src/parsing/reparsing.rs
@@ -27,7 +27,7 @@ pub(crate) fn incremental_reparse(
     }
 
     if let Some((green, new_errors, old_range)) =
-        reparse_block(node, edit, parser::Edition::Edition2021)
+        reparse_block(node, edit, parser::Edition::CURRENT)
     {
         return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
     }
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs
index 7ce83078cb5..fdca069dc82 100644
--- a/crates/test-fixture/src/lib.rs
+++ b/crates/test-fixture/src/lib.rs
@@ -260,7 +260,7 @@ impl ChangeFixture {
 
             let core_crate = crate_graph.add_crate_root(
                 core_file,
-                Edition::Edition2021,
+                Edition::CURRENT,
                 Some(CrateDisplayName::from_canonical_name("core".to_owned())),
                 None,
                 Default::default(),
@@ -299,7 +299,7 @@ impl ChangeFixture {
 
             let proc_macros_crate = crate_graph.add_crate_root(
                 proc_lib_file,
-                Edition::Edition2021,
+                Edition::CURRENT,
                 Some(CrateDisplayName::from_canonical_name("proc_macros".to_owned())),
                 None,
                 Default::default(),