See Twig autoescape enabled and text sanitization APIs updated for more information on Twig autoescaping.
When that was introduced:
t()still implemented Drupal 7's behavior of always escaping the value of an@-prefixed token, even if that value had already been escaped previously. This required using an!-prefixed token for already escaped, or HTML-containing, values, just as in Drupal 7.t()marked the output string as safe (so that Twig wouldn't escape it) even if passed a!-prefixed token value that wasn't.
This has now been changed to:
t()applies the same auto-escaping logic for@-prefixed tokens as is used within Twig. This means that you can use an@-prefixed token even if the value has already been escaped, without it getting double-escaped.
Generally, this means that when calling t() for strings that will be passed to Twig, you should almost always use an @-prefix for tokens. See the documentation of \Drupal\Component\Render\FormattableMarkup::placeholderFormat() for more details on each token type.
Note that per New format_string()/SafeMarkup::format() can be used to apply t()-like replacements, everything stated above for t() also applies for SafeMarkup::format().
Related change records
!placeholder removed from t() and format_string()
SafeMarkup methods are removed
See Twig autoescape enabled and text sanitization APIs updated for a full list of related change records.