about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-12-24 13:18:09 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-12-29 19:16:15 -0800
commit6c8b2dcb1944a1b693778b7d96a99aaad635bbd8 (patch)
treecf00d7c5924c0d285e6903fc3d3b05d4a29a2274 /src
parent8cb193a5cb694ba62c83fb63a804f22720a118cf (diff)
downloadrust-6c8b2dcb1944a1b693778b7d96a99aaad635bbd8.tar.gz
rust-6c8b2dcb1944a1b693778b7d96a99aaad635bbd8.zip
Account for all item kinds when collecting and gateing `_` in item defs
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/astconv.rs67
-rw-r--r--src/librustc_typeck/collect.rs96
-rw-r--r--src/test/ui/self/self-infer.stderr4
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.rs6
-rw-r--r--src/test/ui/typeck/typeck_type_placeholder_item.stderr176
5 files changed, 199 insertions, 150 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 6a681be6f3e..7ce26696e60 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -7,7 +7,7 @@ use crate::hir::def_id::DefId;
 use crate::hir::print;
 use crate::hir::ptr::P;
 use crate::hir::{self, ExprKind, GenericArg, GenericArgs, HirVec};
-use crate::hir::intravisit::{NestedVisitorMap, Visitor};
+use crate::hir::intravisit::Visitor;
 use crate::lint;
 use crate::middle::lang_items::SizedTraitLangItem;
 use crate::middle::resolve_lifetime as rl;
@@ -16,6 +16,7 @@ use crate::require_c_abi_if_c_variadic;
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use errors::{Applicability, DiagnosticId};
+use crate::collect::PlaceholderHirTyCollector;
 use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc::traits;
 use rustc::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
@@ -2747,12 +2748,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     }
 
     pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
-        match ty.kind {
-            hir::TyKind::Infer if expected_ty.is_some() => {
-                self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
-                expected_ty.unwrap()
-            }
-            _ => self.ast_ty_to_ty(ty),
+        if crate::collect::is_infer_ty(ty) && expected_ty.is_some() {
+            self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
+            expected_ty.unwrap()
+        } else {
+            self.ast_ty_to_ty(ty)
         }
     }
 
@@ -2769,23 +2769,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let tcx = self.tcx();
 
         // We proactively collect all the infered type params to emit a single error per fn def.
