Skip to content

Commit a7b727d

Browse files
committed
Account for bounds when denying _ in type parameters
1 parent e6c8596 commit a7b727d

File tree

5 files changed

+78
-13
lines changed

5 files changed

+78
-13
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
514514
self_ty: Option<Ty<'tcx>>,
515515
arg_count_correct: bool,
516516
args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool),
517-
provided_kind: impl Fn(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
517+
mut provided_kind: impl FnMut(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
518518
mut inferred_kind: impl FnMut(
519519
Option<&[subst::GenericArg<'tcx>]>,
520520
&GenericParamDef,
@@ -751,6 +751,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
751751
};
752752

753753
let mut missing_type_params = vec![];
754+
let mut inferred_params = vec![];
754755
let substs = Self::create_substs_for_generic_args(
755756
tcx,
756757
def_id,
@@ -773,7 +774,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
773774
self.ast_region_to_region(&lt, Some(param)).into()
774775
}
775776
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
776-
self.ast_ty_to_ty(&ty).into()
777+
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
778+
inferred_params.push(ty.span);
779+
tcx.types.err.into()
780+
} else {
781+
self.ast_ty_to_ty(&ty).into()
782+
}
777783
}
778784
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
779785
self.ast_const_to_const(&ct.value, tcx.type_of(param.def_id)).into()
@@ -832,6 +838,18 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
832838
}
833839
},
834840
);
841+
if !inferred_params.is_empty() {
842+
// We always collect the spans for placeholder types when evaluating `fn`s, but we
843+
// only want to emit an error complaining about them if infer types (`_`) are not
844+
// allowed. `allow_ty_infer` gates this behavior.
845+
crate::collect::placeholder_type_error(
846+
tcx,
847+
inferred_params[0],
848+
&[],
849+
inferred_params,
850+
false,
851+
);
852+
}
835853

