Skip to content

Commit 91aa3f4

Browse files
committed
Auto merge of #17896 - Veykril:editioned-syntax-kinds, r=Veykril
internal: Properly check the edition for edition dependent syntax kinds This puts the current edition in a bunch of places, most of which I annoted with FIXMEs asside from the ones in ide-assists because I couldnt bother with those
2 parents 2b86639 + f90bdfc commit 91aa3f4

File tree

23 files changed

+347
-129
lines changed

23 files changed

+347
-129
lines changed

crates/hir-def/src/macro_expansion_tests/mod.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use hir_expand::{
2525
InFile, MacroFileId, MacroFileIdExt,
2626
};
2727
use intern::Symbol;
28-
use span::Span;
28+
use span::{Edition, Span};
2929
use stdx::{format_to, format_to_acc};
3030
use syntax::{
3131
ast::{self, edit::IndentLevel},
@@ -257,21 +257,25 @@ fn pretty_print_macro_expansion(
257257
(T![;] | T!['{'] | T!['}'], _) => "\n",
258258
(_, T!['}']) => "\n",
259259
(IDENT | LIFETIME_IDENT, IDENT | LIFETIME_IDENT) => " ",
260-
_ if prev_kind.is_keyword() && curr_kind.is_keyword() => " ",
261-
(IDENT, _) if curr_kind.is_keyword() => " ",
262-
(_, IDENT) if prev_kind.is_keyword() => " ",
260+
_ if prev_kind.is_keyword(Edition::CURRENT)
261+
&& curr_kind.is_keyword(Edition::CURRENT) =>
262+
{
263+
" "
264+
}
265+
(IDENT, _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
266+
(_, IDENT) if prev_kind.is_keyword(Edition::CURRENT) => " ",
263267
(T![>], IDENT) => " ",
264-
(T![>], _) if curr_kind.is_keyword() => " ",
268+
(T![>], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
265269
(T![->], _) | (_, T![->]) => " ",
266270
(T![&&], _) | (_, T![&&]) => " ",
267271
(T![,], _) => " ",
268272
(T![:], IDENT | T!['(']) => " ",
269-
(T![:], _) if curr_kind.is_keyword() => " ",
273+
(T![:], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
270274
(T![fn], T!['(']) => "",
271-
(T![']'], _) if curr_kind.is_keyword() => " ",
275+
(T![']'], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
272276
(T![']'], T![#]) => "\n",
273277
(T![Self], T![::]) => "",
274-
_ if prev_kind.is_keyword() => " ",
278+
_ if prev_kind.is_keyword(Edition::CURRENT) => " ",
275279
_ => "",
276280
};
277281

crates/hir-expand/src/name.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,17 @@ impl Name {
104104

105105
/// Resolve a name from the text of token.
106106
fn resolve(raw_text: &str) -> Name {
107+
// FIXME: Edition
107108
match raw_text.strip_prefix("r#") {
108109
// When `raw_text` starts with "r#" but the name does not coincide with any
109110
// keyword, we never need the prefix so we strip it.
110-
Some(text) if !is_raw_identifier(text) => Name::new_ref(text),
111+
Some(text) if !is_raw_identifier(text, span::Edition::CURRENT) => Name::new_ref(text),
111112
// Keywords (in the current edition) *can* be used as a name in earlier editions of
112113
// Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their
113114
// escaped form.
114-
None if is_raw_identifier(raw_text) => Name::new_text(&format!("r#{}", raw_text)),
115+
None if is_raw_identifier(raw_text, span::Edition::CURRENT) => {
116+
Name::new_text(&format!("r#{}", raw_text))
117+
}
115118
_ => Name::new_text(raw_text),
116119
}
117120
}

crates/ide-completion/src/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use ide_db::{
1515
};
1616
use syntax::{
1717
ast::{self, AttrKind, NameOrNameRef},
18-
AstNode, SmolStr,
18+
AstNode, Edition, SmolStr,
1919
SyntaxKind::{self, *},
2020
SyntaxToken, TextRange, TextSize, T,
2121
};
@@ -468,7 +468,8 @@ impl CompletionContext<'_> {
468468
TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
469469
}
470470
IDENT | LIFETIME_IDENT | UNDERSCORE | INT_NUMBER => self.original_token.text_range(),
471-
_ if kind.is_keyword() => self.original_token.text_range(),
471+
// FIXME: Edition
472+
_ if kind.is_keyword(Edition::CURRENT) => self.original_token.text_range(),
472473
_ => TextRange::empty(self.position.offset),
473474
}
474475
}

crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Utilities for formatting macro expanded nodes until we get a proper formatter.
2+
use span::Edition;
23
use syntax::{
34
ast::make,
45
ted::{self, Position},
@@ -131,5 +132,6 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
131132
}
132133

133134
fn is_text(k: SyntaxKind) -> bool {
134-
k.is_keyword() || k.is_literal() || k == IDENT || k == UNDERSCORE
135+
// FIXME: Edition
136+
k.is_keyword(Edition::CURRENT) || k.is_literal() || k == IDENT || k == UNDERSCORE
135137
}

crates/ide-db/src/syntax_helpers/node_ext.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Various helper functions to work with SyntaxNodes.
22
use itertools::Itertools;
33
use parser::T;
4+
use span::Edition;
45
use syntax::{
56
ast::{self, HasLoopBody, MacroCall, PathSegmentKind, VisibilityKind},
67
AstNode, AstToken, Preorder, RustLanguage, WalkEvent,
@@ -461,7 +462,8 @@ pub fn parse_tt_as_comma_sep_paths(input: ast::TokenTree) -> Option<Vec<ast::Pat
461462
let tokens =
462463
input.syntax().children_with_tokens().skip(1).map_while(|it| match it.into_token() {
463464
// seeing a keyword means the attribute is unclosed so stop parsing here
464-
Some(tok) if tok.kind().is_keyword() => None,
465+
// FIXME: Edition
466+
Some(tok) if tok.kind().is_keyword(Edition::CURRENT) => None,
465467
// don't include the right token tree parenthesis if it exists
466468
tok @ Some(_) if tok == r_paren => None,
467469
// only nodes that we can find are other TokenTrees, those are unexpected in this parse though

crates/ide/src/goto_definition.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use ide_db::{
1717
};
1818
use itertools::Itertools;
1919

20-
use span::FileId;
20+
use span::{Edition, FileId};
2121
use syntax::{
2222
ast::{self, HasLoopBody},
2323
match_ast, AstNode, AstToken,
@@ -55,7 +55,7 @@ pub(crate) fn goto_definition(
5555
| COMMENT => 4,
5656
// index and prefix ops
5757
T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
58-
kind if kind.is_keyword() => 2,
58+
kind if kind.is_keyword(Edition::CURRENT) => 2,
5959
T!['('] | T![')'] => 2,
6060
kind if kind.is_trivia() => 0,
6161
_ => 1,

crates/ide/src/highlight_related.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ide_db::{
1111
},
1212
FxHashMap, FxHashSet, RootDatabase,
1313
};
14-
use span::EditionedFileId;
14+
use span::{Edition, EditionedFileId};
1515
use syntax::{
1616
ast::{self, HasLoopBody},
1717
match_ast, AstNode,
@@ -65,7 +65,7 @@ pub(crate) fn highlight_related(
6565
let token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind {
6666
T![?] => 4, // prefer `?` when the cursor is sandwiched like in `await$0?`
6767
T![->] => 4,
68-
kind if kind.is_keyword() => 3,
68+
kind if kind.is_keyword(Edition::CURRENT) => 3,
6969
IDENT | INT_NUMBER => 2,
7070
T![|] => 1,
7171
_ => 0,

crates/ide/src/hover.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use ide_db::{
1414
FileRange, FxIndexSet, RootDatabase,
1515
};
1616
use itertools::{multizip, Itertools};
17+
use span::Edition;
1718
use syntax::{ast, AstNode, SyntaxKind::*, SyntaxNode, T};
1819

1920
use crate::{
@@ -140,7 +141,7 @@ fn hover_simple(
140141
| T![_] => 4,
141142
// index and prefix ops and closure pipe
142143
T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] | T![|] => 3,
143-
kind if kind.is_keyword() => 2,
144+
kind if kind.is_keyword(Edition::CURRENT) => 2,
144145
T!['('] | T![')'] => 2,
145146
kind if kind.is_trivia() => 0,
146147
_ => 1,

crates/ide/src/hover/render.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_apfloat::{
2020
ieee::{Half as f16, Quad as f128},
2121
Float,
2222
};
23+
use span::Edition;
2324
use stdx::format_to;
2425
use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T};
2526

@@ -251,7 +252,7 @@ pub(super) fn keyword(
251252
config: &HoverConfig,
252253
token: &SyntaxToken,
253254
) -> Option<HoverResult> {
254-
if !token.kind().is_keyword() || !config.documentation || !config.keywords {
255+
if !token.kind().is_keyword(Edition::CURRENT) || !config.documentation || !config.keywords {
255256
return None;
256257
}
257258
let parent = token.parent()?;

crates/ide/src/references.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use ide_db::{
1717
};
1818
use itertools::Itertools;
1919
use nohash_hasher::IntMap;
20+
use span::Edition;
2021
use syntax::{
2122
ast::{self, HasName},
2223
match_ast, AstNode,
@@ -305,7 +306,8 @@ fn handle_control_flow_keywords(
305306
FilePosition { file_id, offset }: FilePosition,
306307
) -> Option<ReferenceSearchResult> {
307308
let file = sema.parse_guess_edition(file_id);
308-
let token = file.syntax().token_at_offset(offset).find(|t| t.kind().is_keyword())?;
309+
let token =
310+
file.syntax().token_at_offset(offset).find(|t| t.kind().is_keyword(Edition::CURRENT))?;
309311

310312
let references = match token.kind() {
311313
T![fn] | T![return] | T![try] => highlight_related::highlight_exit_points(sema, token),

crates/ide/src/rename.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
use hir::{AsAssocItem, HirFileIdExt, InFile, Semantics};
88
use ide_db::{
9+
base_db::SourceDatabase,
910
defs::{Definition, NameClass, NameRefClass},
1011
rename::{bail, format_err, source_edit_from_references, IdentifierKind},
1112
source_change::SourceChangeBuilder,
@@ -162,11 +163,12 @@ pub(crate) fn will_rename_file(
162163
let sema = Semantics::new(db);
163164
let module = sema.file_to_module_def(file_id)?;
164165
let def = Definition::Module(module);
165-
let mut change = if is_raw_identifier(new_name_stem) {
166-
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
167-
} else {
168-
def.rename(&sema, new_name_stem).ok()?
169-
};
166+
let mut change =
167+
if is_raw_identifier(new_name_stem, db.crate_graph()[module.krate().into()].edition) {
168+
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
169+
} else {
170+
def.rename(&sema, new_name_stem).ok()?
171+
};
170172
change.file_system_edits.clear();
171173
Some(change)
172174
}

crates/ide/src/syntax_highlighting/highlight.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ide_db::{
66
defs::{Definition, IdentClass, NameClass, NameRefClass},
77
FxHashMap, RootDatabase, SymbolKind,
88
};
9+
use span::Edition;
910
use stdx::hash_once;
1011
use syntax::{
1112
ast, match_ast, AstNode, AstToken, NodeOrToken,
@@ -41,7 +42,7 @@ pub(super) fn token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> O
4142
HlTag::None.into()
4243
}
4344
p if p.is_punct() => punctuation(sema, token, p),
44-
k if k.is_keyword() => keyword(sema, token, k)?,
45+
k if k.is_keyword(Edition::CURRENT) => keyword(sema, token, k)?,
4546
_ => return None,
4647
};
4748
Some(highlight)

crates/ide/src/syntax_highlighting/macro_.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Syntax highlighting for macro_rules!.
2+
use span::Edition;
23
use syntax::{SyntaxKind, SyntaxToken, TextRange, T};
34

45
use crate::{HlRange, HlTag};
@@ -117,7 +118,7 @@ fn update_macro_state(state: &mut MacroMatcherParseState, tok: &SyntaxToken) {
117118

118119
fn is_metavariable(token: &SyntaxToken) -> Option<TextRange> {
119120
match token.kind() {
120-
kind if kind == SyntaxKind::IDENT || kind.is_keyword() => {
121+
kind if kind == SyntaxKind::IDENT || kind.is_keyword(Edition::CURRENT) => {
121122
if let Some(_dollar) = token.prev_token().filter(|t| t.kind() == T![$]) {
122123
return Some(token.text_range());
123124
}

crates/parser/src/lexed_str.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,8 @@ impl<'a> Converter<'a> {
178178
rustc_lexer::TokenKind::Whitespace => WHITESPACE,
179179

180180
rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE,
181-
rustc_lexer::TokenKind::Ident
182-
if ["async", "await", "dyn", "try"].contains(&token_text)
183-
&& !self.edition.at_least_2018() =>
184-
{
185-
IDENT
186-
}
187-
rustc_lexer::TokenKind::Ident
188-
if token_text == "gen" && !self.edition.at_least_2024() =>
189-
{
190-
IDENT
191-
}
192181
rustc_lexer::TokenKind::Ident => {
193-
SyntaxKind::from_keyword(token_text).unwrap_or(IDENT)
182+
SyntaxKind::from_keyword(token_text, self.edition).unwrap_or(IDENT)
194183
}
195184
rustc_lexer::TokenKind::InvalidPrefix | rustc_lexer::TokenKind::InvalidIdent => {
196185
err = "Ident contains invalid characters";

crates/parser/src/shortcuts.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ impl LexedStr<'_> {
3535
was_joint = false
3636
} else if kind == SyntaxKind::IDENT {
3737
let token_text = self.text(i);
38-
let contextual_kw = if !edition.at_least_2018() && token_text == "dyn" {
39-
SyntaxKind::DYN_KW
40-
} else {
41-
SyntaxKind::from_contextual_keyword(token_text).unwrap_or(SyntaxKind::IDENT)
42-
};
43-
res.push_ident(contextual_kw);
38+
res.push_ident(
39+
SyntaxKind::from_contextual_keyword(token_text, edition)
40+
.unwrap_or(SyntaxKind::IDENT),
41+
)
4442
} else {
4543
if was_joint {
4644
res.was_joint();

0 commit comments

Comments
 (0)