mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rework raw ident suggestions
Use heuristics to determine whethersuggesting raw identifiers is appropriate. Account for raw identifiers when printing a path in a `use` suggestion.
This commit is contained in:
parent
f11759d38c
commit
4f25c618ad
@ -225,8 +225,21 @@ impl<'a> Parser<'a> {
|
||||
self.token.span,
|
||||
&format!("expected identifier, found {}", self.this_token_descr()),
|
||||
);
|
||||
let valid_follow = &[
|
||||
TokenKind::Eq,
|
||||
TokenKind::Colon,
|
||||
TokenKind::Comma,
|
||||
TokenKind::Semi,
|
||||
TokenKind::ModSep,
|
||||
TokenKind::OpenDelim(token::DelimToken::Brace),
|
||||
TokenKind::OpenDelim(token::DelimToken::Paren),
|
||||
TokenKind::CloseDelim(token::DelimToken::Brace),
|
||||
TokenKind::CloseDelim(token::DelimToken::Paren),
|
||||
];
|
||||
if let token::Ident(name, false) = self.token.kind {
|
||||
if Ident::new(name, self.token.span).is_raw_guess() {
|
||||
if Ident::new(name, self.token.span).is_raw_guess() &&
|
||||
self.look_ahead(1, |t| valid_follow.contains(&t.kind))
|
||||
{
|
||||
err.span_suggestion(
|
||||
self.token.span,
|
||||
"you can escape reserved keywords to use them as identifiers",
|
||||
|
@ -2893,15 +2893,16 @@ fn names_to_string(names: &[Name]) -> String {
|
||||
if i > 0 {
|
||||
result.push_str("::");
|
||||
}
|
||||
if name.is_used_keyword() && name.can_be_raw() {
|
||||
result.push_str("r#");
|
||||
}
|
||||
result.push_str(&name.as_str());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn path_names_to_string(path: &Path) -> String {
|
||||
names_to_string(&path.segments.iter()
|
||||
.map(|seg| seg.ident.name)
|
||||
.collect::<Vec<_>>())
|
||||
names_to_string(&path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>())
|
||||
}
|
||||
|
||||
/// A somewhat inefficient routine to obtain the name of a module.
|
||||
|
@ -1013,7 +1013,15 @@ pub mod sym {
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
fn is_used_keyword_2018(self) -> bool {
|
||||
pub fn is_used_keyword(self) -> bool {
|
||||
self.is_used_keyword_2015() || self.is_used_keyword_2018()
|
||||
}
|
||||
|
||||
pub fn is_used_keyword_2015(self) -> bool {
|
||||
self >= kw::As && self <= kw::While
|
||||
}
|
||||
|
||||
pub fn is_used_keyword_2018(self) -> bool {
|
||||
self >= kw::Async && self <= kw::Dyn
|
||||
}
|
||||
|
||||
@ -1057,7 +1065,7 @@ impl Ident {
|
||||
/// Returns `true` if the token is a keyword used in the language.
|
||||
pub fn is_used_keyword(self) -> bool {
|
||||
// Note: `span.edition()` is relatively expensive, don't call it unless necessary.
|
||||
self.name >= kw::As && self.name <= kw::While ||
|
||||
self.name.is_used_keyword_2015() ||
|
||||
self.name.is_used_keyword_2018() && self.span.rust_2018()
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,6 @@ error: expected identifier, found keyword `async`
|
||||
|
|
||||
LL | pub const async fn x() {}
|
||||
| ^^^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | pub const r#async fn x() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `:`, found keyword `fn`
|
||||
--> $DIR/no-const-async.rs:5:17
|
||||
|
@ -3,11 +3,6 @@ error: expected identifier, found keyword `for`
|
||||
|
|
||||
LL | fn foo2<I>(x: <I as for<'x> Foo<&'x isize>>::A)
|
||||
| ^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | fn foo2<I>(x: <I as r#for<'x> Foo<&'x isize>>::A)
|
||||
| ^^^^^
|
||||
|
||||
error: expected one of `::` or `>`, found `Foo`
|
||||
--> $DIR/associated-types-project-from-hrtb-explicit.rs:10:29
|
||||
|
@ -12,11 +12,6 @@ error: expected identifier, found keyword `trait`
|
||||
|
|
||||
LL | trait T {
|
||||
| ^^^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | r#trait T {
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected `:`, found `T`
|
||||
--> $DIR/missing-close-brace-in-struct.rs:4:7
|
||||
|
@ -3,11 +3,6 @@ error: expected identifier, found keyword `let`
|
||||
|
|
||||
LL | let foo: (),
|
||||
| ^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | r#let foo: (),
|
||||
| ^^^^^
|
||||
|
||||
error: expected `:`, found `foo`
|
||||
--> $DIR/removed-syntax-field-let.rs:2:9
|
||||
|
@ -3,11 +3,6 @@ error: expected identifier, found keyword `as`
|
||||
|
|
||||
LL | use std::any:: as foo;
|
||||
| ^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | use std::any:: r#as foo;
|
||||
| ^^^^
|
||||
|
||||
error: expected one of `::`, `;`, or `as`, found `foo`
|
||||
--> $DIR/use-as-where-use-ends-with-mod-sep.rs:1:19
|
||||
|
9
src/test/ui/suggestions/raw-name-use-suggestion.rs
Normal file
9
src/test/ui/suggestions/raw-name-use-suggestion.rs
Normal file
@ -0,0 +1,9 @@
|
||||
mod foo {
|
||||
pub fn r#let() {}
|
||||
pub fn break() {} //~ ERROR expected identifier, found keyword `break`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::let(); //~ ERROR expected identifier, found keyword `let`
|
||||
r#break(); //~ ERROR cannot find function `break` in this scope
|
||||
}
|
36
src/test/ui/suggestions/raw-name-use-suggestion.stderr
Normal file
36
src/test/ui/suggestions/raw-name-use-suggestion.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error: expected identifier, found keyword `break`
|
||||
--> $DIR/raw-name-use-suggestion.rs:3:12
|
||||
|
|
||||
LL | pub fn break() {}
|
||||
| ^^^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | pub fn r#break() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: expected identifier, found keyword `let`
|
||||
--> $DIR/raw-name-use-suggestion.rs:7:10
|
||||
|
|
||||
LL | foo::let();
|
||||
| ^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | foo::r#let();
|
||||
| ^^^^^
|
||||
|
||||
error[E0425]: cannot find function `break` in this scope
|
||||
--> $DIR/raw-name-use-suggestion.rs:8:5
|
||||
|
|
||||
LL | r#break();
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
|
||||
help: possible candidate is found in another module, you can import it into scope
|
||||
|
|
||||
LL | use foo::r#break;
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
@ -6,11 +6,6 @@ LL | let try_result: Option<_> = try {
|
||||
LL |
|
||||
LL | let x = 5;
|
||||
| ^^^ expected identifier, found keyword
|
||||
|
|
||||
help: you can escape reserved keywords to use them as identifiers
|
||||
|
|
||||
LL | r#let x = 5;
|
||||
| ^^^^^
|
||||
|
||||
error[E0574]: expected struct, variant or union type, found macro `try`
|
||||
--> $DIR/try-block-in-edition2015.rs:4:33
|
||||
|
Loading…
Reference in New Issue
Block a user