@@ -35,7 +35,7 @@ use rustc::mir::*;
35
35
use rustc:: traits:: query:: type_op;
36
36
use rustc:: traits:: query:: type_op:: custom:: CustomTypeOp ;
37
37
use rustc:: traits:: query:: { Fallible , NoSolution } ;
38
- use rustc:: traits:: { ObligationCause , PredicateObligations } ;
38
+ use rustc:: traits:: { self , ObligationCause , PredicateObligations } ;
39
39
use rustc:: ty:: adjustment:: { PointerCast } ;
40
40
use rustc:: ty:: fold:: TypeFoldable ;
41
41
use rustc:: ty:: subst:: { Subst , SubstsRef , UnpackedKind , UserSubsts } ;
@@ -501,28 +501,38 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
501
501
// FIXME use place_projection.is_empty() when is available
502
502
if let Place :: Base ( _) = place {
503
503
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 ,
508
510
} ;
509
511
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
+ }
526
536
}
527
537
}
528
538
@@ -1953,18 +1963,32 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1953
1963
}
1954
1964
1955
1965
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
+ }
1968
1992
} ,
1969
1993
1970
1994
Rvalue :: NullaryOp ( _, ty) => {
0 commit comments