Skip to content

Commit 6908451

Browse files
committed
Auto merge of rust-lang#17905 - ChayimFriedman2:edition-dependent-raw-keyword, r=Veykril
fix: Properly account for editions in names This PR touches a lot of parts. But the main changes are changing `hir_expand::Name` to be raw edition-dependently and only when necessary (unrelated to how the user originally wrote the identifier), and changing `is_keyword()` and `is_raw_identifier()` to be edition-aware (this was done in rust-lang#17896, but the FIXMEs were fixed here). It is possible that I missed some cases, but most IDE parts should properly escape (or not escape) identifiers now. The rules of thumb are: - If we show the identifier to the user, its rawness should be determined by the edition of the edited crate. This is nice for IDE features, but really important for changes we insert to the source code. - For tests, I chose `Edition::CURRENT` (so we only have to (maybe) update tests when an edition becomes stable, to avoid churn). - For debugging tools (helper methods and logs), I used `Edition::LATEST`. Reviewing notes: This is a really big PR but most of it is mechanical translation. I changed `Name` displayers to require an edition, and followed the compiler errors. Most methods just propagate the edition requirement. The interesting cases are mostly in `ide-assists`, as sometimes the correct crate to fetch the edition from requires awareness (there may be two). `ide-completions` and `ide-diagnostics` were solved pretty easily by introducing an edition field to their context. `ide` contains many features, for most of them it was propagated to the top level function and there the edition was fetched based on the file. I also fixed all FIXMEs from rust-lang#17896. Some required introducing an edition parameter (usually not for many methods after the changes to `Name`), some were changed to a new method `is_any_identifier()` because they really want any possible keyword. Fixes rust-lang#17895. Fixes rust-lang#17774.
2 parents 2071778 + 3d6129d commit 6908451

File tree

179 files changed

+2480
-1245
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+2480
-1245
lines changed

src/tools/rust-analyzer/crates/hir-def/src/body.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use hir_expand::{name::Name, ExpandError, InFile};
1414
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
1515
use rustc_hash::FxHashMap;
1616
use smallvec::SmallVec;
17-
use span::MacroFileId;
17+
use span::{Edition, MacroFileId};
1818
use syntax::{ast, AstPtr, SyntaxNodePtr};
1919
use triomphe::Arc;
2020

@@ -201,17 +201,23 @@ impl Body {
201201
self.block_scopes.iter().map(move |&block| (block, db.block_def_map(block)))
202202
}
203203

204-
pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
205-
pretty::print_body_hir(db, self, owner)
204+
pub fn pretty_print(
205+
&self,
206+
db: &dyn DefDatabase,
207+
owner: DefWithBodyId,
208+
edition: Edition,
209+
) -> String {
210+
pretty::print_body_hir(db, self, owner, edition)
206211
}
207212

208213
pub fn pretty_print_expr(
209214
&self,
210215
db: &dyn DefDatabase,
211216
owner: DefWithBodyId,
212217
expr: ExprId,
218+
edition: Edition,
213219
) -> String {
214-
pretty::print_expr_hir(db, self, owner, expr)
220+
pretty::print_expr_hir(db, self, owner, expr, edition)
215221
}
216222

217223
fn new(

src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs

+41-24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::fmt::{self, Write};
44

55
use itertools::Itertools;
6+
use span::Edition;
67

78
use crate::{
89
hir::{
@@ -15,20 +16,26 @@ use crate::{
1516

1617
use super::*;
1718

18-
pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String {
19+
pub(super) fn print_body_hir(
20+
db: &dyn DefDatabase,
21+
body: &Body,
22+
owner: DefWithBodyId,
23+
edition: Edition,
24+
) -> String {
1925
let header = match owner {
20-
DefWithBodyId::FunctionId(it) => {
21-
it.lookup(db).id.resolved(db, |it| format!("fn {}", it.name.display(db.upcast())))
22-
}
26+
DefWithBodyId::FunctionId(it) => it
27+
.lookup(db)
28+
.id
29+
.resolved(db, |it| format!("fn {}", it.name.display(db.upcast(), edition))),
2330
DefWithBodyId::StaticId(it) => it
2431
.lookup(db)
2532
.id
26-
.resolved(db, |it| format!("static {} = ", it.name.display(db.upcast()))),
33+
.resolved(db, |it| format!("static {} = ", it.name.display(db.upcast(), edition))),
2734
DefWithBodyId::ConstId(it) => it.lookup(db).id.resolved(db, |it| {
2835
format!(
2936
"const {} = ",
3037
match &it.name {
31-
Some(name) => name.display(db.upcast()).to_string(),
38+
Some(name) => name.display(db.upcast(), edition).to_string(),
3239
None => "_".to_owned(),
3340
}
3441
)
@@ -39,13 +46,13 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
3946
let enum_loc = loc.parent.lookup(db);
4047
format!(
4148
"enum {}::{}",
42-
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast()),
43-
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast()),
49+
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition),
50+
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
4451
)
4552
}
4653
};
4754

48-
let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false };
55+
let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false, edition };
4956
if let DefWithBodyId::FunctionId(it) = owner {
5057
p.buf.push('(');
5158
let function_data = &db.function_data(it);
@@ -86,8 +93,10 @@ pub(super) fn print_expr_hir(
8693
body: &Body,
8794
_owner: DefWithBodyId,
8895
expr: ExprId,
96+
edition: Edition,
8997
) -> String {
90-
let mut p = Printer { db, body, buf: String::new(), indent_level: 0, needs_indent: false };
98+
let mut p =
99+
Printer { db, body, buf: String::new(), indent_level: 0, needs_indent: false, edition };
91100
p.print_expr(expr);
92101
p.buf
93102
}
@@ -113,6 +122,7 @@ struct Printer<'a> {
113122
buf: String,
114123
indent_level: usize,
115124
needs_indent: bool,
125+
edition: Edition,
116126
}
117127

118128
impl Write for Printer<'_> {
@@ -173,13 +183,14 @@ impl Printer<'_> {
173183
Expr::OffsetOf(offset_of) => {
174184
w!(self, "builtin#offset_of(");
175185
self.print_type_ref(&offset_of.container);
186+
let edition = self.edition;
176187
w!(
177188
self,
178189
", {})",
179190
offset_of
180191
.fields
181192
.iter()
182-
.format_with(".", |field, f| f(&field.display(self.db.upcast())))
193+
.format_with(".", |field, f| f(&field.display(self.db.upcast(), edition)))
183194
);
184195
}
185196
Expr::Path(path) => self.print_path(path),
@@ -201,7 +212,7 @@ impl Printer<'_> {
201212
}
202213
Expr::Loop { body, label } => {
203214
if let Some(lbl) = label {
204-
w!(self, "{}: ", self.body[*lbl].name.display(self.db.upcast()));
215+
w!(self, "{}: ", self.body[*lbl].name.display(self.db.upcast(), self.edition));
205216
}
206217
w!(self, "loop ");
207218
self.print_expr(*body);
@@ -221,10 +232,11 @@ impl Printer<'_> {
221232
}
222233
Expr::MethodCall { receiver, method_name, args, generic_args } => {
223234
self.print_expr(*receiver);
224-
w!(self, ".{}", method_name.display(self.db.upcast()));
235+
w!(self, ".{}", method_name.display(self.db.upcast(), self.edition));
225236
if let Some(args) = generic_args {
226237
w!(self, "::<");
227-
print_generic_args(self.db, args, self).unwrap();
238+
let edition = self.edition;
239+
print_generic_args(self.db, args, self, edition).unwrap();
228240
w!(self, ">");
229241
}
230242
w!(self, "(");
@@ -259,13 +271,13 @@ impl Printer<'_> {
259271
Expr::Continue { label } => {
260272
w!(self, "continue");
261273
if let Some(lbl) = label {
262-
w!(self, " {}", self.body[*lbl].name.display(self.db.upcast()));
274+
w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition));
263275
}
264276
}
265277
Expr::Break { expr, label } => {
266278
w!(self, "break");
267279
if let Some(lbl) = label {
268-
w!(self, " {}", self.body[*lbl].name.display(self.db.upcast()));
280+
w!(self, " {}", self.body[*lbl].name.display(self.db.upcast(), self.edition));
269281
}
270282
if let Some(expr) = expr {
271283
self.whitespace();
@@ -307,9 +319,10 @@ impl Printer<'_> {
307319
}
308320

309321
w!(self, "{{");
322+
let edition = self.edition;
310323
self.indented(|p| {
311324
for field in &**fields {
312-
w!(p, "{}: ", field.name.display(self.db.upcast()));
325+
w!(p, "{}: ", field.name.display(self.db.upcast(), edition));
313326
p.print_expr(field.expr);
314327
wln!(p, ",");
315328
}
@@ -326,7 +339,7 @@ impl Printer<'_> {
326339
}
327340
Expr::Field { expr, name } => {
328341
self.print_expr(*expr);
329-
w!(self, ".{}", name.display(self.db.upcast()));
342+
w!(self, ".{}", name.display(self.db.upcast(), self.edition));
330343
}
331344
Expr::Await { expr } => {
332345
self.print_expr(*expr);
@@ -464,8 +477,9 @@ impl Printer<'_> {
464477
}
465478
Expr::Literal(lit) => self.print_literal(lit),
466479
Expr::Block { id: _, statements, tail, label } => {
467-
let label =
468-
label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db.upcast())));
480+
let label = label.map(|lbl| {
481+
format!("{}: ", self.body[lbl].name.display(self.db.upcast(), self.edition))
482+
});
469483
self.print_block(label.as_deref(), statements, tail);
470484
}
471485
Expr::Unsafe { id: _, statements, tail } => {
@@ -539,9 +553,10 @@ impl Printer<'_> {
539553
}
540554

