From b64046a5b072a34a0940785a9301669a2ea00031 Mon Sep 17 00:00:00 2001 From: Jakub Wieczorek Date: Sat, 31 May 2014 00:16:33 +0200 Subject: [PATCH] Make the match arm type mismatch message point to the arm's span Fixes #11319 --- src/librustc/middle/typeck/check/_match.rs | 2 +- .../middle/typeck/infer/error_reporting.rs | 10 ++++++++-- src/librustc/middle/typeck/infer/mod.rs | 10 +++++----- src/test/compile-fail/issue-11319.rs | 19 +++++++++++++++++++ 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/issue-11319.rs diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 072b4ea7fe1..6520a774ad4 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -87,7 +87,7 @@ pub fn check_match(fcx: &FnCtxt, result_ty = infer::common_supertype( fcx.infcx(), - infer::MatchExpression(expr.span), + infer::MatchExpressionArm(expr.span, arm.body.span), true, // result_ty is "expected" here result_ty, bty); diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index ec7f42313bb..c5c3e90d5ea 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -346,7 +346,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> { infer::ExprAssignable(_) => "mismatched types", infer::RelateTraitRefs(_) => "mismatched traits", infer::RelateSelfType(_) => "mismatched types", - infer::MatchExpression(_) => "match arms have incompatible types", + infer::MatchExpressionArm(_, _) => "match arms have incompatible types", infer::IfExpression(_) => "if and else have incompatible types", }; @@ -356,6 +356,12 @@ impl<'a> ErrorReporting for InferCtxt<'a> { message_root_str, expected_found_str, ty::type_err_to_str(self.tcx, terr)).as_slice()); + + match trace.origin { + infer::MatchExpressionArm(_, arm_span) => + self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"), + _ => () + } } fn report_and_explain_type_error(&self, @@ -1281,7 +1287,7 @@ impl<'a> ErrorReportingHelpers for InferCtxt<'a> { infer::RelateSelfType(_) => { format!("type matches impl") } - infer::MatchExpression(_) => { + infer::MatchExpressionArm(_, _) => { format!("match arms have compatible types") } infer::IfExpression(_) => { diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index fa52ef5dab6..e81e2713cd4 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -116,8 +116,8 @@ pub enum TypeOrigin { // Relating trait refs when resolving vtables RelateSelfType(Span), - // Computing common supertype in a match expression - MatchExpression(Span), + // Computing common supertype in the arms of a match expression + MatchExpressionArm(Span, Span), // Computing common supertype in an if expression IfExpression(Span), @@ -831,7 +831,7 @@ impl TypeOrigin { Misc(span) => span, RelateTraitRefs(span) => span, RelateSelfType(span) => span, - MatchExpression(span) => span, + MatchExpressionArm(match_span, _) => match_span, IfExpression(span) => span, } } @@ -853,8 +853,8 @@ impl Repr for TypeOrigin { RelateSelfType(a) => { format!("RelateSelfType({})", a.repr(tcx)) } - MatchExpression(a) => { - format!("MatchExpression({})", a.repr(tcx)) + MatchExpressionArm(a, b) => { + format!("MatchExpressionArm({}, {})", a.repr(tcx), b.repr(tcx)) } IfExpression(a) => { format!("IfExpression({})", a.repr(tcx)) diff --git a/src/test/compile-fail/issue-11319.rs b/src/test/compile-fail/issue-11319.rs new file mode 100644 index 00000000000..1d9250305ef --- /dev/null +++ b/src/test/compile-fail/issue-11319.rs @@ -0,0 +1,19 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + match Some(10) { + //~^ ERROR match arms have incompatible types: expected `bool` but found `()` + Some(5) => false, + Some(2) => true, + None => (), //~ NOTE match arm with an incompatible type + _ => true + } +}