about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs53
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs2
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs40
-rw-r--r--src/test/ui/array-slice-vec/repeat_empty_ok.stderr12
-rw-r--r--src/test/ui/const-generics/issues/issue-61336-2.stderr6
-rw-r--r--src/test/ui/const-generics/issues/issue-61336.stderr6
-rw-r--r--src/test/ui/consts/const-blocks/fn-call-in-non-const.rs2
-rw-r--r--src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr14
-rw-r--r--src/test/ui/consts/const-blocks/migrate-fail.rs4
-rw-r--r--src/test/ui/consts/const-blocks/migrate-fail.stderr28
-rw-r--r--src/test/ui/consts/const-blocks/nll-fail.rs4
-rw-r--r--src/test/ui/consts/const-blocks/nll-fail.stderr28
-rw-r--r--src/test/ui/consts/const-blocks/trait-error.rs2
-rw-r--r--src/test/ui/consts/const-blocks/trait-error.stderr17
-rw-r--r--src/test/ui/consts/const-fn-in-vec.stderr6
-rw-r--r--src/test/ui/lifetimes/copy_modulo_regions.rs19
-rw-r--r--src/test/ui/lifetimes/copy_modulo_regions.stderr14
-rw-r--r--src/test/ui/repeat-expr/infer.rs16
-rw-r--r--src/test/ui/repeat-expr/repeat-expr-in-static.rs (renamed from src/test/ui/repeat-expr-in-static.rs)0
-rw-r--r--src/test/ui/repeat-expr/repeat-to-run-dtor-twice.rs (renamed from src/test/ui/repeat-to-run-dtor-twice.rs)0
-rw-r--r--src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr (renamed from src/test/ui/repeat-to-run-dtor-twice.stderr)6
-rw-r--r--src/test/ui/repeat-expr/repeat_count.rs (renamed from src/test/ui/repeat_count.rs)0
-rw-r--r--src/test/ui/repeat-expr/repeat_count.stderr (renamed from src/test/ui/repeat_count.stderr)0
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
24 files changed, 184 insertions, 97 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6dcdd46816e..c4a190b44cb 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -37,18 +37,13 @@ use rustc_middle::ty::{
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::VariantIdx;
-use rustc_trait_selection::infer::InferCtxtExt as _;
-use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::type_op;
 use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints;
 use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
 use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
 use rustc_trait_selection::traits::query::Fallible;
-use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligation};
+use rustc_trait_selection::traits::PredicateObligation;
 
-use rustc_const_eval::transform::{
-    check_consts::ConstCx, promote_consts::is_const_fn_in_array_repeat_expression,
-};
 use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
 use rustc_mir_dataflow::move_paths::MoveData;
 use rustc_mir_dataflow::ResultsCursor;
@@ -1868,41 +1863,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         Operand::Move(place) => {
                             // Make sure that repeated elements implement `Copy`.
                             let span = body.source_info(location).span;
-                            let ty = operand.ty(body, tcx);
-                            if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
-                                let ccx = ConstCx::new_with_param_env(tcx, body, self.param_env);
-                                let is_const_fn =
-                                    is_const_fn_in_array_repeat_expression(&ccx, &place, &body);
-
-                                debug!("check_rvalue: is_const_fn={:?}", is_const_fn);
-
-                                let def_id = body.source.def_id().expect_local();
-                                let obligation = traits::Obligation::new(
-                                    ObligationCause::new(
-                                        span,
-                                        self.tcx().hir().local_def_id_to_hir_id(def_id),
-                                        traits::ObligationCauseCode::RepeatElementCopy {
-                                            is_const_fn,
-                                        },
-                                    ),
-                                    self.param_env,
-                                    ty::Binder::dummy(ty::TraitRef::new(
-                                        self.tcx().require_lang_item(
-                                            LangItem::Copy,
-                                            Some(self.last_span),
-                                        ),
-                                        tcx.mk_substs_trait(ty, &[]),
-                                    ))
-                                    .without_const()
-                                    .to_predicate(self.tcx()),
-                                );
-                                self.infcx.report_selection_error(
-                                    obligation.clone(),
-                                    &obligation,
-                                    &traits::SelectionError::Unimplemented,
-                                    false,
-                                );
-                            }
+                            let ty = place.ty(body, tcx).ty;
+                            let trait_ref = ty::TraitRef::new(
+                                tcx.require_lang_item(LangItem::Copy, Some(span)),
+                                tcx.mk_substs_trait(ty, &[]),
+                            );
+
+                            self.prove_trait_ref(
+                                trait_ref,
+                                Locations::Single(location),
+                                ConstraintCategory::CopyBound,
+                            );
                         }
                     }
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 0c1ca65c48f..187df6f7de0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2227,7 +2227,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             }
             ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
                 err.note(
-                    "the `Copy` trait is required because the repeated element will be copied",
+                    "the `Copy` trait is required because this value will be copied for each element of the array",
                 );
 
                 if is_const_fn {
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 47cb1ea48cb..a1e8d2040dd 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -1292,9 +1292,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return tcx.ty_error();
         }
 
