From 2560646d9114c76b719fdf853864f5b8d9874f2b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 27 Oct 2015 13:10:41 +0100 Subject: [PATCH] Diagnostic: "`if let` arm with incompatible type" --- src/librustc/middle/infer/error_reporting.rs | 9 ++++++--- src/librustc/middle/infer/mod.rs | 9 ++++++--- src/librustc_typeck/check/_match.rs | 2 +- src/test/compile-fail/if-let-arm-types.rs | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 src/test/compile-fail/if-let-arm-types.rs diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 802b09a1a65..38c7ddc4a3d 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -491,8 +491,11 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { self.check_and_note_conflicting_crates(terr, trace.origin.span()); match trace.origin { - infer::MatchExpressionArm(_, arm_span) => - self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"), + infer::MatchExpressionArm(_, arm_span, source) => match source { + hir::MatchSource::IfLetDesugar{..} => + self.tcx.sess.span_note(arm_span, "`if let` arm with an incompatible type"), + _ => self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"), + }, _ => () } } @@ -1659,7 +1662,7 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { "trait type parameters matches those \ specified on the impl" } - infer::MatchExpressionArm(_, _) => { + infer::MatchExpressionArm(_, _, _) => { "match arms have compatible types" } infer::IfExpression(_) => { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 84673b01033..f80c486f237 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -135,7 +135,7 @@ pub enum TypeOrigin { RelateOutputImplTypes(Span), // Computing common supertype in the arms of a match expression - MatchExpressionArm(Span, Span), + MatchExpressionArm(Span, Span, hir::MatchSource), // Computing common supertype in an if expression IfExpression(Span), @@ -159,7 +159,10 @@ impl TypeOrigin { &TypeOrigin::ExprAssignable(_) => "mismatched types", &TypeOrigin::RelateTraitRefs(_) => "mismatched traits", &TypeOrigin::MethodCompatCheck(_) => "method not compatible with trait", - &TypeOrigin::MatchExpressionArm(_, _) => "match arms have incompatible types", + &TypeOrigin::MatchExpressionArm(_, _, source) => match source { + hir::MatchSource::IfLetDesugar{..} => "`if let` arms have incompatible types", + _ => "match arms have incompatible types", + }, &TypeOrigin::IfExpression(_) => "if and else have incompatible types", &TypeOrigin::IfExpressionWithNoElse(_) => "if may be missing an else clause", &TypeOrigin::RangeExpression(_) => "start and end of range have incompatible types", @@ -1534,7 +1537,7 @@ impl TypeOrigin { RelateTraitRefs(span) => span, RelateSelfType(span) => span, RelateOutputImplTypes(span) => span, - MatchExpressionArm(match_span, _) => match_span, + MatchExpressionArm(match_span, _, _) => match_span, IfExpression(span) => span, IfExpressionWithNoElse(span) => span, RangeExpression(span) => span, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index db5dd19c923..dc6a209d4fc 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -499,7 +499,7 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, result_ty, ), _ => ( - infer::MatchExpressionArm(expr.span, arm.body.span), + infer::MatchExpressionArm(expr.span, arm.body.span, match_src), result_ty, bty, ), diff --git a/src/test/compile-fail/if-let-arm-types.rs b/src/test/compile-fail/if-let-arm-types.rs new file mode 100644 index 00000000000..d179ec015d2 --- /dev/null +++ b/src/test/compile-fail/if-let-arm-types.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types + () + } else { //~ NOTE: `if let` arm with an incompatible type + 1 + }; +}