Repository: symfony/symfony
File: src/Symfony/Component/Form/Extension/Core/Type/CurrencyType.php (PHP)

Code before:
                            }

                            if (null !== $activeAt && null !== $notActiveAt) {
                                throw new InvalidOptionsException('The "active_at" and "not_active_at" options cannot be used together.');
                            }

                            $filteredCurrencyNames = [];

                            $active = match (true) {
                                null !== $activeAt => true,
                                null !== $notActiveAt => false,
                                default => null,
                            };

                            foreach (Currencies::getCurrencyCodes() as $code) {
                                if (!Currencies::isValidInAnyCountry($code, $legalTender, $active, $activeAt ?? $notActiveAt)) {
                                    continue;
                                }

                                $filteredCurrencyNames[$code] = Currencies::getName($code, $choiceTranslationLocale);
                            }

                            return array_flip($filteredCurrencyNames);
                        },
                    ),
                    $choiceTranslationLocale
                );
            },
            'choice_translation_domain' => false,
            'choice_translation_locale' => null,
            'active_at' => new \DateTimeImmutable('today', new \DateTimeZone('Etc/UTC')),
            'not_active_at' => null,
            'legal_tender' => true,
            'invalid_message' => 'Please select a valid currency.',
        ]);

        $resolver->setAllowedTypes('choice_translation_locale', ['null', 'string']);
        $resolver->setAllowedTypes('active_at', [\DateTimeInterface::class, 'null']);
        $resolver->setAllowedTypes('not_active_at', [\DateTimeInterface::class, 'null']);
        $resolver->setAllowedTypes('legal_tender', ['bool', 'null']);
    }

    public function getParent(): ?string
    {
        return ChoiceType::class;
    }

    public function getBlockPrefix(): string
    {
        return 'currency';
    }

Review comment (performance):
other configuration of the filter need to be included in the cache invalidation, to avoid issues when using 2 form types with different settings.

the old callback only had `$choiceTranslationLocale` as state.

Code after:
                    false => '0',
                };

                return ChoiceList::loader(
                    $this,
                    new IntlCallbackChoiceLoader(
                        static function () use ($choiceTranslationLocale, $activeAt, $notActiveAt, $legalTender) {
                            if (null === $activeAt && null === $notActiveAt && null === $legalTender) {
                                return array_flip(Currencies::getNames($choiceTranslationLocale));
                            }

                            $filteredCurrencyNames = [];

                            $active = match (true) {
                                null !== $activeAt => true,
                                null !== $notActiveAt => false,
                                default => null,
                            };

                            foreach (Currencies::getCurrencyCodes() as $code) {
                                if (!Currencies::isValidInAnyCountry($code, $legalTender, $active, $activeAt ?? $notActiveAt)) {
                                    continue;
                                }

                                $filteredCurrencyNames[$code] = Currencies::getName($code, $choiceTranslationLocale);
                            }

                            return array_flip($filteredCurrencyNames);
                        },
                    ),
                    $choiceTranslationLocale.($activeAt ?? $notActiveAt)?->format('Y-m-d\TH:i:s').$legalTenderCacheKey,
                );
            },
            'choice_translation_domain' => false,
            'choice_translation_locale' => null,
            'active_at' => new \DateTimeImmutable('today', new \DateTimeZone('Etc/UTC')),
            'not_active_at' => null,
            'legal_tender' => true,
            'invalid_message' => 'Please select a valid currency.',
        ]);

        $resolver->setAllowedTypes('choice_translation_locale', ['null', 'string']);
        $resolver->setAllowedTypes('active_at', [\DateTimeInterface::class, 'null']);
        $resolver->setAllowedTypes('not_active_at', [\DateTimeInterface::class, 'null']);
        $resolver->setAllowedTypes('legal_tender', ['bool', 'null']);
    }

    public function getParent(): ?string
    {
        return ChoiceType::class;
    }