@@ -7,7 +7,7 @@ use rustc_infer::traits::Reveal;
7
7
use rustc_middle:: mir:: interpret:: Scalar ;
8
8
use rustc_middle:: mir:: visit:: { NonUseContext , PlaceContext , Visitor } ;
9
9
use rustc_middle:: mir:: * ;
10
- use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt } ;
10
+ use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt , Variance } ;
11
11
use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
12
12
use rustc_mir_dataflow:: storage:: always_storage_live_locals;
13
13
use rustc_mir_dataflow:: { Analysis , ResultsCursor } ;
@@ -16,6 +16,8 @@ use rustc_target::spec::abi::Abi;
16
16
17
17
use crate :: util:: is_within_packed;
18
18
19
+ use crate :: util:: relate_types;
20
+
19
21
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
20
22
enum EdgeKind {
21
23
Unwind ,
@@ -602,7 +604,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
602
604
return true ;
603
605
}
604
606
605
- crate :: util:: is_subtype ( self . tcx , self . param_env , src, dest)
607
+ // After borrowck subtyping should be fully explicit via
608
+ // `Subtype` projections.
609
+ let variance = if self . mir_phase >= MirPhase :: Runtime ( RuntimePhase :: Initial ) {
610
+ Variance :: Invariant
611
+ } else {
612
+ Variance :: Covariant
613
+ } ;
614
+
615
+ crate :: util:: relate_types ( self . tcx , self . param_env , variance, src, dest)
606
616
}
607
617
}
608
618
@@ -753,6 +763,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
753
763
}
754
764
}
755
765
}
766
+ ProjectionElem :: Subtype ( ty) => {
767
+ if !relate_types (
768
+ self . tcx ,
769
+ self . param_env ,
770
+ Variance :: Covariant ,
771
+ ty,
772
+ place_ref. ty ( & self . body . local_decls , self . tcx ) . ty ,
773
+ ) {
774
+ self . fail (
775
+ location,
776
+ format ! (
777
+ "Failed subtyping {ty:#?} and {:#?}" ,
778
+ place_ref. ty( & self . body. local_decls, self . tcx) . ty
779
+ ) ,
780
+ )
781
+ }
782
+ }
756
783
_ => { }
757
784
}
758
785
self . super_projection_elem ( place_ref, elem, context, location) ;
@@ -1088,6 +1115,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1088
1115
// LHS and RHS of the assignment must have the same type.
1089
1116
let left_ty = dest. ty ( & self . body . local_decls , self . tcx ) . ty ;
1090
1117
let right_ty = rvalue. ty ( & self . body . local_decls , self . tcx ) ;
1118
+
1091
1119
if !self . mir_assign_valid_types ( right_ty, left_ty) {
1092
1120
self . fail (
1093
1121
location,
0 commit comments