-        struct PlaceholderHirTyCollector(Vec<Span>);
-        impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
-            fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
-                NestedVisitorMap::None
-            }
-            fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
-                if let hir::TyKind::Infer = t.kind {
-                    self.0.push(t.span);
-                }
-                hir::intravisit::walk_ty(self, t)
-            }
-        }
         let mut placeholder_types = vec![];
         let mut output_placeholder_types = vec![];
 
         let input_tys = decl.inputs.iter().map(|a| {
-            let mut visitor = PlaceholderHirTyCollector(vec![]);
+            let mut visitor = PlaceholderHirTyCollector::new();
             visitor.visit_ty(&a);
             if visitor.0.is_empty() || self.allow_ty_infer() {
                 self.ty_of_arg(a, None)
@@ -2796,7 +2784,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         });
         let output_ty = match decl.output {
             hir::Return(ref output) => {
-                let mut visitor = PlaceholderHirTyCollector(vec![]);
+                let mut visitor = PlaceholderHirTyCollector::new();
                 visitor.visit_ty(output);
                 let is_infer = if let hir::TyKind::Infer = output.kind {
                     true
@@ -2820,36 +2808,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         placeholder_types.extend(output_placeholder_types);
 
-        if !placeholder_types.is_empty() {
-            let mut sugg = placeholder_types.iter().cloned()
-                .map(|sp| (sp, "T".to_owned()))
-                .collect::<Vec<_>>();
-            if let Some(span) = ident_span {
-                if generic_params.is_empty() {
-                    sugg.push((span.shrink_to_hi(), "<T>".to_string()));
-                } else {
-                    sugg.push((
-                        generic_params.iter().last().unwrap().span.shrink_to_hi(),
-                        ", T".to_string(),
-                    ));
-                }
-            }
-            let mut err = struct_span_err!(
-                tcx.sess,
-                placeholder_types,
-                E0121,
-                "the type placeholder `_` is not allowed within types on item signatures",
-            );
-            if ident_span.is_some() {
-                err.multipart_suggestion(
-                    "use type parameters instead",
-                    sugg,
-                    Applicability::HasPlaceholders,
-                );
-            }
-            err.emit();
-        }
-
+        crate::collect::placeholder_type_error(
+            tcx,
+            ident_span.unwrap_or(DUMMY_SP),
+            generic_params,
+            placeholder_types,
+            ident_span.is_some(),
+        );
 
         // Find any late-bound regions declared in return type that do
         // not appear in the arguments. These are not well-formed.
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 6ab30c4b7e7..440b894fcf7 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -102,10 +102,88 @@ pub struct ItemCtxt<'tcx> {
 
 ///////////////////////////////////////////////////////////////////////////
 
+crate struct PlaceholderHirTyCollector(crate Vec<Span>);
+
+impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
+        NestedVisitorMap::None
+    }
+    fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
+        if let hir::TyKind::Infer = t.kind {
+            self.0.push(t.span);
+        }
+        hir::intravisit::walk_ty(self, t)
+    }
+}
+
+impl PlaceholderHirTyCollector {
+    pub fn new() -> PlaceholderHirTyCollector {
+        PlaceholderHirTyCollector(vec![])
+    }
+}
+
 struct CollectItemTypesVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
+crate fn placeholder_type_error(
+    tcx: TyCtxt<'tcx>,
+    ident_span: Span,
+    generics: &[hir::GenericParam<'_>],
+    placeholder_types: Vec<Span>,
+    suggest: bool,
+) {
+    if !placeholder_types.is_empty() {
+        let mut sugg: Vec<_> = placeholder_types.iter().map(|sp| (*sp, "T".to_string())).collect();
+        if generics.is_empty() {
+            sugg.push((ident_span.shrink_to_hi(), "<T>".to_string()));
+        } else {
+            sugg.push((generics.iter().last().unwrap().span.shrink_to_hi(), ", T".to_string()));
+        }
+        let mut err = struct_span_err!(
+            tcx.sess,
+            placeholder_types.clone(),
+            E0121,
+            "the type placeholder `_` is not allowed within types on item signatures",
+        );
+        for span in &placeholder_types {
+            err.span_label(*span, "not allowed in type signatures");
+        }
+        if suggest {
+            err.multipart_suggestion(
+                "use type parameters instead",
+                sugg,
+                Applicability::HasPlaceholders,
+            );
+        }
+        err.emit();
+    }
+}
+
+fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
+    let (generics, suggest) = match &item.kind {
+        hir::ItemKind::Union(_, generics)
+        | hir::ItemKind::Enum(_, generics)
+        | hir::ItemKind::Struct(_, generics) => (&generics.params[..], true),
+        hir::ItemKind::Static(ty, ..) => {
+            if let hir::TyKind::Infer = ty.kind {
+                return; // We handle it elsewhere to attempt to suggest an appropriate type.
+            } else {
+                (&[][..], false)
+            }
+        }
+        hir::ItemKind::TyAlias(_, generics) => (&generics.params[..], false),
+        // hir::ItemKind::Fn(..) |
+        // hir::ItemKind::Const(..) => {} // We handle these elsewhere to suggest appropriate type.
+        _ => return,
+    };
+
+    let mut visitor = PlaceholderHirTyCollector::new();
+    visitor.visit_item(item);
+
+    placeholder_type_error(tcx, item.ident.span, generics, visitor.0, suggest);
+}
+
 impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
@@ -113,6 +191,7 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         convert_item(self.tcx, item.hir_id);
+        reject_placeholder_type_signatures_in_item(self.tcx, item);
         intravisit::walk_item(self, item);
     }
 
@@ -200,8 +279,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
     }
 
     fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
-        bad_placeholder_type(self.tcx(), span).emit();
-
+        self.tcx().sess.delay_span_bug(span, "bad placeholder type, but no error was emitted");
         self.tcx().types.err
     }
 
@@ -1189,6 +1267,10 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 .and_then(|body_id| {
                     if let hir::TyKind::Infer = ty.kind {
                         Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident))
+                    } else if is_infer_ty(ty) {
+                        // Infering this would cause a cycle error.
+                        tcx.sess.delay_span_bug(ty.span, "`_` placeholder but no error emitted");
+                        Some(tcx.types.err)
                     } else {
                         None
                     }
@@ -1208,6 +1290,10 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
             ImplItemKind::Const(ref ty, body_id) => {
                 if let hir::TyKind::Infer = ty.kind {
                     infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
+                } else if is_infer_ty(ty) {
+                    // Infering this would cause a cycle error.
+                    tcx.sess.delay_span_bug(ty.span, "`_` placeholder but no error emitted");
+                    tcx.types.err
                 } else {
                     icx.to_ty(ty)
                 }
@@ -1233,6 +1319,10 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 ItemKind::Static(ref ty, .., body_id) | ItemKind::Const(ref ty, body_id) => {
                     if let hir::TyKind::Infer = ty.kind {
                         infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
+                    } else if is_infer_ty(ty) {
+                        // Infering this would cause a cycle error.
+                        tcx.sess.delay_span_bug(ty.span, "`_` placeholder but no error emitted");
+                        tcx.types.err
                     } else {
                         icx.to_ty(ty)
                     }
@@ -1703,7 +1793,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
     }
 }
 
