diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2020-02-13 13:34:00 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-02-27 15:59:26 -0800 |
| commit | a7b727dab3aff466fc88c3ce0916817dc2d093bc (patch) | |
| tree | 91de209b2c2cb063be7638d5858179e9472444b2 /src | |
| parent | e6c85960d164c5f1e30ae9d18002c3e9d435fc46 (diff) | |
| download | rust-a7b727dab3aff466fc88c3ce0916817dc2d093bc.tar.gz rust-a7b727dab3aff466fc88c3ce0916817dc2d093bc.zip | |
Account for bounds when denying `_` in type parameters
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/did_you_mean/bad-assoc-ty.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/did_you_mean/bad-assoc-ty.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/typeck/typeck_type_placeholder_item.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/typeck/typeck_type_placeholder_item.stderr | 50 |
5 files changed, 78 insertions, 13 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 49f38d86d91..d1a6163df2d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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(<, 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, diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs index fccfb7911ce..00845a17b11 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.rs +++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs @@ -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() {} diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 64e49934d87..6d5f3d9f143 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -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`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 86c7c52b271..8ee46343d2d 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -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 } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 95e8f94c6f3..18317d2b974 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -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 @@ -344,6 +344,18 @@ 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 | LL | impl BadTrait<_> for BadStruct<_> {} @@ -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`. |