541555
w!(self, " {{");
556+
let edition = self.edition;
542557
self.indented(|p| {
543558
for arg in args.iter() {
544-
w!(p, "{}: ", arg.name.display(self.db.upcast()));
559+
w!(p, "{}: ", arg.name.display(self.db.upcast(), edition));
545560
p.print_pat(arg.pat);
546561
wln!(p, ",");
547562
}
@@ -686,11 +701,13 @@ impl Printer<'_> {
686701
}
687702

688703
fn print_type_ref(&mut self, ty: &TypeRef) {
689-
print_type_ref(self.db, ty, self).unwrap();
704+
let edition = self.edition;
705+
print_type_ref(self.db, ty, self, edition).unwrap();
690706
}
691707

692708
fn print_path(&mut self, path: &Path) {
693-
print_path(self.db, path, self).unwrap();
709+
let edition = self.edition;
710+
print_path(self.db, path, self, edition).unwrap();
694711
}
695712

696713
fn print_binding(&mut self, id: BindingId) {
@@ -701,6 +718,6 @@ impl Printer<'_> {
701718
BindingAnnotation::Ref => "ref ",
702719
BindingAnnotation::RefMut => "ref mut ",
703720
};
704-
w!(self, "{}{}", mode, name.display(self.db.upcast()));
721+
w!(self, "{}{}", mode, name.display(self.db.upcast(), self.edition));
705722
}
706723
}