+        self.check_repeat_element_needs_copy_bound(element, count, element_ty);
+
         tcx.mk_ty(ty::Array(t, count))
     }
 
+    fn check_repeat_element_needs_copy_bound(
+        &self,
+        element: &hir::Expr<'_>,
+        count: ty::Const<'tcx>,
+        element_ty: Ty<'tcx>,
+    ) {
+        let tcx = self.tcx;
+        // Actual constants as the repeat element get inserted repeatedly instead of getting copied via Copy.
+        match &element.kind {
+            hir::ExprKind::ConstBlock(..) => return,
+            hir::ExprKind::Path(qpath) => {
+                let res = self.typeck_results.borrow().qpath_res(qpath, element.hir_id);
+                if let Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::AnonConst, _) = res
+                {
+                    return;
+                }
+            }
+            _ => {}
+        }
+        // If someone calls a const fn, they can extract that call out into a separate constant (or a const
+        // block in the future), so we check that to tell them that in the diagnostic. Does not affect typeck.
+        let is_const_fn = match element.kind {
+            hir::ExprKind::Call(func, _args) => match *self.node_ty(func.hir_id).kind() {
+                ty::FnDef(def_id, _) => tcx.is_const_fn(def_id),
+                _ => false,
+            },
+            _ => false,
+        };
+
+        // If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
+        // don't copy that one element, we move it. Only check for Copy if the length is larger.
+        if count.try_eval_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
+            let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
+            let code = traits::ObligationCauseCode::RepeatElementCopy { is_const_fn };
+            self.require_type_meets(element_ty, element.span, code, lang_item);
+        }
+    }
+
     fn check_expr_tuple(
         &self,
         elts: &'tcx [hir::Expr<'tcx>],
diff --git a/src/test/ui/array-slice-vec/repeat_empty_ok.stderr b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr
index eba1a8e2278..724bdcd920a 100644
--- a/src/test/ui/array-slice-vec/repeat_empty_ok.stderr
+++ b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr
@@ -1,22 +1,22 @@
 error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
-  --> $DIR/repeat_empty_ok.rs:8:19
+  --> $DIR/repeat_empty_ok.rs:8:20
    |
 LL |     let headers = [Header{value: &[]}; 128];
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
+   |                    ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Header<'_>` with `#[derive(Copy)]`
    |
 LL | #[derive(Copy)]
    |
 
 error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
-  --> $DIR/repeat_empty_ok.rs:13:19
+  --> $DIR/repeat_empty_ok.rs:13:20
    |
 LL |     let headers = [Header{value: &[0]}; 128];
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
+   |                    ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Header<'_>` with `#[derive(Copy)]`
    |
 LL | #[derive(Copy)]
diff --git a/src/test/ui/const-generics/issues/issue-61336-2.stderr b/src/test/ui/const-generics/issues/issue-61336-2.stderr
index 48aaaf5e544..5bb35669623 100644
--- a/src/test/ui/const-generics/issues/issue-61336-2.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336-2.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336-2.rs:6:5
+  --> $DIR/issue-61336-2.rs:6:6
    |
 LL |     [x; { N }]
-   |     ^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+   |      ^ the trait `Copy` is not implemented for `T`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider restricting type parameter `T`
    |
 LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
diff --git a/src/test/ui/const-generics/issues/issue-61336.stderr b/src/test/ui/const-generics/issues/issue-61336.stderr
index 665a1a677a1..8d9e545b456 100644
--- a/src/test/ui/const-generics/issues/issue-61336.stderr
+++ b/src/test/ui/const-generics/issues/issue-61336.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the trait bound `T: Copy` is not satisfied
-  --> $DIR/issue-61336.rs:6:5
+  --> $DIR/issue-61336.rs:6:6
    |
 LL |     [x; N]
