]> git.lizzy.rs Git - rust.git/commitdiff
refactor and fix this-expression-has-type note
authorMazdak Farrokhzad <twingoow@gmail.com>
Mon, 30 Dec 2019 08:08:18 +0000 (09:08 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Mon, 30 Dec 2019 13:05:17 +0000 (14:05 +0100)
18 files changed:
src/librustc/infer/error_reporting/mod.rs
src/librustc_typeck/check/pat.rs
src/test/ui/destructure-trait-ref.stderr
src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision.stderr
src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision2.stderr
src/test/ui/exclusive-range/exclusive_range_pattern_syntax_collision3.stderr
src/test/ui/issues/issue-15896.stderr
src/test/ui/issues/issue-16338.stderr
src/test/ui/mismatched_types/E0409.stderr
src/test/ui/or-patterns/already-bound-name.stderr
src/test/ui/or-patterns/inconsistent-modes.stderr
src/test/ui/or-patterns/or-pattern-mismatch.stderr
src/test/ui/parser/recover-range-pats.stderr
src/test/ui/pattern/pat-struct-field-expr-has-type.stderr
src/test/ui/pattern/pattern-tyvar.stderr
src/test/ui/resolve/resolve-inconsistent-binding-mode.stderr
src/test/ui/resolve/resolve-inconsistent-names.stderr
src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr

index ae629adf8fb5384451ab6e1fa8f230cbe1b5dcf5..5c561a87b0547b8caf45fa16b47afe7ab0e5cb32 100644 (file)
@@ -582,6 +582,7 @@ fn note_error_origin(
     ) {
         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));
index b18a7ac75a282cb2a2b0af6c3f0ef49ad95ff2fd..a3ef41f0de5b59d9f306a41047a8d13919ce9df5 100644 (file)
 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 @@ fn demand_eqtype_pat(
         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 @@ fn check_pat(
 
         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 @@ fn check_pat_lit(
         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 @@ fn check_pat_lit(
         // 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 @@ fn check_pat_range(
         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 @@ fn check_pat_range(
 
         // 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 @@ fn check_pat_ident(
         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 @@ fn check_pat_ident(
                 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 @@ fn check_pat_struct(
         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 @@ fn check_pat_struct(
             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 @@ fn check_pat_tuple_struct(
         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 @@ fn check_pat_tuple_struct(
         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 @@ fn check_pat_tuple_struct(
             };
             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 @@ fn check_pat_tuple(
         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 @@ fn check_pat_tuple(
             // 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 @@ fn check_struct_pat_fields(
         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 @@ fn check_struct_pat_fields(
                 }
             };
 
-            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 @@ fn check_pat_box(
         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 @@ fn check_pat_box(
                 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 @@ fn check_pat_ref(
         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 @@ fn check_pat_ref(
         } 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 @@ fn check_pat_slice(
         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 @@ fn check_pat_slice(
 
         // 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
     }
index f77291969d2db7610957f27101ee855be277ef52..c78166f411d2855d8c3fb287720631bc7b7fe71c 100644 (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<_>`
index 580c80f66c3ca488c6c03859def0d024244168fe..76ae7241ff2771959a918eccf81ac291061ea71b 100644 (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
    |
index 88d45f16ff6c9bb357391c0704d7ca636a610129..5c96f8041feb26cf84ac88905d3518225d3e173e 100644 (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
    |
index 6abba7d7cab10a6bb1a367b3d14ed96f56170c48..17e10324db18187df60dbbd0010c941f59070a18 100644 (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
    |               |
index 0ad49ea1e7fe5efdf69ae78e084f329bcec755ac..b3f0907b81d2595406b87aa7f099a2e02c35be0a 100644 (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`
index 03eb93821b5f22ee345de89e8ea3def019d1b1cc..6878600b0298338535d7e1dd7216e62e5be0a670 100644 (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`
    |
index 098fd74a39da6e88a6a46904a15a7536c611fd9a..2306fb352738f80ef17a57d06ce6e1f8522f1e4c 100644 (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
 
index 360699a8739384661db650427a08400aea2f9d8c..948c91370d0d41496df712a5588f239ab8457917 100644 (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}>`
index 0a36ed5548e5b7f6e3a04d5a4960fa5944ce938e..80d914b8d236cfefd7dd1ff12295e50220fc2b72 100644 (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 _`
index 253f3ef772525db32cb7f74a3983aab3310c1957..bc288e06250751d914801818d0240c36253341cb 100644 (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
 
index 50a44192707f0f88ceac33c6aa6e0629f3ec3c84..3fed64c191a8a2de52c518513935c66e64aa1cd6 100644 (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
index 7962c376a92a833437cbd36997b09545f293e10c..d57a8a0dbc1813ef299b788abad195e00215ac4c 100644 (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`
    |
index 1e671e8d8eff3315abb6ff9e2ff86a0b8da99375..15425da69bcc48595ddf2221f181ae5aa6c4d812 100644 (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`
    |
index 58455024d382757e37e2b46f5e23e96a88de6584..61d1001ce9154f154e0665d3b26b9c3a653a7ecd 100644 (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
    |
index 271495012dab5026b80de48a1daa0076b625cfcd..5c87f7c684f3b0695c6c4b63f76e80a8cc2ae398 100644 (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`
 
index a69011d7450809df657549b3b8630aaaeea69f12..7170adca60dc345b4c6516512a59d687ed7e3340 100644 (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`
    |