From 392538c8303a9d82afa6bdb02219a3506c7b942b Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Tue, 30 Jan 2024 16:05:28 +0100 Subject: [PATCH 1/6] Add edition to parser struct --- crates/parser/src/lib.rs | 7 ++++--- crates/parser/src/parser.rs | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 86c771c0008..abce8e2f482 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -45,6 +45,7 @@ input::Input, lexed_str::LexedStr, output::{Output, Step}, + parser::Edition, shortcuts::StrStep, syntax_kind::SyntaxKind, }; @@ -98,7 +99,7 @@ pub fn parse(&self, input: &Input) -> Output { TopEntryPoint::MetaItem => grammar::entry::top::meta_item, TopEntryPoint::MacroEagerInput => grammar::entry::top::eager_macro_input, }; - let mut p = parser::Parser::new(input); + let mut p = parser::Parser::new(input, Edition::Edition2021); entry_point(&mut p); let events = p.finish(); let res = event::process(events); @@ -163,7 +164,7 @@ pub fn parse(&self, input: &Input) -> Output { PrefixEntryPoint::Item => grammar::entry::prefix::item, PrefixEntryPoint::MetaItem => grammar::entry::prefix::meta_item, }; - let mut p = parser::Parser::new(input); + let mut p = parser::Parser::new(input, Edition::Edition2021); entry_point(&mut p); let events = p.finish(); event::process(events) @@ -189,7 +190,7 @@ pub fn for_node( /// sequence. pub fn parse(self, tokens: &Input) -> Output { let Reparser(r) = self; - let mut p = parser::Parser::new(tokens); + let mut p = parser::Parser::new(tokens, Edition::Edition2021); r(&mut p); let events = p.finish(); event::process(events) diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index 051461243af..df53e13f6ef 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -26,13 +26,27 @@ pub(crate) struct Parser<'t> { pos: usize, events: Vec, steps: Cell, + edition: Edition, +} + +#[non_exhaustive] +pub enum Edition { + Edition2015, + Edition2018, + Edition2021, } static PARSER_STEP_LIMIT: Limit = Limit::new(15_000_000); impl<'t> Parser<'t> { - pub(super) fn new(inp: &'t Input) -> Parser<'t> { - Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0) } + pub(super) fn new(inp: &'t Input, edition: Edition) -> Parser<'t> { + Parser { + inp, + pos: 0, + events: Vec::new(), + steps: Cell::new(0), + edition, + } } pub(crate) fn finish(self) -> Vec { From 454e48142237b421db514330e8c26fb90c90affc Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Tue, 30 Jan 2024 16:45:10 +0100 Subject: [PATCH 2/6] Add edition to all `parse` functions of the parser crate --- crates/mbe/src/syntax_bridge.rs | 2 +- crates/mbe/src/tt_iter.rs | 2 +- crates/parser/src/lib.rs | 12 ++++++------ crates/parser/src/parser.rs | 8 +------- crates/parser/src/tests.rs | 2 +- crates/parser/src/tests/prefix_entries.rs | 2 +- crates/syntax/src/lib.rs | 3 ++- crates/syntax/src/parsing.rs | 3 ++- crates/syntax/src/parsing/reparsing.rs | 2 +- 9 files changed, 16 insertions(+), 20 deletions(-) diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index c934db6b715..a22bbf833aa 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs @@ -131,7 +131,7 @@ pub fn token_tree_to_syntax_node( _ => TokenBuffer::from_subtree(tt), }; let parser_input = to_parser_input(&buffer); - let parser_output = entry_point.parse(&parser_input); + let parser_output = entry_point.parse(&parser_input, parser::Edition::Edition2021); let mut tree_sink = TtTreeSink::new(buffer.begin()); for event in parser_output.iter() { match event { diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index e3d12d87078..12f7deafd6b 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs @@ -143,7 +143,7 @@ pub(crate) fn expect_fragment( ) -> ExpandResult>> { let buffer = tt::buffer::TokenBuffer::from_tokens(self.inner.as_slice()); let parser_input = to_parser_input(&buffer); - let tree_traversal = entry_point.parse(&parser_input); + let tree_traversal = entry_point.parse(&parser_input, parser::Edition::Edition2021); let mut cursor = buffer.begin(); let mut error = false; for step in tree_traversal.iter() { diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index abce8e2f482..f29fba08dd3 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -87,7 +87,7 @@ pub enum TopEntryPoint { } impl TopEntryPoint { - pub fn parse(&self, input: &Input) -> Output { + pub fn parse(&self, input: &Input, edition: Edition) -> Output { let _p = tracing::span!(tracing::Level::INFO, "TopEntryPoint::parse", ?self).entered(); let entry_point: fn(&'_ mut parser::Parser<'_>) = match self { TopEntryPoint::SourceFile => grammar::entry::top::source_file, @@ -99,7 +99,7 @@ pub fn parse(&self, input: &Input) -> Output { TopEntryPoint::MetaItem => grammar::entry::top::meta_item, TopEntryPoint::MacroEagerInput => grammar::entry::top::eager_macro_input, }; - let mut p = parser::Parser::new(input, Edition::Edition2021); + let mut p = parser::Parser::new(input, edition); entry_point(&mut p); let events = p.finish(); let res = event::process(events); @@ -151,7 +151,7 @@ pub enum PrefixEntryPoint { } impl PrefixEntryPoint { - pub fn parse(&self, input: &Input) -> Output { + pub fn parse(&self, input: &Input, edition: Edition) -> Output { let entry_point: fn(&'_ mut parser::Parser<'_>) = match self { PrefixEntryPoint::Vis => grammar::entry::prefix::vis, PrefixEntryPoint::Block => grammar::entry::prefix::block, @@ -164,7 +164,7 @@ pub fn parse(&self, input: &Input) -> Output { PrefixEntryPoint::Item => grammar::entry::prefix::item, PrefixEntryPoint::MetaItem => grammar::entry::prefix::meta_item, }; - let mut p = parser::Parser::new(input, Edition::Edition2021); + let mut p = parser::Parser::new(input, edition); entry_point(&mut p); let events = p.finish(); event::process(events) @@ -188,9 +188,9 @@ pub fn for_node( /// /// Tokens must start with `{`, end with `}` and form a valid brace /// sequence. - pub fn parse(self, tokens: &Input) -> Output { + pub fn parse(self, tokens: &Input, edition: Edition) -> Output { let Reparser(r) = self; - let mut p = parser::Parser::new(tokens, Edition::Edition2021); + let mut p = parser::Parser::new(tokens, edition); r(&mut p); let events = p.finish(); event::process(events) diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index df53e13f6ef..eb8f761a916 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -40,13 +40,7 @@ pub enum Edition { impl<'t> Parser<'t> { pub(super) fn new(inp: &'t Input, edition: Edition) -> Parser<'t> { - Parser { - inp, - pos: 0, - events: Vec::new(), - steps: Cell::new(0), - edition, - } + Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0), edition } } pub(crate) fn finish(self) -> Vec { diff --git a/crates/parser/src/tests.rs b/crates/parser/src/tests.rs index c65219b28dc..6b5bde7a753 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); + let output = entry.parse(&input, crate::Edition::Edition2021); 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 2f3c7febc04..ee8b2d1f43d 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).iter() { + for step in entry.parse(&input, crate::Edition::Edition2021).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 1bb82cc191f..41f560fce2f 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -219,7 +219,8 @@ pub fn reparse_as_comma_separated_expr(self) -> Parse { } } - let parser_output = parser::TopEntryPoint::MacroEagerInput.parse(&parser_input); + let parser_output = parser::TopEntryPoint::MacroEagerInput + .parse(&parser_input, parser::Edition::Edition2021); let mut tokens = self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token); diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs index d750476f63c..35683c9eed9 100644 --- a/crates/syntax/src/parsing.rs +++ b/crates/syntax/src/parsing.rs @@ -13,7 +13,8 @@ pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { let _p = tracing::span!(tracing::Level::INFO, "parse_text").entered(); let lexed = parser::LexedStr::new(text); let parser_input = lexed.to_input(); - let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input); + let parser_output = + parser::TopEntryPoint::SourceFile.parse(&parser_input, parser::Edition::Edition2021); let (node, errors, _eof) = build_tree(lexed, parser_output); (node, errors) } diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 14715b57253..3f48bdddfaf 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs @@ -94,7 +94,7 @@ fn reparse_block( return None; } - let tree_traversal = reparser.parse(&parser_input); + let tree_traversal = reparser.parse(&parser_input, parser::Edition::Edition2021); let (green, new_parser_errors, _eof) = build_tree(lexed, tree_traversal); From 2cf5d8811a4f7467f7c2277483dcd319e57ea549 Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Tue, 30 Jan 2024 16:57:40 +0100 Subject: [PATCH 3/6] Raise edition one more level --- Cargo.lock | 2 + crates/hir-def/Cargo.toml | 1 + .../hir-def/src/macro_expansion_tests/mod.rs | 7 +++- crates/hir-expand/Cargo.toml | 1 + crates/hir-expand/src/builtin_derive_macro.rs | 6 ++- crates/hir-expand/src/db.rs | 2 +- crates/hir-expand/src/fixup.rs | 6 ++- crates/mbe/src/expander/matcher.rs | 40 ++++++++++--------- crates/mbe/src/syntax_bridge.rs | 6 ++- crates/mbe/src/tt_iter.rs | 3 +- crates/syntax/src/lib.rs | 10 +++-- crates/syntax/src/parsing.rs | 5 +-- crates/syntax/src/parsing/reparsing.rs | 7 +++- 13 files changed, 61 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1209cee03c0..0de4ae46df4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,6 +521,7 @@ dependencies = [ "limit", "mbe", "once_cell", + "parser", "profile", "ra-ap-rustc_abi", "ra-ap-rustc_parse_format", @@ -551,6 +552,7 @@ dependencies = [ "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "limit", "mbe", + "parser", "rustc-hash", "smallvec", "span", diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml index 523ff6fc404..1076cab544e 100644 --- a/crates/hir-def/Cargo.toml +++ b/crates/hir-def/Cargo.toml @@ -44,6 +44,7 @@ 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 23b10cfd8e6..67a9d541bcc 100644 --- a/crates/hir-def/src/macro_expansion_tests/mod.rs +++ b/crates/hir-def/src/macro_expansion_tests/mod.rs @@ -316,8 +316,11 @@ fn expand( _: Span, _: Span, ) -> Result { - let (parse, _) = - ::mbe::token_tree_to_syntax_node(subtree, ::mbe::TopEntryPoint::MacroItems); + let (parse, _) = ::mbe::token_tree_to_syntax_node( + subtree, + ::mbe::TopEntryPoint::MacroItems, + parser::Edition::Edition2021, + ); if parse.errors().is_empty() { Ok(subtree.clone()) } else { diff --git a/crates/hir-expand/Cargo.toml b/crates/hir-expand/Cargo.toml index 4f308080156..a9eeb58b2ba 100644 --- a/crates/hir-expand/Cargo.toml +++ b/crates/hir-expand/Cargo.toml @@ -32,6 +32,7 @@ tt.workspace = true mbe.workspace = true limit.workspace = true span.workspace = true +parser.workspace = true [dev-dependencies] expect-test = "1.4.0" diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs index 528038a9ccf..f9fafa9c72b 100644 --- a/crates/hir-expand/src/builtin_derive_macro.rs +++ b/crates/hir-expand/src/builtin_derive_macro.rs @@ -204,7 +204,11 @@ struct BasicAdtInfo { } fn parse_adt(tt: &tt::Subtree, call_site: Span) -> Result { - let (parsed, tm) = &mbe::token_tree_to_syntax_node(tt, mbe::TopEntryPoint::MacroItems); + let (parsed, tm) = &mbe::token_tree_to_syntax_node( + tt, + mbe::TopEntryPoint::MacroItems, + parser::Edition::Edition2021, + ); let macro_items = ast::MacroItems::cast(parsed.syntax_node()) .ok_or_else(|| ExpandError::other("invalid item definition"))?; let item = macro_items.items().next().ok_or_else(|| ExpandError::other("no item found"))?; diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index a961ad14a6f..8fe7a04209e 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) + mbe::token_tree_to_syntax_node(tt, entry_point, parser::Edition::Edition2021) } 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 959595afb57..eed7d4a78eb 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -417,7 +417,11 @@ fn check(ra_fixture: &str, mut expect: Expect) { expect.assert_eq(&actual); // the fixed-up tree should be syntactically valid - let (parse, _) = mbe::token_tree_to_syntax_node(&tt, ::mbe::TopEntryPoint::MacroItems); + let (parse, _) = mbe::token_tree_to_syntax_node( + &tt, + ::mbe::TopEntryPoint::MacroItems, + parser::Edition::Edition2021, + ); assert!( parse.errors().is_empty(), "parse has syntax errors. parse tree:\n{:#?}", diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs index 3170834d54f..2faef23ed17 100644 --- a/crates/mbe/src/expander/matcher.rs +++ b/crates/mbe/src/expander/matcher.rs @@ -743,9 +743,11 @@ fn match_meta_var( ) -> ExpandResult> { let fragment = match kind { MetaVarKind::Path => { - return input.expect_fragment(parser::PrefixEntryPoint::Path).map(|it| { - it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path) - }); + return input + .expect_fragment(parser::PrefixEntryPoint::Path, parser::Edition::Edition2021) + .map(|it| { + it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path) + }); } MetaVarKind::Ty => parser::PrefixEntryPoint::Ty, MetaVarKind::Pat => parser::PrefixEntryPoint::PatTop, @@ -770,21 +772,23 @@ fn match_meta_var( } _ => {} }; - return input.expect_fragment(parser::PrefixEntryPoint::Expr).map(|tt| { - tt.map(|tt| match tt { - tt::TokenTree::Leaf(leaf) => tt::Subtree { - delimiter: tt::Delimiter::invisible_spanned(*leaf.span()), - token_trees: Box::new([leaf.into()]), - }, - tt::TokenTree::Subtree(mut s) => { - if s.delimiter.kind == tt::DelimiterKind::Invisible { - s.delimiter.kind = tt::DelimiterKind::Parenthesis; + return input + .expect_fragment(parser::PrefixEntryPoint::Expr, parser::Edition::Edition2021) + .map(|tt| { + tt.map(|tt| match tt { + tt::TokenTree::Leaf(leaf) => tt::Subtree { + delimiter: tt::Delimiter::invisible_spanned(*leaf.span()), + token_trees: Box::new([leaf.into()]), + }, + tt::TokenTree::Subtree(mut s) => { + if s.delimiter.kind == tt::DelimiterKind::Invisible { + s.delimiter.kind = tt::DelimiterKind::Parenthesis; + } + s } - s - } - }) - .map(Fragment::Expr) - }); + }) + .map(Fragment::Expr) + }); } MetaVarKind::Ident | MetaVarKind::Tt | MetaVarKind::Lifetime | MetaVarKind::Literal => { let tt_result = match kind { @@ -819,7 +823,7 @@ fn match_meta_var( return tt_result.map(|it| Some(Fragment::Tokens(it))).into(); } }; - input.expect_fragment(fragment).map(|it| it.map(Fragment::Tokens)) + input.expect_fragment(fragment, parser::Edition::Edition2021).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 a22bbf833aa..7d1ac242da9 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs @@ -119,6 +119,7 @@ pub fn syntax_node_to_token_tree_modified( pub fn token_tree_to_syntax_node( tt: &tt::Subtree>, entry_point: parser::TopEntryPoint, + edition: parser::Edition, ) -> (Parse, SpanMap) where SpanData: Copy + fmt::Debug, @@ -131,7 +132,7 @@ pub fn token_tree_to_syntax_node( _ => TokenBuffer::from_subtree(tt), }; let parser_input = to_parser_input(&buffer); - let parser_output = entry_point.parse(&parser_input, parser::Edition::Edition2021); + let parser_output = entry_point.parse(&parser_input, edition); let mut tree_sink = TtTreeSink::new(buffer.begin()); for event in parser_output.iter() { match event { @@ -194,7 +195,8 @@ pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char, span: S) -> Vec break, diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index 12f7deafd6b..9c7d7af7b14 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs @@ -140,10 +140,11 @@ impl<'a, S: Copy + fmt::Debug> TtIter<'a, S> { pub(crate) fn expect_fragment( &mut self, entry_point: parser::PrefixEntryPoint, + edition: parser::Edition, ) -> ExpandResult>> { let buffer = tt::buffer::TokenBuffer::from_tokens(self.inner.as_slice()); let parser_input = to_parser_input(&buffer); - let tree_traversal = entry_point.parse(&parser_input, parser::Edition::Edition2021); + let tree_traversal = entry_point.parse(&parser_input, edition); let mut cursor = buffer.begin(); let mut error = false; for step in tree_traversal.iter() { diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 41f560fce2f..1c628a948c2 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -172,7 +172,7 @@ fn full_reparse(&self, indel: &Indel) -> Parse { impl SourceFile { pub fn parse(text: &str) -> Parse { let _p = tracing::span!(tracing::Level::INFO, "SourceFile::parse").entered(); - let (green, errors) = parsing::parse_text(text); + let (green, errors) = parsing::parse_text(text, parser::Edition::Edition2021); let root = SyntaxNode::new_root(green.clone()); assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); @@ -185,7 +185,10 @@ pub fn parse(text: &str) -> Parse { } impl ast::TokenTree { - pub fn reparse_as_comma_separated_expr(self) -> Parse { + pub fn reparse_as_comma_separated_expr( + self, + edition: parser::Edition, + ) -> Parse { let tokens = self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token); let mut parser_input = parser::Input::default(); @@ -219,8 +222,7 @@ pub fn reparse_as_comma_separated_expr(self) -> Parse { } } - let parser_output = parser::TopEntryPoint::MacroEagerInput - .parse(&parser_input, parser::Edition::Edition2021); + let parser_output = parser::TopEntryPoint::MacroEagerInput.parse(&parser_input, edition); let mut tokens = self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token); diff --git a/crates/syntax/src/parsing.rs b/crates/syntax/src/parsing.rs index 35683c9eed9..420f4938e54 100644 --- a/crates/syntax/src/parsing.rs +++ b/crates/syntax/src/parsing.rs @@ -9,12 +9,11 @@ pub(crate) use crate::parsing::reparsing::incremental_reparse; -pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec) { +pub(crate) fn parse_text(text: &str, edition: parser::Edition) -> (GreenNode, Vec) { let _p = tracing::span!(tracing::Level::INFO, "parse_text").entered(); let lexed = parser::LexedStr::new(text); let parser_input = lexed.to_input(); - let parser_output = - parser::TopEntryPoint::SourceFile.parse(&parser_input, parser::Edition::Edition2021); + let parser_output = parser::TopEntryPoint::SourceFile.parse(&parser_input, edition); let (node, errors, _eof) = build_tree(lexed, parser_output); (node, errors) } diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 3f48bdddfaf..5186d48c61c 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs @@ -26,7 +26,9 @@ pub(crate) fn incremental_reparse( return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range)); } - if let Some((green, new_errors, old_range)) = reparse_block(node, edit) { + if let Some((green, new_errors, old_range)) = + reparse_block(node, edit, parser::Edition::Edition2021) + { return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range)); } None @@ -84,6 +86,7 @@ fn reparse_token( fn reparse_block( root: &SyntaxNode, edit: &Indel, + edition: parser::Edition, ) -> Option<(GreenNode, Vec, TextRange)> { let (node, reparser) = find_reparsable_node(root, edit.delete)?; let text = get_text_after_edit(node.clone().into(), edit); @@ -94,7 +97,7 @@ fn reparse_block( return None; } - let tree_traversal = reparser.parse(&parser_input, parser::Edition::Edition2021); + let tree_traversal = reparser.parse(&parser_input, edition); let (green, new_parser_errors, _eof) = build_tree(lexed, tree_traversal); From e7852803c574f450978030e89c91afc55e0a1864 Mon Sep 17 00:00:00 2001 From: Johann Hemmann Date: Tue, 30 Jan 2024 17:01:38 +0100 Subject: [PATCH 4/6] Mark edition field as unused --- crates/parser/src/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index eb8f761a916..f48073701e4 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -26,7 +26,7 @@ pub(crate) struct Parser<'t> { pos: usize, events: Vec, steps: Cell, - edition: Edition, + _edition: Edition, } #[non_exhaustive] @@ -40,7 +40,7 @@ pub enum Edition { impl<'t> Parser<'t> { pub(super) fn new(inp: &'t Input, edition: Edition) -> Parser<'t> { - Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0), edition } + Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0), _edition: edition } } pub(crate) fn finish(self) -> Vec { From 9c75e9fa7d2738c206a43c57297c719d6cc62382 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 14 Apr 2024 15:29:01 +0200 Subject: [PATCH 5/6] Deduplicate Edition enum --- Cargo.lock | 1 + crates/parser/src/edition.rs | 55 ++++++++++++++++++++++++++++++++++++ crates/parser/src/lib.rs | 3 +- crates/parser/src/parser.rs | 8 +----- crates/span/Cargo.toml | 1 + crates/span/src/lib.rs | 53 ++-------------------------------- crates/span/src/map.rs | 4 +-- crates/syntax/src/lib.rs | 2 +- 8 files changed, 65 insertions(+), 62 deletions(-) create mode 100644 crates/parser/src/edition.rs diff --git a/Cargo.lock b/Cargo.lock index 0de4ae46df4..486f78c5ab7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1823,6 +1823,7 @@ dependencies = [ "salsa", "stdx", "syntax", + "text-size", "vfs", ] diff --git a/crates/parser/src/edition.rs b/crates/parser/src/edition.rs new file mode 100644 index 00000000000..26178544f9b --- /dev/null +++ b/crates/parser/src/edition.rs @@ -0,0 +1,55 @@ +//! The edition of the Rust language used in a crate. +// Ideally this would be defined in the span crate, but the dependency chain is all over the place +// wrt to span, parser and syntax. +use std::fmt; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Edition { + Edition2015, + Edition2018, + Edition2021, + Edition2024, +} + +impl Edition { + pub const CURRENT: Edition = Edition::Edition2021; + pub const DEFAULT: Edition = Edition::Edition2015; +} + +#[derive(Debug)] +pub struct ParseEditionError { + invalid_input: String, +} + +impl std::error::Error for ParseEditionError {} +impl fmt::Display for ParseEditionError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "invalid edition: {:?}", self.invalid_input) + } +} + +impl std::str::FromStr for Edition { + type Err = ParseEditionError; + + fn from_str(s: &str) -> Result { + let res = match s { + "2015" => Edition::Edition2015, + "2018" => Edition::Edition2018, + "2021" => Edition::Edition2021, + "2024" => Edition::Edition2024, + _ => return Err(ParseEditionError { invalid_input: s.to_owned() }), + }; + Ok(res) + } +} + +impl fmt::Display for Edition { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Edition::Edition2015 => "2015", + Edition::Edition2018 => "2018", + Edition::Edition2021 => "2021", + Edition::Edition2024 => "2024", + }) + } +} diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index f29fba08dd3..c7ad025f6b0 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -26,6 +26,7 @@ #[cfg(feature = "in-rust-tree")] extern crate rustc_lexer; +mod edition; mod event; mod grammar; mod input; @@ -42,10 +43,10 @@ pub(crate) use token_set::TokenSet; pub use crate::{ + edition::Edition, input::Input, lexed_str::LexedStr, output::{Output, Step}, - parser::Edition, shortcuts::StrStep, syntax_kind::SyntaxKind, }; diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index f48073701e4..5b901f911dc 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -8,6 +8,7 @@ use crate::{ event::Event, input::Input, + Edition, SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, TokenSet, T, }; @@ -29,13 +30,6 @@ pub(crate) struct Parser<'t> { _edition: Edition, } -#[non_exhaustive] -pub enum Edition { - Edition2015, - Edition2018, - Edition2021, -} - static PARSER_STEP_LIMIT: Limit = Limit::new(15_000_000); impl<'t> Parser<'t> { diff --git a/crates/span/Cargo.toml b/crates/span/Cargo.toml index cbda91f0a59..9f85f0107cc 100644 --- a/crates/span/Cargo.toml +++ b/crates/span/Cargo.toml @@ -14,6 +14,7 @@ la-arena.workspace = true salsa.workspace = true rustc-hash.workspace = true hashbrown.workspace = true +text-size.workspace = true # local deps vfs.workspace = true diff --git a/crates/span/src/lib.rs b/crates/span/src/lib.rs index c9109c72d0d..8ca7bc2d38a 100644 --- a/crates/span/src/lib.rs +++ b/crates/span/src/lib.rs @@ -13,59 +13,10 @@ map::{RealSpanMap, SpanMap}, }; -pub use syntax::{TextRange, TextSize}; +pub use syntax::Edition; +pub use text_size::{TextRange, TextSize}; pub use vfs::FileId; -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Edition { - Edition2015, - Edition2018, - Edition2021, - Edition2024, -} - -impl Edition { - pub const CURRENT: Edition = Edition::Edition2021; - pub const DEFAULT: Edition = Edition::Edition2015; -} - -#[derive(Debug)] -pub struct ParseEditionError { - invalid_input: String, -} - -impl std::error::Error for ParseEditionError {} -impl fmt::Display for ParseEditionError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "invalid edition: {:?}", self.invalid_input) - } -} - -impl std::str::FromStr for Edition { - type Err = ParseEditionError; - - fn from_str(s: &str) -> Result { - let res = match s { - "2015" => Edition::Edition2015, - "2018" => Edition::Edition2018, - "2021" => Edition::Edition2021, - "2024" => Edition::Edition2024, - _ => return Err(ParseEditionError { invalid_input: s.to_owned() }), - }; - Ok(res) - } -} - -impl fmt::Display for Edition { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match self { - Edition::Edition2015 => "2015", - Edition::Edition2018 => "2018", - Edition::Edition2021 => "2021", - Edition::Edition2024 => "2024", - }) - } -} #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct FilePosition { pub file_id: FileId, diff --git a/crates/span/src/map.rs b/crates/span/src/map.rs index 1f396a1e97b..6d8c9c30fb5 100644 --- a/crates/span/src/map.rs +++ b/crates/span/src/map.rs @@ -4,11 +4,11 @@ use std::{fmt, hash::Hash}; use stdx::{always, itertools::Itertools}; -use syntax::{TextRange, TextSize}; use vfs::FileId; use crate::{ - ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContextId, ROOT_ERASED_FILE_AST_ID, + ErasedFileAstId, Span, SpanAnchor, SpanData, SyntaxContextId, TextRange, TextSize, + ROOT_ERASED_FILE_AST_ID, }; /// Maps absolute text ranges for the corresponding file to the relevant span data. diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 1c628a948c2..a8a91bc412d 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -60,7 +60,7 @@ }, token_text::TokenText, }; -pub use parser::{SyntaxKind, T}; +pub use parser::{Edition, SyntaxKind, T}; pub use rowan::{ api::Preorder, Direction, GreenNode, NodeOrToken, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent, From 83370fe5d7506b0542686042c41d8518a1130adb Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 14 Apr 2024 15:29:09 +0200 Subject: [PATCH 6/6] Use Edition::CURRENT --- Cargo.lock | 1 - crates/hir-def/Cargo.toml | 1 - crates/hir-def/src/macro_expansion_tests/mod.rs | 2 +- crates/hir-def/src/nameres/collector.rs | 3 +-- crates/hir-expand/src/builtin_derive_macro.rs | 2 +- crates/hir-expand/src/db.rs | 2 +- crates/hir-expand/src/fixup.rs | 2 +- crates/hir-expand/src/name.rs | 1 + crates/hir-ty/src/method_resolution.rs | 2 +- crates/mbe/src/expander/matcher.rs | 6 +++--- crates/mbe/src/syntax_bridge.rs | 2 +- crates/parser/src/tests.rs | 2 +- crates/parser/src/tests/prefix_entries.rs | 2 +- crates/syntax/src/lib.rs | 2 +- crates/syntax/src/parsing/reparsing.rs | 2 +- crates/test-fixture/src/lib.rs | 4 ++-- 16 files changed, 17 insertions(+), 19 deletions(-) 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 @@ fn expand( 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 @@ fn inject_prelude(&mut self) { 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 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 @@ fn check(ra_fixture: &str, mut expect: Expect) { 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 @@ macro_rules! known_names { 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 @@ pub fn parse_exprs_with_sep(tt: &tt::Subtree, sep: char, span: S) -> Vec 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 @@ fn full_reparse(&self, indel: &Indel) -> Parse { impl SourceFile { pub fn parse(text: &str) -> Parse { 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 @@ pub fn parse_with_proc_macros( 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 @@ pub fn parse_with_proc_macros( 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(),