diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6dcdd46816e0d..c4a190b44cbd4 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 0c1ca65c48f6a..187df6f7de0ff 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 47cb1ea48cb54..a1e8d2040dd80 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 eba1a8e2278b7..724bdcd920ab4 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 48aaaf5e5440a..5bb3566962367 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(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 665a1a677a1ab..8d9e545b45689 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(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 19217843759c1..18b4dc714ded0 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; 2] = [no_copy(); 2]; - //~^ ERROR the trait bound `Option: 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 52a1669e33002..5306fed225118 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: 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; 2] = [no_copy(); 2]; - | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option` + | ^^^^^^^^^ the trait `Copy` is not implemented for `Bar` | - = help: the trait `Copy` is implemented for `Option` - = 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` + = 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 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 bb12139a7bae9..d5a17249cc9dd 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; 2] = [x; 2]; - //~^ ERROR the trait bound `Option: 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; 2] = [x; 2]; - //~^ ERROR the trait bound `Option: 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 318fec60290ee..2e7ff5cb8b32c 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: 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; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option` + = 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` - = note: the `Copy` trait is required because the repeated element will be copied -error[E0277]: the trait bound `Option: 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; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option` + = 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` - = 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 871387c1fd0cf..9d4aef39e5401 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; 2] = [x; 2]; - //~^ ERROR the trait bound `Option: 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; 2] = [x; 2]; - //~^ ERROR the trait bound `Option: 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 5a34361aa83b6..c0d273b5a9a2a 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: 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; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option` + = 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` - = note: the `Copy` trait is required because the repeated element will be copied -error[E0277]: the trait bound `Option: 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; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option` + = 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` - = 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 5a614cbdd1561..49d1e9b943420 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); fn main() { [Foo(String::new()); 4]; - //~^ ERROR the trait bound `Foo: 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 6979ff36176cd..ece200ad10b5b 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: 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` + | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | - = help: the trait `Copy` is implemented for `Foo` - = 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` + --> $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 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 f02cb4f1ff193..9eb7524b5044b 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 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 0000000000000..1d5d90ffcb43d --- /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 0000000000000..e027bc45426ed --- /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 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 0000000000000..8197713b97ed0 --- /dev/null +++ b/src/test/ui/repeat-expr/infer.rs @@ -0,0 +1,16 @@ +// check-pass + +#[derive(Clone, Default)] +struct MaybeCopy(T); + +impl Copy for MaybeCopy {} + +fn is_copy(x: T) { + println!("{}", std::any::type_name::()); +} + +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 similarity index 100% rename from src/test/ui/repeat-expr-in-static.rs rename to 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 similarity index 100% rename from src/test/ui/repeat-to-run-dtor-twice.rs rename to 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 similarity index 57% rename from src/test/ui/repeat-to-run-dtor-twice.stderr rename to src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr index 904413712cde1..36b93616375e0 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 similarity index 100% rename from src/test/ui/repeat_count.rs rename to 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 similarity index 100% rename from src/test/ui/repeat_count.stderr rename to 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 1f6f233648152..6b715f727b223 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) {