/// last good node id we found. Note that reaching the crate root (id == 0),
/// is not an error, since items in the crate module have the crate root as
/// parent.
- fn walk_parent_nodes<F>(&self, start_id: NodeId, found: F) -> Result<NodeId, NodeId>
- where F: Fn(&Node<'hir>) -> bool
+ fn walk_parent_nodes<F, F2>(&self,
+ start_id: NodeId,
+ found: F,
+ bail_early: F2)
+ -> Result<NodeId, NodeId>
+ where F: Fn(&Node<'hir>) -> bool, F2: Fn(&Node<'hir>) -> bool
{
let mut id = start_id;
loop {
Some(ref node) => {
if found(node) {
return Ok(parent_node);
+ } else if bail_early(node) {
+ return Err(parent_node);
}
}
None => {
}
}
+ /// Retrieve the NodeId for `id`'s enclosing method, unless there's a
+ /// `while` or `loop` before reacing it, as block tail returns are not
+ /// available in them.
+ ///
+ /// ```
+ /// fn foo(x: usize) -> bool {
+ /// if x == 1 {
+ /// true // `get_return_block` gets passed the `id` corresponding
+ /// } else { // to this, it will return `foo`'s `NodeId`.
+ /// false
+ /// }
+ /// }
+ /// ```
+ ///
+ /// ```
+ /// fn foo(x: usize) -> bool {
+ /// loop {
+ /// true // `get_return_block` gets passed the `id` corresponding
+ /// } // to this, it will return `None`.
+ /// false
+ /// }
+ /// ```
+ pub fn get_return_block(&self, id: NodeId) -> Option<NodeId> {
+ let match_fn = |node: &Node| {
+ match *node {
+ NodeItem(_) |
+ NodeForeignItem(_) |
+ NodeTraitItem(_) |
+ NodeImplItem(_) => true,
+ _ => false,
+ }
+ };
+ let match_non_returning_block = |node: &Node| {
+ match *node {
+ NodeExpr(ref expr) => {
+ match expr.node {
+ ExprWhile(..) | ExprLoop(..) => true,
+ _ => false,
+ }
+ }
+ _ => false,
+ }
+ };
+
+ match self.walk_parent_nodes(id, match_fn, match_non_returning_block) {
+ Ok(id) => Some(id),
+ Err(_) => None,
+ }
+ }
+
/// Retrieve the NodeId for `id`'s parent item, or `id` itself if no
/// parent item is in this map. The "parent item" is the closest parent node
/// in the AST which is recorded by the map and is an item, either an item
NodeTraitItem(_) |
NodeImplItem(_) => true,
_ => false,
- }) {
+ }, |_| false) {
Ok(id) => id,
Err(id) => id,
}
let id = match self.walk_parent_nodes(id, |node| match *node {
NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true,
_ => false,
- }) {
+ }, |_| false) {
Ok(id) => id,
Err(id) => id,
};
NodeImplItem(_) |
NodeBlock(_) => true,
_ => false,
- }) {
+ }, |_| false) {
Ok(id) => Some(id),
Err(_) => None,
}
ObligationCauseCode::VariableType(_) => {
err.note("all local variables must have a statically known size");
}
- ObligationCauseCode::ReturnType => {
+ ObligationCauseCode::SizedReturnType => {
err.note("the return type of a function must have a \
statically known size");
}
but not on the corresponding trait method",
predicate));
}
+ ObligationCauseCode::ReturnType(_) |
+ ObligationCauseCode::BlockTailExpression(_) => (),
}
}
/// Obligation incurred due to an object cast.
ObjectCastObligation(/* Object type */ Ty<'tcx>),
- /// Various cases where expressions must be sized/copy/etc:
- AssignmentLhsSized, // L = X implies that L is Sized
- StructInitializerSized, // S { ... } must be Sized
- VariableType(ast::NodeId), // Type of each variable must be Sized
- ReturnType, // Return type must be Sized
- RepeatVec, // [T,..n] --> T must be Copy
-
- // Types of fields (other than the last) in a struct must be sized.
+ // Various cases where expressions must be sized/copy/etc:
+ /// L = X implies that L is Sized
+ AssignmentLhsSized,
+ /// S { ... } must be Sized
+ StructInitializerSized,
+ /// Type of each variable must be Sized
+ VariableType(ast::NodeId),
+ /// Return type must be Sized
+ SizedReturnType,
+ /// [T,..n] --> T must be Copy
+ RepeatVec,
+
+ /// Types of fields (other than the last) in a struct must be sized.
FieldSized,
- // Constant expressions must be sized.
+ /// Constant expressions must be sized.
ConstSized,
- // static items must have `Sync` type
+ /// static items must have `Sync` type
SharedStatic,
BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
ImplDerivedObligation(DerivedObligationCause<'tcx>),
- // error derived when matching traits/impls; see ObligationCause for more details
+ /// error derived when matching traits/impls; see ObligationCause for more details
CompareImplMethodObligation {
item_name: ast::Name,
impl_item_def_id: DefId,
lint_id: Option<ast::NodeId>,
},
- // Checking that this expression can be assigned where it needs to be
+ /// Checking that this expression can be assigned where it needs to be
// FIXME(eddyb) #11161 is the original Expr required?
ExprAssignable,
- // Computing common supertype in the arms of a match expression
+ /// Computing common supertype in the arms of a match expression
MatchExpressionArm { arm_span: Span,
source: hir::MatchSource },
- // Computing common supertype in an if expression
+ /// Computing common supertype in an if expression
IfExpression,
- // Computing common supertype of an if expression with no else counter-part
+ /// Computing common supertype of an if expression with no else counter-part
IfExpressionWithNoElse,
- // `where a == b`
+ /// `where a == b`
EquatePredicate,
- // `main` has wrong type
+ /// `main` has wrong type
MainFunctionType,
- // `start` has wrong type
+ /// `start` has wrong type
StartFunctionType,
- // intrinsic has wrong type
+ /// intrinsic has wrong type
IntrinsicType,
- // method receiver
+ /// method receiver
MethodReceiver,
- // `return` with no expression
+ /// `return` with no expression
ReturnNoExpression,
+
+ /// `return` with an expression
+ ReturnType(ast::NodeId),
+
+ /// Block implicit return
+ BlockTailExpression(ast::NodeId),
}
#[derive(Clone, Debug, PartialEq, Eq)]
super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
super::StructInitializerSized => Some(super::StructInitializerSized),
super::VariableType(id) => Some(super::VariableType(id)),
- super::ReturnType => Some(super::ReturnType),
+ super::ReturnType(id) => Some(super::ReturnType(id)),
+ super::SizedReturnType => Some(super::SizedReturnType),
super::RepeatVec => Some(super::RepeatVec),
super::FieldSized => Some(super::FieldSized),
super::ConstSized => Some(super::ConstSized),
lint_id: lint_id,
})
}
- super::ExprAssignable => {
- Some(super::ExprAssignable)
- }
+ super::ExprAssignable => Some(super::ExprAssignable),
super::MatchExpressionArm { arm_span, source } => {
Some(super::MatchExpressionArm { arm_span: arm_span,
source: source })
}
- super::IfExpression => {
- Some(super::IfExpression)
- }
- super::IfExpressionWithNoElse => {
- Some(super::IfExpressionWithNoElse)
- }
- super::EquatePredicate => {
- Some(super::EquatePredicate)
- }
- super::MainFunctionType => {
- Some(super::MainFunctionType)
- }
- super::StartFunctionType => {
- Some(super::StartFunctionType)
- }
- super::IntrinsicType => {
- Some(super::IntrinsicType)
- }
- super::MethodReceiver => {
- Some(super::MethodReceiver)
- }
+ super::IfExpression => Some(super::IfExpression),
+ super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
+ super::EquatePredicate => Some(super::EquatePredicate),
+ super::MainFunctionType => Some(super::MainFunctionType),
+ super::StartFunctionType => Some(super::StartFunctionType),
+ super::IntrinsicType => Some(super::IntrinsicType),
+ super::MethodReceiver => Some(super::MethodReceiver),
+ super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
}
}
}
super::AssignmentLhsSized |
super::StructInitializerSized |
super::VariableType(_) |
- super::ReturnType |
+ super::ReturnType(_) |
+ super::SizedReturnType |
super::ReturnNoExpression |
super::RepeatVec |
super::FieldSized |
super::ConstSized |
super::SharedStatic |
+ super::BlockTailExpression(_) |
super::CompareImplMethodObligation { .. } => self.clone(),
super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
super::AssignmentLhsSized |
super::StructInitializerSized |
super::VariableType(_) |
- super::ReturnType |
+ super::ReturnType(_) |
+ super::SizedReturnType |
super::ReturnNoExpression |
super::RepeatVec |
super::FieldSized |
super::ConstSized |
super::SharedStatic |
+ super::BlockTailExpression(_) |
super::CompareImplMethodObligation { .. } => false,
super::ProjectionWf(proj) => proj.visit_with(visitor),
_ => false,
}
}
+
+ pub fn is_suggestable(&self) -> bool {
+ match self.sty {
+ TypeVariants::TyAnon(..) |
+ TypeVariants::TyFnDef(..) |
+ TypeVariants::TyFnPtr(..) |
+ TypeVariants::TyDynamic(..) |
+ TypeVariants::TyClosure(..) |
+ TypeVariants::TyProjection(..) => false,
+ _ => true,
+ }
+ }
}
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TyS<'tcx> {
// don't display multiline suggestions as labels
sugg.substitution_parts[0].substitutions[0].find('\n').is_none() {
let substitution = &sugg.substitution_parts[0].substitutions[0];
- let msg = format!("help: {} `{}`", sugg.msg, substitution);
+ let msg = if substitution.len() == 0 {
+ // This substitution is only removal, don't show it
+ format!("help: {}", sugg.msg)
+ } else {
+ format!("help: {} `{}`", sugg.msg, substitution)
+ };
primary_span.push_span_label(sugg.substitution_spans().next().unwrap(), msg);
} else {
// if there are multiple suggestions, print them all in full
"`return;` in a function whose return type is not `()`");
db.span_label(cause.span, "return type is not ()");
}
+ ObligationCauseCode::BlockTailExpression(blk_id) => {
+ db = fcx.report_mismatched_types(cause, expected, found, err);
+
+ let expr = expression.unwrap_or_else(|| {
+ span_bug!(cause.span,
+ "supposed to be part of a block tail expression, but the \
+ expression is empty");
+ });
+ fcx.suggest_mismatched_types_on_tail(&mut db, expr,
+ expected, found,
+ cause.span, blk_id);
+ }
_ => {
db = fcx.report_mismatched_types(cause, expected, found, err);
}
}
}
+ 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();
+ }
+ }
+
// Checks that the type of `expr` can be coerced to `expected`.
//
// NB: This code relies on `self.diverges` to be accurate. In
// particular, assignments to `!` will be permitted if the
// diverges flag is currently "always".
- 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<DiagnosticBuilder<'tcx>> {
let expected = self.resolve_type_vars_with_obligations(expected);
if let Err(e) = self.try_coerce(expr, checked_ty, self.diverges.get(), expected) {
self.get_best_match(&suggestions).join("\n")));
}
}
- err.emit();
+ return Some(err);
}
+ None
}
fn format_method_suggestion(&self, method: &AssociatedItem) -> String {
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir::map::Node;
use rustc::hir::{self, PatKind};
use rustc::middle::lang_items;
use rustc_back::slice;
*fcx.ps.borrow_mut() = UnsafetyState::function(fn_sig.unsafety, fn_id);
let ret_ty = fn_sig.output();
- fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::ReturnType);
+ fcx.require_type_is_sized(ret_ty, decl.output.span(), traits::SizedReturnType);
let ret_ty = fcx.instantiate_anon_types(&ret_ty);
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
fn_sig = fcx.tcx.mk_fn_sig(
// Require that the predicate holds for the concrete type.
let cause = traits::ObligationCause::new(span, self.body_id,
- traits::ReturnType);
+ traits::SizedReturnType);
self.register_predicate(traits::Obligation::new(cause,
self.param_env,
predicate));
"check_return_expr called outside fn body"));
let ret_ty = ret_coercion.borrow().expected_ty();
- let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty);
+ let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
ret_coercion.borrow_mut()
.coerce(self,
- &self.misc(return_expr.span),
+ &self.cause(return_expr.span,
+ ObligationCauseCode::ReturnType(return_expr.id)),
return_expr,
return_expr_ty,
self.diverges.get());
let mut coerce = ctxt.coerce.as_mut().unwrap();
if let Some(tail_expr_ty) = tail_expr_ty {
let tail_expr = tail_expr.unwrap();
+ let cause = self.cause(tail_expr.span,
+ ObligationCauseCode::BlockTailExpression(blk.id));
coerce.coerce(self,
- &self.misc(tail_expr.span),
+ &cause,
tail_expr,
tail_expr_ty,
self.diverges.get());
ty
}
+ /// Given a `NodeId`, return the `FnDecl` of the method it is enclosed by and whether it is
+ /// `fn main` if it is a method, `None` otherwise.
+ pub fn get_fn_decl(&self, blk_id: ast::NodeId) -> Option<(hir::FnDecl, bool)> {
+ // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
+ // `while` before reaching it, as block tail returns are not available in them.
+ if let Some(fn_id) = self.tcx.hir.get_return_block(blk_id) {
+ let parent = self.tcx.hir.get(fn_id);
+
+ if let Node::NodeItem(&hir::Item {
+ name, node: hir::ItemFn(ref decl, ..), ..
+ }) = parent {
+ decl.clone().and_then(|decl| {
+ // This is less than ideal, it will not present the return type span on any
+ // method called `main`, regardless of whether it is actually the entry point.
+ Some((decl, name == Symbol::intern("main")))
+ })
+ } else if let Node::NodeTraitItem(&hir::TraitItem {
+ node: hir::TraitItemKind::Method(hir::MethodSig {
+ ref decl, ..
+ }, ..), ..
+ }) = parent {
+ decl.clone().and_then(|decl| {
+ Some((decl, false))
+ })
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ }
+
+ /// On implicit return expressions with mismatched types, provide the following suggestions:
+ ///
+ /// - Point out the method's return type as the reason for the expected type
+ /// - Possible missing semicolon
+ /// - Possible missing return type if the return type is the default, and not `fn main()`
+ pub fn suggest_mismatched_types_on_tail(&self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ expression: &'gcx hir::Expr,
+ expected: Ty<'tcx>,
+ found: Ty<'tcx>,
+ cause_span: Span,
+ blk_id: ast::NodeId) {
+ self.suggest_missing_semicolon(err, expression, expected, cause_span);
+
+ if let Some((fn_decl, is_main)) = self.get_fn_decl(blk_id) {
+ // `fn main()` must return `()`, do not suggest changing return type
+ if !is_main {
+ self.suggest_missing_return_type(err, &fn_decl, found);
+ }
+ }
+ }
+
+ /// A common error is to forget to add a semicolon at the end of a block:
+ ///
+ /// ```
+ /// fn foo() {
+ /// bar_that_returns_u32()
+ /// }
+ /// ```
+ ///
+ /// This routine checks if the return expression in a block would make sense on its own as a
+ /// statement and the return type has been left as defaultor has been specified as `()`. If so,
+ /// it suggests adding a semicolon.
+ fn suggest_missing_semicolon(&self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ expression: &'gcx hir::Expr,
+ expected: Ty<'tcx>,
+ cause_span: Span) {
+ if expected.is_nil() {
+ // `BlockTailExpression` only relevant if the tail expr would be
+ // useful on its own.
+ match expression.node {
+ hir::ExprCall(..) |
+ hir::ExprMethodCall(..) |
+ hir::ExprIf(..) |
+ hir::ExprWhile(..) |
+ hir::ExprLoop(..) |
+ hir::ExprMatch(..) |
+ hir::ExprBlock(..) => {
+ let sp = cause_span.next_point();
+ err.span_suggestion(sp,
+ "did you mean to add a semicolon here?",
+ ";".to_string());
+ }
+ _ => (),
+ }
+ }
+ }
+
+
+ /// A possible error is to forget to add a return type that is needed:
+ ///
+ /// ```
+ /// fn foo() {
+ /// bar_that_returns_u32()
+ /// }
+ /// ```
+ ///
+ /// This routine checks if the return type is left as default, the method is not part of an
+ /// `impl` block and that it isn't the `main` method. If so, it suggests setting the return
+ /// type.
+ fn suggest_missing_return_type(&self,
+ err: &mut DiagnosticBuilder<'tcx>,
+ fn_decl: &hir::FnDecl,
+ ty: Ty<'tcx>) {
+
+ // Only recommend changing the return type for methods that
+ // haven't set a return type at all (and aren't `fn main()` or an impl).
+ if let &hir::FnDecl {
+ output: hir::FunctionRetTy::DefaultReturn(span), ..
+ } = fn_decl {
+ if ty.is_suggestable() {
+ err.span_suggestion(span,
+ "possibly return type missing here?",
+ format!("-> {} ", ty));
+ } else {
+ err.span_label(span, "possibly return type missing here?");
+ }
+ }
+ }
+
+
/// A common error is to add an extra semicolon:
///
/// ```
hi: original_span.hi,
ctxt: original_span.ctxt,
};
- err.span_help(span_semi, "consider removing this semicolon:");
+ err.span_suggestion(span_semi, "consider removing this semicolon", "".to_string());
}
// Instantiates the given path, which must refer to an item with the given
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- loop {
- true //~ ERROR mismatched types
- }
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-struct r;
-
-impl Drop for r {
- fn drop(&mut self) {
- true //~ ERROR mismatched types
- }
-}
-
-fn main() {
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- while true {
- true //~ ERROR mismatched types
- //~| expected type `()`
- //~| found type `bool`
- //~| expected (), found bool
- }
-}
+++ /dev/null
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn f() -> String { //~ ERROR mismatched types
- 0u8;
- "bla".to_string(); //~ HELP consider removing this semicolon
-}
-
-fn g() -> String { //~ ERROR mismatched types
- "this won't work".to_string();
- "removeme".to_string(); //~ HELP consider removing this semicolon
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2017 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- for x in 0..3 {
- x //~ ERROR mismatched types
- //~| NOTE expected ()
- //~| NOTE expected type `()`
- }
-}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn blah() -> i32 { //~ ERROR mismatched types
- 1
-
- ; //~ HELP consider removing this semicolon:
-}
-
-fn main() { }
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Regression test for #13428
-
-fn foo() -> String { //~ ERROR mismatched types
- 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
-}
-
-fn bar() -> String { //~ ERROR mismatched types
- "foobar".to_string()
- ; //~ HELP consider removing this semicolon
-}
-
-pub fn main() {}
+++ /dev/null
-// Copyright 2014 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod a {
- pub enum Enum {
- EnumStructVariant { x: u8, y: u8, z: u8 }
- }
-
- 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`
- }
-}
-
-mod b {
- mod test {
- use a;
-
- fn test_enum_struct_variant() {
- 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`
- }
- }
- }
- }
-}
-
-fn main() {}
+++ /dev/null
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn foo(x: i32) {
- |y| x + y
-//~^ ERROR: mismatched types
-}
-
-fn main() {
- let x = foo(5)(2);
-//~^ ERROR: expected function, found `()`
-}
+++ /dev/null
-// Copyright 2015 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::ops::Add;
-
-trait Scalar {}
-impl Scalar for f64 {}
-
-struct Bob;
-
-impl<RHS: Scalar> Add <RHS> for Bob {
- type Output = Bob;
- fn add(self, rhs : RHS) -> Bob { Bob }
-}
-
-fn main() {
- let b = Bob + 3.5;
- b + 3 //~ ERROR E0277
- //~^ ERROR: mismatched types
-}
+++ /dev/null
-// Copyright 2012 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-trait A {
- fn a(&self) {
- || self.b()
- //~^ ERROR no method named `b` found for type `&Self` in the current scope
- //~| ERROR mismatched types
- }
-}
-fn main() {}
+++ /dev/null
-// Copyright 2013 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
- &panic!()
- //~^ ERROR mismatched types
- //~| expected type `()`
- //~| found type `&_`
- //~| expected (), found reference
-}
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ loop {
+ true //~ ERROR mismatched types
+ }
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/block-must-not-have-result-do.rs:13:9
+ |
+13 | true //~ ERROR mismatched types
+ | ^^^^ expected (), found bool
+ |
+ = note: expected type `()`
+ found type `bool`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct r;
+
+impl Drop for r {
+ fn drop(&mut self) {
+ true //~ ERROR mismatched types
+ }
+}
+
+fn main() {
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/block-must-not-have-result-res.rs:15:9
+ |
+15 | true //~ ERROR mismatched types
+ | ^^^^ expected (), found bool
+ |
+ = note: expected type `()`
+ found type `bool`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ while true {
+ true //~ ERROR mismatched types
+ //~| expected type `()`
+ //~| found type `bool`
+ //~| expected (), found bool
+ }
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/block-must-not-have-result-while.rs:13:9
+ |
+13 | true //~ ERROR mismatched types
+ | ^^^^ expected (), found bool
+ |
+ = note: expected type `()`
+ found type `bool`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn f() -> String { //~ ERROR mismatched types
+ 0u8;
+ "bla".to_string(); //~ HELP consider removing this semicolon
+}
+
+fn g() -> String { //~ ERROR mismatched types
+ "this won't work".to_string();
+ "removeme".to_string(); //~ HELP consider removing this semicolon
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/consider-removing-last-semi.rs:11:18
+ |
+11 | fn f() -> String { //~ ERROR mismatched types
+ | __________________^
+12 | | 0u8;
+13 | | "bla".to_string(); //~ HELP consider removing this semicolon
+ | | - help: consider removing this semicolon
+14 | | }
+ | |_^ expected struct `std::string::String`, found ()
+ |
+ = note: expected type `std::string::String`
+ found type `()`
+
+error[E0308]: mismatched types
+ --> $DIR/consider-removing-last-semi.rs:16:18
+ |
+16 | fn g() -> String { //~ ERROR mismatched types
+ | __________________^
+17 | | "this won't work".to_string();
+18 | | "removeme".to_string(); //~ HELP consider removing this semicolon
+ | | - help: consider removing this semicolon
+19 | | }
+ | |_^ expected struct `std::string::String`, found ()
+ |
+ = note: expected type `std::string::String`
+ found type `()`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn blah() -> i32 { //~ ERROR mismatched types
+ 1
+
+ ; //~ HELP consider removing this semicolon:
+}
+
+fn main() { }
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-11714.rs:11:18
+ |
+11 | fn blah() -> i32 { //~ ERROR mismatched types
+ | __________________^
+12 | | 1
+13 | |
+14 | | ; //~ HELP consider removing this semicolon:
+ | | - help: consider removing this semicolon
+15 | | }
+ | |_^ expected i32, found ()
+ |
+ = note: expected type `i32`
+ found type `()`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for #13428
+
+fn foo() -> String { //~ ERROR mismatched types
+ 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
+}
+
+fn bar() -> String { //~ ERROR mismatched types
+ "foobar".to_string()
+ ; //~ HELP consider removing this semicolon
+}
+
+pub fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-13428.rs:13:20
+ |
+13 | fn foo() -> String { //~ ERROR mismatched types
+ | ____________________^
+14 | | format!("Hello {}",
+15 | | "world")
+16 | | // Put the trailing semicolon on its own line to test that the
+17 | | // note message gets the offending semicolon exactly
+18 | | ; //~ HELP consider removing this semicolon
+ | | - help: consider removing this semicolon
+19 | | }
+ | |_^ expected struct `std::string::String`, found ()
+ |
+ = note: expected type `std::string::String`
+ found type `()`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-13428.rs:21:20
+ |
+21 | fn bar() -> String { //~ ERROR mismatched types
+ | ____________________^
+22 | | "foobar".to_string()
+23 | | ; //~ HELP consider removing this semicolon
+ | | - help: consider removing this semicolon
+24 | | }
+ | |_^ expected struct `std::string::String`, found ()
+ |
+ = note: expected type `std::string::String`
+ found type `()`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2014 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod a {
+ pub enum Enum {
+ EnumStructVariant { x: u8, y: u8, z: u8 }
+ }
+
+ 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`
+ }
+}
+
+mod b {
+ mod test {
+ use a;
+
+ fn test_enum_struct_variant() {
+ 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`
+ }
+ }
+ }
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-13624.rs:17:5
+ |
+17 | Enum::EnumStructVariant { x: 1, y: 2, z: 3 }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `a::Enum`
+ |
+ = note: expected type `()`
+ found type `a::Enum`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-13624.rs:32:9
+ |
+32 | a::Enum::EnumStructVariant { x, y, z } => {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `a::Enum`
+ |
+ = note: expected type `()`
+ found type `a::Enum`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo(x: i32) {
+ |y| x + y
+//~^ ERROR: mismatched types
+}
+
+fn main() {
+ let x = foo(5)(2);
+//~^ ERROR: expected function, found `()`
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-20862.rs:12:5
+ |
+11 | fn foo(x: i32) {
+ | - possibly return type missing here?
+12 | |y| x + y
+ | ^^^^^^^^^ expected (), found closure
+ |
+ = note: expected type `()`
+ found type `[closure@$DIR/issue-20862.rs:12:5: 12:14 x:_]`
+
+error[E0618]: expected function, found `()`
+ --> $DIR/issue-20862.rs:17:13
+ |
+17 | let x = foo(5)(2);
+ | ^^^^^^^^^
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2015 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::Add;
+
+trait Scalar {}
+impl Scalar for f64 {}
+
+struct Bob;
+
+impl<RHS: Scalar> Add <RHS> for Bob {
+ type Output = Bob;
+ fn add(self, rhs : RHS) -> Bob { Bob }
+}
+
+fn main() {
+ let b = Bob + 3.5;
+ b + 3 //~ ERROR E0277
+ //~^ ERROR: mismatched types
+}
--- /dev/null
+error[E0277]: the trait bound `{integer}: Scalar` is not satisfied
+ --> $DIR/issue-22645.rs:25:5
+ |
+25 | b + 3 //~ ERROR E0277
+ | ^ the trait `Scalar` is not implemented for `{integer}`
+ |
+ = help: the following implementations were found:
+ <f64 as Scalar>
+ = note: required because of the requirements on the impl of `std::ops::Add<{integer}>` for `Bob`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-22645.rs:25:3
+ |
+25 | b + 3 //~ ERROR E0277
+ | ^^^^^ expected (), found struct `Bob`
+ |
+ = note: expected type `()`
+ found type `Bob`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2012 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait A {
+ fn a(&self) {
+ || self.b()
+ //~^ ERROR no method named `b` found for type `&Self` in the current scope
+ //~| ERROR mismatched types
+ }
+}
+fn main() {}
--- /dev/null
+error[E0599]: no method named `b` found for type `&Self` in the current scope
+ --> $DIR/issue-3563.rs:13:17
+ |
+13 | || self.b()
+ | ^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-3563.rs:13:9
+ |
+12 | fn a(&self) {
+ | - possibly return type missing here?
+13 | || self.b()
+ | ^^^^^^^^^^^ expected (), found closure
+ |
+ = note: expected type `()`
+ found type `[closure@$DIR/issue-3563.rs:13:9: 13:20 self:_]`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2013 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ &panic!()
+ //~^ ERROR mismatched types
+ //~| expected type `()`
+ //~| found type `&_`
+ //~| expected (), found reference
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/issue-5500.rs:12:5
+ |
+12 | &panic!()
+ | ^^^^^^^^^ expected (), found reference
+ |
+ = note: expected type `()`
+ found type `&_`
+
+error: aborting due to previous error(s)
+
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 foo() -> usize {
+ 3
+}
+
+fn bar() {
+ foo()
+}
+
+fn main() {
+ bar()
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/unexpected-return-on-unit.rs:19:5
+ |
+19 | foo()
+ | ^^^^^ expected (), found usize
+ |
+ = note: expected type `()`
+ found type `usize`
+help: did you mean to add a semicolon here?
+ | foo();
+help: possibly return type missing here?
+ | fn bar() -> usize {
+
+error: aborting due to previous error(s)
+
13 | fn plus_one(x: i32) -> i32 {
| ____________________________^
14 | | x + 1;
+ | | - help: consider removing this semicolon
15 | | }
| |_^ expected i32, found ()
|
= note: expected type `i32`
found type `()`
-help: consider removing this semicolon:
- --> $DIR/coercion-missing-tail-expected-type.rs:14:10
- |
-14 | x + 1;
- | ^
error[E0308]: mismatched types
--> $DIR/coercion-missing-tail-expected-type.rs:17:29
17 | fn foo() -> Result<u8, u64> {
| _____________________________^
18 | | Ok(1);
+ | | - help: consider removing this semicolon
19 | | }
| |_^ expected enum `std::result::Result`, found ()
|
= note: expected type `std::result::Result<u8, u64>`
found type `()`
-help: consider removing this semicolon:
- --> $DIR/coercion-missing-tail-expected-type.rs:18:10
- |
-18 | Ok(1);
- | ^
error: aborting due to previous error(s)
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+ for x in 0..3 {
+ x //~ ERROR mismatched types
+ //~| NOTE expected ()
+ //~| NOTE expected type `()`
+ }
+}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/for-loop-has-unit-body.rs:13:9
+ |
+13 | x //~ ERROR mismatched types
+ | ^ expected (), found integral variable
+ |
+ = note: expected type `()`
+ found type `{integer}`
+
+error: aborting due to previous error(s)
+
error[E0308]: mismatched types
--> $DIR/issue-19109.rs:14:5
|
+13 | fn function(t: &mut Trait) {
+ | - help: possibly return type missing here? `-> *mut Trait `
14 | t as *mut Trait
| ^^^^^^^^^^^^^^^ expected (), found *-ptr
|
--> $DIR/token-error-correct-3.rs:25:13
|
25 | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mismatched types
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: did you mean to add a semicolon here? `;`
+ | |
+ | expected (), found enum `std::result::Result`
|
= note: expected type `()`
found type `std::result::Result<bool, std::io::Error>`