@@ -8,6 +8,7 @@ use rustc_infer::traits::query::NoSolution;
8
8
use rustc_infer:: traits:: util:: supertraits;
9
9
use rustc_middle:: traits:: solve:: inspect:: CandidateKind ;
10
10
use rustc_middle:: traits:: solve:: { CanonicalResponse , Certainty , Goal , QueryResult } ;
11
+ use rustc_middle:: traits:: Reveal ;
11
12
use rustc_middle:: ty:: fast_reject:: { DeepRejectCtxt , TreatParams , TreatProjections } ;
12
13
use rustc_middle:: ty:: { self , ToPredicate , Ty , TyCtxt } ;
13
14
use rustc_middle:: ty:: { TraitPredicate , TypeVisitableExt } ;
@@ -120,6 +121,32 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
120
121
return result;
121
122
}
122
123
124
+ // Don't call `type_of` on a local TAIT that's in the defining scope,
125
+ // since that may require calling `typeck` on the same item we're
126
+ // currently type checking, which will result in a fatal cycle that
127
+ // ideally we want to avoid, since we can make progress on this goal
128
+ // via an alias bound or a locally-inferred hidden type instead.
129
+ //
130
+ // Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since
131
+ // we already normalize the self type in
132
+ // `assemble_candidates_after_normalizing_self_ty`, and we'd
133
+ // just be registering an identical candidate here.
134
+ //
135
+ // Returning `Err(NoSolution)` here is ok in `SolverMode::Coherence`
136
+ // since we'll always be registering an ambiguous candidate in
137
+ // `assemble_candidates_after_normalizing_self_ty` due to normalizing
138
+ // the TAIT.
139
+ if let ty:: Alias ( ty:: Opaque , opaque_ty) = goal. predicate . self_ty ( ) . kind ( ) {
140
+ if matches ! ( goal. param_env. reveal( ) , Reveal :: All )
141
+ || opaque_ty
142
+ . def_id
143
+ . as_local ( )
144
+ . is_some_and ( |def_id| ecx. can_define_opaque_ty ( def_id) )
145
+ {
146
+ return Err ( NoSolution ) ;
147
+ }
148
+ }
149
+
123
150
ecx. probe_and_evaluate_goal_for_constituent_tys (
124
151
goal,
125
152
structural_traits:: instantiate_constituent_tys_for_auto_trait,
0 commit comments