Skip to content

Commit

Permalink
Auto merge of #17896 - Veykril:editioned-syntax-kinds, r=Veykril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Aug 15, 2024
2 parents 2b86639 + f90bdfc commit 91aa3f4
Show file tree
Hide file tree
Showing 23 changed files with 347 additions and 129 deletions.
20 changes: 12 additions & 8 deletions crates/hir-def/src/macro_expansion_tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use hir_expand::{
InFile, MacroFileId, MacroFileIdExt,
};
use intern::Symbol;
use span::Span;
use span::{Edition, Span};
use stdx::{format_to, format_to_acc};
use syntax::{
ast::{self, edit::IndentLevel},
Expand Down Expand Up @@ -257,21 +257,25 @@ fn pretty_print_macro_expansion(
(T![;] | T!['{'] | T!['}'], _) => "\n",
(_, T!['}']) => "\n",
(IDENT | LIFETIME_IDENT, IDENT | LIFETIME_IDENT) => " ",
_ if prev_kind.is_keyword() && curr_kind.is_keyword() => " ",
(IDENT, _) if curr_kind.is_keyword() => " ",
(_, IDENT) if prev_kind.is_keyword() => " ",
_ if prev_kind.is_keyword(Edition::CURRENT)
&& curr_kind.is_keyword(Edition::CURRENT) =>
{
" "
}
(IDENT, _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(_, IDENT) if prev_kind.is_keyword(Edition::CURRENT) => " ",
(T![>], IDENT) => " ",
(T![>], _) if curr_kind.is_keyword() => " ",
(T![>], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![->], _) | (_, T![->]) => " ",
(T![&&], _) | (_, T![&&]) => " ",
(T![,], _) => " ",
(T![:], IDENT | T!['(']) => " ",
(T![:], _) if curr_kind.is_keyword() => " ",
(T![:], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![fn], T!['(']) => "",
(T![']'], _) if curr_kind.is_keyword() => " ",
(T![']'], _) if curr_kind.is_keyword(Edition::CURRENT) => " ",
(T![']'], T![#]) => "\n",
(T![Self], T![::]) => "",
_ if prev_kind.is_keyword() => " ",
_ if prev_kind.is_keyword(Edition::CURRENT) => " ",
_ => "",
};

Expand Down
7 changes: 5 additions & 2 deletions crates/hir-expand/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,17 @@ impl Name {

/// Resolve a name from the text of token.
fn resolve(raw_text: &str) -> Name {
// FIXME: Edition
match raw_text.strip_prefix("r#") {
// When `raw_text` starts with "r#" but the name does not coincide with any
// keyword, we never need the prefix so we strip it.
Some(text) if !is_raw_identifier(text) => Name::new_ref(text),
Some(text) if !is_raw_identifier(text, span::Edition::CURRENT) => Name::new_ref(text),
// Keywords (in the current edition) *can* be used as a name in earlier editions of
// Rust, e.g. "try" in Rust 2015. Even in such cases, we keep track of them in their
// escaped form.
None if is_raw_identifier(raw_text) => Name::new_text(&format!("r#{}", raw_text)),
None if is_raw_identifier(raw_text, span::Edition::CURRENT) => {
Name::new_text(&format!("r#{}", raw_text))
}
_ => Name::new_text(raw_text),
}
}
Expand Down
5 changes: 3 additions & 2 deletions crates/ide-completion/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use ide_db::{
};
use syntax::{
ast::{self, AttrKind, NameOrNameRef},
AstNode, SmolStr,
AstNode, Edition, SmolStr,
SyntaxKind::{self, *},
SyntaxToken, TextRange, TextSize, T,
};
Expand Down Expand Up @@ -468,7 +468,8 @@ impl CompletionContext<'_> {
TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
}
IDENT | LIFETIME_IDENT | UNDERSCORE | INT_NUMBER => self.original_token.text_range(),
_ if kind.is_keyword() => self.original_token.text_range(),
// FIXME: Edition
_ if kind.is_keyword(Edition::CURRENT) => self.original_token.text_range(),
_ => TextRange::empty(self.position.offset),
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Utilities for formatting macro expanded nodes until we get a proper formatter.
use span::Edition;
use syntax::{
ast::make,
ted::{self, Position},
Expand Down Expand Up @@ -131,5 +132,6 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
}

fn is_text(k: SyntaxKind) -> bool {
k.is_keyword() || k.is_literal() || k == IDENT || k == UNDERSCORE
// FIXME: Edition
k.is_keyword(Edition::CURRENT) || k.is_literal() || k == IDENT || k == UNDERSCORE
}
4 changes: 3 additions & 1 deletion crates/ide-db/src/syntax_helpers/node_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Various helper functions to work with SyntaxNodes.
use itertools::Itertools;
use parser::T;
use span::Edition;
use syntax::{
ast::{self, HasLoopBody, MacroCall, PathSegmentKind, VisibilityKind},
AstNode, AstToken, Preorder, RustLanguage, WalkEvent,
Expand Down Expand Up @@ -461,7 +462,8 @@ pub fn parse_tt_as_comma_sep_paths(input: ast::TokenTree) -> Option<Vec<ast::Pat
let tokens =
input.syntax().children_with_tokens().skip(1).map_while(|it| match it.into_token() {
// seeing a keyword means the attribute is unclosed so stop parsing here
Some(tok) if tok.kind().is_keyword() => None,
// FIXME: Edition
Some(tok) if tok.kind().is_keyword(Edition::CURRENT) => None,
// don't include the right token tree parenthesis if it exists
tok @ Some(_) if tok == r_paren => None,
// only nodes that we can find are other TokenTrees, those are unexpected in this parse though
Expand Down
4 changes: 2 additions & 2 deletions crates/ide/src/goto_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use ide_db::{
};
use itertools::Itertools;

use span::FileId;
use span::{Edition, FileId};
use syntax::{
ast::{self, HasLoopBody},
match_ast, AstNode, AstToken,
Expand Down Expand Up @@ -55,7 +55,7 @@ pub(crate) fn goto_definition(
| COMMENT => 4,
// index and prefix ops
T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] => 3,
kind if kind.is_keyword() => 2,
kind if kind.is_keyword(Edition::CURRENT) => 2,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
Expand Down
4 changes: 2 additions & 2 deletions crates/ide/src/highlight_related.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ide_db::{
},
FxHashMap, FxHashSet, RootDatabase,
};
use span::EditionedFileId;
use span::{Edition, EditionedFileId};
use syntax::{
ast::{self, HasLoopBody},
match_ast, AstNode,
Expand Down Expand Up @@ -65,7 +65,7 @@ pub(crate) fn highlight_related(
let token = pick_best_token(syntax.token_at_offset(offset), |kind| match kind {
T![?] => 4, // prefer `?` when the cursor is sandwiched like in `await$0?`
T![->] => 4,
kind if kind.is_keyword() => 3,
kind if kind.is_keyword(Edition::CURRENT) => 3,
IDENT | INT_NUMBER => 2,
T![|] => 1,
_ => 0,
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use ide_db::{
FileRange, FxIndexSet, RootDatabase,
};
use itertools::{multizip, Itertools};
use span::Edition;
use syntax::{ast, AstNode, SyntaxKind::*, SyntaxNode, T};

use crate::{
Expand Down Expand Up @@ -140,7 +141,7 @@ fn hover_simple(
| T![_] => 4,
// index and prefix ops and closure pipe
T!['['] | T![']'] | T![?] | T![*] | T![-] | T![!] | T![|] => 3,
kind if kind.is_keyword() => 2,
kind if kind.is_keyword(Edition::CURRENT) => 2,
T!['('] | T![')'] => 2,
kind if kind.is_trivia() => 0,
_ => 1,
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/hover/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc_apfloat::{
ieee::{Half as f16, Quad as f128},
Float,
};
use span::Edition;
use stdx::format_to;
use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T};

Expand Down Expand Up @@ -251,7 +252,7 @@ pub(super) fn keyword(
config: &HoverConfig,
token: &SyntaxToken,
) -> Option<HoverResult> {
if !token.kind().is_keyword() || !config.documentation || !config.keywords {
if !token.kind().is_keyword(Edition::CURRENT) || !config.documentation || !config.keywords {
return None;
}
let parent = token.parent()?;
Expand Down
4 changes: 3 additions & 1 deletion crates/ide/src/references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use ide_db::{
};
use itertools::Itertools;
use nohash_hasher::IntMap;
use span::Edition;
use syntax::{
ast::{self, HasName},
match_ast, AstNode,
Expand Down Expand Up @@ -305,7 +306,8 @@ fn handle_control_flow_keywords(
FilePosition { file_id, offset }: FilePosition,
) -> Option<ReferenceSearchResult> {
let file = sema.parse_guess_edition(file_id);
let token = file.syntax().token_at_offset(offset).find(|t| t.kind().is_keyword())?;
let token =
file.syntax().token_at_offset(offset).find(|t| t.kind().is_keyword(Edition::CURRENT))?;

let references = match token.kind() {
T![fn] | T![return] | T![try] => highlight_related::highlight_exit_points(sema, token),
Expand Down
12 changes: 7 additions & 5 deletions crates/ide/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use hir::{AsAssocItem, HirFileIdExt, InFile, Semantics};
use ide_db::{
base_db::SourceDatabase,
defs::{Definition, NameClass, NameRefClass},
rename::{bail, format_err, source_edit_from_references, IdentifierKind},
source_change::SourceChangeBuilder,
Expand Down Expand Up @@ -162,11 +163,12 @@ pub(crate) fn will_rename_file(
let sema = Semantics::new(db);
let module = sema.file_to_module_def(file_id)?;
let def = Definition::Module(module);
let mut change = if is_raw_identifier(new_name_stem) {
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
} else {
def.rename(&sema, new_name_stem).ok()?
};
let mut change =
if is_raw_identifier(new_name_stem, db.crate_graph()[module.krate().into()].edition) {
def.rename(&sema, &SmolStr::from_iter(["r#", new_name_stem])).ok()?
} else {
def.rename(&sema, new_name_stem).ok()?
};
change.file_system_edits.clear();
Some(change)
}
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/syntax_highlighting/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ide_db::{
defs::{Definition, IdentClass, NameClass, NameRefClass},
FxHashMap, RootDatabase, SymbolKind,
};
use span::Edition;
use stdx::hash_once;
use syntax::{
ast, match_ast, AstNode, AstToken, NodeOrToken,
Expand Down Expand Up @@ -41,7 +42,7 @@ pub(super) fn token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> O
HlTag::None.into()
}
p if p.is_punct() => punctuation(sema, token, p),
k if k.is_keyword() => keyword(sema, token, k)?,
k if k.is_keyword(Edition::CURRENT) => keyword(sema, token, k)?,
_ => return None,
};
Some(highlight)
Expand Down
3 changes: 2 additions & 1 deletion crates/ide/src/syntax_highlighting/macro_.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Syntax highlighting for macro_rules!.
use span::Edition;
use syntax::{SyntaxKind, SyntaxToken, TextRange, T};

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

fn is_metavariable(token: &SyntaxToken) -> Option<TextRange> {
match token.kind() {
kind if kind == SyntaxKind::IDENT || kind.is_keyword() => {
kind if kind == SyntaxKind::IDENT || kind.is_keyword(Edition::CURRENT) => {
if let Some(_dollar) = token.prev_token().filter(|t| t.kind() == T![$]) {
return Some(token.text_range());
}
Expand Down
13 changes: 1 addition & 12 deletions crates/parser/src/lexed_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +178,8 @@ impl<'a> Converter<'a> {
rustc_lexer::TokenKind::Whitespace => WHITESPACE,

rustc_lexer::TokenKind::Ident if token_text == "_" => UNDERSCORE,
rustc_lexer::TokenKind::Ident
if ["async", "await", "dyn", "try"].contains(&token_text)
&& !self.edition.at_least_2018() =>
{
IDENT
}
rustc_lexer::TokenKind::Ident
if token_text == "gen" && !self.edition.at_least_2024() =>
{
IDENT
}
rustc_lexer::TokenKind::Ident => {
SyntaxKind::from_keyword(token_text).unwrap_or(IDENT)
SyntaxKind::from_keyword(token_text, self.edition).unwrap_or(IDENT)
}
rustc_lexer::TokenKind::InvalidPrefix | rustc_lexer::TokenKind::InvalidIdent => {
err = "Ident contains invalid characters";
Expand Down
10 changes: 4 additions & 6 deletions crates/parser/src/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ impl LexedStr<'_> {
was_joint = false
} else if kind == SyntaxKind::IDENT {
let token_text = self.text(i);
let contextual_kw = if !edition.at_least_2018() && token_text == "dyn" {
SyntaxKind::DYN_KW
} else {
SyntaxKind::from_contextual_keyword(token_text).unwrap_or(SyntaxKind::IDENT)
};
res.push_ident(contextual_kw);
res.push_ident(
SyntaxKind::from_contextual_keyword(token_text, edition)
.unwrap_or(SyntaxKind::IDENT),
)
} else {
if was_joint {
res.was_joint();
Expand Down
Loading

0 comments on commit 91aa3f4

Please sign in to comment.