@@ -748,7 +748,7 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
748
748
/// annotations. Part of the reason for this setup is that it allows us to enforce basic
749
749
/// WF criteria on the types even if the code that referenced them is dead
750
750
/// code (see #54943).
751
- instantiated_type_annotations : FxHashMap < UserTypeAnnotationIndex , UserType < ' tcx > > ,
751
+ instantiated_type_annotations : FxHashMap < UserTypeAnnotationIndex , Ty < ' tcx > > ,
752
752
}
753
753
754
754
struct BorrowCheckContext < ' a , ' tcx : ' a > {
@@ -920,17 +920,58 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
920
920
self . mir. user_type_annotations
921
921
) ;
922
922
for annotation_index in self . mir . user_type_annotations . indices ( ) {
923
- let CanonicalUserTypeAnnotation { span, ref user_ty } =
923
+ let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } =
924
924
self . mir . user_type_annotations [ annotation_index] ;
925
- let ( mut annotation, _) = self . infcx . instantiate_canonical_with_fresh_inference_vars (
925
+ let ( annotation, _) = self . infcx . instantiate_canonical_with_fresh_inference_vars (
926
926
span, user_ty
927
927
) ;
928
928
match annotation {
929
- UserType :: Ty ( ref mut ty) =>
930
- * ty = self . normalize ( ty, Locations :: All ( span) ) ,
931
- _ => { } ,
929
+ UserType :: Ty ( mut ty) => {
930
+ ty = self . normalize ( ty, Locations :: All ( span) ) ;
931
+
932
+ if let Err ( terr) = self . eq_types (
933
+ ty,
934
+ inferred_ty,
935
+ Locations :: All ( span) ,
936
+ ConstraintCategory :: BoringNoLocation ,
937
+ ) {
938
+ span_mirbug ! (
939
+ self ,
940
+ self . mir. user_type_annotations[ annotation_index] ,
941
+ "bad user type ({:?} = {:?}): {:?}" ,
942
+ ty,
943
+ inferred_ty,
944
+ terr
945
+ ) ;
946
+ }
947
+
948
+ self . prove_predicate (
949
+ ty:: Predicate :: WellFormed ( inferred_ty) ,
950
+ Locations :: All ( span) ,
951
+ ConstraintCategory :: TypeAnnotation ,
952
+ ) ;
953
+ } ,
954
+ UserType :: TypeOf ( def_id, user_substs) => {
955
+ if let Err ( terr) = self . fully_perform_op (
956
+ Locations :: All ( span) ,
957
+ ConstraintCategory :: BoringNoLocation ,
958
+ self . param_env . and ( type_op:: ascribe_user_type:: AscribeUserType :: new (
959
+ inferred_ty, def_id, user_substs,
960
+ ) ) ,
961
+ ) {
962
+ span_mirbug ! (
963
+ self ,
964
+ self . mir. user_type_annotations[ annotation_index] ,
965
+ "bad user type AscribeUserType({:?}, {:?} {:?}): {:?}" ,
966
+ inferred_ty,
967
+ def_id,
968
+ user_substs,
969
+ terr
970
+ ) ;
971
+ }
972
+ } ,
932
973
}
933
- self . instantiated_type_annotations . insert ( annotation_index, annotation ) ;
974
+ self . instantiated_type_annotations . insert ( annotation_index, inferred_ty ) ;
934
975
}
935
976
debug ! (
936
977
"instantiate_user_type_annotations: instantiated_type_annotations={:?}" ,
@@ -1067,58 +1108,23 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1067
1108
a, v, user_ty, locations,
1068
1109
) ;
1069
1110
1070
- let type_annotation = self . instantiated_type_annotations [ & user_ty. base ] ;
1071
- match type_annotation {
1072
- UserType :: Ty ( ty) => {
1073
- // The `TypeRelating` code assumes that "unresolved inference
1074
- // variables" appear in the "a" side, so flip `Contravariant`
1075
- // ambient variance to get the right relationship.
1076
- let v1 = ty:: Contravariant . xform ( v) ;
1077
- let tcx = self . infcx . tcx ;
1111
+ let annotated_type = self . instantiated_type_annotations [ & user_ty. base ] ;
1112
+ let mut curr_projected_ty = PlaceTy :: from_ty ( annotated_type) ;
1078
1113
1079
- // We need to follow any provided projetions into the type.
1080
- //
1081
- // if we hit a ty var as we descend, then just skip the
1082
- // attempt to relate the mir local with any type.
1083
- #[ derive( Debug ) ] struct HitTyVar ;
1084
- let mut curr_projected_ty: Result < PlaceTy , HitTyVar > ;
1085
-
1086
- curr_projected_ty = Ok ( PlaceTy :: from_ty ( ty) ) ;
1087
- for proj in & user_ty. projs {
1088
- let projected_ty = if let Ok ( projected_ty) = curr_projected_ty {
1089
- projected_ty
1090
- } else {
1091
- break ;
1092
- } ;
1093
- curr_projected_ty = projected_ty. projection_ty_core (
1094
- tcx, proj, |this, field, & ( ) | {
1095
- if this. to_ty ( tcx) . is_ty_var ( ) {
1096
- Err ( HitTyVar )
1097
- } else {
1098
- let ty = this. field_ty ( tcx, field) ;
1099
- Ok ( self . normalize ( ty, locations) )
1100
- }
1101
- } ) ;
1102
- }
1103
- debug ! ( "user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}" ,
1104
- user_ty. base, ty, user_ty. projs, curr_projected_ty) ;
1114
+ let tcx = self . infcx . tcx ;
1105
1115
1106
- if let Ok ( projected_ty) = curr_projected_ty {
1107
- let ty = projected_ty. to_ty ( tcx) ;
1108
- self . relate_types ( ty, v1, a, locations, category) ?;
1109
- }
1110
- }
1111
- UserType :: TypeOf ( def_id, user_substs) => {
1112
- let projs = self . infcx . tcx . intern_projs ( & user_ty. projs ) ;
1113
- self . fully_perform_op (
1114
- locations,
1115
- category,
1116
- self . param_env . and ( type_op:: ascribe_user_type:: AscribeUserType :: new (
1117
- a, v, def_id, user_substs, projs,
1118
- ) ) ,
1119
- ) ?;
1120
- }
1116
+ for proj in & user_ty. projs {
1117
+ let projected_ty = curr_projected_ty. projection_ty_core ( tcx, proj, |this, field, & ( ) | {
1118
+ let ty = this. field_ty ( tcx, field) ;
1119
+ self . normalize ( ty, locations)
1120
+ } ) ;
1121
+ curr_projected_ty = projected_ty;
1121
1122
}
1123
+ debug ! ( "user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}" ,
1124
+ user_ty. base, annotated_type, user_ty. projs, curr_projected_ty) ;
1125
+
1126
+ let ty = curr_projected_ty. to_ty ( tcx) ;
1127
+ self . relate_types ( a, v, ty, locations, category) ?;
1122
1128
1123
1129
Ok ( ( ) )
1124
1130
}
0 commit comments