]> git.lizzy.rs Git - rust.git/commitdiff
Try to use the first char in the trait name as type param
authorEsteban Küber <esteban@kuber.com.ar>
Sun, 5 Apr 2020 21:55:06 +0000 (14:55 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Sat, 11 Apr 2020 21:34:01 +0000 (14:34 -0700)
src/librustc_hir/hir.rs
src/librustc_trait_selection/traits/error_reporting/suggestions.rs
src/librustc_typeck/collect.rs
src/test/ui/suggestions/impl-trait-with-missing-bounds.rs
src/test/ui/suggestions/impl-trait-with-missing-bounds.stderr

index b4744a7d6db1f1c11f882b592d6979e171f62e8b..f26fc402a9ac2d7c1cec78fba72bd201a1d994d8 100644 (file)
@@ -438,13 +438,15 @@ pub fn bounds_span(&self) -> Option<Span> {
 }
 
 pub trait NextTypeParamName {
-    fn next_type_param_name(&self) -> &'static str;
+    fn next_type_param_name(&self, name: Option<&str>) -> String;
 }
 
 impl NextTypeParamName for &[GenericParam<'_>] {
-    fn next_type_param_name(&self) -> &'static str {
+    fn next_type_param_name(&self, name: Option<&str>) -> String {
         // This is the whitelist of possible parameter names that we might suggest.
-        let possible_names = ["T", "U", "V", "X", "Y", "Z", "A", "B", "C", "D", "E", "F", "G"];
+        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_string().to_uppercase());
+        let name = name.as_ref().map(|s| s.as_str());
+        let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"];
         let used_names = self
             .iter()
             .filter_map(|p| match p.name {
@@ -457,6 +459,7 @@ fn next_type_param_name(&self) -> &'static str {
             .iter()
             .find(|n| !used_names.contains(&Symbol::intern(n)))
             .unwrap_or(&"ParamName")
+            .to_string()
     }
 }
 
index 16bdfe5d0d1ecfdfa82b5636fb6d5c72ae0517cd..152b4fb7c566e243c48e989661963150a321ac0b 100644 (file)
@@ -211,14 +211,14 @@ fn suggest_restriction(
             }
         }
 
-        let type_param_name = generics.params.next_type_param_name();
+        let type_param_name = generics.params.next_type_param_name(Some(&name));
         // The type param `T: Trait` we will suggest to introduce.
         let type_param = format!("{}: {}", type_param_name, name);
 
         // FIXME: modify the `trait_ref` instead of string shenanigans.
         // Turn `<impl Trait as Foo>::Bar: Qux` into `<T as Foo>::Bar: Qux`.
         let pred = trait_ref.without_const().to_predicate().to_string();
-        let pred = pred.replace(&impl_name, type_param_name);
+        let pred = pred.replace(&impl_name, &type_param_name);
         let mut sugg = vec![
             match generics
                 .params
index eb8f46e83bbf5308c05d7eba4d701a46590bd5e1..47754c3704c79c1004e87f2cac8913e0ca464984 100644 (file)
@@ -135,7 +135,7 @@ struct CollectItemTypesVisitor<'tcx> {
     if placeholder_types.is_empty() {
         return;
     }
-    let type_name = generics.next_type_param_name();
+    let type_name = generics.next_type_param_name(None);
 
     let mut sugg: Vec<_> =
         placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
index 6947bc0a734b9c8ced2e7421aa7572a0a76290c4..6e9e8821cfea788236640aafe3733744b07a4c7a 100644 (file)
@@ -24,7 +24,7 @@ fn baz(t: impl std::fmt::Debug, constraints: impl Iterator) {
     }
 }
 
-fn bat<K, T: std::fmt::Debug>(t: T, constraints: impl Iterator, _: K) {
+fn bat<I, T: std::fmt::Debug>(t: T, constraints: impl Iterator, _: I) {
     for constraint in constraints {
         qux(t);
         qux(constraint);
index 2d48be42233eae341fea0c00e10e654884410c38..e1c40e2537b3ec29bb63aeb71b67c2864d6b3171 100644 (file)
@@ -10,7 +10,7 @@ LL | fn qux(_: impl std::fmt::Debug) {}
    = help: the trait `std::fmt::Debug` is not implemented for `<impl Iterator as std::iter::Iterator>::Item`
 help: introduce a type parameter with a trait bound instead of using `impl Trait`
    |
-LL | fn foo<T: Iterator>(constraints: T) where <T as std::iter::Iterator>::Item: std::fmt::Debug  {
+LL | fn foo<I: Iterator>(constraints: I) where <I as std::iter::Iterator>::Item: std::fmt::Debug  {
    |       ^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `<impl Iterator as std::iter::Iterator>::Item` doesn't implement `std::fmt::Debug`
@@ -25,7 +25,7 @@ LL | fn qux(_: impl std::fmt::Debug) {}
    = help: the trait `std::fmt::Debug` is not implemented for `<impl Iterator as std::iter::Iterator>::Item`
 help: introduce a type parameter with a trait bound instead of using `impl Trait`
    |
-LL | fn bar<T, U: Iterator>(t: T, constraints: U) where T: std::fmt::Debug, <U as std::iter::Iterator>::Item: std::fmt::Debug  {
+LL | fn bar<T, I: Iterator>(t: T, constraints: I) where T: std::fmt::Debug, <I as std::iter::Iterator>::Item: std::fmt::Debug  {
    |         ^^^^^^^^^^^^^                     ^                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `<impl Iterator as std::iter::Iterator>::Item` doesn't implement `std::fmt::Debug`
@@ -40,7 +40,7 @@ LL | fn qux(_: impl std::fmt::Debug) {}
    = help: the trait `std::fmt::Debug` is not implemented for `<impl Iterator as std::iter::Iterator>::Item`
 help: introduce a type parameter with a trait bound instead of using `impl Trait`
    |
-LL | fn baz<T: Iterator>(t: impl std::fmt::Debug, constraints: T) where <T as std::iter::Iterator>::Item: std::fmt::Debug  {
+LL | fn baz<I: Iterator>(t: impl std::fmt::Debug, constraints: I) where <I as std::iter::Iterator>::Item: std::fmt::Debug  {
    |       ^^^^^^^^^^^^^                                       ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `<impl Iterator as std::iter::Iterator>::Item` doesn't implement `std::fmt::Debug`
@@ -55,7 +55,7 @@ LL | fn qux(_: impl std::fmt::Debug) {}
    = help: the trait `std::fmt::Debug` is not implemented for `<impl Iterator as std::iter::Iterator>::Item`
 help: introduce a type parameter with a trait bound instead of using `impl Trait`
    |
-LL | fn bat<K, T: std::fmt::Debug, U: Iterator>(t: T, constraints: U, _: K) where <U as std::iter::Iterator>::Item: std::fmt::Debug  {
+LL | fn bat<I, T: std::fmt::Debug, U: Iterator>(t: T, constraints: U, _: I) where <U as std::iter::Iterator>::Item: std::fmt::Debug  {
    |                             ^^^^^^^^^^^^^                     ^        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `<impl Iterator + std::fmt::Debug as std::iter::Iterator>::Item` doesn't implement `std::fmt::Debug`
@@ -70,7 +70,7 @@ LL | fn qux(_: impl std::fmt::Debug) {}
    = help: the trait `std::fmt::Debug` is not implemented for `<impl Iterator + std::fmt::Debug as std::iter::Iterator>::Item`
 help: introduce a type parameter with a trait bound instead of using `impl Trait`
    |
-LL | fn bak<T: Iterator + std::fmt::Debug>(constraints: T) where <T as std::iter::Iterator>::Item: std::fmt::Debug  {
+LL | fn bak<I: Iterator + std::fmt::Debug>(constraints: I) where <I as std::iter::Iterator>::Item: std::fmt::Debug  {
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors