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 ```
This commit is contained in:
commit
88fade54e1
@ -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(_) => {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
),
|
||||
|
17
src/test/compile-fail/if-let-arm-types.rs
Normal file
17
src/test/compile-fail/if-let-arm-types.rs
Normal file
@ -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
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user