refactor and fix this-expression-has-type note

This commit is contained in:
Mazdak Farrokhzad 2019-12-30 09:08:18 +01:00
parent f35840f77c
commit d7e2f3aee5
18 changed files with 135 additions and 104 deletions

View File

@ -582,6 +582,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) {
match cause.code {
ObligationCauseCode::Pattern { span, ty } => {
let ty = self.resolve_vars_if_possible(&ty);
if ty.is_suggestable() {
// don't show type `_`
err.span_label(span, format!("this expression has type `{}`", ty));

View File

@ -30,16 +30,48 @@ pointers. If you encounter this error you should try to avoid dereferencing the
You can read more about trait objects in the Trait Objects section of the Reference: \
https://doc.rust-lang.org/reference/types.html#trait-objects";
/// Information about the expected type at the top level of type checking a pattern.
///
/// **NOTE:** This is only for use by diagnostics. Do NOT use for type checking logic!
#[derive(Copy, Clone)]
struct TopInfo<'tcx> {
/// The `expected` type at the top level of type checking a pattern.
expected: Ty<'tcx>,
/// The span giving rise to the `expected` type, if one could be provided.
///
/// This is the span of the scrutinee as in:
///
/// - `match scrutinee { ... }`
/// - `let _ = scrutinee;`
///
/// This is used to point to add context in type errors.
/// In the following example, `span` corresponds to the `a + b` expression:
///
/// ```text
/// error[E0308]: mismatched types
/// --> src/main.rs:L:C
/// |
/// L | let temp: usize = match a + b {
/// | ----- this expression has type `usize`
/// L | Ok(num) => num,
/// | ^^^^^^^ expected `usize`, found enum `std::result::Result`
/// |
/// = note: expected type `usize`
/// found type `std::result::Result<_, _>`
/// ```
span: Option<Span>,
}
impl<'tcx> FnCtxt<'_, 'tcx> {
fn demand_eqtype_pat_diag(
&self,
cause_span: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
match_expr_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
let cause = if let Some(span) = match_expr_span {
self.cause(cause_span, Pattern { span, ty: expected })
let cause = if let Some(span) = ti.span {
self.cause(cause_span, Pattern { span, ty: ti.expected })
} else {
self.misc(cause_span)
};
@ -51,41 +83,33 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
cause_span: Span,
expected: Ty<'tcx>,
actual: Ty<'tcx>,
match_expr_span: Option<Span>,
ti: TopInfo<'tcx>,
) {
self.demand_eqtype_pat_diag(cause_span, expected, actual, match_expr_span)
.map(|mut err| err.emit());
self.demand_eqtype_pat_diag(cause_span, expected, actual, ti).map(|mut err| err.emit());
}
}
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Type check the given top level pattern against the `expected` type.
///
/// If a `Some(span)` is provided, then the `span` represents the scrutinee's span.
/// The scrutinee is found in e.g. `match scrutinee { ... }` and `let pat = scrutinee;`.
pub fn check_pat_top(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, span: Option<Span>) {
let def_bm = BindingMode::BindByValue(hir::Mutability::Not);
self.check_pat(pat, expected, def_bm, span);
self.check_pat(pat, expected, def_bm, TopInfo { expected, span });
}
/// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
/// expression arm guard, and it points to the match discriminant to add context in type errors.
/// In the following example, `discrim_span` corresponds to the `a + b` expression:
/// Type check the given `pat` against the `expected` type
/// with the provided `def_bm` (default binding mode).
///
/// ```text
/// error[E0308]: mismatched types
/// --> src/main.rs:5:9
/// |
/// 4 | let temp: usize = match a + b {
/// | ----- this expression has type `usize`
/// 5 | Ok(num) => num,
/// | ^^^^^^^ expected `usize`, found enum `std::result::Result`
/// |
/// = note: expected type `usize`
/// found type `std::result::Result<_, _>`
/// ```
/// Outside of this module, `check_pat_top` should always be used.
/// Conversely, inside this module, `check_pat_top` should never be used.
fn check_pat(
&self,
pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) {
debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
@ -98,48 +122,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = match pat.kind {
PatKind::Wild => expected,
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span),
PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti),
PatKind::Range(begin, end, _) => {
match self.check_pat_range(pat.span, begin, end, expected, discrim_span) {
match self.check_pat_range(pat.span, begin, end, expected, ti) {
None => return,
Some(ty) => ty,
}
}
PatKind::Binding(ba, var_id, _, sub) => {
self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, discrim_span)
self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, ti)
}
PatKind::TupleStruct(ref qpath, subpats, ddpos) => {
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
}
PatKind::TupleStruct(ref qpath, subpats, ddpos) => self.check_pat_tuple_struct(
pat,
qpath,
subpats,
ddpos,
expected,
def_bm,
discrim_span,
),
PatKind::Path(ref qpath) => {
self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
}
PatKind::Struct(ref qpath, fields, etc) => {
self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
}
PatKind::Or(pats) => {
for pat in pats {
self.check_pat(pat, expected, def_bm, discrim_span);
self.check_pat(pat, expected, def_bm, ti);
}
expected
}
PatKind::Tuple(elements, ddpos) => {
self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
}
PatKind::Box(inner) => {
self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, ti)
}
PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, def_bm, ti),
PatKind::Ref(inner, mutbl) => {
self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span)
self.check_pat_ref(pat, inner, mutbl, expected, def_bm, ti)
}
PatKind::Slice(before, slice, after) => {
self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span)
self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, ti)
}
};
@ -316,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
lt: &hir::Expr<'tcx>,
expected: Ty<'tcx>,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
// We've already computed the type above (when checking for a non-ref pat),
// so avoid computing it again.
@ -350,7 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// then that's equivalent to there existing a LUB.
if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
err.emit_unless(
discrim_span
ti.span
.filter(|&s| {
// In the case of `if`- and `while`-expressions we've already checked
// that `scrutinee: bool`. We know that the pattern is `true`,
@ -370,7 +386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs: &'tcx hir::Expr<'tcx>,
rhs: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Option<Ty<'tcx>> {
let lhs_ty = self.check_expr(lhs);
let rhs_ty = self.check_expr(rhs);
@ -391,7 +407,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Subtyping doesn't matter here, as the value is some kind of scalar.
let demand_eqtype = |x_span, y_span, x_ty, y_ty| {
self.demand_eqtype_pat_diag(x_span, expected, x_ty, discrim_span).map(|mut err| {
self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti).map(|mut err| {
self.endpoint_has_type(&mut err, y_span, y_ty);
err.emit();
});
@ -465,7 +481,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sub: Option<&'tcx Pat<'tcx>>,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
// Determine the binding mode...
let bm = match ba {
@ -495,17 +511,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected
}
};
self.demand_eqtype_pat(pat.span, eq_ty, local_ty, discrim_span);
self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti);
// If there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be.
if var_id != pat.hir_id {
let vt = self.local_ty(pat.span, var_id).decl_ty;
self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
self.demand_eqtype_pat(pat.span, vt, local_ty, ti);
}
if let Some(p) = sub {
self.check_pat(&p, expected, def_bm, discrim_span);
self.check_pat(&p, expected, def_bm, ti);
}
local_ty
@ -584,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
etc: bool,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
// Resolve the path and check the definition for errors.
let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
@ -592,25 +608,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
variant_ty
} else {
for field in fields {
self.check_pat(&field.pat, self.tcx.types.err, def_bm, discrim_span);
self.check_pat(&field.pat, self.tcx.types.err, def_bm, ti);
}
return self.tcx.types.err;
};
// Type-check the path.
self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
// Type-check subpatterns.
if self.check_struct_pat_fields(
pat_ty,
pat.hir_id,
pat.span,
variant,
fields,
etc,
def_bm,
discrim_span,
) {
if self
.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm, ti)
{
pat_ty
} else {
self.tcx.types.err
@ -660,12 +669,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ddpos: Option<usize>,
expected: Ty<'tcx>,
def_bm: BindingMode,
match_arm_pat_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let on_error = || {
for pat in subpats {
self.check_pat(&pat, tcx.types.err, def_bm, match_arm_pat_span);
self.check_pat(&pat, tcx.types.err, def_bm, ti);
}
};
let report_unexpected_res = |res: Res| {
@ -726,7 +735,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
// Type-check the tuple struct pattern against the expected type.
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, match_arm_pat_span);
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti);
let had_err = diag.is_some();
diag.map(|mut err| err.emit());
@ -740,7 +749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
self.check_pat(&subpat, field_ty, def_bm, match_arm_pat_span);
self.check_pat(&subpat, field_ty, def_bm, ti);
self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
}
@ -844,7 +853,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ddpos: Option<usize>,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let mut expected_len = elements.len();
@ -871,12 +880,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// further errors being emitted when using the bindings. #50333
let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat(elem, &tcx.types.err, def_bm, discrim_span);
self.check_pat(elem, &tcx.types.err, def_bm, ti);
}
tcx.mk_tup(element_tys_iter)
} else {
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, discrim_span);
self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, ti);
}
pat_ty
}
@ -891,7 +900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &'tcx [hir::FieldPat<'tcx>],
etc: bool,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> bool {
let tcx = self.tcx;
@ -941,7 +950,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
self.check_pat(&field.pat, field_ty, def_bm, discrim_span);
self.check_pat(&field.pat, field_ty, def_bm, ti);
}
let mut unmentioned_fields = variant
@ -1118,7 +1127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
inner: &'tcx Pat<'tcx>,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, &inner) {
@ -1129,12 +1138,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: inner.span,
});
let box_ty = tcx.mk_box(inner_ty);
self.demand_eqtype_pat(span, expected, box_ty, discrim_span);
self.demand_eqtype_pat(span, expected, box_ty, ti);
(box_ty, inner_ty)
} else {
(tcx.types.err, tcx.types.err)
};
self.check_pat(&inner, inner_ty, def_bm, discrim_span);
self.check_pat(&inner, inner_ty, def_bm, ti);
box_ty
}
@ -1145,7 +1154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
mutbl: hir::Mutability,
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
let expected = self.shallow_resolve(expected);
@ -1180,7 +1189,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
(tcx.types.err, tcx.types.err)
};
self.check_pat(&inner, inner_ty, def_bm, discrim_span);
self.check_pat(&inner, inner_ty, def_bm, ti);
rptr_ty
}
@ -1209,7 +1218,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
after: &'tcx [&'tcx Pat<'tcx>],
expected: Ty<'tcx>,
def_bm: BindingMode,
discrim_span: Option<Span>,
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let err = self.tcx.types.err;
let expected = self.structurally_resolved_type(span, expected);
@ -1234,15 +1243,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type check all the patterns before `slice`.
for elt in before {
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
self.check_pat(&elt, inner_ty, def_bm, ti);
}
// Type check the `slice`, if present, against its expected type.
if let Some(slice) = slice {
self.check_pat(&slice, slice_ty, def_bm, discrim_span);
self.check_pat(&slice, slice_ty, def_bm, ti);
}
// Type check the elements after `slice`, if present.
for elt in after {
self.check_pat(&elt, inner_ty, def_bm, discrim_span);
self.check_pat(&elt, inner_ty, def_bm, ti);
}
expected
}

