about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAmjad Alsharafi <amjadsharafi10@gmail.com>2020-09-04 01:47:35 +0800
committerAmjad Alsharafi <amjadsharafi10@gmail.com>2020-09-04 22:17:28 +0800
commit8f2d9069a8c19c5471c4f3490ce21eb910cf3074 (patch)
treee41f1a8ac62f0bc5f0556b08f8c07b58ae251e11
parent08deb863bdebfcbbb71c18acf903eca84f1df4e7 (diff)
downloadrust-8f2d9069a8c19c5471c4f3490ce21eb910cf3074.tar.gz
rust-8f2d9069a8c19c5471c4f3490ce21eb910cf3074.zip
Implementation of incompatible features error
If two features are defined as incompatible, using them together would
result in an error
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs34
-rw-r--r--compiler/rustc_feature/src/active.rs5
-rw-r--r--compiler/rustc_feature/src/lib.rs2
-rw-r--r--src/test/ui/const-generics/min-and-full-same-time.rs7
-rw-r--r--src/test/ui/const-generics/min-and-full-same-time.stderr13
5 files changed, 60 insertions, 1 deletions
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0ee8ef55e61..97e6b363eff 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -608,6 +608,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
 
 pub fn check_crate(krate: &ast::Crate, sess: &Session) {
     maybe_stage_features(sess, krate);
+    check_incompatible_features(sess);
     let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() };
 
     let spans = sess.parse_sess.gated_spans.spans.borrow();
@@ -677,3 +678,36 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
         }
     }
 }
+
+fn check_incompatible_features(sess: &Session) {
+    let features = sess.features_untracked();
+
+    let declared_features = features
+        .declared_lang_features
+        .iter()
+        .copied()
+        .map(|(name, span, _)| (name, span))
+        .chain(features.declared_lib_features.iter().copied());
+
+    for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES
+        .iter()
+        .filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2))
+    {
+        if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) {
+            if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
+            {
+                let spans = vec![f1_span, f2_span];
+                sess.struct_span_err(
+                    spans.clone(),
+                    &format!(
+                        "features `{}` and `{}` are incompatible, using them at the same time \
+                        is not allowed",
+                        f1_name, f2_name
+                    ),
+                )
+                .help("remove one of these features")
+                .emit();
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index e858980738d..3d7b3da45cc 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -605,3 +605,8 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
     sym::lazy_normalization_consts,
     sym::specialization,
 ];
+
+/// Some features are not allowed to be used together at the same time, if
+/// the two are present, produce an error
+pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] =
+    &[(sym::const_generics, sym::min_const_generics)];
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 4393368cd45..15564a59658 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -131,7 +131,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU3
 }
 
 pub use accepted::ACCEPTED_FEATURES;
-pub use active::{Features, ACTIVE_FEATURES, INCOMPLETE_FEATURES};
+pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES, INCOMPLETE_FEATURES};
 pub use builtin_attrs::{
     deprecated_attributes, find_gated_cfg, is_builtin_attr_name, AttributeGate, AttributeTemplate,
     AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
diff --git a/src/test/ui/const-generics/min-and-full-same-time.rs b/src/test/ui/const-generics/min-and-full-same-time.rs
new file mode 100644
index 00000000000..2365adc3a86
--- /dev/null
+++ b/src/test/ui/const-generics/min-and-full-same-time.rs
@@ -0,0 +1,7 @@
+#![feature(const_generics)]
+//~^ ERROR features `const_generics` and `min_const_generics` are incompatible
+#![allow(incomplete_features)]
+#![feature(min_const_generics)]
+
+
+fn main() {}
diff --git a/src/test/ui/const-generics/min-and-full-same-time.stderr b/src/test/ui/const-generics/min-and-full-same-time.stderr
new file mode 100644
index 00000000000..907fec9bbe1
--- /dev/null
+++ b/src/test/ui/const-generics/min-and-full-same-time.stderr
@@ -0,0 +1,13 @@
+error: features `const_generics` and `min_const_generics` are incompatible, using them at the same time is not allowed
+  --> $DIR/min-and-full-same-time.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+...
+LL | #![feature(min_const_generics)]
+   |            ^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove one of these features
+
+error: aborting due to previous error
+