Skip to content

Commit fe7b4f2

Browse files
authored
Merge pull request #19699 from ChayimFriedman2/escape-label
fix: Escape raw names in labels properly
2 parents 509408b + e6ebf0b commit fe7b4f2

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

crates/hir-expand/src/name.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ impl Name {
191191
// FIXME: Remove this in favor of `display`, see fixme on `as_str`
192192
#[doc(hidden)]
193193
pub fn display_no_db(&self, edition: Edition) -> impl fmt::Display + '_ {
194-
Display { name: self, needs_escaping: is_raw_identifier(self.symbol.as_str(), edition) }
194+
Display { name: self, edition }
195195
}
196196

197197
pub fn symbol(&self) -> &Symbol {
@@ -201,15 +201,28 @@ impl Name {
201201

202202
struct Display<'a> {
203203
name: &'a Name,
204-
needs_escaping: bool,
204+
edition: Edition,
205205
}
206206

207207
impl fmt::Display for Display<'_> {
208208
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209-
if self.needs_escaping {
210-
write!(f, "r#")?;
209+
let mut symbol = self.name.symbol.as_str();
210+
211+
if symbol == "'static" {
212+
// FIXME: '`static` can also be a label, and there it does need escaping.
213+
// But knowing where it is will require adding a parameter to `display()`,
214+
// and that is an infectious change.
215+
return f.write_str(symbol);
216+
}
217+
218+
if let Some(s) = symbol.strip_prefix('\'') {
219+
f.write_str("'")?;
220+
symbol = s;
221+
}
222+
if is_raw_identifier(symbol, self.edition) {
223+
f.write_str("r#")?;
211224
}
212-
fmt::Display::fmt(self.name.symbol.as_str(), f)
225+
f.write_str(symbol)
213226
}
214227
}
215228

crates/ide-completion/src/completions/lifetime.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,13 @@ fn foo<'lifetime>(foo: &'a$0) {}
116116
check(
117117
r#"
118118
struct Foo;
119-
impl<'impl> Foo {
119+
impl<'r#impl> Foo {
120120
fn foo<'func>(&'a$0 self) {}
121121
}
122122
"#,
123123
expect![[r#"
124124
lt 'func
125-
lt 'impl
125+
lt 'r#impl
126126
lt 'static
127127
"#]],
128128
);

crates/ide-completion/src/tests/expression.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,3 +2110,19 @@ fn foo() {
21102110
"#]],
21112111
);
21122112
}
2113+
2114+
#[test]
2115+
fn escaped_label() {
2116+
check(
2117+
r#"
2118+
fn main() {
2119+
'r#break: {
2120+
break '$0;
2121+
}
2122+
}
2123+
"#,
2124+
expect![[r#"
2125+
lb 'r#break
2126+
"#]],
2127+
);
2128+
}

0 commit comments

Comments
 (0)