]> git.lizzy.rs Git - rust.git/commitdiff
Account for bad placeholder types in where clauses
authorEsteban Küber <esteban@kuber.com.ar>
Mon, 23 Mar 2020 01:50:30 +0000 (18:50 -0700)
committerEsteban Küber <esteban@kuber.com.ar>
Mon, 23 Mar 2020 19:55:46 +0000 (12:55 -0700)
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/collect.rs
src/test/ui/did_you_mean/bad-assoc-ty.rs
src/test/ui/did_you_mean/bad-assoc-ty.stderr
src/test/ui/typeck/typeck_type_placeholder_item.rs
src/test/ui/typeck/typeck_type_placeholder_item.stderr

index 3ee6d5df7356b385887ad9d24bf1fcd9e642bee0..378a68315b2898d1213f63756814d26b3d705119 100644 (file)
@@ -20,7 +20,7 @@
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::Visitor;
+use rustc_hir::intravisit::{walk_generics, Visitor};
 use rustc_hir::print;
 use rustc_hir::{Constness, ExprKind, GenericArg, GenericArgs};
 use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS};
@@ -838,18 +838,6 @@ fn create_substs_for_ast_path<'a>(
                 }
             },
         );
-        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,
@@ -2739,7 +2727,13 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
             }
             hir::TyKind::BareFn(ref bf) => {
                 require_c_abi_if_c_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);
-                tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl, &[], None))
+                tcx.mk_fn_ptr(self.ty_of_fn(
+                    bf.unsafety,
+                    bf.abi,
+                    &bf.decl,
+                    &hir::Generics::empty(),
+                    None,
+                ))
             }
             hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
@@ -2922,7 +2916,7 @@ pub fn ty_of_fn(
         unsafety: hir::Unsafety,
         abi: abi::Abi,
         decl: &hir::FnDecl<'_>,
-        generic_params: &[hir::GenericParam<'_>],
+        generics: &hir::Generics<'_>,
         ident_span: Option<Span>,
     ) -> ty::PolyFnSig<'tcx> {
         debug!("ty_of_fn");
@@ -2934,6 +2928,8 @@ pub fn ty_of_fn(
         for ty in decl.inputs {
             visitor.visit_ty(ty);
         }
+        walk_generics(&mut visitor, generics);
+
         let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
         let output_ty = match decl.output {
             hir::FnRetTy::Return(ref output) => {
@@ -2955,7 +2951,7 @@ pub fn ty_of_fn(
             crate::collect::placeholder_type_error(
                 tcx,
                 ident_span.map(|sp| sp.shrink_to_hi()).unwrap_or(DUMMY_SP),
-                generic_params,
+                &generics.params[..],
                 visitor.0,
                 ident_span.is_some(),
             );
@@ -2981,8 +2977,7 @@ pub fn ty_of_fn(
                 tcx.sess,
                 decl.output.span(),
                 E0581,
-                "return type references {} \
-                                            which is not constrained by the fn input types",
+                "return type references {} which is not constrained by the fn input types",
                 lifetime_name
             );
             if let ty::BrAnon(_) = *br {
@@ -2993,8 +2988,7 @@ pub fn ty_of_fn(
                 // though we can easily give a hint that ought to be
                 // relevant.
                 err.note(
-                    "lifetimes appearing in an associated type \
-                          are not considered constrained",
+                    "lifetimes appearing in an associated type are not considered constrained",
                 );
             }
             err.emit();
index e4bd42f61c32129bd5c385fe5676979f02afbe0f..ce0be5083573cb1fdd37ad117ec577930a7b9484 100644 (file)
@@ -1003,7 +1003,14 @@ fn typeck_tables_of_with_fallback<'tcx>(
         let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
             let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
                 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
-                AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl, &[], None)
+                AstConv::ty_of_fn(
+                    &fcx,
+                    header.unsafety,
+                    header.abi,
+                    decl,
+                    &hir::Generics::empty(),
+                    None,
+                )
             } else {
                 tcx.fn_sig(def_id)
             };
index a79c065307796e9f719fd21a8129fa4917cded4b..2de43a6b1ef15bf4b593cc34680752dd11cd7097 100644 (file)
@@ -1502,7 +1502,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
                     sig.header.unsafety,
                     sig.header.abi,
                     &sig.decl,
-                    &generics.params[..],
+                    &generics,
                     Some(ident.span),
                 ),
             }
@@ -1513,14 +1513,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
             ident,
             generics,
             ..
-        }) => AstConv::ty_of_fn(
-            &icx,
-            header.unsafety,
-            header.abi,
-            decl,
-            &generics.params[..],
-            Some(ident.span),
-        ),
+        }) => {
+            AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl, &generics, Some(ident.span))
+        }
 
         ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(ref fn_decl, _, _), .. }) => {
             let abi = tcx.hir().get_foreign_abi(hir_id);
@@ -2142,7 +2137,14 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     } else {
         hir::Unsafety::Unsafe
     };
