From fb52883690831a0bbb8b97d75eadc696dd2fd422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 24 Dec 2019 15:12:01 -0800 Subject: [PATCH] Account for existing type params when suggesting replacing `_` for a new one --- src/librustc_typeck/collect.rs | 25 +++++- .../ui/typeck/typeck_type_placeholder_item.rs | 6 ++ .../typeck_type_placeholder_item.stderr | 84 ++++++++++++------- 3 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 440b894fcf7e..ccff01755e93 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -134,11 +134,30 @@ crate fn placeholder_type_error( suggest: bool, ) { if !placeholder_types.is_empty() { - let mut sugg: Vec<_> = placeholder_types.iter().map(|sp| (*sp, "T".to_string())).collect(); + let possible_names = ["T", "K", "L", "A", "B", "C"]; + let used_names = generics.iter().filter_map(|p| match p.name { + hir::ParamName::Plain(ident) => Some(ident.name), + _ => None, + }).collect::>(); + + let mut type_name = "ParamName"; + for name in &possible_names { + if !used_names.contains(&Symbol::intern(name)) { + type_name = name; + break; + } + } + + let mut sugg: Vec<_> = placeholder_types.iter() + .map(|sp| (*sp, type_name.to_string())) + .collect(); if generics.is_empty() { - sugg.push((ident_span.shrink_to_hi(), "".to_string())); + sugg.push((ident_span.shrink_to_hi(), format!("<{}>", type_name))); } else { - sugg.push((generics.iter().last().unwrap().span.shrink_to_hi(), ", T".to_string())); + sugg.push(( + generics.iter().last().unwrap().span.shrink_to_hi(), + format!(", {}", type_name), + )); } let mut err = struct_span_err!( tcx.sess, diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 0ec5d80f2414..d1fb51e0fe24 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -19,6 +19,12 @@ static TEST5: (_, _) = (1, 2); fn test6(_: _) { } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +fn test6_b(_: _, _: T) { } +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + +fn test6_c(_: _, _: (T, K, L, A, B)) { } +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn test7(x: _) { let _x: usize = x; } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index dbb014edd426..20a74b3dac33 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -54,7 +54,29 @@ LL | fn test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:22:13 + --> $DIR/typeck_type_placeholder_item.rs:22:18 + | +LL | fn test6_b(_: _, _: T) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_b(_: K, _: T) { } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:25:30 + | +LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn test6_c(_: C, _: (T, K, L, A, B)) { } + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:28:13 | LL | fn test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -65,7 +87,7 @@ LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:25:22 + --> $DIR/typeck_type_placeholder_item.rs:31:22 | LL | fn test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -76,7 +98,7 @@ LL | fn test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:47:8 + --> $DIR/typeck_type_placeholder_item.rs:53:8 | LL | a: _, | ^ not allowed in type signatures @@ -95,7 +117,7 @@ LL | b: (T, T), | error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:53:21 + --> $DIR/typeck_type_placeholder_item.rs:59:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -104,7 +126,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace this with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:56:22 + --> $DIR/typeck_type_placeholder_item.rs:62:22 | LL | fn fn_test2() -> (_, _) { (5, 5) } | ^^^^^^ @@ -113,7 +135,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace this with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:59:22 + --> $DIR/typeck_type_placeholder_item.rs:65:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -122,7 +144,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:62:22 + --> $DIR/typeck_type_placeholder_item.rs:68:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -131,7 +153,7 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:65:23 + --> $DIR/typeck_type_placeholder_item.rs:71:23 | LL | static FN_TEST5: (_, _) = (1, 2); | ^ ^ not allowed in type signatures @@ -139,7 +161,7 @@ LL | static FN_TEST5: (_, _) = (1, 2); | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:68:20 + --> $DIR/typeck_type_placeholder_item.rs:74:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -150,7 +172,7 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:71:20 + --> $DIR/typeck_type_placeholder_item.rs:77:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -161,7 +183,7 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:74:29 + --> $DIR/typeck_type_placeholder_item.rs:80:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -172,7 +194,7 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:96:12 + --> $DIR/typeck_type_placeholder_item.rs:102:12 | LL | a: _, | ^ not allowed in type signatures @@ -191,19 +213,19 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:101:27 + --> $DIR/typeck_type_placeholder_item.rs:107:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^^^^^^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:101:27 + --> $DIR/typeck_type_placeholder_item.rs:107:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:105:29 + --> $DIR/typeck_type_placeholder_item.rs:111:29 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | ^^^^^^ @@ -212,7 +234,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace this with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:108:21 + --> $DIR/typeck_type_placeholder_item.rs:114:21 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ^ ^ not allowed in type signatures @@ -225,7 +247,7 @@ LL | fn fn_test13(x: T) -> (i32, T) { (x, x) } | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:113:31 + --> $DIR/typeck_type_placeholder_item.rs:119:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -236,7 +258,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:115:31 + --> $DIR/typeck_type_placeholder_item.rs:121:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -249,7 +271,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:117:31 + --> $DIR/typeck_type_placeholder_item.rs:123:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -260,7 +282,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:119:26 + --> $DIR/typeck_type_placeholder_item.rs:125:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -271,7 +293,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:121:26 + --> $DIR/typeck_type_placeholder_item.rs:127:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -284,7 +306,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:123:28 + --> $DIR/typeck_type_placeholder_item.rs:129:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -295,7 +317,7 @@ LL | fn assoc_fn_test3() -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:31:24 + --> $DIR/typeck_type_placeholder_item.rs:37:24 | LL | fn test9(&self) -> _ { () } | ^ @@ -304,7 +326,7 @@ LL | fn test9(&self) -> _ { () } | help: replace this with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:34:27 + --> $DIR/typeck_type_placeholder_item.rs:40:27 | LL | fn test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -315,7 +337,7 @@ LL | fn test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:39:24 + --> $DIR/typeck_type_placeholder_item.rs:45:24 | LL | fn clone(&self) -> _ { Test9 } | ^ @@ -324,7 +346,7 @@ LL | fn clone(&self) -> _ { Test9 } | help: replace this with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:42:37 + --> $DIR/typeck_type_placeholder_item.rs:48:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures @@ -335,7 +357,7 @@ LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:80:31 + --> $DIR/typeck_type_placeholder_item.rs:86:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -344,7 +366,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace this with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:83:34 + --> $DIR/typeck_type_placeholder_item.rs:89:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -355,7 +377,7 @@ LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:88:28 + --> $DIR/typeck_type_placeholder_item.rs:94:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -364,7 +386,7 @@ LL | fn clone(&self) -> _ { FnTest9 } | help: replace this with the correct return type: `main::FnTest9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:91:41 + --> $DIR/typeck_type_placeholder_item.rs:97:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -374,7 +396,7 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ -error: aborting due to 36 previous errors +error: aborting due to 38 previous errors Some errors have detailed explanations: E0121, E0282. For more information about an error, try `rustc --explain E0121`.