fix(resolver): Make features singular; we only track one
diff --git a/src/cargo/core/resolver/dep_cache.rs b/src/cargo/core/resolver/dep_cache.rs
index 3ca34b7..2a93ced 100644
--- a/src/cargo/core/resolver/dep_cache.rs
+++ b/src/cargo/core/resolver/dep_cache.rs
@@ -530,9 +530,7 @@
                                 closest
                             ))
                         }
-                        Some(p) => {
-                            ActivateError::Conflict(p, ConflictReason::MissingFeatures(feat))
-                        }
+                        Some(p) => ActivateError::Conflict(p, ConflictReason::MissingFeature(feat)),
                     };
                 }
                 if deps.iter().any(|dep| dep.is_optional()) {
@@ -595,9 +593,7 @@
                     )),
                     // This code path currently isn't used, since `foo/bar`
                     // and `dep:` syntax is not allowed in a dependency.
-                    Some(p) => {
-                        ActivateError::Conflict(p, ConflictReason::MissingFeatures(dep_name))
-                    }
+                    Some(p) => ActivateError::Conflict(p, ConflictReason::MissingFeature(dep_name)),
                 }
             }
             RequirementError::Cycle(feat) => ActivateError::Fatal(anyhow::format_err!(
diff --git a/src/cargo/core/resolver/errors.rs b/src/cargo/core/resolver/errors.rs
index 6c8679e..d743e26 100644
--- a/src/cargo/core/resolver/errors.rs
+++ b/src/cargo/core/resolver/errors.rs
@@ -137,7 +137,7 @@
                     has_semver = true;
                 }
                 ConflictReason::Links(link) => {
-                    msg.push_str("\n\nthe package `");
+                    msg.push_str("\n\npackage `");
                     msg.push_str(&*dep.package_name());
                     msg.push_str("` links to the native library `");
                     msg.push_str(link);
@@ -150,46 +150,46 @@
                     msg.push_str(link);
                     msg.push_str("\"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.");
                 }
-                ConflictReason::MissingFeatures(features) => {
-                    msg.push_str("\n\nthe package `");
+                ConflictReason::MissingFeature(feature) => {
+                    msg.push_str("\n\npackage `");
                     msg.push_str(&*p.name());
                     msg.push_str("` depends on `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("`, with features: `");
-                    msg.push_str(features);
+                    msg.push_str("` with feature `");
+                    msg.push_str(feature);
                     msg.push_str("` but `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("` does not have these features.\n");
+                    msg.push_str("` does not have that feature.\n");
                     // p == parent so the full path is redundant.
                 }
-                ConflictReason::RequiredDependencyAsFeature(features) => {
-                    msg.push_str("\n\nthe package `");
+                ConflictReason::RequiredDependencyAsFeature(feature) => {
+                    msg.push_str("\n\npackage `");
                     msg.push_str(&*p.name());
                     msg.push_str("` depends on `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("`, with features: `");
-                    msg.push_str(features);
+                    msg.push_str("` with feature `");
+                    msg.push_str(feature);
                     msg.push_str("` but `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("` does not have these features.\n");
+                    msg.push_str("` does not have that feature.\n");
                     msg.push_str(
-                        " It has a required dependency with that name, \
+                        " A required dependency with that name exists, \
                          but only optional dependencies can be used as features.\n",
                     );
                     // p == parent so the full path is redundant.
                 }
-                ConflictReason::NonImplicitDependencyAsFeature(features) => {
-                    msg.push_str("\n\nthe package `");
+                ConflictReason::NonImplicitDependencyAsFeature(feature) => {
+                    msg.push_str("\n\npackage `");
                     msg.push_str(&*p.name());
                     msg.push_str("` depends on `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("`, with features: `");
-                    msg.push_str(features);
+                    msg.push_str("` with feature `");
+                    msg.push_str(feature);
                     msg.push_str("` but `");
                     msg.push_str(&*dep.package_name());
-                    msg.push_str("` does not have these features.\n");
+                    msg.push_str("` does not have that feature.\n");
                     msg.push_str(
-                        " It has an optional dependency with that name, \
+                        " An optional dependency with that name exists, \
                          but that dependency uses the \"dep:\" \
                          syntax in the features table, so it does not have an \
                          implicit feature with that name.\n",
diff --git a/src/cargo/core/resolver/types.rs b/src/cargo/core/resolver/types.rs
index 2a5c51a..8bc1c9f 100644
--- a/src/cargo/core/resolver/types.rs
+++ b/src/cargo/core/resolver/types.rs
@@ -339,10 +339,10 @@
     /// we're only allowed one per dependency graph.
     Links(InternedString),
 
-    /// A dependency listed features that weren't actually available on the
+    /// A dependency listed a feature that wasn't actually available on the
     /// candidate. For example we tried to activate feature `foo` but the
     /// candidate we're activating didn't actually have the feature `foo`.
-    MissingFeatures(InternedString),
+    MissingFeature(InternedString),
 
     /// A dependency listed a feature that ended up being a required dependency.
     /// For example we tried to activate feature `foo` but the
@@ -360,8 +360,8 @@
         matches!(self, ConflictReason::Links(_))
     }
 
-    pub fn is_missing_features(&self) -> bool {
-        matches!(self, ConflictReason::MissingFeatures(_))
+    pub fn is_missing_feature(&self) -> bool {
+        matches!(self, ConflictReason::MissingFeature(_))
     }
 
     pub fn is_required_dependency_as_features(&self) -> bool {
diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs
index 17d8228..f3ed272 100644
--- a/tests/testsuite/build_script.rs
+++ b/tests/testsuite/build_script.rs
@@ -1032,7 +1032,7 @@
     ... required by package `foo v0.5.0 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.5.0
 
-the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
+package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
 package `foo v0.5.0 ([ROOT]/foo)`
 Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "a"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
 
@@ -1159,7 +1159,7 @@
     ... which satisfies path dependency `a` of package `foo v0.5.0 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.5.0
 
-the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
+package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
 package `foo v0.5.0 ([ROOT]/foo)`
 Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "a"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
 
@@ -4767,7 +4767,7 @@
     ... required by package `foo v0.5.0 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.5.0
 
-the package `a` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
+package `a` links to the native library `a`, but it conflicts with a previous package which links to `a` as well:
 package `foo v0.5.0 ([ROOT]/foo)`
 Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = "a"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links.
 
diff --git a/tests/testsuite/features.rs b/tests/testsuite/features.rs
index cdc4adc..3362057 100644
--- a/tests/testsuite/features.rs
+++ b/tests/testsuite/features.rs
@@ -219,7 +219,7 @@
     ... required by package `foo v0.0.1 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.0.1
 
-the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features.
+package `foo` depends on `bar` with feature `bar` but `bar` does not have that feature.
 
 
 failed to select a version for `bar` which could resolve this conflict
@@ -279,7 +279,7 @@
     ... required by package `foo v0.0.1 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.0.1
 
-the package `foo` depends on `bar`, with features: `bar` but `bar` does not have these features.
+package `foo` depends on `bar` with feature `bar` but `bar` does not have that feature.
 
 
 failed to select a version for `bar` which could resolve this conflict
@@ -499,8 +499,8 @@
     ... required by package `foo v0.0.1 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.0.1
 
-the package `foo` depends on `bar`, with features: `baz` but `bar` does not have these features.
- It has a required dependency with that name, but only optional dependencies can be used as features.
+package `foo` depends on `bar` with feature `baz` but `bar` does not have that feature.
+ A required dependency with that name exists, but only optional dependencies can be used as features.
 
 
 failed to select a version for `bar` which could resolve this conflict
diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs
index 13eeac1..711fde2 100644
--- a/tests/testsuite/test.rs
+++ b/tests/testsuite/test.rs
@@ -4007,7 +4007,7 @@
     ... required by package `foo v0.1.0 ([ROOT]/foo)`
 versions that meet the requirements `*` are: 0.1.0
 
-the package `foo` depends on `foo`, with features: `missing` but `foo` does not have these features.
+package `foo` depends on `foo` with feature `missing` but `foo` does not have that feature.
 
 
 failed to select a version for `foo` which could resolve this conflict