-fn is_infer_ty(ty: &hir::Ty<'_>) -> bool {
+crate fn is_infer_ty(ty: &hir::Ty<'_>) -> bool {
     match &ty.kind {
         hir::TyKind::Infer => true,
         hir::TyKind::Slice(ty) | hir::TyKind::Array(ty, _) => is_infer_ty(ty),
diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr
index b064928d8a3..1475b212b56 100644
--- a/src/test/ui/self/self-infer.stderr
+++ b/src/test/ui/self/self-infer.stderr
@@ -2,7 +2,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
   --> $DIR/self-infer.rs:4:16
    |
 LL |     fn f(self: _) {}
-   |                ^
+   |                ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -13,7 +13,7 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
   --> $DIR/self-infer.rs:5:17
    |
 LL |     fn g(self: &_) {}
-   |                 ^
+   |                 ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs
index 03ee61486c6..0ec5d80f241 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item.rs
+++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs
@@ -15,7 +15,6 @@ static TEST4: _ = 145;
 
 static TEST5: (_, _) = (1, 2);
 //~^ 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 test6(_: _) { }
 //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
@@ -48,8 +47,6 @@ struct Test10 {
     a: _,
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
     b: (_, _),
-    //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
-    //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures
 }
 
 pub fn main() {
@@ -67,7 +64,6 @@ pub fn main() {
 
     static FN_TEST5: (_, _) = (1, 2);
     //~^ 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 fn_test6(_: _) { }
     //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
@@ -100,8 +96,6 @@ pub fn main() {
         a: _,
         //~^ ERROR the type placeholder `_` is not allowed within types on item signatures
         b: (_, _),
-        //~^ 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 fn_test11(_: _) -> (_, _) { panic!() }
diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
index 0edfa07a656..dbb014edd42 100644
--- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr
@@ -38,19 +38,15 @@ error[E0121]: the type placeholder `_` is not allowed within types on item signa
   --> $DIR/typeck_type_placeholder_item.rs:16:16
    |
 LL | static TEST5: (_, _) = (1, 2);
-   |                ^ not allowed in type signatures
+   |                ^  ^ not allowed in type signatures
+   |                |
+   |                not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:16:19
-   |
-LL | static TEST5: (_, _) = (1, 2);
-   |                   ^ not allowed in type signatures
-
-error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:20:13
+  --> $DIR/typeck_type_placeholder_item.rs:19:13
    |
 LL | fn test6(_: _) { }
-   |             ^
+   |             ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -58,10 +54,10 @@ LL | fn test6<T>(_: T) { }
    |         ^^^    ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:23:13
+  --> $DIR/typeck_type_placeholder_item.rs:22:13
    |
 LL | fn test7(x: _) { let _x: usize = x; }
-   |             ^
+   |             ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -69,10 +65,10 @@ LL | fn test7<T>(x: T) { let _x: usize = x; }
    |         ^^^    ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:26:22
+  --> $DIR/typeck_type_placeholder_item.rs:25:22
    |
 LL | fn test8(_f: fn() -> _) { }
-   |                      ^
+   |                      ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -80,43 +76,26 @@ LL | fn test8<T>(_f: fn() -> T) { }
    |         ^^^             ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:48:8
+  --> $DIR/typeck_type_placeholder_item.rs:47:8
    |
 LL |     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:50:9
-   |
+LL |
 LL |     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:50:12
+   |         ^  ^ not allowed in type signatures
+   |         |
+   |         not allowed in type signatures
    |
-LL |     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:100:12
-   |
-LL |         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:102:13
+help: use type parameters instead
    |
-LL |         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:102:16
+LL | struct Test10<T> {
+LL |     a: T,
+LL |
+LL |     b: (T, T),
    |
-LL |         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:56:21
+  --> $DIR/typeck_type_placeholder_item.rs:53:21
    |
 LL |     fn fn_test() -> _ { 5 }
    |                     ^
@@ -125,7 +104,7 @@ LL |     fn fn_test() -> _ { 5 }
    |                     help: replace this with the correct return type: `i32`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:59:22
+  --> $DIR/typeck_type_placeholder_item.rs:56:22
    |
 LL |     fn fn_test2() -> (_, _) { (5, 5) }
    |                      ^^^^^^
@@ -134,7 +113,7 @@ LL |     fn fn_test2() -> (_, _) { (5, 5) }
    |                      help: replace this with the correct return type: `(i32, i32)`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:62:22
+  --> $DIR/typeck_type_placeholder_item.rs:59:22
    |
 LL |     static FN_TEST3: _ = "test";
    |                      ^
@@ -143,7 +122,7 @@ LL |     static FN_TEST3: _ = "test";
    |                      help: replace `_` with the correct type: `&'static str`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:65:22
+  --> $DIR/typeck_type_placeholder_item.rs:62:22
    |
 LL |     static FN_TEST4: _ = 145;
    |                      ^
@@ -152,22 +131,18 @@ LL |     static FN_TEST4: _ = 145;
    |                      help: replace `_` with the correct type: `i32`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:68:23
-   |
-LL |     static FN_TEST5: (_, _) = (1, 2);
-   |                       ^ not allowed in type signatures
-
-error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:68:26
+  --> $DIR/typeck_type_placeholder_item.rs:65:23
    |
 LL |     static FN_TEST5: (_, _) = (1, 2);
-   |                          ^ not allowed in type signatures
+   |                       ^  ^ not allowed in type signatures
+   |                       |
+   |                       not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:72:20
+  --> $DIR/typeck_type_placeholder_item.rs:68:20
    |
 LL |     fn fn_test6(_: _) { }
-   |                    ^
+   |                    ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -175,10 +150,10 @@ LL |     fn fn_test6<T>(_: T) { }
    |                ^^^    ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:75:20
+  --> $DIR/typeck_type_placeholder_item.rs:71:20
    |
 LL |     fn fn_test7(x: _) { let _x: usize = x; }
-   |                    ^
+   |                    ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -186,30 +161,49 @@ LL |     fn fn_test7<T>(x: T) { let _x: usize = x; }
    |                ^^^    ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:78:29
+  --> $DIR/typeck_type_placeholder_item.rs:74:29
    |
 LL |     fn fn_test8(_f: fn() -> _) { }
-   |                             ^
+   |                             ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
 LL |     fn fn_test8<T>(_f: fn() -> T) { }
    |                ^^^             ^
 
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures
+  --> $DIR/typeck_type_placeholder_item.rs:96:12
+   |
+LL |         a: _,
+   |            ^ not allowed in type signatures
+LL |
+LL |         b: (_, _),
+   |             ^  ^ not allowed in type signatures
+   |             |
+   |             not allowed in type signatures
+   |
+help: use type parameters instead
+   |
+LL |     struct FnTest10<T> {
+LL |         a: T,
+LL |
+LL |         b: (T, T),
+   |
+
 error[E0282]: type annotations needed
-  --> $DIR/typeck_type_placeholder_item.rs:107:27
+  --> $DIR/typeck_type_placeholder_item.rs:101:27
    |
 LL |     fn fn_test11(_: _) -> (_, _) { panic!() }
    |                           ^^^^^^ cannot infer type
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:107:27
+  --> $DIR/typeck_type_placeholder_item.rs:101:27
    |
 LL |     fn fn_test11(_: _) -> (_, _) { panic!() }
    |                           ^^^^^^ not allowed in type signatures
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:111:29
+  --> $DIR/typeck_type_placeholder_item.rs:105:29
    |
 LL |     fn fn_test12(x: i32) -> (_, _) { (x, x) }
    |                             ^^^^^^
@@ -218,10 +212,12 @@ LL |     fn fn_test12(x: i32) -> (_, _) { (x, x) }
    |                             help: replace this with the correct return type: `(i32, i32)`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:114:21
+  --> $DIR/typeck_type_placeholder_item.rs:108:21
    |
 LL |     fn fn_test13(x: _) -> (i32, _) { (x, x) }
-   |                     ^           ^
+   |                     ^           ^ not allowed in type signatures
+   |                     |
+   |                     not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -229,10 +225,10 @@ LL |     fn fn_test13<T>(x: T) -> (i32, T) { (x, x) }
    |                 ^^^    ^           ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:119:31
+  --> $DIR/typeck_type_placeholder_item.rs:113:31
    |
 LL |     fn method_test1(&self, x: _);
-   |                               ^
+   |                               ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -240,10 +236,12 @@ LL |     fn method_test1<T>(&self, x: T);
    |                    ^^^           ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:121:31
+  --> $DIR/typeck_type_placeholder_item.rs:115:31
    |
 LL |     fn method_test2(&self, x: _) -> _;
-   |                               ^     ^
+   |                               ^     ^ not allowed in type signatures
+   |                               |
+   |                               not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -251,10 +249,10 @@ LL |     fn method_test2<T>(&self, x: T) -> T;
    |                    ^^^           ^     ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:123:31
+  --> $DIR/typeck_type_placeholder_item.rs:117:31
    |
 LL |     fn method_test3(&self) -> _;
-   |                               ^
+   |                               ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -262,10 +260,10 @@ LL |     fn method_test3<T>(&self) -> T;
    |                    ^^^           ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:125:26
+  --> $DIR/typeck_type_placeholder_item.rs:119:26
    |
 LL |     fn assoc_fn_test1(x: _);
-   |                          ^
+   |                          ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -273,10 +271,12 @@ LL |     fn assoc_fn_test1<T>(x: T);
    |                      ^^^    ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:127:26
+  --> $DIR/typeck_type_placeholder_item.rs:121:26
    |
 LL |     fn assoc_fn_test2(x: _) -> _;
-   |                          ^     ^
+   |                          ^     ^ not allowed in type signatures
+   |                          |
+   |                          not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -284,10 +284,10 @@ LL |     fn assoc_fn_test2<T>(x: T) -> T;
    |                      ^^^    ^     ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:129:28
+  --> $DIR/typeck_type_placeholder_item.rs:123:28
    |
 LL |     fn assoc_fn_test3() -> _;
-   |                            ^
+   |                            ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -295,7 +295,7 @@ LL |     fn assoc_fn_test3<T>() -> T;
    |                      ^^^      ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:32:24
+  --> $DIR/typeck_type_placeholder_item.rs:31:24
    |
 LL |     fn test9(&self) -> _ { () }
    |                        ^
@@ -304,10 +304,10 @@ LL |     fn test9(&self) -> _ { () }
    |                        help: replace this with the correct return type: `()`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:35:27
+  --> $DIR/typeck_type_placeholder_item.rs:34:27
    |
 LL |     fn test10(&self, _x : _) { }
-   |                           ^
+   |                           ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -315,7 +315,7 @@ LL |     fn test10<T>(&self, _x : T) { }
    |              ^^^             ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:40:24
+  --> $DIR/typeck_type_placeholder_item.rs:39:24
    |
 LL |     fn clone(&self) -> _ { Test9 }
    |                        ^
@@ -324,10 +324,10 @@ LL |     fn clone(&self) -> _ { Test9 }
    |                        help: replace this with the correct return type: `Test9`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:43:37
+  --> $DIR/typeck_type_placeholder_item.rs:42:37
    |
 LL |     fn clone_from(&mut self, other: _) { *self = Test9; }
-   |                                     ^
+   |                                     ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -335,7 +335,7 @@ LL |     fn clone_from<T>(&mut self, other: T) { *self = Test9; }
    |                  ^^^                   ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:84:31
+  --> $DIR/typeck_type_placeholder_item.rs:80:31
    |
 LL |         fn fn_test9(&self) -> _ { () }
    |                               ^
@@ -344,10 +344,10 @@ LL |         fn fn_test9(&self) -> _ { () }
    |                               help: replace this with the correct return type: `()`
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:87:34
+  --> $DIR/typeck_type_placeholder_item.rs:83:34
    |
 LL |         fn fn_test10(&self, _x : _) { }
-   |                                  ^
+   |                                  ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
@@ -355,7 +355,7 @@ LL |         fn fn_test10<T>(&self, _x : T) { }
    |                     ^^^             ^
 
 error[E0121]: the type placeholder `_` is not allowed within types on item signatures
-  --> $DIR/typeck_type_placeholder_item.rs:92:28
+  --> $DIR/typeck_type_placeholder_item.rs:88:28
    |
 LL |         fn clone(&self) -> _ { FnTest9 }
    |                            ^
@@ -364,17 +364,17 @@ LL |         fn clone(&self) -> _ { FnTest9 }
    |                            help: replace this 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:95:41
+  --> $DIR/typeck_type_placeholder_item.rs:91:41
    |
 LL |         fn clone_from(&mut self, other: _) { *self = FnTest9; }
-   |                                         ^
+   |                                         ^ not allowed in type signatures
    |
 help: use type parameters instead
    |
 LL |         fn clone_from<T>(&mut self, other: T) { *self = FnTest9; }
    |                      ^^^                   ^
 
-error: aborting due to 42 previous errors
+error: aborting due to 36 previous errors
 
 Some errors have detailed explanations: E0121, E0282.
 For more information about an error, try `rustc --explain E0121`.