@@ -7,6 +7,7 @@ use rustc_middle::mir::ConstraintCategory;
77use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeFoldable , Upcast } ;
88use rustc_span:: Span ;
99use rustc_span:: def_id:: DefId ;
10+ use rustc_trait_selection:: solve:: NoSolution ;
1011use rustc_trait_selection:: traits:: ObligationCause ;
1112use rustc_trait_selection:: traits:: query:: type_op:: custom:: CustomTypeOp ;
1213use rustc_trait_selection:: traits:: query:: type_op:: { self , TypeOpOutput } ;
@@ -177,6 +178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
177178 if self . infcx . next_trait_solver ( ) {
178179 let body = self . body ;
179180 let param_env = self . infcx . param_env ;
181+ // FIXME: Make this into a real type op?
180182 self . fully_perform_op (
181183 location. to_locations ( ) ,
182184 ConstraintCategory :: Boring ,
@@ -213,6 +215,40 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
213215 }
214216 }
215217
218+ #[ instrument( skip( self ) , level = "debug" ) ]
219+ pub ( super ) fn structurally_resolve (
220+ & mut self ,
221+ ty : Ty < ' tcx > ,
222+ location : impl NormalizeLocation ,
223+ ) -> Ty < ' tcx > {
224+ if self . infcx . next_trait_solver ( ) {
225+ let body = self . body ;
226+ let param_env = self . infcx . param_env ;
227+ // FIXME: Make this into a real type op?
228+ self . fully_perform_op (
229+ location. to_locations ( ) ,
230+ ConstraintCategory :: Boring ,
231+ CustomTypeOp :: new (
232+ |ocx| {
233+ ocx. structurally_normalize (
234+ & ObligationCause :: misc (
235+ location. to_locations ( ) . span ( body) ,
236+ body. source . def_id ( ) . expect_local ( ) ,
237+ ) ,
238+ param_env,
239+ ty,
240+ )
241+ . map_err ( |_| NoSolution )
242+ } ,
243+ "normalizing struct tail" ,
244+ ) ,
245+ )
246+ . unwrap_or_else ( |guar| Ty :: new_error ( self . tcx ( ) , guar) )
247+ } else {
248+ self . normalize ( ty, location)
249+ }
250+ }
251+
216252 #[ instrument( skip( self ) , level = "debug" ) ]
217253 pub ( super ) fn ascribe_user_type (
218254 & mut self ,
0 commit comments