@@ -46,6 +46,7 @@ use syntax::tokenstream::{TokenTree, TokenStream};
46
46
use syntax:: ast;
47
47
use syntax:: attr;
48
48
use syntax:: source_map:: Spanned ;
49
+ use syntax:: edition:: Edition ;
49
50
use syntax:: feature_gate:: { AttributeGate , AttributeType , Stability , deprecated_attributes} ;
50
51
use syntax_pos:: { BytePos , Span , SyntaxContext } ;
51
52
use syntax:: symbol:: keywords;
@@ -1876,30 +1877,33 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
1876
1877
}
1877
1878
1878
1879
declare_lint ! {
1879
- pub ASYNC_IDENTS ,
1880
+ pub KEYWORD_IDENTS ,
1880
1881
Allow ,
1881
- "detects `async` being used as an identifier"
1882
+ "detects edition keywords being used as an identifier"
1882
1883
}
1883
1884
1884
- /// Checks for uses of `async` as an identifier
1885
+ /// Checks for uses of edtion keywords used as an identifier
1885
1886
#[ derive( Clone ) ]
1886
- pub struct Async2018 ;
1887
+ pub struct KeywordIdents ;
1887
1888
1888
- impl LintPass for Async2018 {
1889
+ impl LintPass for KeywordIdents {
1889
1890
fn get_lints ( & self ) -> LintArray {
1890
- lint_array ! ( ASYNC_IDENTS )
1891
+ lint_array ! ( KEYWORD_IDENTS )
1891
1892
}
1892
1893
}
1893
1894
1894
- impl Async2018 {
1895
+ impl KeywordIdents {
1895
1896
fn check_tokens ( & mut self , cx : & EarlyContext , tokens : TokenStream ) {
1896
1897
for tt in tokens. into_trees ( ) {
1897
1898
match tt {
1898
1899
TokenTree :: Token ( span, tok) => match tok. ident ( ) {
1899
1900
// only report non-raw idents
1900
- Some ( ( ident, false ) ) if ident. as_str ( ) == "async" => {
1901
- self . report ( cx, span. substitute_dummy ( ident. span ) )
1902
- } ,
1901
+ Some ( ( ident, false ) ) => {
1902
+ self . check_ident ( cx, ast:: Ident {
1903
+ span : span. substitute_dummy ( ident. span ) ,
1904
+ ..ident
1905
+ } ) ;
1906
+ }
1903
1907
_ => { } ,
1904
1908
}
1905
1909
TokenTree :: Delimited ( _, ref delim) => {
@@ -1908,38 +1912,47 @@ impl Async2018 {
1908
1912
}
1909
1913
}
1910
1914
}
1911
- fn report ( & mut self , cx : & EarlyContext , span : Span ) {
1912
- // don't lint `r#async`
1913
- if cx. sess . parse_sess . raw_identifier_spans . borrow ( ) . contains ( & span) {
1914
- return ;
1915
- }
1916
- let mut lint = cx. struct_span_lint (
1917
- ASYNC_IDENTS ,
1918
- span,
1919
- "`async` is a keyword in the 2018 edition" ,
1920
- ) ;
1921
-
1922
- // Don't suggest about raw identifiers if the feature isn't active
1923
- lint. span_suggestion_with_applicability (
1924
- span,
1925
- "you can use a raw identifier to stay compatible" ,
1926
- "r#async" . to_string ( ) ,
1927
- Applicability :: MachineApplicable ,
1928
- ) ;
1929
- lint. emit ( )
1930
- }
1931
1915
}
1932
1916
1933
- impl EarlyLintPass for Async2018 {
1917
+ impl EarlyLintPass for KeywordIdents {
1934
1918
fn check_mac_def ( & mut self , cx : & EarlyContext , mac_def : & ast:: MacroDef , _id : ast:: NodeId ) {
1935
1919
self . check_tokens ( cx, mac_def. stream ( ) ) ;
1936
1920
}
1937
1921
fn check_mac ( & mut self , cx : & EarlyContext , mac : & ast:: Mac ) {
1938
1922
self . check_tokens ( cx, mac. node . tts . clone ( ) . into ( ) ) ;
1939
1923
}
1940
1924
fn check_ident ( & mut self , cx : & EarlyContext , ident : ast:: Ident ) {
1941
- if ident. as_str ( ) == "async" {
1942
- self . report ( cx, ident. span ) ;
1925
+ let next_edition = match cx. sess . edition ( ) {
1926
+ Edition :: Edition2015 => {
1927
+ match & ident. as_str ( ) [ ..] {
1928
+ "async" |
1929
+ "try" => Edition :: Edition2018 ,
1930
+ _ => return ,
1931
+ }
1932
+ }
1933
+
1934
+ // no new keywords yet for 2018 edition and beyond
1935
+ _ => return ,
1936
+ } ;
1937
+
1938
+ // don't lint `r#foo`
1939
+ if cx. sess . parse_sess . raw_identifier_spans . borrow ( ) . contains ( & ident. span ) {
1940
+ return ;
1943
1941
}
1942
+
1943
+ let mut lint = cx. struct_span_lint (
1944
+ KEYWORD_IDENTS ,
1945
+ ident. span ,
1946
+ & format ! ( "`{}` is a keyword in the {} edition" ,
1947
+ ident. as_str( ) ,
1948
+ next_edition) ,
1949
+ ) ;
1950
+ lint. span_suggestion_with_applicability (
1951
+ ident. span ,
1952
+ "you can use a raw identifier to stay compatible" ,
1953
+ format ! ( "r#{}" , ident. as_str( ) ) ,
1954
+ Applicability :: MachineApplicable ,
1955
+ ) ;
1956
+ lint. emit ( )
1944
1957
}
1945
1958
}
0 commit comments