@@ -748,7 +748,7 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> {
748748 /// annotations. Part of the reason for this setup is that it allows us to enforce basic
749749 /// WF criteria on the types even if the code that referenced them is dead
750750 /// code (see #54943).
751- instantiated_type_annotations : FxHashMap < UserTypeAnnotationIndex , UserType < ' tcx > > ,
751+ instantiated_type_annotations : FxHashMap < UserTypeAnnotationIndex , Ty < ' tcx > > ,
752752}
753753
754754struct BorrowCheckContext < ' a , ' tcx : ' a > {
@@ -920,17 +920,58 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
920920 self . mir. user_type_annotations
921921 ) ;
922922 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 } =
924924 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 (
926926 span, user_ty
927927 ) ;
928928 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+ } ,
932973 }
933- self . instantiated_type_annotations . insert ( annotation_index, annotation ) ;
974+ self . instantiated_type_annotations . insert ( annotation_index, inferred_ty ) ;
934975 }
935976 debug ! (
936977 "instantiate_user_type_annotations: instantiated_type_annotations={:?}" ,
@@ -1067,58 +1108,23 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
10671108 a, v, user_ty, locations,
10681109 ) ;
10691110
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) ;
10781113
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 ;
11051115
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;
11211122 }
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) ?;
11221128
11231129 Ok ( ( ) )
11241130 }
0 commit comments