]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_lint/builtin.rs
Make "await" a pseudo-edition keyword
[rust.git] / src / librustc_lint / builtin.rs
index b662b825013937a055422d7792e2c652d9e5603c..adf23a5cf2c855564e43d1f7a7fb40f67e15a9a7 100644 (file)
@@ -783,7 +783,7 @@ impl EarlyLintPass for DeprecatedAttr {
     fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
         for &&(n, _, ref g) in &self.depr_attrs {
             if attr.name() == n {
-                if let &AttributeGate::Gated(Stability::Deprecated(link),
+                if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
                                              ref name,
                                              ref reason,
                                              _) = g {
@@ -792,7 +792,7 @@ fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
                     let mut err = cx.struct_span_lint(DEPRECATED, attr.span, &msg);
                     err.span_suggestion_short_with_applicability(
                         attr.span,
-                        "remove this attribute",
+                        suggestion.unwrap_or("remove this attribute"),
                         String::new(),
                         Applicability::MachineApplicable
                     );
@@ -1612,7 +1612,7 @@ fn validate_const<'a, 'tcx>(
     gid: ::rustc::mir::interpret::GlobalId<'tcx>,
     what: &str,
 ) {
-    let ecx = ::rustc_mir::interpret::mk_eval_cx(tcx, gid.instance, param_env).unwrap();
+    let ecx = ::rustc_mir::const_eval::mk_eval_cx(tcx, gid.instance, param_env).unwrap();
     let result = (|| {
         let op = ecx.const_to_op(constant)?;
         let mut todo = vec![(op, Vec::new())];
@@ -1934,21 +1934,52 @@ fn check_mac(&mut self, cx: &EarlyContext, mac: &ast::Mac) {
         self.check_tokens(cx, mac.node.tts.clone().into());
     }
     fn check_ident(&mut self, cx: &EarlyContext, ident: ast::Ident) {
-        let next_edition = match cx.sess.edition() {
+        let ident_str = &ident.as_str()[..];
+        let cur_edition = cx.sess.edition();
+        let is_raw_ident = |ident: ast::Ident| {
+            cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span)
+        };
+        let next_edition = match cur_edition {
             Edition::Edition2015 => {
-                match &ident.as_str()[..] {
-                    "async" |
-                    "try" => Edition::Edition2018,
+                match ident_str {
+                    "async" | "try" | "dyn" => Edition::Edition2018,
+                    // Only issue warnings for `await` if the `async_await`
+                    // feature isn't being used. Otherwise, users need
+                    // to keep using `await` for the macro exposed by std.
+                    "await" if !cx.sess.features_untracked().async_await => Edition::Edition2018,
                     _ => return,
                 }
             }
 
             // no new keywords yet for 2018 edition and beyond
-            _ => return,
+            // However, `await` is a "false" keyword in the 2018 edition,
+            // and can only be used if the `async_await` feature is enabled.
+            // Otherwise, we emit an error.
+            _ => {
+                if "await" == ident_str
+                    && !cx.sess.features_untracked().async_await
+                    && !is_raw_ident(ident)
+                {
+                    let mut err = struct_span_err!(
+                        cx.sess,
+                        ident.span,
+                        E0721,
+                        "`await` is a keyword in the {} edition", cur_edition,
+                    );
+                    err.span_suggestion_with_applicability(
+                        ident.span,
+                        "you can use a raw identifier to stay compatible",
+                        "r#await".to_string(),
+                        Applicability::MachineApplicable,
+                    );
+                    err.emit();
+                }
+                return
+            },
         };
 
         // don't lint `r#foo`
-        if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) {
+        if is_raw_ident(ident) {
             return;
         }