diff --git a/src/Type/Accessory/AccessoryLiteralStringType.php b/src/Type/Accessory/AccessoryLiteralStringType.php index eac0986542..da1a00a16a 100644 --- a/src/Type/Accessory/AccessoryLiteralStringType.php +++ b/src/Type/Accessory/AccessoryLiteralStringType.php @@ -153,7 +153,11 @@ public function getOffsetValueType(Type $offsetType): Type public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $unionValues = true): Type { - return $this; + if ($valueType->isLiteralString()->yes()) { + return $this; + } + + return new StringType(); } public function setExistingOffsetValueType(Type $offsetType, Type $valueType): Type diff --git a/tests/PHPStan/Analyser/nsrt/bug-3981.php b/tests/PHPStan/Analyser/nsrt/bug-3981.php index 438e676569..1f982a8250 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-3981.php +++ b/tests/PHPStan/Analyser/nsrt/bug-3981.php @@ -27,4 +27,17 @@ public function doFoo(string $s, string $nonEmptyString): void assertType('non-empty-string', $s); } + /** + * @param literal-string $literalString + * @param literal-string $anotherLiteralString + */ + public function doBar(string $literalString, string $generalString): void + { + $literalString[0] = 'a'; + assertType('literal-string&non-empty-string', $literalString); + + $literalString[1] = $generalString; + assertType('non-empty-string', $literalString); + } + }