about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-06-11 13:15:53 +0200
committerGitHub <noreply@github.com>2020-06-11 13:15:53 +0200
commit298467ee9a7fa1bbc93383c3a67ea569a6e7c22c (patch)
treea8dc5451a4b50b0a62d05c8b03d3a8d5480e7b74
parent3ddf48053e83f4949d00dcaf6eb8d9e28fc6bb95 (diff)
parent6da17d244b08e5f14edd1645fbd07d1f042d00b7 (diff)
downloadrust-298467ee9a7fa1bbc93383c3a67ea569a6e7c22c.tar.gz
rust-298467ee9a7fa1bbc93383c3a67ea569a6e7c22c.zip
Rollup merge of #72380 - lcnr:const_context, r=estebank
Fix `is_const_context`, update `check_for_cast`

A better version of #71477

Adds `fn enclosing_body_owner` and uses it in `is_const_context`.
`is_const_context` now uses the same mechanism as `mir_const_qualif` as it was previously incorrect.
Renames `is_const_context` to `is_inside_const_context`.

I also updated `check_for_cast` in the second commit, so r? @estebank

(I removed one lvl of indentation, so it might be easier to review by hiding whitespace changes)
-rw-r--r--src/librustc_middle/hir/map/mod.rs24
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs2
-rw-r--r--src/librustc_typeck/check/demand.rs396
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/ui/consts/enum-discr-type-err.stderr8
-rw-r--r--src/test/ui/issues/issue-31910.stderr5
-rw-r--r--src/test/ui/numeric/const-scope.stderr10
-rw-r--r--src/test/ui/repeat_count.rs3
-rw-r--r--src/test/ui/repeat_count.stderr21
9 files changed, 228 insertions, 245 deletions
diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index 53e88787323..b1dafb3c885 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
@@ -335,6 +335,16 @@ impl<'hir> Map<'hir> {
         }
     }
 
+    pub fn enclosing_body_owner(&self, hir_id: HirId) -> HirId {
+        for (parent, _) in self.parent_iter(hir_id) {
+            if let Some(body) = self.maybe_body_owned_by(parent) {
+                return self.body_owner(body);
+            }
+        }
+
+        bug!("no `enclosing_body_owner` for hir_id `{}`", hir_id);
+    }
+
     /// Returns the `HirId` that corresponds to the definition of
     /// which this is the body of, i.e., a `fn`, `const` or `static`
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
@@ -537,18 +547,8 @@ impl<'hir> Map<'hir> {
 
     /// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
     /// Used exclusively for diagnostics, to avoid suggestion function calls.
-    pub fn is_const_context(&self, hir_id: HirId) -> bool {
-        let parent_id = self.get_parent_item(hir_id);
-        match self.get(parent_id) {
-            Node::Item(&Item { kind: ItemKind::Const(..) | ItemKind::Static(..), .. })
-            | Node::TraitItem(&TraitItem { kind: TraitItemKind::Const(..), .. })
-            | Node::ImplItem(&ImplItem { kind: ImplItemKind::Const(..), .. })
-            | Node::AnonConst(_) => true,
-            Node::Item(&Item { kind: ItemKind::Fn(ref sig, ..), .. }) => {
-                sig.header.constness == Constness::Const
-            }
-            _ => false,
-        }
+    pub fn is_inside_const_context(&self, hir_id: HirId) -> bool {
+        self.body_const_context(self.local_def_id(self.enclosing_body_owner(hir_id))).is_some()
     }
 
     /// Whether `hir_id` corresponds to a `mod` or a crate.
diff --git a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
index e04ed8b83de..4d4b6fb9386 100644
--- a/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/mutability_errors.rs
@@ -495,7 +495,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let closure_id = hir.as_local_hir_id(self.mir_def_id);
         let fn_call_id = hir.get_parent_node(closure_id);
         let node = hir.get(fn_call_id);
-        let item_id = hir.get_parent_item(fn_call_id);
+        let item_id = hir.enclosing_body_owner(fn_call_id);
         let mut look_at_return = true;
         // If we can detect the expression to be an `fn` call where the closure was an argument,
         // we point at the `fn` definition argument...
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 700b9359d06..7ac88698985 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -15,6 +15,8 @@ use rustc_span::Span;
 
 use super::method::probe;
 
+use std::fmt;
+
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn emit_coerce_suggestions(
         &self,
@@ -670,16 +672,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         checked_ty: Ty<'tcx>,
         expected_ty: Ty<'tcx>,
     ) -> bool {
-        if self.tcx.hir().is_const_context(expr.hir_id) {
-            // Shouldn't suggest `.into()` on `const`s.
-            // FIXME(estebank): modify once we decide to suggest `as` casts
-            return false;
-        }
         if self.tcx.sess.source_map().is_imported(expr.span) {
             // Ignore if span is from within a macro.
             return false;
         }
 
+        let src = if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
+            src
+        } else {
+            return false;
+        };
+
         // If casting this expression to a given numeric type would be appropriate in case of a type
         // mismatch.
         //
@@ -708,6 +711,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             String::new()
         };
+
         if let hir::ExprKind::Call(path, args) = &expr.kind {
             if let (hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)), 1) =
                 (&path.kind, args.len())
