about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-10-28 06:00:19 +0000
committerbors <bors@rust-lang.org>2015-10-28 06:00:19 +0000
commit88fade54e163f899befc7d5ec09ce5f17fe57555 (patch)
treebaadcf9e6c04d2209f7cf1c36e97ea49e48286d5
parent8974297b4a533cc6e04a1a6f0b32f2fe9e481d78 (diff)
parent2560646d9114c76b719fdf853864f5b8d9874f2b (diff)
downloadrust-88fade54e163f899befc7d5ec09ce5f17fe57555.tar.gz
rust-88fade54e163f899befc7d5ec09ce5f17fe57555.zip
Auto merge of #29398 - jonas-schievink:if-let-arms, r=arielb1
Closes #29314

The code from #29314:
```rust
fn main() {
    if let Some(b) = None {
        ()
    } else {
        1
    };
}
```
now prints this:
```
test.rs:2:5: 6:6 error: `if let` arms have incompatible types: expected `()`, found `_` (expected (), found integral variable) [E0308]
test.rs:2     if let Some(b) = None {
test.rs:3         ()
test.rs:4     } else {
test.rs:5         1
test.rs:6     };
test.rs:2:5: 6:6 help: run `rustc --explain E0308` to see a detailed explanation
test.rs:4:12: 6:6 note: `if let` arm with an incompatible type
test.rs:4     } else {
test.rs:5         1
test.rs:6     };
error: aborting due to previous error
```
-rw-r--r--src/librustc/middle/infer/error_reporting.rs9
-rw-r--r--src/librustc/middle/infer/mod.rs9
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/test/compile-fail/if-let-arm-types.rs17
4 files changed, 30 insertions, 7 deletions
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 <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() {
+    if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types
+        ()
+    } else {                //~ NOTE: `if let` arm with an incompatible type
+        1
+    };
+}