diff --git a/pyrefly/lib/alt/operators.rs b/pyrefly/lib/alt/operators.rs index 0a081e908b..2799aaeee9 100644 --- a/pyrefly/lib/alt/operators.rs +++ b/pyrefly/lib/alt/operators.rs @@ -444,7 +444,7 @@ impl<'a, Ans: LookupAnswer> AnswersSolver<'a, Ans> { || ErrorContext::UnaryOp(x.op.as_str().to_owned(), self.for_display(t.clone())); match t { Type::Literal(lit) if let Some(ret) = f(lit) => ret, - Type::ClassType(_) | Type::SelfType(_) => { + Type::ClassType(_) | Type::SelfType(_) | Type::Quantified(_) => { self.call_method_or_error(t, method, x.range, &[], &[], errors, Some(&context)) } Type::Literal(Lit::Enum(lit_enum)) => self.call_method_or_error( diff --git a/pyrefly/lib/test/operators.rs b/pyrefly/lib/test/operators.rs index 57c0fc5a07..e179a5e884 100644 --- a/pyrefly/lib/test/operators.rs +++ b/pyrefly/lib/test/operators.rs @@ -286,6 +286,27 @@ assert_type(~c, Literal[100]) "#, ); +testcase!( + test_unary_dunders_typevar_bound, + r#" +from typing import Self + +class Foo: + def __neg__(self) -> Self: + return self + def __pos__(self) -> Self: + return self + def __invert__(self) -> Self: + return self + +def test[F: Foo](foo: F) -> F: + a: F = -foo + b: F = +foo + c: F = ~foo + return c + "#, +); + testcase!( test_unary_error, r#"