about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-02-13 13:34:00 -0800
committerEsteban Küber <esteban@kuber.com.ar>2020-02-27 15:59:26 -0800
commita7b727dab3aff466fc88c3ce0916817dc2d093bc (patch)
tree91de209b2c2cb063be7638d5858179e9472444b2 /src
parente6c85960d164c5f1e30ae9d18002c3e9d435fc46 (diff)
downloadrust-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.rs22
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-ty.rs4
-rw-r--r--src/test/ui/did_you_mean/bad-assoc-ty.stderr10
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.rs5
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.stderr50
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(&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,
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`.