From 0d0b75ac7e8420a8226457ed4ce698d86011df6e Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Sat, 18 Jul 2026 13:09:39 +0900 Subject: [PATCH] fix --- pyrefly/lib/solver/subset.rs | 4 ++++ pyrefly/lib/test/generic_basic.rs | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/pyrefly/lib/solver/subset.rs b/pyrefly/lib/solver/subset.rs index b2495f9647..897d34b143 100644 --- a/pyrefly/lib/solver/subset.rs +++ b/pyrefly/lib/solver/subset.rs @@ -1791,6 +1791,10 @@ impl<'a, Ans: LookupAnswer> Subset<'a, Ans> { // Therefore try these quantified cases, but only pick them if they work. (Type::Quantified(q), u) if let Restriction::Bound(bound) = q.restriction() + // A bare inference variable can preserve the quantified type itself. Expanding + // it to its bound here would make inference depend on which argument is checked + // first (https://github.com/facebook/pyrefly/issues/4187). + && !matches!(u, Type::Union(union) if union.members.iter().any(|t| matches!(t, Type::Var(_)))) && self .solver .with_snapshot(&u.collect_maybe_placeholder_vars(), || { diff --git a/pyrefly/lib/test/generic_basic.rs b/pyrefly/lib/test/generic_basic.rs index c80e5a509d..d3b06f2a8b 100644 --- a/pyrefly/lib/test/generic_basic.rs +++ b/pyrefly/lib/test/generic_basic.rs @@ -705,6 +705,30 @@ assert_type(bad(Sub), Sub) "#, ); +// Regression test for https://github.com/facebook/pyrefly/issues/4187 +testcase!( + test_generic_keyword_inference_is_order_independent, + r#" +class P: ... + +class Controller[T: P]: + value: T + +def target[T: P]( + value: T | None = None, + *, + controller: Controller[T] | None = None, +) -> None: ... + +def caller[T: P]( + value: T | None, + controller: Controller[T] | None, +) -> None: + target(value=value, controller=controller) + target(controller=controller, value=value) +"#, +); + testcase!( test_generic_alias_fields, r#"