Hey,
I can't tell whether I'm mistaken, this is a bug, or changing record-update desugaring produced a surprising consequence, but updating a lazy record field with Strict enabled seems to force it. Constructing the record doesn't force that field.
Here's a sample test:
{-# LANGUAGE Strict, OverloadedRecordDot #-}
import Prelude hiding (id)
import Debug.Trace
data Member = Member
{id :: Int, years :: ~Int}
main = do
let member = Member {id = 17, years = 39}
let revised = member {years = trace "FORCED" 46}
print revised.id
With GHC v9.12.4, “FORCED” appears. It doesn't with v9.2.8. Disabling Strict also prevents it, of course.
The approximate core looks like
case trace "FORCED" 46 of years
__DEFAULT -> case member of
Member id _ -> Member id years
and, as I understand it, the case-of around trace forces evaluation. I'm generally happy for Strict to make every case and let strict (sparing us countless ! bang patterns), but when the field being explicitly updated was declared lazy, this feels like a bug or an accidental design consequence.
How does that look to you?