diff --git a/packages/pyright-internal/src/analyzer/operations.ts b/packages/pyright-internal/src/analyzer/operations.ts index 6ffd1233968b..ca2672395fed 100644 --- a/packages/pyright-internal/src/analyzer/operations.ts +++ b/packages/pyright-internal/src/analyzer/operations.ts @@ -1037,7 +1037,10 @@ function calcLiteralForBinaryOp(operator: OperatorType, leftType: Type, rightTyp // infinity, so we need to adjust the result if the signs // of the operands are different. if (leftLiteralValue !== rightLiteralValue && leftLiteralValue !== BigInt(0)) { - if (leftLiteralValue < BigInt(0) !== rightLiteralValue < BigInt(0)) { + if ( + leftLiteralValue < BigInt(0) !== rightLiteralValue < BigInt(0) && + leftLiteralValue !== rightLiteralValue * BigInt(-1) + ) { newValue -= BigInt(1); } } @@ -1055,9 +1058,13 @@ function calcLiteralForBinaryOp(operator: OperatorType, leftType: Type, rightTyp } } } else if (operator === OperatorType.LeftShift) { - newValue = leftLiteralValue << rightLiteralValue; + if (rightLiteralValue >= BigInt(0)) { + newValue = leftLiteralValue << rightLiteralValue; + } } else if (operator === OperatorType.RightShift) { - newValue = leftLiteralValue >> rightLiteralValue; + if (rightLiteralValue >= BigInt(0)) { + newValue = leftLiteralValue >> rightLiteralValue; + } } else if (operator === OperatorType.BitwiseAnd) { newValue = leftLiteralValue & rightLiteralValue; } else if (operator === OperatorType.BitwiseOr) { diff --git a/packages/pyright-internal/src/tests/samples/operator8.py b/packages/pyright-internal/src/tests/samples/operator8.py index 1a3d2b89b021..654658819ab6 100644 --- a/packages/pyright-internal/src/tests/samples/operator8.py +++ b/packages/pyright-internal/src/tests/samples/operator8.py @@ -71,6 +71,18 @@ def func1(a: Literal[1, 2], b: Literal[0, 4], c: Literal[3, 4]): c10 = 0 // 6 reveal_type(c10, expected_text="Literal[0]") + c11 = -6 // 6 + reveal_type(c11, expected_text="Literal[-1]") + + c12 = 6 // -6 + reveal_type(c12, expected_text="Literal[-1]") + + c13 = 1 << -1 + reveal_type(c13, expected_text="int") + + c14 = 1 >> -1 + reveal_type(c14, expected_text="int") + def func2(cond: bool): c1 = "Hi " + ("Steve" if cond else "Amy")