diff options
| author | bors <bors@rust-lang.org> | 2015-10-28 06:00:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-10-28 06:00:19 +0000 |
| commit | 88fade54e163f899befc7d5ec09ce5f17fe57555 (patch) | |
| tree | baadcf9e6c04d2209f7cf1c36e97ea49e48286d5 | |
| parent | 8974297b4a533cc6e04a1a6f0b32f2fe9e481d78 (diff) | |
| parent | 2560646d9114c76b719fdf853864f5b8d9874f2b (diff) | |
| download | rust-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.rs | 9 | ||||
| -rw-r--r-- | src/librustc/middle/infer/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc_typeck/check/_match.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/if-let-arm-types.rs | 17 |
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 + }; +} |
