As sibling comments mention, this would struggle with edge-cases, and require too much buy-in from packagers.
A less ambitious approach would be creating/extending a static analyser/linter for Nix (there are already a few out there). This could nudge packagers towards certain styles, which language implementations could optimise for.
For example, an interpreter could have multiple implementations of the attrset interface (key/value mappings) with different performance characteristics, using some default for literals like '{ foo = "bar"; }' and a specialised version for known use-cases like nixpkgs.lib.nameValuePair ( https://github.com/NixOS/nixpkgs/blob/e9e53499b26ad98ac97f97... ) (mentioned in a sibling)
Linters could then spot when such functions are appropriate, e.g.
Found literal name/value pair on line 123:
{ name = "x"; value = "y"; }
This can be slow, consider using:
nixpkgs.lib.nameValuePair "x" "y"'
A less ambitious approach would be creating/extending a static analyser/linter for Nix (there are already a few out there). This could nudge packagers towards certain styles, which language implementations could optimise for.
For example, an interpreter could have multiple implementations of the attrset interface (key/value mappings) with different performance characteristics, using some default for literals like '{ foo = "bar"; }' and a specialised version for known use-cases like nixpkgs.lib.nameValuePair ( https://github.com/NixOS/nixpkgs/blob/e9e53499b26ad98ac97f97... ) (mentioned in a sibling)
Linters could then spot when such functions are appropriate, e.g.