src/tools/rust-analyzer/crates/hir-def/src/body/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ fn main() {
219219
},
220220
);
221221
}"#]]
222-
.assert_eq(&body.pretty_print(&db, def))
222+
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
223223
}
224224

225225
#[test]
@@ -285,7 +285,7 @@ impl SsrError {
285285
),
286286
);
287287
}"#]]
288-
.assert_eq(&body.pretty_print(&db, def))
288+
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
289289
}
290290

291291
#[test]
@@ -333,5 +333,5 @@ fn f(a: i32, b: u32) -> String {
333333
);
334334
};
335335
}"#]]
336-
.assert_eq(&body.pretty_print(&db, def))
336+
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
337337
}

src/tools/rust-analyzer/crates/hir-def/src/find_path.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ mod tests {
651651
use expect_test::{expect, Expect};
652652
use hir_expand::db::ExpandDatabase;
653653
use itertools::Itertools;
654+
use span::Edition;
654655
use stdx::format_to;
655656
use syntax::ast::AstNode;
656657
use test_fixture::WithFixture;
@@ -717,8 +718,10 @@ mod tests {
717718
"{:7}(imports {}): {}\n",
718719
format!("{:?}", prefix),
719720
if ignore_local_imports { '✖' } else { '✔' },
720-
found_path
721-
.map_or_else(|| "<unresolvable>".to_owned(), |it| it.display(&db).to_string()),
721+
found_path.map_or_else(
722+
|| "<unresolvable>".to_owned(),
723+
|it| it.display(&db, Edition::CURRENT).to_string()
724+
),
722725
);
723726
}
724727
expect.assert_eq(&res);