836854
self.complain_about_missing_type_params(
837855
missing_type_params,

src/test/ui/did_you_mean/bad-assoc-ty.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,8 @@ type I = ty!()::AssocTy;
4545
//~^ ERROR missing angle brackets in associated item path
4646
//~| ERROR ambiguous associated type
4747

48+
trait K<A, B> {}
49+
fn foo<X: K<_, _>>(x: X) {}
50+
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
51+
4852
fn main() {}

src/test/ui/did_you_mean/bad-assoc-ty.stderr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,15 @@ error[E0223]: ambiguous associated type
122122
LL | type I = ty!()::AssocTy;
123123
| ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
124124

125-
error: aborting due to 19 previous errors
125+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
126+
--> $DIR/bad-assoc-ty.rs:49:13
127+
|
128+
LL | fn foo<X: K<_, _>>(x: X) {}
129+
| ^ ^ not allowed in type signatures
130+
| |
131+
| not allowed in type signatures
132+
133+
error: aborting due to 20 previous errors
126134

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

src/test/ui/typeck/typeck_type_placeholder_item.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,12 @@ trait BadTrait<_> {}
157157
//~^ ERROR expected identifier, found reserved identifier `_`
158158
impl BadTrait<_> for BadStruct<_> {}
159159
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
160+
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
161+
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
160162

161163
fn impl_trait() -> impl BadTrait<_> {
162164
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
165+
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
163166
unimplemented!()
164167
}
165168

@@ -174,12 +177,14 @@ struct BadStruct2<_, T>(_, T);
174177

175178
type X = Box<_>;
176179
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
180+
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
177181

178182
struct Struct;
179183
trait Trait<T> {}
180184
impl Trait<usize> for Struct {}
181185
type Y = impl Trait<_>;
182186
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
187+
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
183188
fn foo() -> Y {
184189
Struct
185190
}

src/test/ui/typeck/typeck_type_placeholder_item.stderr

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ LL | trait BadTrait<_> {}
1111
| ^ expected identifier, found reserved identifier
1212

1313
error: expected identifier, found reserved identifier `_`
14-
--> $DIR/typeck_type_placeholder_item.rs:166:19
14+
--> $DIR/typeck_type_placeholder_item.rs:169:19
1515
|
1616
LL | struct BadStruct1<_, _>(_);
1717
| ^ expected identifier, found reserved identifier
1818

1919
error: expected identifier, found reserved identifier `_`
20-
--> $DIR/typeck_type_placeholder_item.rs:166:22
20+
--> $DIR/typeck_type_placeholder_item.rs:169:22
2121
|
2222
LL | struct BadStruct1<_, _>(_);
2323
| ^ expected identifier, found reserved identifier
2424

2525
error: expected identifier, found reserved identifier `_`
26-
--> $DIR/typeck_type_placeholder_item.rs:171:19
26+
--> $DIR/typeck_type_placeholder_item.rs:174:19
2727
|
2828
LL | struct BadStruct2<_, T>(_, T);
2929
| ^ expected identifier, found reserved identifier
3030

3131
error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters
32-
--> $DIR/typeck_type_placeholder_item.rs:166:22
32+
--> $DIR/typeck_type_placeholder_item.rs:169:22
3333
|
3434
LL | struct BadStruct1<_, _>(_);
3535
| - ^ already used
@@ -343,6 +343,18 @@ help: use type parameters instead
343343
LL | struct BadStruct<T>(T);
344344
| ^ ^
345345

346+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
347+
--> $DIR/typeck_type_placeholder_item.rs:158:32
348+
|
349+
LL | impl BadTrait<_> for BadStruct<_> {}
350+
| ^ not allowed in type signatures
351+
352+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
353+
--> $DIR/typeck_type_placeholder_item.rs:158:15
354+
|
355+
LL | impl BadTrait<_> for BadStruct<_> {}
356+
| ^ not allowed in type signatures
357+
346358
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
347359
--> $DIR/typeck_type_placeholder_item.rs:158:15
348360
|
@@ -357,13 +369,13 @@ LL | impl<T> BadTrait<T> for BadStruct<T> {}
357369
| ^^^ ^ ^
358370

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

365377
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
366-
--> $DIR/typeck_type_placeholder_item.rs:166:25
378+
--> $DIR/typeck_type_placeholder_item.rs:169:25
367379
|
368380
LL | struct BadStruct1<_, _>(_);
369381
| ^ not allowed in type signatures
@@ -374,7 +386,7 @@ LL | struct BadStruct1<T, _>(T);
374386
| ^ ^
375387

376388
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
377-
--> $DIR/typeck_type_placeholder_item.rs:171:25
389+
--> $DIR/typeck_type_placeholder_item.rs:174:25
378390
|
379391
LL | struct BadStruct2<_, T>(_, T);
380392
| ^ not allowed in type signatures
@@ -385,7 +397,13 @@ LL | struct BadStruct2<K, T>(K, T);
385397
| ^ ^
386398

387399
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
388-
--> $DIR/typeck_type_placeholder_item.rs:175:14
400+
--> $DIR/typeck_type_placeholder_item.rs:178:14
401+
|
402+
LL | type X = Box<_>;
403+
| ^ not allowed in type signatures
404+
405+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
406+
--> $DIR/typeck_type_placeholder_item.rs:178:14
389407
|
390408
LL | type X = Box<_>;
391409
| ^ not allowed in type signatures
@@ -505,7 +523,19 @@ LL | fn clone_from<T>(&mut self, other: T) { *self = FnTest9; }
505523
| ^^^ ^
506524

507525
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
508-
--> $DIR/typeck_type_placeholder_item.rs:181:21
526+
--> $DIR/typeck_type_placeholder_item.rs:163:34
527+
|
528+
LL | fn impl_trait() -> impl BadTrait<_> {
529+
| ^ not allowed in type signatures
530+
531+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
532+
--> $DIR/typeck_type_placeholder_item.rs:185:21
533+
|
534+
LL | type Y = impl Trait<_>;
535+
| ^ not allowed in type signatures
536+
537+
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
538+
--> $DIR/typeck_type_placeholder_item.rs:185:21
509539
|
510540
LL | type Y = impl Trait<_>;
511541
| ^ not allowed in type signatures
@@ -546,7 +576,7 @@ LL | fn clone(&self) -> _ { FnTest9 }
546576
| not allowed in type signatures
547577
| help: replace with the correct return type: `main::FnTest9`
548578

549-
error: aborting due to 58 previous errors
579+
error: aborting due to 63 previous errors
550580

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

0 commit comments

Comments
 (0)