Try to use the first char in the trait name as type param

This commit is contained in:
Esteban Küber 2020-04-05 14:55:06 -07:00
parent 01169572a2
commit 1e3bdc08c9
5 changed files with 15 additions and 12 deletions

View File

@ -438,13 +438,15 @@ impl GenericParam<'hir> {
} }
pub trait NextTypeParamName { 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<'_>] { 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. // 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 let used_names = self
.iter() .iter()
.filter_map(|p| match p.name { .filter_map(|p| match p.name {
@ -457,6 +459,7 @@ impl NextTypeParamName for &[GenericParam<'_>] {
.iter() .iter()
.find(|n| !used_names.contains(&Symbol::intern(n))) .find(|n| !used_names.contains(&Symbol::intern(n)))
.unwrap_or(&"ParamName") .unwrap_or(&"ParamName")
.to_string()
} }
} }

View 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. // The type param `T: Trait` we will suggest to introduce.
let type_param = format!("{}: {}", type_param_name, name); let type_param = format!("{}: {}", type_param_name, name);
// FIXME: modify the `trait_ref` instead of string shenanigans. // FIXME: modify the `trait_ref` instead of string shenanigans.
// Turn `<impl Trait as Foo>::Bar: Qux` into `<T as Foo>::Bar: Qux`. // 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 = 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![ let mut sugg = vec![
match generics match generics
.params .params

View File

@ -135,7 +135,7 @@ crate fn placeholder_type_error(
if placeholder_types.is_empty() { if placeholder_types.is_empty() {
return; return;
} }
let type_name = generics.next_type_param_name(); let type_name = generics.next_type_param_name(None);
let mut sugg: Vec<_> = let mut sugg: Vec<_> =
placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect(); placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();

View 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 { for constraint in constraints {
qux(t); qux(t);
qux(constraint); qux(constraint);

View 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: 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` 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` 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: 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` 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` 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: 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` 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` 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: 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` 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` 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: 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` 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 error: aborting due to 5 previous errors