Auto merge of #52375 - oli-obk:the_early_lint_pass_gets_the_worm, r=M… · rust-lang/rust@12ed235 (original) (raw)
`@@ -41,6 +41,7 @@ use lint::{LintPass, LateLintPass, EarlyLintPass, EarlyContext};
`
41
41
``
42
42
`use std::collections::HashSet;
`
43
43
``
``
44
`+
use syntax::tokenstream::{TokenTree, TokenStream};
`
44
45
`use syntax::ast;
`
45
46
`use syntax::attr;
`
46
47
`use syntax::codemap::Spanned;
`
`@@ -1784,3 +1785,70 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestFunctions {
`
1784
1785
`};
`
1785
1786
`}
`
1786
1787
`}
`
``
1788
+
``
1789
`+
declare_lint! {
`
``
1790
`+
pub ASYNC_IDENTS,
`
``
1791
`+
Allow,
`
``
1792
`` +
"detects async
being used as an identifier"
``
``
1793
`+
}
`
``
1794
+
``
1795
`` +
/// Checks for uses of async
as an identifier
``
``
1796
`+
#[derive(Clone)]
`
``
1797
`+
pub struct Async2018;
`
``
1798
+
``
1799
`+
impl LintPass for Async2018 {
`
``
1800
`+
fn get_lints(&self) -> LintArray {
`
``
1801
`+
lint_array!(ASYNC_IDENTS)
`
``
1802
`+
}
`
``
1803
`+
}
`
``
1804
+
``
1805
`+
impl Async2018 {
`
``
1806
`+
fn check_tokens(&mut self, cx: &EarlyContext, tokens: TokenStream) {
`
``
1807
`+
for tt in tokens.into_trees() {
`
``
1808
`+
match tt {
`
``
1809
`+
TokenTree::Token(span, tok) => match tok.ident() {
`
``
1810
`+
// only report non-raw idents
`
``
1811
`+
Some((ident, false)) if ident.as_str() == "async" => {
`
``
1812
`+
self.report(cx, span.substitute_dummy(ident.span))
`
``
1813
`+
},
`
``
1814
`+
_ => {},
`
``
1815
`+
}
`
``
1816
`+
TokenTree::Delimited(_, ref delim) => {
`
``
1817
`+
self.check_tokens(cx, delim.tts.clone().into())
`
``
1818
`+
},
`
``
1819
`+
}
`
``
1820
`+
}
`
``
1821
`+
}
`
``
1822
`+
fn report(&mut self, cx: &EarlyContext, span: Span) {
`
``
1823
`` +
// don't lint r#async
``
``
1824
`+
if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&span) {
`
``
1825
`+
return;
`
``
1826
`+
}
`
``
1827
`+
let mut lint = cx.struct_span_lint(
`
``
1828
`+
ASYNC_IDENTS,
`
``
1829
`+
span,
`
``
1830
`` +
"async
is a keyword in the 2018 edition",
``
``
1831
`+
);
`
``
1832
`+
lint.span_suggestion_with_applicability(
`
``
1833
`+
span,
`
``
1834
`+
"you can use a raw identifier to stay compatible",
`
``
1835
`+
"r#async".to_string(),
`
``
1836
`+
Applicability::MachineApplicable,
`
``
1837
`+
);
`
``
1838
`+
lint.emit()
`
``
1839
`+
}
`
``
1840
`+
}
`
``
1841
+
``
1842
`+
impl EarlyLintPass for Async2018 {
`
``
1843
`+
fn check_mac_def(&mut self, cx: &EarlyContext, mac_def: &ast::MacroDef, _id: ast::NodeId) {
`
``
1844
`+
self.check_tokens(cx, mac_def.stream());
`
``
1845
`+
}
`
``
1846
`+
fn check_mac(&mut self, cx: &EarlyContext, mac: &ast::Mac) {
`
``
1847
`+
self.check_tokens(cx, mac.node.tts.clone().into());
`
``
1848
`+
}
`
``
1849
`+
fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) {
`
``
1850
`+
if ident.as_str() == "async" {
`
``
1851
`+
self.report(cx, ident.span);
`
``
1852
`+
}
`
``
1853
`+
}
`
``
1854
`+
}
`