@@ -38,11 +38,13 @@ use rustc_middle::ty::{
3838use rustc_span:: def_id:: CRATE_DEF_ID ;
3939use rustc_span:: { Span , DUMMY_SP } ;
4040use rustc_target:: abi:: VariantIdx ;
41+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
4142use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
4243use rustc_trait_selection:: traits:: query:: type_op:: custom:: CustomTypeOp ;
4344use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
4445use rustc_trait_selection:: traits:: query:: Fallible ;
4546use rustc_trait_selection:: traits:: PredicateObligation ;
47+ use rustc_trait_selection:: traits:: { fully_solve_obligation, Obligation , ObligationCause } ;
4648
4749use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
4850use rustc_mir_dataflow:: move_paths:: MoveData ;
@@ -1154,6 +1156,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11541156 self . infcx . tcx
11551157 }
11561158
1159+ fn structurally_resolved_ty ( & self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
1160+ if self . tcx ( ) . trait_solver_next ( ) && let ty:: Alias ( ty:: Projection , projection_ty) = * ty. kind ( ) {
1161+ let new_infer_ty = self . infcx . next_ty_var ( TypeVariableOrigin {
1162+ kind : TypeVariableOriginKind :: NormalizeProjectionType ,
1163+ span : DUMMY_SP ,
1164+ } ) ;
1165+ let obligation = Obligation :: new (
1166+ self . tcx ( ) ,
1167+ ObligationCause :: dummy ( ) ,
1168+ self . param_env ,
1169+ ty:: Binder :: dummy ( ty:: ProjectionPredicate {
1170+ projection_ty,
1171+ term : new_infer_ty. into ( ) ,
1172+ } ) ,
1173+ ) ;
1174+
1175+ if self . infcx . predicate_may_hold ( & obligation) {
1176+ fully_solve_obligation ( & self . infcx , obligation) ;
1177+ return self . infcx . resolve_vars_if_possible ( new_infer_ty) ;
1178+ }
1179+ }
1180+
1181+ ty
1182+ }
1183+
11571184 #[ instrument( skip( self , body, location) , level = "debug" ) ]
11581185 fn check_stmt ( & mut self , body : & Body < ' tcx > , stmt : & Statement < ' tcx > , location : Location ) {
11591186 let tcx = self . tcx ( ) ;
@@ -1871,6 +1898,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
18711898 Rvalue :: Cast ( cast_kind, op, ty) => {
18721899 self . check_operand ( op, location) ;
18731900
1901+ let structurally_resolved_cast_tys = || {
1902+ (
1903+ self . structurally_resolved_ty ( op. ty ( body, tcx) ) ,
1904+ self . structurally_resolved_ty ( * ty) ,
1905+ )
1906+ } ;
1907+
18741908 match cast_kind {
18751909 CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
18761910 let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -1902,7 +1936,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19021936 }
19031937
19041938 CastKind :: Pointer ( PointerCast :: ClosureFnPointer ( unsafety) ) => {
1905- let sig = match op. ty ( body, tcx) . kind ( ) {
1939+ let sig = match self . structurally_resolved_ty ( op. ty ( body, tcx) ) . kind ( ) {
19061940 ty:: Closure ( _, substs) => substs. as_closure ( ) . sig ( ) ,
19071941 _ => bug ! ( ) ,
19081942 } ;
@@ -1971,10 +2005,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19712005 // get the constraints from the target type (`dyn* Clone`)
19722006 //
19732007 // apply them to prove that the source type `Foo` implements `Clone` etc
1974- let ( existential_predicates, region) = match ty. kind ( ) {
1975- Dynamic ( predicates, region, ty:: DynStar ) => ( predicates, region) ,
1976- _ => panic ! ( "Invalid dyn* cast_ty" ) ,
1977- } ;
2008+ let ( existential_predicates, region) =
2009+ match self . structurally_resolved_ty ( * ty) . kind ( ) {
2010+ Dynamic ( predicates, region, ty:: DynStar ) => ( predicates, region) ,
2011+ _ => panic ! ( "Invalid dyn* cast_ty" ) ,
2012+ } ;
19782013
19792014 let self_ty = op. ty ( body, tcx) ;
19802015
@@ -2001,7 +2036,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20012036 let ty:: RawPtr ( ty:: TypeAndMut {
20022037 ty : ty_from,
20032038 mutbl : hir:: Mutability :: Mut ,
2004- } ) = op. ty ( body, tcx) . kind ( ) else {
2039+ } ) = self . structurally_resolved_ty ( op. ty ( body, tcx) ) . kind ( ) else {
20052040 span_mirbug ! (
20062041 self ,
20072042 rvalue,
@@ -2013,7 +2048,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20132048 let ty:: RawPtr ( ty:: TypeAndMut {
20142049 ty : ty_to,
20152050 mutbl : hir:: Mutability :: Not ,
2016- } ) = ty . kind ( ) else {
2051+ } ) = self . structurally_resolved_ty ( * ty ) . kind ( ) else {
20172052 span_mirbug ! (
20182053 self ,
20192054 rvalue,
@@ -2042,7 +2077,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20422077 CastKind :: Pointer ( PointerCast :: ArrayToPointer ) => {
20432078 let ty_from = op. ty ( body, tcx) ;
20442079
2045- let opt_ty_elem_mut = match ty_from. kind ( ) {
2080+ let opt_ty_elem_mut = match self . structurally_resolved_ty ( ty_from) . kind ( ) {
20462081 ty:: RawPtr ( ty:: TypeAndMut { mutbl : array_mut, ty : array_ty } ) => {
20472082 match array_ty. kind ( ) {
20482083 ty:: Array ( ty_elem, _) => Some ( ( ty_elem, * array_mut) ) ,
@@ -2062,7 +2097,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20622097 return ;
20632098 } ;
20642099
2065- let ( ty_to, ty_to_mut) = match ty . kind ( ) {
2100+ let ( ty_to, ty_to_mut) = match self . structurally_resolved_ty ( * ty ) . kind ( ) {
20662101 ty:: RawPtr ( ty:: TypeAndMut { mutbl : ty_to_mut, ty : ty_to } ) => {
20672102 ( ty_to, * ty_to_mut)
20682103 }
@@ -2106,9 +2141,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21062141 }
21072142
21082143 CastKind :: PointerExposeAddress => {
2109- let ty_from = op . ty ( body , tcx ) ;
2144+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21102145 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2111- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2146+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21122147 match ( cast_ty_from, cast_ty_to) {
21132148 ( Some ( CastTy :: Ptr ( _) | CastTy :: FnPtr ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
21142149 _ => {
@@ -2124,9 +2159,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21242159 }
21252160
21262161 CastKind :: PointerFromExposedAddress => {
2127- let ty_from = op . ty ( body , tcx ) ;
2162+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21282163 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2129- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2164+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21302165 match ( cast_ty_from, cast_ty_to) {
21312166 ( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
21322167 _ => {
@@ -2141,9 +2176,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21412176 }
21422177 }
21432178 CastKind :: IntToInt => {
2144- let ty_from = op . ty ( body , tcx ) ;
2179+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21452180 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2146- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2181+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21472182 match ( cast_ty_from, cast_ty_to) {
21482183 ( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
21492184 _ => {
@@ -2158,9 +2193,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21582193 }
21592194 }
21602195 CastKind :: IntToFloat => {
2161- let ty_from = op . ty ( body , tcx ) ;
2196+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21622197 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2163- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2198+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21642199 match ( cast_ty_from, cast_ty_to) {
21652200 ( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Float ) ) => ( ) ,
21662201 _ => {
@@ -2175,9 +2210,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21752210 }
21762211 }
21772212 CastKind :: FloatToInt => {
2178- let ty_from = op . ty ( body , tcx ) ;
2213+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21792214 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2180- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2215+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21812216 match ( cast_ty_from, cast_ty_to) {
21822217 ( Some ( CastTy :: Float ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
21832218 _ => {
@@ -2192,9 +2227,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
21922227 }
21932228 }
21942229 CastKind :: FloatToFloat => {
2195- let ty_from = op . ty ( body , tcx ) ;
2230+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
21962231 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2197- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2232+ let cast_ty_to = CastTy :: from_ty ( ty) ;
21982233 match ( cast_ty_from, cast_ty_to) {
21992234 ( Some ( CastTy :: Float ) , Some ( CastTy :: Float ) ) => ( ) ,
22002235 _ => {
@@ -2209,9 +2244,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22092244 }
22102245 }
22112246 CastKind :: FnPtrToPtr => {
2212- let ty_from = op . ty ( body , tcx ) ;
2247+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
22132248 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2214- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2249+ let cast_ty_to = CastTy :: from_ty ( ty) ;
22152250 match ( cast_ty_from, cast_ty_to) {
22162251 ( Some ( CastTy :: FnPtr ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
22172252 _ => {
@@ -2226,9 +2261,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
22262261 }
22272262 }
22282263 CastKind :: PtrToPtr => {
2229- let ty_from = op . ty ( body , tcx ) ;
2264+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
22302265 let cast_ty_from = CastTy :: from_ty ( ty_from) ;
2231- let cast_ty_to = CastTy :: from_ty ( * ty) ;
2266+ let cast_ty_to = CastTy :: from_ty ( ty) ;
22322267 match ( cast_ty_from, cast_ty_to) {
22332268 ( Some ( CastTy :: Ptr ( _) ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
22342269 _ => {
0 commit comments