@@ -38,11 +38,13 @@ use rustc_middle::ty::{
38
38
use rustc_span:: def_id:: CRATE_DEF_ID ;
39
39
use rustc_span:: { Span , DUMMY_SP } ;
40
40
use rustc_target:: abi:: VariantIdx ;
41
+ use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
41
42
use rustc_trait_selection:: traits:: query:: type_op:: custom:: scrape_region_constraints;
42
43
use rustc_trait_selection:: traits:: query:: type_op:: custom:: CustomTypeOp ;
43
44
use rustc_trait_selection:: traits:: query:: type_op:: { TypeOp , TypeOpOutput } ;
44
45
use rustc_trait_selection:: traits:: query:: Fallible ;
45
46
use rustc_trait_selection:: traits:: PredicateObligation ;
47
+ use rustc_trait_selection:: traits:: { fully_solve_obligation, Obligation , ObligationCause } ;
46
48
47
49
use rustc_mir_dataflow:: impls:: MaybeInitializedPlaces ;
48
50
use rustc_mir_dataflow:: move_paths:: MoveData ;
@@ -1154,6 +1156,31 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1154
1156
self . infcx . tcx
1155
1157
}
1156
1158
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
+
1157
1184
#[ instrument( skip( self , body, location) , level = "debug" ) ]
1158
1185
fn check_stmt ( & mut self , body : & Body < ' tcx > , stmt : & Statement < ' tcx > , location : Location ) {
1159
1186
let tcx = self . tcx ( ) ;
@@ -1871,6 +1898,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1871
1898
Rvalue :: Cast ( cast_kind, op, ty) => {
1872
1899
self . check_operand ( op, location) ;
1873
1900
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
+
1874
1908
match cast_kind {
1875
1909
CastKind :: Pointer ( PointerCast :: ReifyFnPointer ) => {
1876
1910
let fn_sig = op. ty ( body, tcx) . fn_sig ( tcx) ;
@@ -1902,7 +1936,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1902
1936
}
1903
1937
1904
1938
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 ( ) {
1906
1940
ty:: Closure ( _, substs) => substs. as_closure ( ) . sig ( ) ,
1907
1941
_ => bug ! ( ) ,
1908
1942
} ;
@@ -1971,10 +2005,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1971
2005
// get the constraints from the target type (`dyn* Clone`)
1972
2006
//
1973
2007
// 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
+ } ;
1978
2013
1979
2014
let self_ty = op. ty ( body, tcx) ;
1980
2015
@@ -2001,7 +2036,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2001
2036
let ty:: RawPtr ( ty:: TypeAndMut {
2002
2037
ty : ty_from,
2003
2038
mutbl : hir:: Mutability :: Mut ,
2004
- } ) = op. ty ( body, tcx) . kind ( ) else {
2039
+ } ) = self . structurally_resolved_ty ( op. ty ( body, tcx) ) . kind ( ) else {
2005
2040
span_mirbug ! (
2006
2041
self ,
2007
2042
rvalue,
@@ -2013,7 +2048,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2013
2048
let ty:: RawPtr ( ty:: TypeAndMut {
2014
2049
ty : ty_to,
2015
2050
mutbl : hir:: Mutability :: Not ,
2016
- } ) = ty . kind ( ) else {
2051
+ } ) = self . structurally_resolved_ty ( * ty ) . kind ( ) else {
2017
2052
span_mirbug ! (
2018
2053
self ,
2019
2054
rvalue,
@@ -2042,7 +2077,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2042
2077
CastKind :: Pointer ( PointerCast :: ArrayToPointer ) => {
2043
2078
let ty_from = op. ty ( body, tcx) ;
2044
2079
2045
- let opt_ty_elem_mut = match ty_from. kind ( ) {
2080
+ let opt_ty_elem_mut = match self . structurally_resolved_ty ( ty_from) . kind ( ) {
2046
2081
ty:: RawPtr ( ty:: TypeAndMut { mutbl : array_mut, ty : array_ty } ) => {
2047
2082
match array_ty. kind ( ) {
2048
2083
ty:: Array ( ty_elem, _) => Some ( ( ty_elem, * array_mut) ) ,
@@ -2062,7 +2097,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2062
2097
return ;
2063
2098
} ;
2064
2099
2065
- let ( ty_to, ty_to_mut) = match ty . kind ( ) {
2100
+ let ( ty_to, ty_to_mut) = match self . structurally_resolved_ty ( * ty ) . kind ( ) {
2066
2101
ty:: RawPtr ( ty:: TypeAndMut { mutbl : ty_to_mut, ty : ty_to } ) => {
2067
2102
( ty_to, * ty_to_mut)
2068
2103
}
@@ -2106,9 +2141,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2106
2141
}
2107
2142
2108
2143
CastKind :: PointerExposeAddress => {
2109
- let ty_from = op . ty ( body , tcx ) ;
2144
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2110
2145
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) ;
2112
2147
match ( cast_ty_from, cast_ty_to) {
2113
2148
( Some ( CastTy :: Ptr ( _) | CastTy :: FnPtr ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
2114
2149
_ => {
@@ -2124,9 +2159,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2124
2159
}
2125
2160
2126
2161
CastKind :: PointerFromExposedAddress => {
2127
- let ty_from = op . ty ( body , tcx ) ;
2162
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2128
2163
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) ;
2130
2165
match ( cast_ty_from, cast_ty_to) {
2131
2166
( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
2132
2167
_ => {
@@ -2141,9 +2176,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2141
2176
}
2142
2177
}
2143
2178
CastKind :: IntToInt => {
2144
- let ty_from = op . ty ( body , tcx ) ;
2179
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2145
2180
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) ;
2147
2182
match ( cast_ty_from, cast_ty_to) {
2148
2183
( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
2149
2184
_ => {
@@ -2158,9 +2193,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2158
2193
}
2159
2194
}
2160
2195
CastKind :: IntToFloat => {
2161
- let ty_from = op . ty ( body , tcx ) ;
2196
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2162
2197
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) ;
2164
2199
match ( cast_ty_from, cast_ty_to) {
2165
2200
( Some ( CastTy :: Int ( _) ) , Some ( CastTy :: Float ) ) => ( ) ,
2166
2201
_ => {
@@ -2175,9 +2210,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2175
2210
}
2176
2211
}
2177
2212
CastKind :: FloatToInt => {
2178
- let ty_from = op . ty ( body , tcx ) ;
2213
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2179
2214
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) ;
2181
2216
match ( cast_ty_from, cast_ty_to) {
2182
2217
( Some ( CastTy :: Float ) , Some ( CastTy :: Int ( _) ) ) => ( ) ,
2183
2218
_ => {
@@ -2192,9 +2227,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2192
2227
}
2193
2228
}
2194
2229
CastKind :: FloatToFloat => {
2195
- let ty_from = op . ty ( body , tcx ) ;
2230
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2196
2231
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) ;
2198
2233
match ( cast_ty_from, cast_ty_to) {
2199
2234
( Some ( CastTy :: Float ) , Some ( CastTy :: Float ) ) => ( ) ,
2200
2235
_ => {
@@ -2209,9 +2244,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2209
2244
}
2210
2245
}
2211
2246
CastKind :: FnPtrToPtr => {
2212
- let ty_from = op . ty ( body , tcx ) ;
2247
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2213
2248
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) ;
2215
2250
match ( cast_ty_from, cast_ty_to) {
2216
2251
( Some ( CastTy :: FnPtr ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
2217
2252
_ => {
@@ -2226,9 +2261,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2226
2261
}
2227
2262
}
2228
2263
CastKind :: PtrToPtr => {
2229
- let ty_from = op . ty ( body , tcx ) ;
2264
+ let ( ty_from, ty ) = structurally_resolved_cast_tys ( ) ;
2230
2265
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) ;
2232
2267
match ( cast_ty_from, cast_ty_to) {
2233
2268
( Some ( CastTy :: Ptr ( _) ) , Some ( CastTy :: Ptr ( _) ) ) => ( ) ,
2234
2269
_ => {
0 commit comments