Fixes #19991.
expr: &ast::Expr,
discrim: &ast::Expr,
arms: &[ast::Arm],
- expected: Expectation<'tcx>) {
+ expected: Expectation<'tcx>,
+ match_src: ast::MatchSource) {
let tcx = fcx.ccx.tcx;
let discrim_ty = fcx.infcx().next_ty_var();
if ty::type_is_error(result_ty) || ty::type_is_error(bty) {
ty::mk_err()
} else {
+ let (origin, expected, found) = match match_src {
+ /* if-let construct without an else block */
+ ast::MatchIfLetDesugar(contains_else_arm) if !contains_else_arm => (
+ infer::IfExpressionWithNoElse(expr.span),
+ bty,
+ result_ty,
+ ),
+ _ => (
+ infer::MatchExpressionArm(expr.span, arm.body.span),
+ result_ty,
+ bty,
+ ),
+ };
+
infer::common_supertype(
fcx.infcx(),
- infer::MatchExpressionArm(expr.span, arm.body.span),
- true, // result_ty is "expected" here
- result_ty,
- bty
+ origin,
+ true,
+ expected,
+ found,
)
}
});
fcx.write_nil(id);
}
}
- ast::ExprMatch(ref discrim, ref arms, _) => {
- _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected);
+ ast::ExprMatch(ref discrim, ref arms, match_src) => {
+ _match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected, match_src);
}
ast::ExprClosure(_, opt_kind, ref decl, ref body) => {
closure::check_expr_closure(fcx, expr, opt_kind, &**decl, &**body, expected);
#[deriving(Clone, Copy, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
pub enum MatchSource {
MatchNormal,
- MatchIfLetDesugar,
+ MatchIfLetDesugar(bool /* contains_else_arm */),
MatchWhileLetDesugar,
}
arms.extend(else_if_arms.into_iter());
arms.push(else_arm);
- let match_expr = fld.cx.expr(span, ast::ExprMatch(expr, arms, ast::MatchIfLetDesugar));
+ let match_expr = fld.cx.expr(span, ast::ExprMatch(expr,
+ arms,
+ ast::MatchIfLetDesugar(elseopt.is_some())));
fld.fold_expr(match_expr)
}
--- /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.
+
+// Test if the sugared if-let construct correctly prints "missing an else clause" when an else
+// clause does not exist, instead of the unsympathetic "match arms have incompatible types"
+
+fn main() {
+ if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause: expected `()`
+ 765i32
+ };
+}