src/tools/rust-analyzer/crates/hir-def/src/hir/format_args.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ pub(crate) fn parse(
250250
}
251251
}
252252
ArgRef::Name(name, span) => {
253-
let name = Name::new(name, tt::IdentIsRaw::No, call_ctx);
253+
let name = Name::new(name, call_ctx);
254254
if let Some((index, _)) = args.by_name(&name) {
255255
record_usage(name, span);
256256
// Name found in `args`, so we resolve it to its index.

src/tools/rust-analyzer/crates/hir-def/src/hir/type_ref.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use hir_expand::{
1010
AstId,
1111
};
1212
use intern::{sym, Interned, Symbol};
13+
use span::Edition;
1314
use syntax::ast::{self, HasGenericArgs, HasName, IsString};
1415

1516
use crate::{
@@ -419,18 +420,22 @@ impl ConstRef {
419420
param.default_val().map(|default| Self::from_const_arg(lower_ctx, Some(default)))
420421
}
421422

422-
pub fn display<'a>(&'a self, db: &'a dyn ExpandDatabase) -> impl fmt::Display + 'a {
423-
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef);
423+
pub fn display<'a>(
424+
&'a self,
425+
db: &'a dyn ExpandDatabase,
426+
edition: Edition,
427+
) -> impl fmt::Display + 'a {
428+
struct Display<'a>(&'a dyn ExpandDatabase, &'a ConstRef, Edition);
424429
impl fmt::Display for Display<'_> {
425430
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426431
match self.1 {
427432
ConstRef::Scalar(s) => s.fmt(f),
428-
ConstRef::Path(n) => n.display(self.0).fmt(f),
433+
ConstRef::Path(n) => n.display(self.0, self.2).fmt(f),
429434
ConstRef::Complex(_) => f.write_str("{const}"),
430435
}
431436
}
432437
}
433-
Display(db, self)
438+
Display(db, self, edition)
434439
}
435440

436441
// We special case literals and single identifiers, to speed up things.

src/tools/rust-analyzer/crates/hir-def/src/import_map.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use hir_expand::name::Name;
88
use itertools::Itertools;
99
use rustc_hash::FxHashSet;
1010
use smallvec::SmallVec;
11+
use span::Edition;
1112
use stdx::{format_to, TupleExt};
1213
use syntax::ToSmolStr;
1314
use triomphe::Arc;
@@ -66,7 +67,12 @@ impl ImportMap {
6667
for (k, v) in self.item_to_info_map.iter() {
6768
format_to!(out, "{:?} ({:?}) -> ", k, v.1);
6869
for v in &v.0 {
69-
format_to!(out, "{}:{:?}, ", v.name.display(db.upcast()), v.container);
70+
format_to!(
71+
out,
72+
"{}:{:?}, ",
73+
v.name.display(db.upcast(), Edition::CURRENT),
74+
v.container
75+
);
7076
}
7177
format_to!(out, "\n");
7278
}
@@ -83,7 +89,7 @@ impl ImportMap {
8389
// We've only collected items, whose name cannot be tuple field so unwrapping is fine.
8490
.flat_map(|(&item, (info, _))| {
8591
info.iter().enumerate().map(move |(idx, info)| {
86-
(item, info.name.display(db.upcast()).to_smolstr(), idx as u32)
92+
(item, info.name.unescaped().display(db.upcast()).to_smolstr(), idx as u32)
8793
})
8894
})
8995
.collect();
@@ -461,7 +467,7 @@ fn search_maps(
461467
query.search_mode.check(
462468
&query.query,
463469
query.case_sensitive,
464-
&info.name.display(db.upcast()).to_smolstr(),
470+
&info.name.unescaped().display(db.upcast()).to_smolstr(),
465471
)
466472
});
467473
res.extend(iter.map(TupleExt::head));
@@ -577,7 +583,7 @@ mod tests {
577583
Some(format!(
578584
"{}::{}",
579585
render_path(db, &trait_info[0]),
580-
assoc_item_name.display(db.upcast())
586+
assoc_item_name.display(db.upcast(), Edition::CURRENT)
581587
))
582588
}
583589

@@ -616,7 +622,7 @@ mod tests {
616622
module = parent;
617623
}
618624

619-
segments.iter().rev().map(|it| it.display(db.upcast())).join("::")
625+
segments.iter().rev().map(|it| it.display(db.upcast(), Edition::CURRENT)).join("::")
620626
}
621627

622628
#[test]

0 commit comments

Comments
 (0)