@@ -232,11 +232,9 @@ enum FieldAccessError {
232232 OutOfRange { field_count : usize } ,
233233}
234234
235- /// Verifies that MIR types are sane to not crash further checks .
235+ /// Verifies that MIR types are sane.
236236///
237- /// The sanitize_XYZ methods here take an MIR object and compute its
238- /// type, calling `span_mirbug` and returning an error type if there
239- /// is a problem.
237+ /// FIXME: This should be merged with the actual `TypeChecker`.
240238struct TypeVerifier < ' a , ' b , ' tcx > {
241239 typeck : & ' a mut TypeChecker < ' b , ' tcx > ,
242240 promoted : & ' b IndexSlice < Promoted , Body < ' tcx > > ,
@@ -251,7 +249,33 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
251249 }
252250
253251 fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , location : Location ) {
254- self . sanitize_place ( place, location, context) ;
252+ self . super_place ( place, context, location) ;
253+ let tcx = self . tcx ( ) ;
254+ let place_ty = place. ty ( self . body ( ) , tcx) ;
255+ if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) = context {
256+ let trait_ref = ty:: TraitRef :: new (
257+ tcx,
258+ tcx. require_lang_item ( LangItem :: Copy , Some ( self . last_span ) ) ,
259+ [ place_ty. ty ] ,
260+ ) ;
261+
262+ // To have a `Copy` operand, the type `T` of the
263+ // value must be `Copy`. Note that we prove that `T: Copy`,
264+ // rather than using the `is_copy_modulo_regions`
265+ // test. This is important because
266+ // `is_copy_modulo_regions` ignores the resulting region
267+ // obligations and assumes they pass. This can result in
268+ // bounds from `Copy` impls being unsoundly ignored (e.g.,
269+ // #29149). Note that we decide to use `Copy` before knowing
270+ // whether the bounds fully apply: in effect, the rule is
271+ // that if a value of some type could implement `Copy`, then
272+ // it must.
273+ self . typeck . prove_trait_ref (
274+ trait_ref,
275+ location. to_locations ( ) ,
276+ ConstraintCategory :: CopyBound ,
277+ ) ;
278+ }
255279 }
256280
257281 fn visit_projection_elem (
@@ -379,7 +403,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
379403 } ;
380404
381405 let promoted_body = & self . promoted [ promoted] ;
382- self . sanitize_promoted ( promoted_body, location) ;
406+ self . verify_promoted ( promoted_body, location) ;
383407
384408 let promoted_ty = promoted_body. return_ty ( ) ;
385409 check_err ( self , promoted_body, ty, promoted_ty) ;
@@ -483,40 +507,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
483507 self . typeck . infcx . tcx
484508 }
485509
486- /// Checks that the types internal to the `place` match up with
487- /// what would be expected.
488- #[ instrument( level = "debug" , skip( self , location) , ret) ]
489- fn sanitize_place ( & mut self , place : & Place < ' tcx > , location : Location , context : PlaceContext ) {
490- self . super_place ( place, context, location) ;
491- let tcx = self . tcx ( ) ;
492- let place_ty = place. ty ( self . body ( ) , tcx) ;
493- if let PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) = context {
494- let trait_ref = ty:: TraitRef :: new (
495- tcx,
496- tcx. require_lang_item ( LangItem :: Copy , Some ( self . last_span ) ) ,
497- [ place_ty. ty ] ,
498- ) ;
499-
500- // To have a `Copy` operand, the type `T` of the
501- // value must be `Copy`. Note that we prove that `T: Copy`,
502- // rather than using the `is_copy_modulo_regions`
503- // test. This is important because
504- // `is_copy_modulo_regions` ignores the resulting region
505- // obligations and assumes they pass. This can result in
506- // bounds from `Copy` impls being unsoundly ignored (e.g.,
507- // #29149). Note that we decide to use `Copy` before knowing
508- // whether the bounds fully apply: in effect, the rule is
509- // that if a value of some type could implement `Copy`, then
510- // it must.
511- self . typeck . prove_trait_ref (
512- trait_ref,
513- location. to_locations ( ) ,
514- ConstraintCategory :: CopyBound ,
515- ) ;
516- }
517- }
518-
519- fn sanitize_promoted ( & mut self , promoted_body : & ' b Body < ' tcx > , location : Location ) {
510+ fn verify_promoted ( & mut self , promoted_body : & ' b Body < ' tcx > , location : Location ) {
520511 // Determine the constraints from the promoted MIR by running the type
521512 // checker on the promoted MIR, then transfer the constraints back to
522513 // the main MIR, changing the locations to the provided location.
0 commit comments