-    let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl, &[], None);
+    let fty = AstConv::ty_of_fn(
+        &ItemCtxt::new(tcx, def_id),
+        unsafety,
+        abi,
+        decl,
+        &hir::Generics::empty(),
+        None,
+    );
 
     // Feature gate SIMD types in FFI, since I am not sure that the
     // ABIs are handled at all correctly. -huonw
index 00845a17b116b5cbc56c22f64aea440b4fcf6009..e66b432ede20c5b00399a399f04e104d0313c7ae 100644 (file)
@@ -49,4 +49,36 @@ trait K<A, B> {}
 fn foo<X: K<_, _>>(x: X) {}
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
 
+fn bar<F>(_: F) where F: Fn() -> _ {}
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+
+fn baz<F: Fn() -> _>(_: F) {}
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+
+struct L<F>(F) where F: Fn() -> _;
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+struct M<F> where F: Fn() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    a: F,
+}
+enum N<F> where F: Fn() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+    Foo(F),
+}
+
+union O<F> where F: Fn() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+//~| ERROR unions with non-`Copy` fields are unstable
+    foo: F,
+}
+
+trait P<F> where F: Fn() -> _ {
+//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+}
+
+trait Q {
+    fn foo<F>(_: F) where F: Fn() -> _ {}
+    //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
+}
+
 fn main() {}
index 6d5f3d9f14348de332a9f645758ec6d214d097bb..875c02bae4ae01ac71a859ce5644b9a71bb35349 100644 (file)
@@ -57,6 +57,19 @@ LL | type J = ty!(u8);
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error[E0658]: unions with non-`Copy` fields are unstable
+  --> $DIR/bad-assoc-ty.rs:69:1
+   |
+LL | / union O<F> where F: Fn() -> _ {
+LL | |
+LL | |
+LL | |     foo: F,
+LL | | }
+   | |_^
+   |
+   = note: see issue #55149 <https://github.com/rust-lang/rust/issues/55149> for more information
+   = help: add `#![feature(untagged_unions)]` to the crate attributes to enable
+
 error[E0223]: ambiguous associated type
   --> $DIR/bad-assoc-ty.rs:1:10
    |
@@ -129,8 +142,101 @@ LL | fn foo<X: K<_, _>>(x: X) {}
    |             ^  ^ not allowed in type signatures
    |             |
    |             not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | fn foo<X, T: K<T, T>>(x: X) {}
+   |         ^^^    ^  ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:52:34
+   |
+LL | fn bar<F>(_: F) where F: Fn() -> _ {}
+   |                                  ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | fn bar<F, T>(_: F) where F: Fn() -> T {}
+   |         ^^^                         ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:55:19
+   |
+LL | fn baz<F: Fn() -> _>(_: F) {}
+   |                   ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | fn baz<F, T: Fn() -> T>(_: F) {}
+   |         ^^^          ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:58:33
+   |
+LL | struct L<F>(F) where F: Fn() -> _;
+   |                                 ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | struct L<F, T>(F) where F: Fn() -> T;
+   |           ^^^                      ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:60:30
+   |
+LL | struct M<F> where F: Fn() -> _ {
+   |                              ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | struct M<F, T> where F: Fn() -> T {
+   |           ^^^                   ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:64:28
+   |
+LL | enum N<F> where F: Fn() -> _ {
+   |                            ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | enum N<F, T> where F: Fn() -> T {
+   |         ^^^                   ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:69:29
+   |
+LL | union O<F> where F: Fn() -> _ {
+   |                             ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | union O<F, T> where F: Fn() -> T {
+   |          ^^^                   ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:75:29
+   |
+LL | trait P<F> where F: Fn() -> _ {
+   |                             ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL | trait P<F, T> where F: Fn() -> T {
+   |          ^^^                   ^
+
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/bad-assoc-ty.rs:80:38
+   |
+LL |     fn foo<F>(_: F) where F: Fn() -> _ {}
+   |                                      ^ not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     fn foo<F, T>(_: F) where F: Fn() -> T {}
+   |             ^^^                         ^
 
-error: aborting due to 20 previous errors
+error: aborting due to 29 previous errors
 
-Some errors have detailed explanations: E0121, E0223.
+Some errors have detailed explanations: E0121, E0223, E0658.
 For more information about an error, try `rustc --explain E0121`.
index 6cd2b8c75b639eb71aef482a524c168d70e1df6a..5444fc62d82118c5779d4abd37ff70562663773e 100644 (file)
@@ -158,12 +158,9 @@ 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!()
 }
 
@@ -178,14 +175,12 @@ fn impl_trait() -> impl BadTrait<_> {
 
 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
 }
index dc86ab30dfe415a3a067627339659ae25c0a8a8f..955765e1175cef3210d892720fec89567ea6389c 100644 (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:170:19
+  --> $DIR/typeck_type_placeholder_item.rs:167:19
    |
 LL | struct BadStruct1<_, _>(_);
    |                   ^ expected identifier, found reserved identifier
 
 error: expected identifier, found reserved identifier `_`
-  --> $DIR/typeck_type_placeholder_item.rs:170:22
+  --> $DIR/typeck_type_placeholder_item.rs:167:22
    |
 LL | struct BadStruct1<_, _>(_);
    |                      ^ expected identifier, found reserved identifier
 
 error: expected identifier, found reserved identifier `_`
-  --> $DIR/typeck_type_placeholder_item.rs:175:19
+  --> $DIR/typeck_type_placeholder_item.rs:172:19
    |
 LL | struct BadStruct2<_, T>(_, T);
    |                   ^ expected identifier, found reserved identifier
 
 error: associated constant in `impl` without body
-  --> $DIR/typeck_type_placeholder_item.rs:208:5
+  --> $DIR/typeck_type_placeholder_item.rs:203:5
    |
 LL |     const C: _;
    |     ^^^^^^^^^^-
@@ -37,7 +37,7 @@ LL |     const C: _;
    |               help: provide a definition for the constant: `= <expr>;`
 
 error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters
-  --> $DIR/typeck_type_placeholder_item.rs:170:22
+  --> $DIR/typeck_type_placeholder_item.rs:167:22
    |
 LL | struct BadStruct1<_, _>(_);
    |                   -  ^ already used
@@ -351,18 +351,6 @@ 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:159: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:159: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:159:15
    |
@@ -377,13 +365,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:164:34
+  --> $DIR/typeck_type_placeholder_item.rs:162: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:170:25
+  --> $DIR/typeck_type_placeholder_item.rs:167:25
    |
 LL | struct BadStruct1<_, _>(_);
    |                         ^ not allowed in type signatures
@@ -394,7 +382,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:175:25
+  --> $DIR/typeck_type_placeholder_item.rs:172:25
    |
 LL | struct BadStruct2<_, T>(_, T);
    |                         ^ not allowed in type signatures
@@ -405,13 +393,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:179: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:179:14
+  --> $DIR/typeck_type_placeholder_item.rs:176:14
    |
 LL | type X = Box<_>;
    |              ^ not allowed in type signatures
@@ -531,37 +513,25 @@ 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:164: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:186: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:186:21
+  --> $DIR/typeck_type_placeholder_item.rs:182: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:195:14
+  --> $DIR/typeck_type_placeholder_item.rs:190:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:197:14
+  --> $DIR/typeck_type_placeholder_item.rs:192:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:199:14
+  --> $DIR/typeck_type_placeholder_item.rs:194:14
    |
 LL |     const D: _ = 42;
    |              ^
@@ -606,25 +576,25 @@ LL |         fn clone(&self) -> _ { FnTest9 }
    |                            help: replace with the correct return type: `main::FnTest9`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:204:14
+  --> $DIR/typeck_type_placeholder_item.rs:199:14
    |
 LL |     type A = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:206:14
+  --> $DIR/typeck_type_placeholder_item.rs:201:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:208:14
+  --> $DIR/typeck_type_placeholder_item.rs:203:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:211:14
+  --> $DIR/typeck_type_placeholder_item.rs:206:14
    |
 LL |     const D: _ = 42;
    |              ^
@@ -632,7 +602,7 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace `_` with the correct type: `i32`
 
-error: aborting due to 71 previous errors
+error: aborting due to 66 previous errors
 
 Some errors have detailed explanations: E0121, E0282, E0403.
 For more information about an error, try `rustc --explain E0121`.