View File

@ -44,7 +44,9 @@ error[E0308]: mismatched types
--> $DIR/destructure-trait-ref.rs:42:13
|
LL | let box box x = box 1isize as Box<dyn T>;
| ^^^^^ expected trait `T`, found struct `std::boxed::Box`
| ^^^^^ ------------------------ this expression has type `std::boxed::Box<dyn T>`
| |
| expected trait `T`, found struct `std::boxed::Box`
|
= note: expected trait object `dyn T`
found struct `std::boxed::Box<_>`

View File

@ -8,7 +8,7 @@ error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision.rs:5:13
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `std::ops::Range<{integer}>`
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [_, 99.., _] => {},
| ^^ expected struct `std::ops::Range`, found integer
|

View File

@ -14,7 +14,7 @@ error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision2.rs:5:13
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `std::ops::Range<{integer}>`
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [_, 99..] => {},
| ^^ expected struct `std::ops::Range`, found integer
|

View File

@ -8,7 +8,7 @@ error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:12
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `std::ops::Range<{integer}>`
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| ^ expected struct `std::ops::Range`, found integer
|
@ -19,7 +19,7 @@ error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:15
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this expression has type `std::ops::Range<{integer}>`
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| ^^ --- this is of type `{integer}`
| |
@ -32,7 +32,7 @@ error[E0308]: mismatched types
--> $DIR/exclusive_range_pattern_syntax_collision3.rs:5:19
|
LL | match [5..4, 99..105, 43..44] {
| ----------------------- this match expression has type `std::ops::Range<{integer}>`
| ----------------------- this expression has type `[std::ops::Range<{integer}>; 3]`
LL | [..9, 99..100, _] => {},
| -- ^^^ expected struct `std::ops::Range`, found integer
| |

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-15896.rs:11:11
|
LL | let u = match e {
| - this expression has type `main::R`
| - this expression has type `main::E`
LL | E::B(
LL | Tau{t: x},
| ^^^^^^^^^ expected enum `main::R`, found struct `main::Tau`

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-16338.rs:7:9
|
LL | let Slice { data: data, len: len } = "foo";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `str`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----- this expression has type `&str`
| |
| expected `str`, found struct `Slice`
|

View File

@ -9,6 +9,8 @@ LL | (0, ref y) | (y, 0) => {}
error[E0308]: mismatched types
--> $DIR/E0409.rs:5:23
|
LL | match x {
| - this expression has type `({integer}, {integer})`
LL | (0, ref y) | (y, 0) => {}
| ^ expected `&{integer}`, found integer

View File

@ -94,7 +94,9 @@ error[E0308]: mismatched types
--> $DIR/already-bound-name.rs:33:31
|
LL | let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
| ^ expected integer, found enum `E`
| ^ ------- this expression has type `E<E<{integer}>>`
| |
| expected integer, found enum `E`
|
= note: expected type `{integer}`
found type `E<{integer}>`

View File

@ -60,7 +60,9 @@ error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:13:25
|
LL | let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
| ^^^^^^^^^ types differ in mutability
| ^^^^^^^^^ ------ this expression has type `std::result::Result<&u8, &mut u8>`
| |
| types differ in mutability
|
= note: expected type `&&u8`
found type `&mut &mut u8`
@ -69,7 +71,9 @@ error[E0308]: mismatched types
--> $DIR/inconsistent-modes.rs:16:31
|
LL | let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
| ^^^^^^^^^ types differ in mutability
| ^^^^^^^^^ ----------- this expression has type `std::result::Result<({integer}, &{integer}), (_, _)>`
| |
| types differ in mutability
|
= note: expected type `&{integer}`
found type `&mut _`

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/or-pattern-mismatch.rs:3:68
|
LL | fn main() { match Blah::A(1, 1, 2) { Blah::A(_, x, y) | Blah::B(x, y) => { } } }
| ^ expected `usize`, found `isize`
| ---------------- this expression has type `Blah` ^ expected `usize`, found `isize`
error: aborting due to previous error

View File

@ -425,8 +425,9 @@ error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:23:16
|
LL | if let X.. .0 = 0 {}
| - ^^ expected integer, found floating-point number
| |
| - ^^ - this expression has type `u8`
| | |
| | expected integer, found floating-point number
| this is of type `u8`
error[E0029]: only char and numeric types are allowed in range patterns
@ -457,8 +458,9 @@ error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:36:16
|
LL | if let X..=.0 = 0 {}
| - ^^ expected integer, found floating-point number
| |
| - ^^ - this expression has type `u8`
| | |
| | expected integer, found floating-point number
| this is of type `u8`
error[E0029]: only char and numeric types are allowed in range patterns
@ -489,8 +491,9 @@ error[E0308]: mismatched types
--> $DIR/recover-range-pats.rs:52:17
|
LL | if let X... .0 = 0 {}
| - ^^ expected integer, found floating-point number
| |
| - ^^ - this expression has type `u8`
| | |
| | expected integer, found floating-point number
| this is of type `u8`
error[E0029]: only char and numeric types are allowed in range patterns

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/pat-struct-field-expr-has-type.rs:7:16
|
LL | match (S { f: 42 }) {
| ------------- this expression has type `u8`
| ------------- this expression has type `S`
LL | S { f: Ok(_) } => {}
| ^^^^^ expected `u8`, found enum `std::result::Result`
|

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/pattern-tyvar.rs:5:18
|
LL | match t {
| - this expression has type `std::option::Option<std::vec::Vec<isize>>`
| - this expression has type `Bar`
LL | Bar::T1(_, Some::<isize>(x)) => {
| ^^^^^^^^^^^^^^^^ expected struct `std::vec::Vec`, found `isize`
|

View File

@ -23,18 +23,24 @@ LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:7:32
|
LL | match x {
| - this expression has type `Opts`
LL | Opts::A(ref i) | Opts::B(i) => {}
| ^ expected `&isize`, found `isize`
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:16:32
|
LL | match x {
| - this expression has type `Opts`
LL | Opts::A(ref i) | Opts::B(i) => {}
| ^ expected `&isize`, found `isize`
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-binding-mode.rs:25:36
|
LL | match x {
| - this expression has type `Opts`
LL | Opts::A(ref mut i) | Opts::B(ref i) => {}
| ^^^^^ types differ in mutability
|

View File

@ -86,6 +86,8 @@ LL | (CONST1, _) | (_, Const2) => ()
error[E0308]: mismatched types
--> $DIR/resolve-inconsistent-names.rs:19:19
|
LL | match x {
| - this expression has type `(E, E)`
LL | (A, B) | (ref B, c) | (c, A) => ()
| ^^^^^ expected enum `E`, found `&E`

View File

@ -697,7 +697,7 @@ error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:86:12
|
LL | if let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
| |
| expected `bool`, found struct `std::ops::Range`
|
@ -885,7 +885,7 @@ error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:150:15
|
LL | while let Range { start: true, end } = t..&&false {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `bool`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool`
| |
| expected `bool`, found struct `std::ops::Range`
|