From 555fb3ac858bd4480cae33b3d313c8f802cd9c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 1 Sep 2016 10:13:47 -0700 Subject: [PATCH 1/2] Detect missing `;` on methods with return type `()` On a given file `foo.rs`: ```rust fn foo() { return 1; } fn main() { 3 } ``` Provide the following output: ```bash error[E0308]: mismatched types --> foo.rs:2:12 | 1 | fn foo() { | ^ possibly return type `{integer}` missing in this fn? 2 | return 1; | ^ expected (), found integral variable | = note: expected type `()` = note: found type `{integer}` error[E0308]: mismatched types --> foo.rs:6:5 | 6 | 3 | ^ | | | possibly `;` missing here? | expected (), found integral variable | = note: expected type `()` = note: found type `{integer}` error: aborting due to 2 previous errors ``` --- src/librustc_typeck/check/demand.rs | 48 +++++++++++++++++-- .../block-must-not-have-result-do.rs | 10 +++- .../block-must-not-have-result-res.rs | 10 +++- .../block-must-not-have-result-while.rs | 13 +++-- .../compile-fail/expected-return-on-unit.rs | 19 ++++++++ src/test/compile-fail/issue-13624.rs | 20 ++++---- src/test/compile-fail/issue-19109.rs | 13 +++-- src/test/compile-fail/issue-20862.rs | 13 ++++- src/test/compile-fail/issue-22645.rs | 9 ++++ src/test/compile-fail/issue-3563.rs | 7 +++ src/test/compile-fail/issue-5500.rs | 10 ++-- .../specialization-default-projection.rs | 16 ++++++- .../compile-fail/token-error-correct-3.rs | 13 +++-- .../compile-fail/unexpected-return-on-unit.rs | 24 ++++++++++ 14 files changed, 193 insertions(+), 32 deletions(-) create mode 100644 src/test/compile-fail/expected-return-on-unit.rs create mode 100644 src/test/compile-fail/unexpected-return-on-unit.rs diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index ef1c08bdab549..1ae18b01b7dc6 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -10,9 +10,11 @@ use check::FnCtxt; -use rustc::ty::Ty; -use rustc::infer::{InferOk}; +use hir::map::Node; +use rustc::infer::{InferOk, TypeTrace}; use rustc::traits::ObligationCause; +use rustc::ty::Ty; +use rustc::ty::error::TypeError; use syntax_pos::Span; use rustc::hir; @@ -57,7 +59,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Err(e) = self.try_coerce(expr, checked_ty, expected) { let cause = self.misc(expr.span); let expr_ty = self.resolve_type_vars_with_obligations(checked_ty); - self.report_mismatched_types(&cause, expected, expr_ty, e); + let trace = TypeTrace::types(&cause, true, expected, expr_ty); + let mut diag = self.report_and_explain_type_error(trace, &e); + + if let Node::NodeBlock(block) = self.tcx.map + .get(self.tcx.map.get_parent_node(expr.id)) + { + if let TypeError::Sorts(ref values) = e { + if values.expected.is_nil() { + // An implicit return to a method with return type `()` + diag.span_label(expr.span, + &"possibly missing `;` here?"); + // Get the current node's method definition + if let Node::NodeExpr(item) = self.tcx.map + .get(self.tcx.map.get_parent_node(block.id)) + { + // The fn has a default return type of () + if let Node::NodeItem(&hir::Item { + name, + node: hir::ItemFn(ref decl, ..), + .. + }) = self.tcx.map.get(self.tcx.map.get_parent_node(item.id)) { + // `main` *must* have return type () + if name.as_str() != "main" { + decl.clone().and_then(|decl| { + if let hir::FnDecl { + output: hir::FunctionRetTy::DefaultReturn(span), + .. + } = decl { + diag.span_label(span, + &format!("possibly return type `{}` \ + missing in this fn?", + values.found)); + } + }); + } + } + } + } + } + }; + diag.emit(); } } } diff --git a/src/test/compile-fail/block-must-not-have-result-do.rs b/src/test/compile-fail/block-must-not-have-result-do.rs index 2a6c71dbe3923..a7499cd526fe1 100644 --- a/src/test/compile-fail/block-must-not-have-result-do.rs +++ b/src/test/compile-fail/block-must-not-have-result-do.rs @@ -10,6 +10,14 @@ fn main() { loop { - true //~ ERROR mismatched types + true + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found bool + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `bool` + //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/block-must-not-have-result-res.rs b/src/test/compile-fail/block-must-not-have-result-res.rs index 8728685fc8b02..e1aa9d249265e 100644 --- a/src/test/compile-fail/block-must-not-have-result-res.rs +++ b/src/test/compile-fail/block-must-not-have-result-res.rs @@ -12,7 +12,15 @@ struct r; impl Drop for r { fn drop(&mut self) { - true //~ ERROR mismatched types + true + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found bool + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `bool` + //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/block-must-not-have-result-while.rs b/src/test/compile-fail/block-must-not-have-result-while.rs index a0fb470e1e4d0..1e970074ca375 100644 --- a/src/test/compile-fail/block-must-not-have-result-while.rs +++ b/src/test/compile-fail/block-must-not-have-result-while.rs @@ -10,9 +10,14 @@ fn main() { while true { - true //~ ERROR mismatched types - //~| expected type `()` - //~| found type `bool` - //~| expected (), found bool + true + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found bool + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `bool` + //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/expected-return-on-unit.rs b/src/test/compile-fail/expected-return-on-unit.rs new file mode 100644 index 0000000000000..742a8b48491a9 --- /dev/null +++ b/src/test/compile-fail/expected-return-on-unit.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we do some basic error correcton in the tokeniser (and don't spew +// too many bogus errors). + +fn main() { + return 1; + //~^ mismatched types + //~| expected type `()` + //~| found type `{integer}` +} diff --git a/src/test/compile-fail/issue-13624.rs b/src/test/compile-fail/issue-13624.rs index e4ed87c3cb0cd..328aa0690efaa 100644 --- a/src/test/compile-fail/issue-13624.rs +++ b/src/test/compile-fail/issue-13624.rs @@ -15,10 +15,14 @@ mod a { pub fn get_enum_struct_variant() -> () { Enum::EnumStructVariant { x: 1, y: 2, z: 3 } - //~^ ERROR mismatched types - //~| expected type `()` - //~| found type `a::Enum` - //~| expected (), found enum `a::Enum` + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found enum `a::Enum` + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `a::Enum` + //~| NOTE: found type `a::Enum` } } @@ -30,10 +34,10 @@ mod b { let enum_struct_variant = ::a::get_enum_struct_variant(); match enum_struct_variant { a::Enum::EnumStructVariant { x, y, z } => { - //~^ ERROR mismatched types - //~| expected type `()` - //~| found type `a::Enum` - //~| expected (), found enum `a::Enum` + //~^ ERROR: mismatched types + //~| NOTE: expected (), found enum `a::Enum` + //~| NOTE: expected type `()` + //~| NOTE: found type `a::Enum` } } } diff --git a/src/test/compile-fail/issue-19109.rs b/src/test/compile-fail/issue-19109.rs index 580684e2e140b..c74e44a9871d9 100644 --- a/src/test/compile-fail/issue-19109.rs +++ b/src/test/compile-fail/issue-19109.rs @@ -11,11 +11,16 @@ trait Trait { } fn function(t: &mut Trait) { + //~^ NOTE: possibly return type `*mut Trait` missing in this fn? t as *mut Trait - //~^ ERROR: mismatched types - //~| NOTE: expected type `()` - //~| NOTE: found type `*mut Trait` - //~| NOTE: expected (), found *-ptr + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found *-ptr + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `*mut Trait` + //~| NOTE: found type `*mut Trait` } fn main() { } diff --git a/src/test/compile-fail/issue-20862.rs b/src/test/compile-fail/issue-20862.rs index 9df6358399869..1a1409d4b742d 100644 --- a/src/test/compile-fail/issue-20862.rs +++ b/src/test/compile-fail/issue-20862.rs @@ -9,11 +9,20 @@ // except according to those terms. fn foo(x: i32) { + //~^ NOTE: possibly return type |y| x + y -//~^ ERROR: mismatched types + //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found closure + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type + //~| NOTE: found type } + fn main() { let x = foo(5)(2); -//~^ ERROR: expected function, found `()` + //~^ ERROR: expected function, found `()` } diff --git a/src/test/compile-fail/issue-22645.rs b/src/test/compile-fail/issue-22645.rs index 81f66e3e2cfee..4fa60bc762458 100644 --- a/src/test/compile-fail/issue-22645.rs +++ b/src/test/compile-fail/issue-22645.rs @@ -24,4 +24,13 @@ fn main() { let b = Bob + 3.5; b + 3 //~ ERROR E0277 //~^ ERROR: mismatched types + //~| ERROR: mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type + //~| NOTE: found type + //~| NOTE: the trait `Scalar` is not implemented for `{integer}` + //~| NOTE: required because of the requirements on the impl of `std::ops::Add<{integer}>` } diff --git a/src/test/compile-fail/issue-3563.rs b/src/test/compile-fail/issue-3563.rs index 7928c04b9df87..a4873005b0414 100644 --- a/src/test/compile-fail/issue-3563.rs +++ b/src/test/compile-fail/issue-3563.rs @@ -13,6 +13,13 @@ trait A { || self.b() //~^ ERROR no method named `b` found for type `&Self` in the current scope //~| ERROR mismatched types + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found closure + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type + //~| NOTE: found type } } fn main() {} diff --git a/src/test/compile-fail/issue-5500.rs b/src/test/compile-fail/issue-5500.rs index 1cbb7588e17df..998e53d07292a 100644 --- a/src/test/compile-fail/issue-5500.rs +++ b/src/test/compile-fail/issue-5500.rs @@ -11,7 +11,11 @@ fn main() { &panic!() //~^ ERROR mismatched types - //~| expected type `()` - //~| found type `&_` - //~| expected (), found reference + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found reference + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `&_` + //~| NOTE: found type `&_` } diff --git a/src/test/compile-fail/specialization/specialization-default-projection.rs b/src/test/compile-fail/specialization/specialization-default-projection.rs index 96cbd7a485251..aa0a24bbcd321 100644 --- a/src/test/compile-fail/specialization/specialization-default-projection.rs +++ b/src/test/compile-fail/specialization/specialization-default-projection.rs @@ -28,14 +28,26 @@ fn generic() -> ::Assoc { // `T` could be some downstream crate type that specializes (or, // for that matter, `u8`). - () //~ ERROR mismatched types + () + //~^ ERROR mismatched types + //~| NOTE: expected associated type, found () + //~| NOTE: expected type `::Assoc` + //~| NOTE: found type `()` } fn monomorphic() -> () { // Even though we know that `()` is not specialized in a // downstream crate, typeck refuses to project here. - generic::<()>() //~ ERROR mismatched types + generic::<()>() + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found associated type + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type + //~| NOTE: found type } fn main() { diff --git a/src/test/compile-fail/token-error-correct-3.rs b/src/test/compile-fail/token-error-correct-3.rs index 5f21bf18d7b1b..c07ffb7cedc68 100644 --- a/src/test/compile-fail/token-error-correct-3.rs +++ b/src/test/compile-fail/token-error-correct-3.rs @@ -22,10 +22,15 @@ pub mod raw { //~| NOTE unresolved name callback(path.as_ref(); //~ NOTE: unclosed delimiter //~^ ERROR: expected one of - fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types - //~^ expected (), found enum `std::result::Result` - //~| expected type `()` - //~| found type `std::result::Result` + fs::create_dir_all(path.as_ref()).map(|()| true) + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found enum `std::result::Result` + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `std::result::Result` + //~| NOTE: found type `std::result::Result` } else { //~ ERROR: incorrect close delimiter: `}` //~^ ERROR: expected one of Ok(false); diff --git a/src/test/compile-fail/unexpected-return-on-unit.rs b/src/test/compile-fail/unexpected-return-on-unit.rs new file mode 100644 index 0000000000000..506efdea38fe5 --- /dev/null +++ b/src/test/compile-fail/unexpected-return-on-unit.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that we do some basic error correcton in the tokeniser (and don't spew +// too many bogus errors). + +fn main() { + 1 + //~^ ERROR mismatched types + //~| ERROR mismatched types + //~| NOTE: possibly missing `;` here? + //~| NOTE: expected (), found integral variable + //~| NOTE: expected type `()` + //~| NOTE: expected type `()` + //~| NOTE: found type `{integer}` + //~| NOTE: found type `{integer}` +} From a45366c7061925107734530033de38383ad586a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 22 Nov 2016 19:12:56 -0800 Subject: [PATCH 2/2] Move check to `FnCtxt::check_block_with_expected` --- src/librustc_typeck/check/demand.rs | 57 +++++------------- src/librustc_typeck/check/mod.rs | 58 +++++++++++++++++-- .../block-must-not-have-result-do.rs | 5 +- .../block-must-not-have-result-res.rs | 5 +- .../block-must-not-have-result-while.rs | 5 +- .../consider-removing-last-semi.rs | 16 +++-- src/test/compile-fail/issue-11714.rs | 8 ++- src/test/compile-fail/issue-13428.rs | 16 +++-- src/test/compile-fail/issue-13624.rs | 5 +- src/test/compile-fail/issue-19109.rs | 15 ++--- src/test/compile-fail/issue-20862.rs | 17 +++--- src/test/compile-fail/issue-22645.rs | 15 ++--- src/test/compile-fail/issue-3563.rs | 13 ++--- src/test/compile-fail/issue-5500.rs | 10 +--- src/test/compile-fail/issue-6458-4.rs | 8 ++- .../liveness-return-last-stmt-semi.rs | 30 ++++++++-- .../specialization-default-projection.rs | 5 +- .../compile-fail/token-error-correct-3.rs | 5 +- .../compile-fail/unexpected-return-on-unit.rs | 5 +- 19 files changed, 162 insertions(+), 136 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 1ae18b01b7dc6..df991179f6198 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -10,11 +10,10 @@ use check::FnCtxt; -use hir::map::Node; use rustc::infer::{InferOk, TypeTrace}; use rustc::traits::ObligationCause; use rustc::ty::Ty; -use rustc::ty::error::TypeError; +use errors; use syntax_pos::Span; use rustc::hir; @@ -53,53 +52,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - // Checks that the type of `expr` can be coerced to `expected`. - pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) { + pub fn demand_coerce_diag(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) + -> Option> + { let expected = self.resolve_type_vars_with_obligations(expected); if let Err(e) = self.try_coerce(expr, checked_ty, expected) { let cause = self.misc(expr.span); let expr_ty = self.resolve_type_vars_with_obligations(checked_ty); let trace = TypeTrace::types(&cause, true, expected, expr_ty); - let mut diag = self.report_and_explain_type_error(trace, &e); - if let Node::NodeBlock(block) = self.tcx.map - .get(self.tcx.map.get_parent_node(expr.id)) - { - if let TypeError::Sorts(ref values) = e { - if values.expected.is_nil() { - // An implicit return to a method with return type `()` - diag.span_label(expr.span, - &"possibly missing `;` here?"); - // Get the current node's method definition - if let Node::NodeExpr(item) = self.tcx.map - .get(self.tcx.map.get_parent_node(block.id)) - { - // The fn has a default return type of () - if let Node::NodeItem(&hir::Item { - name, - node: hir::ItemFn(ref decl, ..), - .. - }) = self.tcx.map.get(self.tcx.map.get_parent_node(item.id)) { - // `main` *must* have return type () - if name.as_str() != "main" { - decl.clone().and_then(|decl| { - if let hir::FnDecl { - output: hir::FunctionRetTy::DefaultReturn(span), - .. - } = decl { - diag.span_label(span, - &format!("possibly return type `{}` \ - missing in this fn?", - values.found)); - } - }); - } - } - } - } - } - }; - diag.emit(); + Some(self.report_and_explain_type_error(trace, &e)) + } else { + None + } + } + + // Checks that the type of `expr` can be coerced to `expected`. + pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) { + if let Some(mut err) = self.demand_coerce_diag(expr, checked_ty, expected) { + err.emit(); } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 093a023291ac4..4e78289b828a9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -124,6 +124,7 @@ use rustc::hir::intravisit::{self, Visitor}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::{self, PatKind}; use rustc::hir::print as pprust; +use rustc::hir::map::Node; use rustc_back::slice; use rustc_const_eval::eval_length; @@ -3666,7 +3667,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.check_expr_closure(expr, capture, &decl, &body, expected) } hir::ExprBlock(ref b) => { - self.check_block_with_expected(&b, expected) + self.check_block_with_expected(&b, expected) } hir::ExprCall(ref callee, ref args) => { self.check_call(expr, &callee, &args[..], expected) @@ -4085,7 +4086,57 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else if let ExpectHasType(ety) = expected { if let Some(ref e) = blk.expr { // Coerce the tail expression to the right type. - self.demand_coerce(e, ty, ety); + if let Some(mut err) = self.demand_coerce_diag(e, ty, ety) { + // Be helpful when the user wrote `{... expr}` and + // adding a `;` is enough to fix the error. + if ety.is_nil() { + let span = Span { + lo: e.span.hi, + hi: e.span.hi + BytePos(1), + expn_id: e.span.expn_id + }; + err.span_label(span, &"consider adding a semicolon here"); + } + + // Is the block part of a fn? + let parent = self.tcx.map.get(self.tcx.map.get_parent(blk.id)); + let fn_decl = if let Node::NodeItem(&hir::Item { + name, node: hir::ItemFn(ref decl, ..), .. + }) = parent { + // `fn main` must return `()` + if name.as_str() != "main" { + decl.clone().and_then(|decl| { + Some(decl) + }) + } else { + None + } + } else if let Node::NodeTraitItem(&hir::TraitItem { + node: hir::TraitItem_::MethodTraitItem(hir::MethodSig { + ref decl, .. + }, ..), .. + }) = parent { + decl.clone().and_then(|decl| { + Some(decl) + }) + } else { + // Do not recomend changing return type of `ImplItemKind::Method` + None + }; + + // Only recommend changing the return type for methods that + // haven't set a return type at all. + if let Some(hir::FnDecl { + output: hir::FunctionRetTy::DefaultReturn(span), + .. + }) = fn_decl { + err.span_label(span, + &format!("possibly return type `{}` \ + missing here", + ty)); + } + err.emit(); + } } else { // We're not diverging and there's an expected type, which, // in case it's not `()`, could result in an error higher-up. @@ -4118,9 +4169,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hi: original_span.hi, expn_id: original_span.expn_id }; - err.span_help(span_semi, "consider removing this semicolon:"); + err.span_label(span_semi, &"consider removing this semicolon"); } - err.emit(); } } diff --git a/src/test/compile-fail/block-must-not-have-result-do.rs b/src/test/compile-fail/block-must-not-have-result-do.rs index a7499cd526fe1..03385bcc5e768 100644 --- a/src/test/compile-fail/block-must-not-have-result-do.rs +++ b/src/test/compile-fail/block-must-not-have-result-do.rs @@ -12,12 +12,9 @@ fn main() { loop { true //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found bool //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `bool` //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/block-must-not-have-result-res.rs b/src/test/compile-fail/block-must-not-have-result-res.rs index e1aa9d249265e..29a0f920194f5 100644 --- a/src/test/compile-fail/block-must-not-have-result-res.rs +++ b/src/test/compile-fail/block-must-not-have-result-res.rs @@ -14,12 +14,9 @@ impl Drop for r { fn drop(&mut self) { true //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found bool //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `bool` //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/block-must-not-have-result-while.rs b/src/test/compile-fail/block-must-not-have-result-while.rs index 1e970074ca375..2b2e9c3386ea9 100644 --- a/src/test/compile-fail/block-must-not-have-result-while.rs +++ b/src/test/compile-fail/block-must-not-have-result-while.rs @@ -12,12 +12,9 @@ fn main() { while true { true //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found bool //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `bool` //~| NOTE: found type `bool` } } diff --git a/src/test/compile-fail/consider-removing-last-semi.rs b/src/test/compile-fail/consider-removing-last-semi.rs index 530a0e4156228..fa78f05bf23a9 100644 --- a/src/test/compile-fail/consider-removing-last-semi.rs +++ b/src/test/compile-fail/consider-removing-last-semi.rs @@ -8,14 +8,22 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f() -> String { //~ ERROR mismatched types +fn f() -> String { + //~^ ERROR mismatched types + //~| NOTE expected struct `std::string::String`, found () + //~| NOTE expected type `std::string::String` + //~| NOTE found type `()` 0u8; - "bla".to_string(); //~ HELP consider removing this semicolon + "bla".to_string(); //~ NOTE consider removing this semicolon } -fn g() -> String { //~ ERROR mismatched types +fn g() -> String { + //~^ ERROR mismatched types + //~| NOTE expected struct `std::string::String`, found () + //~| NOTE expected type `std::string::String` + //~| NOTE found type `()` "this won't work".to_string(); - "removeme".to_string(); //~ HELP consider removing this semicolon + "removeme".to_string(); //~ NOTE consider removing this semicolon } fn main() {} diff --git a/src/test/compile-fail/issue-11714.rs b/src/test/compile-fail/issue-11714.rs index 192f78e41cb43..c550af1b95e0b 100644 --- a/src/test/compile-fail/issue-11714.rs +++ b/src/test/compile-fail/issue-11714.rs @@ -8,10 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn blah() -> i32 { //~ ERROR mismatched types +fn blah() -> i32 { + //~^ ERROR mismatched types + //~| NOTE expected i32, found () + //~| NOTE expected type `i32` + //~| NOTE found type `()` 1 - ; //~ HELP consider removing this semicolon: + ; //~ NOTE consider removing this semicolon } fn main() { } diff --git a/src/test/compile-fail/issue-13428.rs b/src/test/compile-fail/issue-13428.rs index 9406199afc231..d5d719de9fdef 100644 --- a/src/test/compile-fail/issue-13428.rs +++ b/src/test/compile-fail/issue-13428.rs @@ -10,17 +10,25 @@ // Regression test for #13428 -fn foo() -> String { //~ ERROR mismatched types +fn foo() -> String { + //~^ ERROR mismatched types + //~| NOTE expected struct `std::string::String`, found () + //~| NOTE expected type `std::string::String` + //~| NOTE found type `()` format!("Hello {}", "world") // Put the trailing semicolon on its own line to test that the // note message gets the offending semicolon exactly - ; //~ HELP consider removing this semicolon + ; //~ NOTE consider removing this semicolon } -fn bar() -> String { //~ ERROR mismatched types +fn bar() -> String { + //~^ ERROR mismatched types + //~| NOTE expected struct `std::string::String`, found () + //~| NOTE expected type `std::string::String` + //~| NOTE found type `()` "foobar".to_string() - ; //~ HELP consider removing this semicolon + ; //~ NOTE consider removing this semicolon } pub fn main() {} diff --git a/src/test/compile-fail/issue-13624.rs b/src/test/compile-fail/issue-13624.rs index 328aa0690efaa..96e185ed8e20d 100644 --- a/src/test/compile-fail/issue-13624.rs +++ b/src/test/compile-fail/issue-13624.rs @@ -16,12 +16,9 @@ mod a { pub fn get_enum_struct_variant() -> () { Enum::EnumStructVariant { x: 1, y: 2, z: 3 } //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found enum `a::Enum` //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `a::Enum` //~| NOTE: found type `a::Enum` } } diff --git a/src/test/compile-fail/issue-19109.rs b/src/test/compile-fail/issue-19109.rs index c74e44a9871d9..e133988beb77f 100644 --- a/src/test/compile-fail/issue-19109.rs +++ b/src/test/compile-fail/issue-19109.rs @@ -11,16 +11,13 @@ trait Trait { } fn function(t: &mut Trait) { - //~^ NOTE: possibly return type `*mut Trait` missing in this fn? + //~^ NOTE possibly return type `*mut Trait` missing here t as *mut Trait - //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? - //~| NOTE: expected (), found *-ptr - //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `*mut Trait` - //~| NOTE: found type `*mut Trait` + //~^ ERROR mismatched types + //~| NOTE consider adding a semicolon here + //~| NOTE expected (), found *-ptr + //~| NOTE expected type `()` + //~| NOTE found type `*mut Trait` } fn main() { } diff --git a/src/test/compile-fail/issue-20862.rs b/src/test/compile-fail/issue-20862.rs index 1a1409d4b742d..bb3edf9d17817 100644 --- a/src/test/compile-fail/issue-20862.rs +++ b/src/test/compile-fail/issue-20862.rs @@ -9,20 +9,17 @@ // except according to those terms. fn foo(x: i32) { - //~^ NOTE: possibly return type + //~^ NOTE possibly return type |y| x + y - //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? - //~| NOTE: expected (), found closure - //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type - //~| NOTE: found type + //~^ ERROR mismatched types + //~| NOTE consider adding a semicolon here + //~| NOTE expected (), found closure + //~| NOTE expected type `()` + //~| NOTE found type } fn main() { let x = foo(5)(2); - //~^ ERROR: expected function, found `()` + //~^ ERROR expected function, found `()` } diff --git a/src/test/compile-fail/issue-22645.rs b/src/test/compile-fail/issue-22645.rs index 4fa60bc762458..ef7650020eae1 100644 --- a/src/test/compile-fail/issue-22645.rs +++ b/src/test/compile-fail/issue-22645.rs @@ -24,13 +24,10 @@ fn main() { let b = Bob + 3.5; b + 3 //~ ERROR E0277 //~^ ERROR: mismatched types - //~| ERROR: mismatched types - //~| NOTE: possibly missing `;` here? - //~| NOTE: expected (), found - //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type - //~| NOTE: found type - //~| NOTE: the trait `Scalar` is not implemented for `{integer}` - //~| NOTE: required because of the requirements on the impl of `std::ops::Add<{integer}>` + //~| NOTE consider adding a semicolon here + //~| NOTE expected (), found + //~| NOTE expected type `()` + //~| NOTE found type + //~| NOTE the trait `Scalar` is not implemented for `{integer}` + //~| NOTE required because of the requirements on the impl of `std::ops::Add<{integer}>` } diff --git a/src/test/compile-fail/issue-3563.rs b/src/test/compile-fail/issue-3563.rs index a4873005b0414..784f55689c6b8 100644 --- a/src/test/compile-fail/issue-3563.rs +++ b/src/test/compile-fail/issue-3563.rs @@ -9,17 +9,14 @@ // except according to those terms. trait A { - fn a(&self) { + fn a(&self) { //~ possibly return type || self.b() //~^ ERROR no method named `b` found for type `&Self` in the current scope //~| ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? - //~| NOTE: expected (), found closure - //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type - //~| NOTE: found type + //~| NOTE consider adding a semicolon here + //~| NOTE expected (), found closure + //~| NOTE expected type `()` + //~| NOTE found type } } fn main() {} diff --git a/src/test/compile-fail/issue-5500.rs b/src/test/compile-fail/issue-5500.rs index 998e53d07292a..54d8e35edd696 100644 --- a/src/test/compile-fail/issue-5500.rs +++ b/src/test/compile-fail/issue-5500.rs @@ -11,11 +11,7 @@ fn main() { &panic!() //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? - //~| NOTE: expected (), found reference - //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `&_` - //~| NOTE: found type `&_` + //~| NOTE expected (), found reference + //~| NOTE expected type `()` + //~| NOTE found type `&_` } diff --git a/src/test/compile-fail/issue-6458-4.rs b/src/test/compile-fail/issue-6458-4.rs index a078cdea4ac4d..e22486345fde0 100644 --- a/src/test/compile-fail/issue-6458-4.rs +++ b/src/test/compile-fail/issue-6458-4.rs @@ -8,8 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn foo(b: bool) -> Result { //~ ERROR mismatched types - Err("bar".to_string()); //~ HELP consider removing this semicolon +fn foo(b: bool) -> Result { + //~^ ERROR mismatched types + //~| NOTE expected enum `std::result::Result`, found () + //~| NOTE expected type `std::result::Result` + //~| NOTE found type `()` + Err("bar".to_string()); //~ NOTE consider removing this semicolon } fn main() { diff --git a/src/test/compile-fail/liveness-return-last-stmt-semi.rs b/src/test/compile-fail/liveness-return-last-stmt-semi.rs index ada91c38d48c3..8b1ee14b912e8 100644 --- a/src/test/compile-fail/liveness-return-last-stmt-semi.rs +++ b/src/test/compile-fail/liveness-return-last-stmt-semi.rs @@ -11,19 +11,37 @@ // regression test for #8005 macro_rules! test { () => { fn foo() -> i32 { 1; } } } - //~^ ERROR mismatched types - //~| HELP consider removing this semicolon +//~^ ERROR mismatched types +//~| NOTE expected i32, found () +//~| NOTE expected type `i32` +//~| NOTE found type `()` +//~| NOTE consider removing this semicolon -fn no_return() -> i32 {} //~ ERROR mismatched types +fn no_return() -> i32 {} + //~^ ERROR mismatched types + //~| NOTE expected i32, found () + //~| NOTE expected type `i32` + //~| NOTE found type `()` -fn bar(x: u32) -> u32 { //~ ERROR mismatched types - x * 2; //~ HELP consider removing this semicolon +fn bar(x: u32) -> u32 { + //~^ ERROR mismatched types + //~| NOTE expected u32, found () + //~| NOTE expected type `u32` + //~| NOTE found type `()` + x * 2; //~ NOTE consider removing this semicolon } -fn baz(x: u64) -> u32 { //~ ERROR mismatched types +fn baz(x: u64) -> u32 { + //~^ ERROR mismatched types + //~| NOTE expected u32, found () + //~| NOTE expected type `u32` + //~| NOTE found type `()` x * 2; } fn main() { test!(); + //~^ NOTE in this expansion of test! + //~| NOTE in this expansion of test! + //~| NOTE in this expansion of test! } diff --git a/src/test/compile-fail/specialization/specialization-default-projection.rs b/src/test/compile-fail/specialization/specialization-default-projection.rs index aa0a24bbcd321..9abac07634a2f 100644 --- a/src/test/compile-fail/specialization/specialization-default-projection.rs +++ b/src/test/compile-fail/specialization/specialization-default-projection.rs @@ -41,12 +41,9 @@ fn monomorphic() -> () { generic::<()>() //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found associated type //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type //~| NOTE: found type } diff --git a/src/test/compile-fail/token-error-correct-3.rs b/src/test/compile-fail/token-error-correct-3.rs index c07ffb7cedc68..0df64412c35ef 100644 --- a/src/test/compile-fail/token-error-correct-3.rs +++ b/src/test/compile-fail/token-error-correct-3.rs @@ -24,12 +24,9 @@ pub mod raw { //~^ ERROR: expected one of fs::create_dir_all(path.as_ref()).map(|()| true) //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found enum `std::result::Result` //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `std::result::Result` //~| NOTE: found type `std::result::Result` } else { //~ ERROR: incorrect close delimiter: `}` //~^ ERROR: expected one of diff --git a/src/test/compile-fail/unexpected-return-on-unit.rs b/src/test/compile-fail/unexpected-return-on-unit.rs index 506efdea38fe5..7bc2798103db4 100644 --- a/src/test/compile-fail/unexpected-return-on-unit.rs +++ b/src/test/compile-fail/unexpected-return-on-unit.rs @@ -14,11 +14,8 @@ fn main() { 1 //~^ ERROR mismatched types - //~| ERROR mismatched types - //~| NOTE: possibly missing `;` here? + //~| NOTE: consider adding a semicolon here //~| NOTE: expected (), found integral variable //~| NOTE: expected type `()` - //~| NOTE: expected type `()` - //~| NOTE: found type `{integer}` //~| NOTE: found type `{integer}` }