@@ -297,25 +297,61 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
297297 fn try_normalize_ty (
298298 & mut self ,
299299 param_env : ty:: ParamEnv < ' tcx > ,
300- mut ty : Ty < ' tcx > ,
301- ) -> Result < Option < Ty < ' tcx > > , NoSolution > {
302- for _ in 0 ..self . local_overflow_limit ( ) {
303- let ty:: Alias ( _, projection_ty) = * ty. kind ( ) else {
304- return Ok ( Some ( ty) ) ;
305- } ;
306-
307- let normalized_ty = self . next_ty_infer ( ) ;
300+ ty : Ty < ' tcx > ,
301+ ) -> Option < Ty < ' tcx > > {
302+ self . try_normalize_ty_recur ( param_env, 0 , ty)
303+ }
304+
305+ fn try_normalize_ty_recur (
306+ & mut self ,
307+ param_env : ty:: ParamEnv < ' tcx > ,
308+ depth : usize ,
309+ ty : Ty < ' tcx > ,
310+ ) -> Option < Ty < ' tcx > > {
311+ if depth >= self . local_overflow_limit ( ) {
312+ return None ;
313+ }
314+
315+ let ty:: Alias ( kind, projection_ty) = * ty. kind ( ) else {
316+ return Some ( ty) ;
317+ } ;
318+
319+ // We do no always define opaque types eagerly to allow non-defining uses in the defining scope.
320+ if let ( DefineOpaqueTypes :: No , ty:: AliasKind :: Opaque ) = ( define_opaque_types, kind) {
321+ if let Some ( def_id) = projection_ty. def_id . as_local ( ) {
322+ if self
323+ . unify_existing_opaque_tys (
324+ param_env,
325+ OpaqueTypeKey { def_id, args : projection_ty. args } ,
326+ self . next_ty_infer ( ) ,
327+ )
328+ . is_empty ( )
329+ {
330+ return Some ( ty) ;
331+ }
332+ }
333+ }
334+
335+ // FIXME(@lcnr): If the normalization of the alias adds an inference constraint which
336+ // causes a previously added goal to fail, then we treat the alias as rigid.
337+ //
338+ // These feels like a potential issue, I should look into writing some tests here
339+ // and then probably changing `commit_if_ok` to not inherit the parent goals.
340+ match self . commit_if_ok ( |this| {
341+ let normalized_ty = this. next_ty_infer ( ) ;
308342 let normalizes_to_goal = Goal :: new (
309- self . tcx ( ) ,
343+ this . tcx ( ) ,
310344 param_env,
311345 ty:: ProjectionPredicate { projection_ty, term : normalized_ty. into ( ) } ,
312346 ) ;
313- self . add_goal ( normalizes_to_goal) ;
314- self . try_evaluate_added_goals ( ) ?;
315- ty = self . resolve_vars_if_possible ( normalized_ty) ;
347+ this. add_goal ( normalizes_to_goal) ;
348+ this. try_evaluate_added_goals ( ) ?;
349+ let ty = this. resolve_vars_if_possible ( normalized_ty) ;
350+ Ok ( this. try_normalize_ty_recur ( param_env, depth + 1 , ty) )
351+ } ) {
352+ Ok ( ty) => ty,
353+ Err ( NoSolution ) => Some ( ty) ,
316354 }
317-
318- Ok ( None )
319355 }
320356}
321357
0 commit comments