diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f3ac159a3aa..6a681be6f3e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -7,6 +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::lint; use crate::middle::lang_items::SizedTraitLangItem; use crate::middle::resolve_lifetime as rl; @@ -66,6 +67,8 @@ pub trait AstConv<'tcx> { /// Returns the type to use when a type is omitted. fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>; + fn allow_ty_infer(&self) -> bool; + /// Returns the const to use when a const is omitted. fn ct_infer( &self, @@ -2593,7 +2596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } 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)) + tcx.mk_fn_ptr(self.ty_of_fn(bf.unsafety, bf.abi, &bf.decl, &[], None)) } hir::TyKind::TraitObject(ref bounds, ref lifetime) => { self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime) @@ -2758,14 +2761,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { unsafety: hir::Unsafety, abi: abi::Abi, decl: &hir::FnDecl<'_>, + generic_params: &[hir::GenericParam<'_>], + ident_span: Option, ) -> ty::PolyFnSig<'tcx> { debug!("ty_of_fn"); let tcx = self.tcx(); - let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None)); + // We proactively collect all the infered type params to emit a single error per fn def. + struct PlaceholderHirTyCollector(Vec); + 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![]); + visitor.visit_ty(&a); + if visitor.0.is_empty() || self.allow_ty_infer() { + self.ty_of_arg(a, None) + } else { + placeholder_types.extend(visitor.0); + tcx.types.err + } + }); let output_ty = match decl.output { - hir::Return(ref output) => self.ast_ty_to_ty(output), + hir::Return(ref output) => { + let mut visitor = PlaceholderHirTyCollector(vec![]); + visitor.visit_ty(output); + let is_infer = if let hir::TyKind::Infer = output.kind { + true + } else { + false + }; + if (is_infer || !visitor.0.is_empty()) && !self.allow_ty_infer() { + output_placeholder_types.extend(visitor.0); + tcx.types.err + } else { + self.ast_ty_to_ty(output) + } + } hir::DefaultReturn(..) => tcx.mk_unit(), }; @@ -2774,6 +2818,39 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let bare_fn_ty = ty::Binder::bind(tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi)); + 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::>(); + if let Some(span) = ident_span { + if generic_params.is_empty() { + sugg.push((span.shrink_to_hi(), "".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(); + } + + // 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/check/mod.rs b/src/librustc_typeck/check/mod.rs index c6c3ada49e3..d9beb8ee3bd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -963,7 +963,7 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { 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) + AstConv::ty_of_fn(&fcx, header.unsafety, header.abi, decl, &[], None) } else { tcx.fn_sig(def_id) }; @@ -1069,6 +1069,7 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> { let ty = fcx.normalize_ty(span, ty); fcx.require_type_is_sized(ty, span, code); } + fcx.select_all_obligations_or_error(); if fn_decl.is_some() { @@ -2563,6 +2564,10 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { Some(self.next_region_var(v)) } + fn allow_ty_infer(&self) -> bool { + true + } + fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { if let Some(param) = param { if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9604a9ade92..6ab30c4b7e7 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -195,6 +195,10 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { None } + fn allow_ty_infer(&self) -> bool { + false + } + fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { bad_placeholder_type(self.tcx(), span).emit(); @@ -1699,9 +1703,26 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } +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), + hir::TyKind::Tup(tys) + if !tys.is_empty() + && tys.iter().all(|ty| match ty.kind { + hir::TyKind::Infer => true, + _ => false, + }) => + { + true + } + _ => false, + } +} + pub fn get_infer_ret_ty(output: &'hir hir::FunctionRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> { if let hir::FunctionRetTy::Return(ref ty) = output { - if let hir::TyKind::Infer = ty.kind { + if is_infer_ty(ty) { return Some(&**ty); } } @@ -1719,10 +1740,12 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { match tcx.hir().get(hir_id) { TraitItem(hir::TraitItem { kind: TraitItemKind::Method(sig, TraitMethod::Provided(_)), + ident, + generics, .. }) - | ImplItem(hir::ImplItem { kind: ImplItemKind::Method(sig, _), .. }) - | Item(hir::Item { kind: ItemKind::Fn(sig, _, _), .. }) => { + | ImplItem(hir::ImplItem { kind: ImplItemKind::Method(sig, _), ident, generics, .. }) + | Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), ident, .. }) => { match get_infer_ret_ty(&sig.decl.output) { Some(ty) => { let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id]; @@ -1731,7 +1754,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { if ret_ty != tcx.types.err { diag.span_suggestion( ty.span, - "replace `_` with the correct return type", + "replace this with the correct return type", ret_ty.to_string(), Applicability::MaybeIncorrect, ); @@ -1739,14 +1762,30 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { diag.emit(); ty::Binder::bind(fn_sig) } - None => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl), + None => AstConv::ty_of_fn( + &icx, + sig.header.unsafety, + sig.header.abi, + &sig.decl, + &generics.params[..], + Some(ident.span), + ), } } TraitItem(hir::TraitItem { kind: TraitItemKind::Method(FnSig { header, decl }, _), + ident, + generics, .. - }) => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl), + }) => AstConv::ty_of_fn( + &icx, + header.unsafety, + header.abi, + decl, + &generics.params[..], + Some(ident.span), + ), ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(ref fn_decl, _, _), .. }) => { let abi = tcx.hir().get_foreign_abi(hir_id); @@ -2351,7 +2390,7 @@ 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); + let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl, &[], None); // Feature gate SIMD types in FFI, since I am not sure that the // ABIs are handled at all correctly. -huonw diff --git a/src/test/ui/error-codes/E0121.stderr b/src/test/ui/error-codes/E0121.stderr index beb8941320b..5da9a4c080f 100644 --- a/src/test/ui/error-codes/E0121.stderr +++ b/src/test/ui/error-codes/E0121.stderr @@ -5,7 +5,7 @@ LL | fn foo() -> _ { 5 } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `i32` + | help: replace this with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/E0121.rs:3:13 diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr index f91cfe5eb62..b064928d8a3 100644 --- a/src/test/ui/self/self-infer.stderr +++ b/src/test/ui/self/self-infer.stderr @@ -2,13 +2,23 @@ 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 + | +LL | fn f(self: T) {} + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/self-infer.rs:5:17 | LL | fn g(self: &_) {} - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn g(self: &T) {} + | ^^^ ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 46a5b8580dc..03ee61486c6 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -6,7 +6,6 @@ fn test() -> _ { 5 } fn test2() -> (_, _) { (5, 5) } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures -//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures static TEST3: _ = "test"; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures @@ -59,7 +58,6 @@ pub fn main() { fn fn_test2() -> (_, _) { (5, 5) } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures - //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures static FN_TEST3: _ = "test"; //~^ ERROR the type placeholder `_` is not allowed within types on item signatures @@ -106,4 +104,28 @@ pub fn main() { //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures } + fn fn_test11(_: _) -> (_, _) { panic!() } + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~| ERROR type annotations needed + + fn fn_test12(x: i32) -> (_, _) { (x, x) } + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + + fn fn_test13(x: _) -> (i32, _) { (x, x) } + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures } + +trait T { + fn method_test1(&self, x: _); + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn method_test2(&self, x: _) -> _; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn method_test3(&self) -> _; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn assoc_fn_test1(x: _); + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn assoc_fn_test2(x: _) -> _; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn assoc_fn_test3() -> _; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures +} \ No newline at end of file diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 2b4d9966c3d..0edfa07a656 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -5,22 +5,19 @@ LL | fn test() -> _ { 5 } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `i32` + | 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:7:16 + --> $DIR/typeck_type_placeholder_item.rs:7:15 | LL | fn test2() -> (_, _) { (5, 5) } - | ^ not allowed in type signatures + | ^^^^^^ + | | + | not allowed in type signatures + | 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:7:19 - | -LL | fn test2() -> (_, _) { (5, 5) } - | ^ not allowed in type signatures - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:11:15 + --> $DIR/typeck_type_placeholder_item.rs:10:15 | LL | static TEST3: _ = "test"; | ^ @@ -29,7 +26,7 @@ LL | static 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:14:15 + --> $DIR/typeck_type_placeholder_item.rs:13:15 | LL | static TEST4: _ = 145; | ^ @@ -38,94 +35,106 @@ LL | static 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:17:16 + --> $DIR/typeck_type_placeholder_item.rs:16:16 | 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:17:19 + --> $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:21:13 + --> $DIR/typeck_type_placeholder_item.rs:20:13 | LL | fn test6(_: _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn test6(_: T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:24:13 + --> $DIR/typeck_type_placeholder_item.rs:23:13 | LL | fn test7(x: _) { let _x: usize = x; } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn test7(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:27:22 + --> $DIR/typeck_type_placeholder_item.rs:26:22 | LL | fn test8(_f: fn() -> _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn test8(_f: fn() -> T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:49:8 + --> $DIR/typeck_type_placeholder_item.rs:48: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:51:9 + --> $DIR/typeck_type_placeholder_item.rs:50:9 | 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:51:12 + --> $DIR/typeck_type_placeholder_item.rs:50:12 | 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:12 + --> $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:104:13 + --> $DIR/typeck_type_placeholder_item.rs:102:13 | 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:104:16 + --> $DIR/typeck_type_placeholder_item.rs:102:16 | 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:57:21 + --> $DIR/typeck_type_placeholder_item.rs:56:21 | LL | fn fn_test() -> _ { 5 } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `i32` + | 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:60:23 + --> $DIR/typeck_type_placeholder_item.rs:59:22 | LL | fn fn_test2() -> (_, _) { (5, 5) } - | ^ not allowed in type signatures + | ^^^^^^ + | | + | not allowed in type signatures + | 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:60:26 - | -LL | fn fn_test2() -> (_, _) { (5, 5) } - | ^ not allowed in type signatures - -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:64:22 + --> $DIR/typeck_type_placeholder_item.rs:62:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -134,7 +143,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:67:22 + --> $DIR/typeck_type_placeholder_item.rs:65:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -143,95 +152,229 @@ 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:70:23 + --> $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:70:26 + --> $DIR/typeck_type_placeholder_item.rs:68:26 | 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:74:20 + --> $DIR/typeck_type_placeholder_item.rs:72:20 | LL | fn fn_test6(_: _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn fn_test6(_: T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:77:20 + --> $DIR/typeck_type_placeholder_item.rs:75:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn fn_test7(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:80:29 + --> $DIR/typeck_type_placeholder_item.rs:78:29 | LL | fn fn_test8(_f: fn() -> _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn fn_test8(_f: fn() -> T) { } + | ^^^ ^ + +error[E0282]: type annotations needed + --> $DIR/typeck_type_placeholder_item.rs:107: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:33:24 + --> $DIR/typeck_type_placeholder_item.rs:107: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 + | +LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } + | ^^^^^^ + | | + | not allowed in type signatures + | 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 + | +LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } + | ^ ^ + | +help: use type parameters instead + | +LL | fn fn_test13(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 + | +LL | fn method_test1(&self, x: _); + | ^ + | +help: use type parameters instead + | +LL | fn method_test1(&self, x: T); + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:121:31 + | +LL | fn method_test2(&self, x: _) -> _; + | ^ ^ + | +help: use type parameters instead + | +LL | fn method_test2(&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 + | +LL | fn method_test3(&self) -> _; + | ^ + | +help: use type parameters instead + | +LL | fn method_test3(&self) -> T; + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:125:26 + | +LL | fn assoc_fn_test1(x: _); + | ^ + | +help: use type parameters instead + | +LL | fn assoc_fn_test1(x: T); + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:127:26 + | +LL | fn assoc_fn_test2(x: _) -> _; + | ^ ^ + | +help: use type parameters instead + | +LL | fn assoc_fn_test2(x: T) -> T; + | ^^^ ^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:129:28 + | +LL | fn assoc_fn_test3() -> _; + | ^ + | +help: use type parameters instead + | +LL | fn assoc_fn_test3() -> T; + | ^^^ ^ + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:32:24 | LL | fn test9(&self) -> _ { () } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `()` + | 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:36:27 + --> $DIR/typeck_type_placeholder_item.rs:35:27 | LL | fn test10(&self, _x : _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn test10(&self, _x : T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:41:24 + --> $DIR/typeck_type_placeholder_item.rs:40:24 | LL | fn clone(&self) -> _ { Test9 } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `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:44:37 + --> $DIR/typeck_type_placeholder_item.rs:43:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn clone_from(&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:86:31 + --> $DIR/typeck_type_placeholder_item.rs:84:31 | LL | fn fn_test9(&self) -> _ { () } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `()` + | 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:89:34 + --> $DIR/typeck_type_placeholder_item.rs:87:34 | LL | fn fn_test10(&self, _x : _) { } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn fn_test10(&self, _x : T) { } + | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:94:28 + --> $DIR/typeck_type_placeholder_item.rs:92:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `main::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:97:41 + --> $DIR/typeck_type_placeholder_item.rs:95:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } - | ^ not allowed in type signatures + | ^ + | +help: use type parameters instead + | +LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } + | ^^^ ^ -error: aborting due to 34 previous errors +error: aborting due to 42 previous errors -For more information about this error, try `rustc --explain E0121`. +Some errors have detailed explanations: E0121, E0282. +For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr index c5b9566290c..ab002381b1f 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -5,7 +5,7 @@ LL | fn test1() -> _ { Some(42) } | ^ | | | not allowed in type signatures - | help: replace `_` with the correct return type: `std::option::Option` + | help: replace this with the correct return type: `std::option::Option` error[E0121]: the type placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:7:14