@@ -260,26 +260,38 @@ RequirementMachine::getLongestValidPrefix(const MutableTerm &term) const {
260260// / concrete type).
261261bool RequirementMachine::isCanonicalTypeInContext (Type type) const {
262262 // Look for non-canonical type parameters.
263- return !type.findIf ([&](Type component) -> bool {
264- if (!component->isTypeParameter ())
265- return false ;
263+ class Walker : public TypeWalker {
264+ const RequirementMachine &Self;
266265
267- auto term = Context. getMutableTermForType (component-> getCanonicalType (),
268- /* proto= */ nullptr );
266+ public:
267+ explicit Walker ( const RequirementMachine &self) : Self(self) {}
269268
270- System.simplify (term);
271- verify (term);
269+ Action walkToTypePre (Type component) override {
270+ if (!component->isTypeParameter ())
271+ return Action::Continue;
272272
273- auto *props = Map. lookUpProperties (term);
274- if (!props)
275- return false ;
273+ auto term = Self. Context . getMutableTermForType (
274+ component-> getCanonicalType (),
275+ /* proto= */ nullptr ) ;
276276
277- if (props-> isConcreteType ())
278- return true ;
277+ Self. System . simplify (term);
278+ Self. verify (term) ;
279279
280- auto anchor = Context.getTypeForTerm (term, {});
281- return CanType (anchor) != CanType (component);
282- });
280+ auto anchor = Self.Context .getTypeForTerm (term, {});
281+ if (CanType (anchor) != CanType (component))
282+ return Action::Stop;
283+
284+ auto *props = Self.Map .lookUpProperties (term);
285+ if (props && props->isConcreteType ())
286+ return Action::Stop;
287+
288+ // The parent of a canonical type parameter might be non-canonical
289+ // because it is concrete.
290+ return Action::SkipChildren;
291+ }
292+ };
293+
294+ return !type.walk (Walker (*this ));
283295}
284296
285297// / Unlike most other queries, the input type can be any type, not just a
0 commit comments