@@ -749,222 +753,200 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             checked_ty, expected_ty,
         );
 
-        let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8);
-
-        if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
-            let cast_suggestion = format!(
-                "{}{}{}{} as {}",
-                prefix,
-                if needs_paren { "(" } else { "" },
-                src,
-                if needs_paren { ")" } else { "" },
-                expected_ty,
-            );
-            let try_into_suggestion = format!(
-                "{}{}{}{}.try_into().unwrap()",
-                prefix,
-                if needs_paren { "(" } else { "" },
-                src,
-                if needs_paren { ")" } else { "" },
-            );
-            let into_suggestion = format!(
-                "{}{}{}{}.into()",
-                prefix,
-                if needs_paren { "(" } else { "" },
-                src,
-                if needs_paren { ")" } else { "" },
-            );
-            let suffix_suggestion = format!(
-                "{}{}{}{}",
-                if needs_paren { "(" } else { "" },
-                if let (ty::Int(_) | ty::Uint(_), ty::Float(_)) =
-                    (&expected_ty.kind, &checked_ty.kind,)
-                {
-                    // Remove fractional part from literal, for example `42.0f32` into `42`
-                    let src = src.trim_end_matches(&checked_ty.to_string());
-                    src.split('.').next().unwrap()
+        let with_opt_paren: fn(&dyn fmt::Display) -> String =
+            if expr.precedence().order() < PREC_POSTFIX {
+                |s| format!("({})", s)
+            } else {
+                |s| s.to_string()
+            };
+
+        let cast_suggestion = format!("{}{} as {}", prefix, with_opt_paren(&src), expected_ty);
+        let try_into_suggestion = format!("{}{}.try_into().unwrap()", prefix, with_opt_paren(&src));
+        let into_suggestion = format!("{}{}.into()", prefix, with_opt_paren(&src));
+        let suffix_suggestion = with_opt_paren(&format_args!(
+            "{}{}",
+            if matches!(
+                (&expected_ty.kind, &checked_ty.kind),
+                (ty::Int(_) | ty::Uint(_), ty::Float(_))
+            ) {
+                // Remove fractional part from literal, for example `42.0f32` into `42`
+                let src = src.trim_end_matches(&checked_ty.to_string());
+                src.split('.').next().unwrap()
+            } else {
+                src.trim_end_matches(&checked_ty.to_string())
+            },
+            expected_ty,
+        ));
+        let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| {
+            if let hir::ExprKind::Lit(lit) = &expr.kind { lit.node.is_suffixed() } else { false }
+        };
+
+        let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id);
+        let suggest_to_change_suffix_or_into =
+            |err: &mut DiagnosticBuilder<'_>, is_fallible: bool| {
+                let msg = if literal_is_ty_suffixed(expr) {
+                    &lit_msg
+                } else if in_const_context {
+                    // Do not recommend `into` or `try_into` in const contexts.
+                    return;
+                } else if is_fallible {
+                    &try_msg
                 } else {
-                    src.trim_end_matches(&checked_ty.to_string())
-                },
-                expected_ty,
-                if needs_paren { ")" } else { "" },
-            );
-            let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| {
-                if let hir::ExprKind::Lit(lit) = &expr.kind {
-                    lit.node.is_suffixed()
+                    &msg
+                };
+                let suggestion = if literal_is_ty_suffixed(expr) {
+                    suffix_suggestion.clone()
+                } else if is_fallible {
+                    try_into_suggestion
                 } else {
-                    false
-                }
+                    into_suggestion.clone()
+                };
+                err.span_suggestion(expr.span, msg, suggestion, Applicability::MachineApplicable);
             };
 
