@@ -35,7 +35,7 @@ use rustc::mir::*;
3535use rustc:: traits:: query:: type_op;
3636use rustc:: traits:: query:: type_op:: custom:: CustomTypeOp ;
3737use rustc:: traits:: query:: { Fallible , NoSolution } ;
38- use rustc:: traits:: { ObligationCause , PredicateObligations } ;
38+ use rustc:: traits:: { self , ObligationCause , PredicateObligations } ;
3939use rustc:: ty:: adjustment:: { PointerCast } ;
4040use rustc:: ty:: fold:: TypeFoldable ;
4141use rustc:: ty:: subst:: { Subst , SubstsRef , UnpackedKind , UserSubsts } ;
@@ -501,28 +501,38 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
501501 // FIXME use place_projection.is_empty() when is available
502502 if let Place :: Base ( _) = place {
503503 if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) = context {
504- let tcx = self . tcx ( ) ;
505- let trait_ref = ty:: TraitRef {
506- def_id : tcx. lang_items ( ) . copy_trait ( ) . unwrap ( ) ,
507- substs : tcx. mk_substs_trait ( place_ty. ty , & [ ] ) ,
504+ let is_promoted = match place {
505+ Place :: Base ( PlaceBase :: Static ( box Static {
506+ kind : StaticKind :: Promoted ( _) ,
507+ ..
508+ } ) ) => true ,
509+ _ => false ,
508510 } ;
509511
510- // In order to have a Copy operand, the type T of the
511- // value must be Copy. Note that we prove that T: Copy,
512- // rather than using the `is_copy_modulo_regions`
513- // test. This is important because
514- // `is_copy_modulo_regions` ignores the resulting region
515- // obligations and assumes they pass. This can result in
516- // bounds from Copy impls being unsoundly ignored (e.g.,
517- // #29149). Note that we decide to use Copy before knowing
518- // whether the bounds fully apply: in effect, the rule is
519- // that if a value of some type could implement Copy, then
520- // it must.
521- self . cx . prove_trait_ref (
522- trait_ref,
523- location. to_locations ( ) ,
524- ConstraintCategory :: CopyBound ,
525- ) ;
512+ if !is_promoted {
513+ let tcx = self . tcx ( ) ;
514+ let trait_ref = ty:: TraitRef {
515+ def_id : tcx. lang_items ( ) . copy_trait ( ) . unwrap ( ) ,
516+ substs : tcx. mk_substs_trait ( place_ty. ty , & [ ] ) ,
517+ } ;
518+
519+ // In order to have a Copy operand, the type T of the
520+ // value must be Copy. Note that we prove that T: Copy,
521+ // rather than using the `is_copy_modulo_regions`
522+ // test. This is important because
523+ // `is_copy_modulo_regions` ignores the resulting region
524+ // obligations and assumes they pass. This can result in
525+ // bounds from Copy impls being unsoundly ignored (e.g.,
526+ // #29149). Note that we decide to use Copy before knowing
527+ // whether the bounds fully apply: in effect, the rule is
528+ // that if a value of some type could implement Copy, then
529+ // it must.
530+ self . cx . prove_trait_ref (
531+ trait_ref,
532+ location. to_locations ( ) ,
533+ ConstraintCategory :: CopyBound ,
534+ ) ;
535+ }
526536 }
527537 }
528538
@@ -1953,18 +1963,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19531963 }
19541964
19551965 Rvalue :: Repeat ( operand, len) => if * len > 1 {
1956- let operand_ty = operand. ty ( body, tcx) ;
1957-
1958- let trait_ref = ty:: TraitRef {
1959- def_id : tcx. lang_items ( ) . copy_trait ( ) . unwrap ( ) ,
1960- substs : tcx. mk_substs_trait ( operand_ty, & [ ] ) ,
1961- } ;
1962-
1963- self . prove_trait_ref (
1964- trait_ref,
1965- location. to_locations ( ) ,
1966- ConstraintCategory :: CopyBound ,
1967- ) ;
1966+ if let Operand :: Move ( _) = operand {
1967+ // While this is located in `nll::typeck` this error is not an NLL error, it's
1968+ // a required check to make sure that repeated elements implement `Copy`.
1969+ let span = body. source_info ( location) . span ;
1970+ let ty = operand. ty ( body, tcx) ;
1971+ if !self . infcx . type_is_copy_modulo_regions ( self . param_env , ty, span) {
1972+ self . infcx . report_selection_error (
1973+ & traits:: Obligation :: new (
1974+ ObligationCause :: new (
1975+ span,
1976+ self . tcx ( ) . hir ( ) . def_index_to_hir_id ( self . mir_def_id . index ) ,
1977+ traits:: ObligationCauseCode :: RepeatVec ,
1978+ ) ,
1979+ self . param_env ,
1980+ ty:: Predicate :: Trait ( ty:: Binder :: bind ( ty:: TraitPredicate {
1981+ trait_ref : ty:: TraitRef :: new (
1982+ self . tcx ( ) . lang_items ( ) . copy_trait ( ) . unwrap ( ) ,
1983+ tcx. mk_substs_trait ( ty, & [ ] ) ,
1984+ ) ,
1985+ } ) ) ,
1986+ ) ,
1987+ & traits:: SelectionError :: Unimplemented ,
1988+ false ,
1989+ ) ;
1990+ }
1991+ }
19681992 } ,
19691993
19701994 Rvalue :: NullaryOp ( _, ty) => {
0 commit comments