Skip to content

Commit

Permalink
Account for Paths on is_suggestable_infer_ty
Browse files Browse the repository at this point in the history
Fix #68162.
  • Loading branch information
estebank committed Jan 15, 2020
1 parent 30ca215 commit 268a1ff
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 45 deletions.
27 changes: 20 additions & 7 deletions src/librustc_typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,16 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
}
}

fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool {
generic_args
.iter()
.filter_map(|arg| match arg {
hir::GenericArg::Type(ty) => Some(ty),
_ => None,
})
.any(is_suggestable_infer_ty)
}

/// Whether `ty` is a type with `_` placeholders that can be infered. Used in diagnostics only to
/// use inference to provide suggestions for the appropriate type if possible.
fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
Expand All @@ -1815,13 +1825,16 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty),
Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
Def(_, generic_args) => generic_args
.iter()
.filter_map(|arg| match arg {
hir::GenericArg::Type(ty) => Some(ty),
_ => None,
})
.any(is_suggestable_infer_ty),
Def(_, generic_args) => are_suggestable_generic_args(generic_args),
Path(hir::QPath::TypeRelative(ty, segment)) => {
is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args)
}
Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => {
ty_opt.map_or(false, is_suggestable_infer_ty)
|| segments
.iter()
.any(|segment| are_suggestable_generic_args(segment.generic_args().args))
}
_ => false,
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/typeck/typeck_type_placeholder_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ struct Test10 {
}

