]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/feature_gate.rs
Rollup merge of #53413 - eddyb:featured-in-the-latest-edition, r=varkor
[rust.git] / src / libsyntax / feature_gate.rs
index dcae9b1e9ca7eabfa494328cb63d7100266b7364..7a8a7b073185a6477dfeb8fdbb73dec1995d1202 100644 (file)
@@ -1526,27 +1526,29 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) {
             }
         }
 
-        match attr.parse_meta(self.context.parse_sess) {
-            Ok(meta) => {
-                // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
-                let mut allow_attr_literal = false;
-                if attr.path == "repr" {
-                    if let Some(content) = meta.meta_item_list() {
-                        allow_attr_literal = content.iter().any(
-                            |c| c.check_name("align") || c.check_name("packed"));
+        if !self.context.features.unrestricted_attribute_tokens {
+            // Unfortunately, `parse_meta` cannot be called speculatively because it can report
+            // errors by itself, so we have to call it only if the feature is disabled.
+            match attr.parse_meta(self.context.parse_sess) {
+                Ok(meta) => {
+                    // allow attr_literals in #[repr(align(x))] and #[repr(packed(n))]
+                    let mut allow_attr_literal = false;
+                    if attr.path == "repr" {
+                        if let Some(content) = meta.meta_item_list() {
+                            allow_attr_literal = content.iter().any(
+                                |c| c.check_name("align") || c.check_name("packed"));
+                        }
                     }
-                }
 
-                if !allow_attr_literal && contains_novel_literal(&meta) {
-                    gate_feature_post!(&self, attr_literals, attr.span,
-                                    "non-string literals in attributes, or string \
-                                    literals in top-level positions, are experimental");
+                    if !allow_attr_literal && contains_novel_literal(&meta) {
+                        gate_feature_post!(&self, attr_literals, attr.span,
+                                        "non-string literals in attributes, or string \
+                                        literals in top-level positions, are experimental");
+                    }
+                }
+                Err(mut err) => {
+                    err.help("try enabling `#![feature(unrestricted_attribute_tokens)]`").emit()
                 }
-            }
-            Err(mut err) => {
-                err.cancel();
-                gate_feature_post!(&self, unrestricted_attribute_tokens, attr.span,
-                                    "arbitrary tokens in non-macro attributes are unstable");
             }
         }
     }
@@ -1920,6 +1922,11 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
         err.emit();
     }
 
+    // Some features are known to be incomplete and using them is likely to have
+    // unanticipated results, such as compiler crashes. We warn the user about these
+    // to alert them.
+    let incomplete_features = ["generic_associated_types"];
+
     let mut features = Features::new();
     let mut edition_enabled_features = FxHashMap();
 
@@ -1959,6 +1966,16 @@ fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
                 continue
             };
 
+            if incomplete_features.iter().any(|f| *f == name.as_str()) {
+                span_handler.struct_span_warn(
+                    mi.span,
+                    &format!(
+                        "the feature `{}` is incomplete and may cause the compiler to crash",
+                        name
+                    )
+                ).emit();
+            }
+
             if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
                 if *edition <= crate_edition {
                     continue;