Account for bounds when denying _ in type parameters

This commit is contained in:
Esteban Küber 2020-02-13 13:34:00 -08:00
parent e6c85960d1
commit a7b727dab3
5 changed files with 78 additions and 13 deletions

View file

@ -514,7 +514,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self_ty: Option<Ty<'tcx>>,
arg_count_correct: bool,
args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool),
provided_kind: impl Fn(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
mut provided_kind: impl FnMut(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
mut inferred_kind: impl FnMut(
Option<&[subst::GenericArg<'tcx>]>,
&GenericParamDef,
@ -751,6 +751,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
let mut missing_type_params = vec![];
let mut inferred_params = vec![];
let substs = Self::create_substs_for_generic_args(
tcx,
def_id,
@ -773,7 +774,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ast_region_to_region(&lt, Some(param)).into()
}
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
self.ast_ty_to_ty(&ty).into()
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
inferred_params.push(ty.span);
tcx.types.err.into()
} else {
self.ast_ty_to_ty(&ty).into()
}
}
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
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 {
}
},
);
if !inferred_params.is_empty() {
// We always collect the spans for placeholder types when evaluating `fn`s, but we
// only want to emit an error complaining about them if infer types (`_`) are not
// allowed. `allow_ty_infer` gates this behavior.
crate::collect::placeholder_type_error(
tcx,
inferred_params[0],
&[],
inferred_params,
false,
);
}
self.complain_about_missing_type_params(
missing_type_params,

View file

@ -45,4 +45,8 @@ type I = ty!()::AssocTy;
//~^ ERROR missing angle brackets in associated item path
//~| ERROR ambiguous associated type
trait K<A, B> {}
fn foo<X: K<_, _>>(x: X) {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
fn main() {}

View file

@ -122,7 +122,15 @@ error[E0223]: ambiguous associated type
LL | type I = ty!()::AssocTy;
| ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<u8 as Trait>::AssocTy`
error: aborting due to 19 previous errors
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/bad-assoc-ty.rs:49:13
|
LL | fn foo<X: K<_, _>>(x: X) {}
| ^ ^ not allowed in type signatures
| |
| not allowed in type signatures
error: aborting due to 20 previous errors
Some errors have detailed explanations: E0121, E0223.
For more information about an error, try `rustc --explain E0121`.

View file

@ -157,9 +157,12 @@ trait BadTrait<_> {}
//~^ ERROR expected identifier, found reserved identifier `_`
impl BadTrait<_> for BadStruct<_> {}
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
fn impl_trait() -> impl BadTrait<_> {
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
unimplemented!()
}
@ -174,12 +177,14 @@ struct BadStruct2<_, T>(_, T);
type X = Box<_>;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
struct Struct;
trait Trait<T> {}
impl Trait<usize> for Struct {}
type Y = impl Trait<_>;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
//~| ERROR the type placeholder `_` is not allowed within types on item signatures
fn foo() -> Y {
Struct
}

View file

@ -11,25 +11,25 @@ LL | trait BadTrait<_> {}
| ^ expected identifier, found reserved identifier
error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:166:19
--> $DIR/typeck_type_placeholder_item.rs:169:19
|
LL | struct BadStruct1<_, _>(_);
| ^ expected identifier, found reserved identifier
error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:166:22
--> $DIR/typeck_type_placeholder_item.rs:169:22
|
LL | struct BadStruct1<_, _>(_);
| ^ expected identifier, found reserved identifier
error: expected identifier, found reserved identifier `_`
--> $DIR/typeck_type_placeholder_item.rs:171:19
--> $DIR/typeck_type_placeholder_item.rs:174: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:166:22
--> $DIR/typeck_type_placeholder_item.rs:169:22
|
LL | struct BadStruct1<_, _>(_);
| - ^ already used
@ -343,6 +343,18 @@ help: use type parameters instead
LL | struct BadStruct<T>(T);
| ^ ^
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:158:32
|
LL | impl BadTrait<_> for BadStruct<_> {}
| ^ not allowed in type signatures
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:158:15
|
LL | impl BadTrait<_> for BadStruct<_> {}
| ^ not allowed in type signatures
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:158:15
|
@ -357,13 +369,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:161:34
--> $DIR/typeck_type_placeholder_item.rs:163: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:166:25
--> $DIR/typeck_type_placeholder_item.rs:169:25
|
LL | struct BadStruct1<_, _>(_);
| ^ not allowed in type signatures
@ -374,7 +386,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:171:25
--> $DIR/typeck_type_placeholder_item.rs:174:25
|
LL | struct BadStruct2<_, T>(_, T);
| ^ not allowed in type signatures
@ -385,7 +397,13 @@ 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:175:14
--> $DIR/typeck_type_placeholder_item.rs:178:14
|
LL | type X = Box<_>;
| ^ not allowed in type signatures
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:178:14
|
LL | type X = Box<_>;
| ^ not allowed in type signatures
@ -505,7 +523,19 @@ 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:181:21
--> $DIR/typeck_type_placeholder_item.rs:163: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:185:21
|
LL | type Y = impl Trait<_>;
| ^ not allowed in type signatures
error[E0121]: the type placeholder `_` is not allowed within types on item signatures
--> $DIR/typeck_type_placeholder_item.rs:185:21
|
LL | type Y = impl Trait<_>;
| ^ not allowed in type signatures
@ -546,7 +576,7 @@ LL | fn clone(&self) -> _ { FnTest9 }
| not allowed in type signatures
| help: replace with the correct return type: `main::FnTest9`
error: aborting due to 58 previous errors
error: aborting due to 63 previous errors
Some errors have detailed explanations: E0121, E0282, E0403.
For more information about an error, try `rustc --explain E0121`.