pub fn main() {
static A = 42;
//~^ ERROR missing type for `static` item
static B: _ = 42;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
static C: Option<_> = Some(42);
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures

fn fn_test() -> _ { 5 }
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures

Expand Down
97 changes: 59 additions & 38 deletions src/test/ui/typeck/typeck_type_placeholder_item.stderr
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:146:18
--> $DIR/typeck_type_placeholder_item.rs:153:18
|
LL | struct BadStruct<_>(_);
| ^ expected identifier, found reserved identifier

error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:149:16
--> $DIR/typeck_type_placeholder_item.rs:156:16
|
LL | trait BadTrait<_> {}
| ^ expected identifier, found reserved identifier

error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:159:19
--> $DIR/typeck_type_placeholder_item.rs:166:19
|
LL | struct BadStruct1<_, _>(_);
| ^ expected identifier, found reserved identifier

error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:159:22
--> $DIR/typeck_type_placeholder_item.rs:166:22
|
LL | struct BadStruct1<_, _>(_);
| ^ expected identifier, found reserved identifier

error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:164:19
--> $DIR/typeck_type_placeholder_item.rs:171:19
|
LL | struct BadStruct2<_, T>(_, T);
| ^ expected identifier, found reserved identifier

error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters
--> $DIR/typeck_type_placeholder_item.rs:159:22
--> $DIR/typeck_type_placeholder_item.rs:166:22
|
LL | struct BadStruct1<_, _>(_);
| - ^ already used
Expand Down Expand Up @@ -177,8 +177,29 @@ LL |
LL | b: (T, T),
|

error: missing type for `static` item
--> $DIR/typeck_type_placeholder_item.rs:71:12
|
LL | static A = 42;
| ^ help: provide a type for the item: `A: i32`

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:73:15
|
LL | static B: _ = 42;
| ^
| |
| not allowed in type signatures
| 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:75:15
|
LL | static C: Option<_> = Some(42);
| ^^^^^^^^^ not allowed in type signatures

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:71:21
--> $DIR/typeck_type_placeholder_item.rs:78:21
|
LL | fn fn_test() -> _ { 5 }
| ^
Expand All @@ -187,7 +208,7 @@ LL | fn fn_test() -> _ { 5 }
| help: replace 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:74:23
--> $DIR/typeck_type_placeholder_item.rs:81:23
|
LL | fn fn_test2() -> (_, _) { (5, 5) }
| -^--^-
Expand All @@ -197,7 +218,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) }
| help: replace 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:77:22
--> $DIR/typeck_type_placeholder_item.rs:84:22
|
LL | static FN_TEST3: _ = "test";
| ^
Expand All @@ -206,7 +227,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:80:22
--> $DIR/typeck_type_placeholder_item.rs:87:22
|
LL | static FN_TEST4: _ = 145;
| ^
Expand All @@ -215,13 +236,13 @@ 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:83:22
--> $DIR/typeck_type_placeholder_item.rs:90:22
|
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:86:20
--> $DIR/typeck_type_placeholder_item.rs:93:20
|
LL | fn fn_test6(_: _) { }
| ^ not allowed in type signatures
Expand All @@ -232,7 +253,7 @@ LL | fn fn_test6<T>(_: T) { }
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:89:20
--> $DIR/typeck_type_placeholder_item.rs:96:20
|
LL | fn fn_test7(x: _) { let _x: usize = x; }
| ^ not allowed in type signatures
Expand All @@ -243,13 +264,13 @@ LL | fn fn_test7<T>(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:92:29
--> $DIR/typeck_type_placeholder_item.rs:99:29
|
LL | fn fn_test8(_f: fn() -> _) { }
| ^ not allowed in type signatures

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:92:29
--> $DIR/typeck_type_placeholder_item.rs:99:29
|
LL | fn fn_test8(_f: fn() -> _) { }
| ^ not allowed in type signatures
Expand All @@ -260,7 +281,7 @@ LL | fn fn_test8<T>(_f: fn() -> T) { }
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:115:12
--> $DIR/typeck_type_placeholder_item.rs:122:12
|
LL | a: _,
| ^ not allowed in type signatures
Expand All @@ -279,21 +300,21 @@ LL | b: (T, T),
|

error[E0282]: type annotations needed
--> $DIR/typeck_type_placeholder_item.rs:120:27
--> $DIR/typeck_type_placeholder_item.rs:127: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:120:28
--> $DIR/typeck_type_placeholder_item.rs:127:28
|
LL | fn fn_test11(_: _) -> (_, _) { panic!() }
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:124:30
--> $DIR/typeck_type_placeholder_item.rs:131:30
|
LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
| -^--^-
Expand All @@ -303,7 +324,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) }
| help: replace 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:127:33
--> $DIR/typeck_type_placeholder_item.rs:134:33
|
LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
| ------^-
Expand All @@ -312,7 +333,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) }
| help: replace 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:146:21
--> $DIR/typeck_type_placeholder_item.rs:153:21
|
LL | struct BadStruct<_>(_);
| ^ not allowed in type signatures
Expand All @@ -323,7 +344,7 @@ LL | struct BadStruct<T>(T);
| ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:151:15
--> $DIR/typeck_type_placeholder_item.rs:158:15
|
LL | impl BadTrait<_> for BadStruct<_> {}
| ^ ^ not allowed in type signatures
Expand All @@ -336,13 +357,13 @@ LL | impl<T> BadTrait<T> for BadStruct<T> {}
| ^^^ ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:154:34
--> $DIR/typeck_type_placeholder_item.rs:161:34
|
LL | fn impl_trait() -> impl BadTrait<_> {
| ^ not allowed in type signatures

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:159:25
--> $DIR/typeck_type_placeholder_item.rs:166:25
|
LL | struct BadStruct1<_, _>(_);
| ^ not allowed in type signatures
Expand All @@ -353,7 +374,7 @@ LL | struct BadStruct1<T, _>(T);
| ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:164:25
--> $DIR/typeck_type_placeholder_item.rs:171:25
|
LL | struct BadStruct2<_, T>(_, T);
| ^ not allowed in type signatures
Expand All @@ -364,7 +385,7 @@ LL | struct BadStruct2<K, T>(K, T);
| ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:168:14
--> $DIR/typeck_type_placeholder_item.rs:175:14
|
LL | type X = Box<_>;
| ^ not allowed in type signatures
Expand All @@ -381,7 +402,7 @@ LL | fn test10<T>(&self, _x : T) { }
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:132:31
--> $DIR/typeck_type_placeholder_item.rs:139:31
|
LL | fn method_test1(&self, x: _);
| ^ not allowed in type signatures
Expand All @@ -392,7 +413,7 @@ LL | fn method_test1<T>(&self, x: T);
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:134:31
--> $DIR/typeck_type_placeholder_item.rs:141:31
|
LL | fn method_test2(&self, x: _) -> _;
| ^ ^ not allowed in type signatures
Expand All @@ -405,7 +426,7 @@ LL | fn method_test2<T>(&self, x: T) -> T;
| ^^^ ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:136:31
--> $DIR/typeck_type_placeholder_item.rs:143:31
|
LL | fn method_test3(&self) -> _;
| ^ not allowed in type signatures
Expand All @@ -416,7 +437,7 @@ LL | fn method_test3<T>(&self) -> T;
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:138:26
--> $DIR/typeck_type_placeholder_item.rs:145:26
|
LL | fn assoc_fn_test1(x: _);
| ^ not allowed in type signatures
Expand All @@ -427,7 +448,7 @@ LL | fn assoc_fn_test1<T>(x: T);
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:140:26
--> $DIR/typeck_type_placeholder_item.rs:147:26
|
LL | fn assoc_fn_test2(x: _) -> _;
| ^ ^ not allowed in type signatures
Expand All @@ -440,7 +461,7 @@ LL | fn assoc_fn_test2<T>(x: T) -> T;
| ^^^ ^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:142:28
--> $DIR/typeck_type_placeholder_item.rs:149:28
|
LL | fn assoc_fn_test3() -> _;
| ^ not allowed in type signatures
Expand All @@ -462,7 +483,7 @@ LL | fn clone_from<T>(&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:102:34
--> $DIR/typeck_type_placeholder_item.rs:109:34
|
LL | fn fn_test10(&self, _x : _) { }
| ^ not allowed in type signatures
Expand All @@ -473,7 +494,7 @@ LL | fn fn_test10<T>(&self, _x : T) { }
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:110:41
--> $DIR/typeck_type_placeholder_item.rs:117:41
|
LL | fn clone_from(&mut self, other: _) { *self = FnTest9; }
| ^ not allowed in type signatures
Expand All @@ -484,7 +505,7 @@ LL | fn clone_from<T>(&mut self, other: T) { *self = FnTest9; }
| ^^^ ^

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:174:21
--> $DIR/typeck_type_placeholder_item.rs:181:21
|
LL | type Y = impl Trait<_>;
| ^ not allowed in type signatures
Expand All @@ -508,7 +529,7 @@ LL | fn clone(&self) -> _ { Test9 }
| help: replace 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:99:31
--> $DIR/typeck_type_placeholder_item.rs:106:31
|
LL | fn fn_test9(&self) -> _ { () }
| ^
Expand All @@ -517,15 +538,15 @@ LL | fn fn_test9(&self) -> _ { () }
| help: replace with the correct return type: `()`

error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:107:28
--> $DIR/typeck_type_placeholder_item.rs:114:28
|
LL | fn clone(&self) -> _ { FnTest9 }
| ^
| |
| not allowed in type signatures
| help: replace with the correct return type: `main::FnTest9`

error: aborting due to 55 previous errors
error: aborting due to 58 previous errors

Some errors have detailed explanations: E0121, E0282, E0403.
For more information about an error, try `rustc --explain E0121`.

0 comments on commit 268a1ff

Please sign in to comment.