-            let suggest_to_change_suffix_or_into =
-                |err: &mut DiagnosticBuilder<'_>, is_fallible: bool| {
+        match (&expected_ty.kind, &checked_ty.kind) {
+            (&ty::Int(ref exp), &ty::Int(ref found)) => {
+                let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                    (Some(exp), Some(found)) if exp < found => true,
+                    (None, Some(8 | 16)) => false,
+                    (None, _) | (_, None) => true,
+                    _ => false,
+                };
+                suggest_to_change_suffix_or_into(err, is_fallible);
+                true
+            }
+            (&ty::Uint(ref exp), &ty::Uint(ref found)) => {
+                let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                    (Some(exp), Some(found)) if exp < found => true,
+                    (None, Some(8 | 16)) => false,
+                    (None, _) | (_, None) => true,
+                    _ => false,
+                };
+                suggest_to_change_suffix_or_into(err, is_fallible);
+                true
+            }
+            (&ty::Int(exp), &ty::Uint(found)) => {
+                let is_fallible = match (exp.bit_width(), found.bit_width()) {
+                    (Some(exp), Some(found)) if found < exp => false,
+                    (None, Some(8)) => false,
+                    _ => true,
+                };
+                suggest_to_change_suffix_or_into(err, is_fallible);
+                true
+            }
+            (&ty::Uint(_), &ty::Int(_)) => {
+                suggest_to_change_suffix_or_into(err, true);
+                true
+            }
+            (&ty::Float(ref exp), &ty::Float(ref found)) => {
+                if found.bit_width() < exp.bit_width() {
+                    suggest_to_change_suffix_or_into(err, false);
+                } else if literal_is_ty_suffixed(expr) {
                     err.span_suggestion(
                         expr.span,
-                        if literal_is_ty_suffixed(expr) {
-                            &lit_msg
-                        } else if is_fallible {
-                            &try_msg
-                        } else {
-                            &msg
-                        },
-                        if literal_is_ty_suffixed(expr) {
-                            suffix_suggestion.clone()
-                        } else if is_fallible {
-                            try_into_suggestion
-                        } else {
-                            into_suggestion.clone()
-                        },
+                        &lit_msg,
+                        suffix_suggestion,
                         Applicability::MachineApplicable,
                     );
-                };
-
-            match (&expected_ty.kind, &checked_ty.kind) {
-                (&ty::Int(ref exp), &ty::Int(ref found)) => {
-                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
-                        (Some(exp), Some(found)) if exp < found => true,
-                        (None, Some(8 | 16)) => false,
-                        (None, _) | (_, None) => true,
-                        _ => false,
-                    };
-                    suggest_to_change_suffix_or_into(err, is_fallible);
-                    true
-                }
-                (&ty::Uint(ref exp), &ty::Uint(ref found)) => {
-                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
-                        (Some(exp), Some(found)) if exp < found => true,
-                        (None, Some(8 | 16)) => false,
-                        (None, _) | (_, None) => true,
-                        _ => false,
-                    };
-                    suggest_to_change_suffix_or_into(err, is_fallible);
-                    true
-                }
-                (&ty::Int(exp), &ty::Uint(found)) => {
-                    let is_fallible = match (exp.bit_width(), found.bit_width()) {
-                        (Some(exp), Some(found)) if found < exp => false,
-                        (None, Some(8)) => false,
-                        _ => true,
-                    };
-                    suggest_to_change_suffix_or_into(err, is_fallible);
-                    true
-                }
-                (&ty::Uint(_), &ty::Int(_)) => {
-                    suggest_to_change_suffix_or_into(err, true);
-                    true
-                }
-                (&ty::Float(ref exp), &ty::Float(ref found)) => {
-                    if found.bit_width() < exp.bit_width() {
-                        suggest_to_change_suffix_or_into(err, false);
-                    } else if literal_is_ty_suffixed(expr) {
-                        err.span_suggestion(
-                            expr.span,
-                            &lit_msg,
-                            suffix_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else if can_cast {
-                        // Missing try_into implementation for `f64` to `f32`
-                        err.span_suggestion(
-                            expr.span,
-                            &format!("{}, producing the closest possible value", cast_msg),
-                            cast_suggestion,
-                            Applicability::MaybeIncorrect, // lossy conversion
-                        );
-                    }
-                    true
+                } else if can_cast {
+                    // Missing try_into implementation for `f64` to `f32`
+                    err.span_suggestion(
+                        expr.span,
+                        &format!("{}, producing the closest possible value", cast_msg),
+                        cast_suggestion,
+                        Applicability::MaybeIncorrect, // lossy conversion
+                    );
                 }
-                (&ty::Uint(_) | &ty::Int(_), &ty::Float(_)) => {
-                    if literal_is_ty_suffixed(expr) {
-                        err.span_suggestion(
-                            expr.span,
-                            &lit_msg,
-                            suffix_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else if can_cast {
-                        // Missing try_into implementation for `{float}` to `{integer}`
-                        err.span_suggestion(
-                            expr.span,
-                            &format!("{}, rounding the float towards zero", msg),
-                            cast_suggestion,
-                            Applicability::MaybeIncorrect, // lossy conversion
-                        );
-                    }
-                    true
+                true
+            }
+            (&ty::Uint(_) | &ty::Int(_), &ty::Float(_)) => {
+                if literal_is_ty_suffixed(expr) {
+                    err.span_suggestion(
+                        expr.span,
+                        &lit_msg,
+                        suffix_suggestion,
+                        Applicability::MachineApplicable,
+                    );
+                } else if can_cast {
+                    // Missing try_into implementation for `{float}` to `{integer}`
+                    err.span_suggestion(
+                        expr.span,
+                        &format!("{}, rounding the float towards zero", msg),
+                        cast_suggestion,
+                        Applicability::MaybeIncorrect, // lossy conversion
+                    );
                 }
-                (&ty::Float(ref exp), &ty::Uint(ref found)) => {
-                    // if `found` is `None` (meaning found is `usize`), don't suggest `.into()`
-                    if exp.bit_width() > found.bit_width().unwrap_or(256) {
-                        err.span_suggestion(
-                            expr.span,
-                            &format!(
-                                "{}, producing the floating point representation of the integer",
-                                msg,
-                            ),
-                            into_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else if literal_is_ty_suffixed(expr) {
-                        err.span_suggestion(
-                            expr.span,
-                            &lit_msg,
-                            suffix_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else {
-                        // Missing try_into implementation for `{integer}` to `{float}`
-                        err.span_suggestion(
-                            expr.span,
-                            &format!(
-                                "{}, producing the floating point representation of the integer,
+                true
+            }
+            (&ty::Float(ref exp), &ty::Uint(ref found)) => {
+                // if `found` is `None` (meaning found is `usize`), don't suggest `.into()`
+                if exp.bit_width() > found.bit_width().unwrap_or(256) {
+                    err.span_suggestion(
+                        expr.span,
+                        &format!(
+                            "{}, producing the floating point representation of the integer",
+                            msg,
+                        ),
+                        into_suggestion,
+                        Applicability::MachineApplicable,
+                    );
+                } else if literal_is_ty_suffixed(expr) {
+                    err.span_suggestion(
+                        expr.span,
+                        &lit_msg,
+                        suffix_suggestion,
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    // Missing try_into implementation for `{integer}` to `{float}`
+                    err.span_suggestion(
+                        expr.span,
+                        &format!(
+                            "{}, producing the floating point representation of the integer,
                                  rounded if necessary",
-                                cast_msg,
-                            ),
-                            cast_suggestion,
-                            Applicability::MaybeIncorrect, // lossy conversion
-                        );
-                    }
-                    true
+                            cast_msg,
+                        ),
+                        cast_suggestion,
+                        Applicability::MaybeIncorrect, // lossy conversion
+                    );
                 }
-                (&ty::Float(ref exp), &ty::Int(ref found)) => {
-                    // if `found` is `None` (meaning found is `isize`), don't suggest `.into()`
-                    if exp.bit_width() > found.bit_width().unwrap_or(256) {
-                        err.span_suggestion(
-                            expr.span,
-                            &format!(
-                                "{}, producing the floating point representation of the integer",
-                                &msg,
-                            ),
-                            into_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else if literal_is_ty_suffixed(expr) {
-                        err.span_suggestion(
-                            expr.span,
-                            &lit_msg,
-                            suffix_suggestion,
-                            Applicability::MachineApplicable,
-                        );
-                    } else {
-                        // Missing try_into implementation for `{integer}` to `{float}`
-                        err.span_suggestion(
-                            expr.span,
-                            &format!(
-                                "{}, producing the floating point representation of the integer, \
-                                 rounded if necessary",
-                                &msg,
-                            ),
-                            cast_suggestion,
-                            Applicability::MaybeIncorrect, // lossy conversion
-                        );
-                    }
-                    true
+                true
+            }
+            (&ty::Float(ref exp), &ty::Int(ref found)) => {
+                // if `found` is `None` (meaning found is `isize`), don't suggest `.into()`
+                if exp.bit_width() > found.bit_width().unwrap_or(256) {
+                    err.span_suggestion(
+                        expr.span,
+                        &format!(
+                            "{}, producing the floating point representation of the integer",
+                            &msg,
+                        ),
+                        into_suggestion,
+                        Applicability::MachineApplicable,
+                    );
+                } else if literal_is_ty_suffixed(expr) {
+                    err.span_suggestion(
+                        expr.span,
+                        &lit_msg,
+                        suffix_suggestion,
+                        Applicability::MachineApplicable,
+                    );
+                } else {
+                    // Missing try_into implementation for `{integer}` to `{float}`
+                    err.span_suggestion(
+                        expr.span,
+                        &format!(
+                            "{}, producing the floating point representation of the integer, \
+                                rounded if necessary",
+                            &msg,
+                        ),
+                        cast_suggestion,
+                        Applicability::MaybeIncorrect, // lossy conversion
+                    );
                 }
-                _ => false,
+                true
             }
-        } else {
-            false
+            _ => false,
         }
     }
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f2aeed4f1e4..18846813c45 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -5091,7 +5091,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) {
-        if self.tcx.hir().is_const_context(expr.hir_id) {
+        if self.tcx.hir().is_inside_const_context(expr.hir_id) {
             // Do not suggest `Box::new` in const context.
             return;
         }
@@ -5128,7 +5128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> bool {
         // Handle #68197.
 
-        if self.tcx.hir().is_const_context(expr.hir_id) {
+        if self.tcx.hir().is_inside_const_context(expr.hir_id) {
             // Do not suggest `Box::new` in const context.
             return false;
         }
diff --git a/src/test/ui/consts/enum-discr-type-err.stderr b/src/test/ui/consts/enum-discr-type-err.stderr
index 492b79e2e60..9834a99b79a 100644
--- a/src/test/ui/consts/enum-discr-type-err.stderr
+++ b/src/test/ui/consts/enum-discr-type-err.stderr
@@ -11,10 +11,6 @@ LL | | }
    | |_- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |             $( $v = $s::V.try_into().unwrap(), )*
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/enum-discr-type-err.rs:18:21
@@ -29,10 +25,6 @@ LL | | }
    | |_- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
-help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |             $( $v = $s::V.try_into().unwrap(), )*
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-31910.stderr b/src/test/ui/issues/issue-31910.stderr
index c5c988cdaa7..2603c944207 100644
--- a/src/test/ui/issues/issue-31910.stderr
+++ b/src/test/ui/issues/issue-31910.stderr
@@ -3,11 +3,6 @@ error[E0308]: mismatched types
    |
 LL |     X = Trait::Number,
    |         ^^^^^^^^^^^^^ expected `isize`, found `i32`
-   |
-help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
-   |
-LL |     X = Trait::Number.try_into().unwrap(),
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/numeric/const-scope.stderr b/src/test/ui/numeric/const-scope.stderr
index 6e1990e3a72..d7f18e19b41 100644
--- a/src/test/ui/numeric/const-scope.stderr
+++ b/src/test/ui/numeric/const-scope.stderr
@@ -3,6 +3,11 @@ error[E0308]: mismatched types
    |
 LL | const C: i32 = 1i8;
    |                ^^^ expected `i32`, found `i8`
+   |
+help: change the type of the numeric literal from `i8` to `i32`
+   |
+LL | const C: i32 = 1i32;
+   |                ^^^^
 
 error[E0308]: mismatched types
   --> $DIR/const-scope.rs:2:15
@@ -17,6 +22,11 @@ LL |     let c: i32 = 1i8;
    |            ---   ^^^ expected `i32`, found `i8`
    |            |
    |            expected due to this
+   |
+help: change the type of the numeric literal from `i8` to `i32`
+   |
+LL |     let c: i32 = 1i32;
+   |                  ^^^^
 
 error[E0308]: mismatched types
   --> $DIR/const-scope.rs:6:17
diff --git a/src/test/ui/repeat_count.rs b/src/test/ui/repeat_count.rs
index aca7af144a9..7e30491f0bd 100644
--- a/src/test/ui/repeat_count.rs
+++ b/src/test/ui/repeat_count.rs
@@ -22,6 +22,9 @@ fn main() {
     let f = [0_usize; -1_isize];
     //~^ ERROR mismatched types
     //~| expected `usize`, found `isize`
+    let f = [0; 4u8];
+    //~^ ERROR mismatched types
+    //~| expected `usize`, found `u8`
     struct G {
         g: (),
     }
diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr
index 4a2d1d9f921..6a081e23d9d 100644
--- a/src/test/ui/repeat_count.stderr
+++ b/src/test/ui/repeat_count.stderr
@@ -29,7 +29,7 @@ LL |     let e = [0; "foo"];
    |                 ^^^^^ expected `usize`, found `&str`
 
 error[E0308]: mismatched types
-  --> $DIR/repeat_count.rs:28:17
+  --> $DIR/repeat_count.rs:31:17
    |
 LL |     let g = [0; G { g: () }];
    |                 ^^^^^^^^^^^ expected `usize`, found struct `main::G`
@@ -39,24 +39,25 @@ error[E0308]: mismatched types
    |
 LL |     let f = [0; -4_isize];
    |                 ^^^^^^^^ expected `usize`, found `isize`
-   |
-help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit
-   |
-LL |     let f = [0; (-4_isize).try_into().unwrap()];
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/repeat_count.rs:22:23
    |
 LL |     let f = [0_usize; -1_isize];
    |                       ^^^^^^^^ expected `usize`, found `isize`
+
+error[E0308]: mismatched types
+  --> $DIR/repeat_count.rs:25:17
+   |
+LL |     let f = [0; 4u8];
+   |                 ^^^ expected `usize`, found `u8`
    |
-help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit
+help: change the type of the numeric literal from `u8` to `usize`
    |
-LL |     let f = [0_usize; (-1_isize).try_into().unwrap()];
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let f = [0; 4usize];
+   |                 ^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
 Some errors have detailed explanations: E0308, E0435.
 For more information about an error, try `rustc --explain E0308`.