-   |     ^^^^^^ the trait `Copy` is not implemented for `T`
+   |      ^ the trait `Copy` is not implemented for `T`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider restricting type parameter `T`
    |
 LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] {
diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs b/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs
index 19217843759..18b4dc714de 100644
--- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs
+++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs
@@ -12,5 +12,5 @@ const fn copy() -> u32 {
 fn main() {
     let _: [u32; 2] = [copy(); 2];
     let _: [Option<Bar>; 2] = [no_copy(); 2];
-    //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied
+    //~^ ERROR the trait bound `Bar: Copy` is not satisfied
 }
diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
index 52a1669e330..5306fed2251 100644
--- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
+++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr
@@ -1,13 +1,17 @@
-error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
-  --> $DIR/fn-call-in-non-const.rs:14:31
+error[E0277]: the trait bound `Bar: Copy` is not satisfied
+  --> $DIR/fn-call-in-non-const.rs:14:32
    |
 LL |     let _: [Option<Bar>; 2] = [no_copy(); 2];
-   |                               ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
+   |                                ^^^^^^^^^ the trait `Copy` is not implemented for `Bar`
    |
-   = help: the trait `Copy` is implemented for `Option<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
    = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];`
    = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
+help: consider annotating `Bar` with `#[derive(Copy)]`
+   |
+LL | #[derive(Copy)]
+   |
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-blocks/migrate-fail.rs b/src/test/ui/consts/const-blocks/migrate-fail.rs
index bb12139a7ba..d5a17249cc9 100644
--- a/src/test/ui/consts/const-blocks/migrate-fail.rs
+++ b/src/test/ui/consts/const-blocks/migrate-fail.rs
@@ -11,13 +11,13 @@ mod non_constants {
     fn no_impl_copy_empty_value_multiple_elements() {
         let x = None;
         let arr: [Option<Bar>; 2] = [x; 2];
-        //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277]
+        //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277]
     }
 
     fn no_impl_copy_value_multiple_elements() {
         let x = Some(Bar);
         let arr: [Option<Bar>; 2] = [x; 2];
-        //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277]
+        //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277]
     }
 }
 
diff --git a/src/test/ui/consts/const-blocks/migrate-fail.stderr b/src/test/ui/consts/const-blocks/migrate-fail.stderr
index 318fec60290..2e7ff5cb8b3 100644
--- a/src/test/ui/consts/const-blocks/migrate-fail.stderr
+++ b/src/test/ui/consts/const-blocks/migrate-fail.stderr
@@ -1,20 +1,28 @@
-error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
-  --> $DIR/migrate-fail.rs:13:37
+error[E0277]: the trait bound `Bar: Copy` is not satisfied
+  --> $DIR/migrate-fail.rs:13:38
    |
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
-   |                                     ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
+   |                                      ^ the trait `Copy` is not implemented for `Bar`
+   |
+   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Bar` with `#[derive(Copy)]`
+   |
+LL | #[derive(Copy)]
    |
-   = help: the trait `Copy` is implemented for `Option<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
 
-error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
-  --> $DIR/migrate-fail.rs:19:37
+error[E0277]: the trait bound `Bar: Copy` is not satisfied
+  --> $DIR/migrate-fail.rs:19:38
    |
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
-   |                                     ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
+   |                                      ^ the trait `Copy` is not implemented for `Bar`
+   |
+   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Bar` with `#[derive(Copy)]`
+   |
+LL | #[derive(Copy)]
    |
-   = help: the trait `Copy` is implemented for `Option<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-blocks/nll-fail.rs b/src/test/ui/consts/const-blocks/nll-fail.rs
index 871387c1fd0..9d4aef39e54 100644
--- a/src/test/ui/consts/const-blocks/nll-fail.rs
+++ b/src/test/ui/consts/const-blocks/nll-fail.rs
@@ -10,13 +10,13 @@ mod non_constants {
     fn no_impl_copy_empty_value_multiple_elements() {
         let x = None;
         let arr: [Option<Bar>; 2] = [x; 2];
-        //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277]
+        //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277]
     }
 
     fn no_impl_copy_value_multiple_elements() {
         let x = Some(Bar);
         let arr: [Option<Bar>; 2] = [x; 2];
-        //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277]
+        //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277]
     }
 }
 
diff --git a/src/test/ui/consts/const-blocks/nll-fail.stderr b/src/test/ui/consts/const-blocks/nll-fail.stderr
index 5a34361aa83..c0d273b5a9a 100644
--- a/src/test/ui/consts/const-blocks/nll-fail.stderr
+++ b/src/test/ui/consts/const-blocks/nll-fail.stderr
@@ -1,20 +1,28 @@
-error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
-  --> $DIR/nll-fail.rs:12:37
+error[E0277]: the trait bound `Bar: Copy` is not satisfied
+  --> $DIR/nll-fail.rs:12:38
    |
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
-   |                                     ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
+   |                                      ^ the trait `Copy` is not implemented for `Bar`
+   |
+   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Bar` with `#[derive(Copy)]`
+   |
+LL | #[derive(Copy)]
    |
-   = help: the trait `Copy` is implemented for `Option<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
 
-error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied
-  --> $DIR/nll-fail.rs:18:37
+error[E0277]: the trait bound `Bar: Copy` is not satisfied
+  --> $DIR/nll-fail.rs:18:38
    |
 LL |         let arr: [Option<Bar>; 2] = [x; 2];
-   |                                     ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>`
+   |                                      ^ the trait `Copy` is not implemented for `Bar`
+   |
+   = note: required because of the requirements on the impl of `Copy` for `Option<Bar>`
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
+help: consider annotating `Bar` with `#[derive(Copy)]`
+   |
+LL | #[derive(Copy)]
    |
-   = help: the trait `Copy` is implemented for `Option<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-blocks/trait-error.rs b/src/test/ui/consts/const-blocks/trait-error.rs
index 5a614cbdd15..49d1e9b9434 100644
--- a/src/test/ui/consts/const-blocks/trait-error.rs
+++ b/src/test/ui/consts/const-blocks/trait-error.rs
@@ -3,5 +3,5 @@ struct Foo<T>(T);
 
 fn main() {
     [Foo(String::new()); 4];
-    //~^ ERROR the trait bound `Foo<String>: Copy` is not satisfied [E0277]
+    //~^ ERROR the trait bound `String: Copy` is not satisfied [E0277]
 }
diff --git a/src/test/ui/consts/const-blocks/trait-error.stderr b/src/test/ui/consts/const-blocks/trait-error.stderr
index 6979ff36176..ece200ad10b 100644
--- a/src/test/ui/consts/const-blocks/trait-error.stderr
+++ b/src/test/ui/consts/const-blocks/trait-error.stderr
@@ -1,11 +1,18 @@
-error[E0277]: the trait bound `Foo<String>: Copy` is not satisfied
-  --> $DIR/trait-error.rs:5:5
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/trait-error.rs:5:6
    |
 LL |     [Foo(String::new()); 4];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Foo<String>`
+   |      ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
-   = help: the trait `Copy` is implemented for `Foo<T>`
-   = note: the `Copy` trait is required because the repeated element will be copied
+note: required because of the requirements on the impl of `Copy` for `Foo<String>`
+  --> $DIR/trait-error.rs:1:10
+   |
+LL | #[derive(Copy, Clone)]
+   |          ^^^^
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
+   = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];`
+   = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-fn-in-vec.stderr b/src/test/ui/consts/const-fn-in-vec.stderr
index f02cb4f1ff1..9eb7524b504 100644
--- a/src/test/ui/consts/const-fn-in-vec.stderr
+++ b/src/test/ui/consts/const-fn-in-vec.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/const-fn-in-vec.rs:4:32
+  --> $DIR/const-fn-in-vec.rs:4:33
    |
 LL |     let strings: [String; 5] = [String::new(); 5];
-   |                                ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |                                 ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
    = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];`
    = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information
 
diff --git a/src/test/ui/lifetimes/copy_modulo_regions.rs b/src/test/ui/lifetimes/copy_modulo_regions.rs
new file mode 100644
index 00000000000..1d5d90ffcb4
--- /dev/null
+++ b/src/test/ui/lifetimes/copy_modulo_regions.rs
@@ -0,0 +1,19 @@
+#![feature(nll)]
+
+#[derive(Clone)]
+struct Foo<'a>(fn(&'a ()) -> &'a ());
+
+impl Copy for Foo<'static> {}
+
+fn mk_foo<'a>() -> Foo<'a> {
+    println!("mk_foo");
+    Foo(|x| x)
+}
+
+fn foo<'a>() -> [Foo<'a>; 100] {
+    [mk_foo::<'a>(); 100] //~ ERROR lifetime may not live long enough
+}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/lifetimes/copy_modulo_regions.stderr b/src/test/ui/lifetimes/copy_modulo_regions.stderr
new file mode 100644
index 00000000000..e027bc45426
--- /dev/null
+++ b/src/test/ui/lifetimes/copy_modulo_regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/copy_modulo_regions.rs:14:5
+   |
+LL | fn foo<'a>() -> [Foo<'a>; 100] {
+   |        -- lifetime `'a` defined here
+LL |     [mk_foo::<'a>(); 100]
+   |     ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |
+   = note: requirement occurs because of the type `Foo<'_>`, which makes the generic argument `'_` invariant
+   = note: the struct `Foo<'a>` is invariant over the parameter `'a`
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/repeat-expr/infer.rs b/src/test/ui/repeat-expr/infer.rs
new file mode 100644
index 00000000000..8197713b97e
--- /dev/null
+++ b/src/test/ui/repeat-expr/infer.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#[derive(Clone, Default)]
+struct MaybeCopy<T>(T);
+
+impl Copy for MaybeCopy<u8> {}
+
+fn is_copy<T: Copy>(x: T) {
+    println!("{}", std::any::type_name::<T>());
+}
+
+fn main() {
+    is_copy(MaybeCopy::default());
+    [MaybeCopy::default(); 13];
+    // didn't work, because `Copy` was only checked in the mir
+}
diff --git a/src/test/ui/repeat-expr-in-static.rs b/src/test/ui/repeat-expr/repeat-expr-in-static.rs
index 0b895379330..0b895379330 100644
--- a/src/test/ui/repeat-expr-in-static.rs
+++ b/src/test/ui/repeat-expr/repeat-expr-in-static.rs
diff --git a/src/test/ui/repeat-to-run-dtor-twice.rs b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.rs
index 0cd8eceefc5..0cd8eceefc5 100644
--- a/src/test/ui/repeat-to-run-dtor-twice.rs
+++ b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.rs
diff --git a/src/test/ui/repeat-to-run-dtor-twice.stderr b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr
index 904413712cd..36b93616375 100644
--- a/src/test/ui/repeat-to-run-dtor-twice.stderr
+++ b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the trait bound `Foo: Copy` is not satisfied
-  --> $DIR/repeat-to-run-dtor-twice.rs:17:13
+  --> $DIR/repeat-to-run-dtor-twice.rs:17:15
    |
 LL |     let _ = [ a; 5 ];
-   |             ^^^^^^^^ the trait `Copy` is not implemented for `Foo`
+   |               ^ the trait `Copy` is not implemented for `Foo`
    |
-   = note: the `Copy` trait is required because the repeated element will be copied
+   = note: the `Copy` trait is required because this value will be copied for each element of the array
 help: consider annotating `Foo` with `#[derive(Copy)]`
    |
 LL | #[derive(Copy)]
diff --git a/src/test/ui/repeat_count.rs b/src/test/ui/repeat-expr/repeat_count.rs
index 96abff4ab41..96abff4ab41 100644
--- a/src/test/ui/repeat_count.rs
+++ b/src/test/ui/repeat-expr/repeat_count.rs
diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat-expr/repeat_count.stderr
index 59bcd954a1f..59bcd954a1f 100644
--- a/src/test/ui/repeat_count.stderr
+++ b/src/test/ui/repeat-expr/repeat_count.stderr
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 1f6f2336481..6b715f727b2 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -7,7 +7,7 @@ use std::path::Path;
 
 const ENTRY_LIMIT: usize = 1000;
 // FIXME: The following limits should be reduced eventually.
-const ROOT_ENTRY_LIMIT: usize = 980;
+const ROOT_ENTRY_LIMIT: usize = 977;
 const ISSUES_ENTRY_LIMIT: usize = 2278;
 
 fn check_entries(path: &Path, bad: &mut bool) {