Selectively bringing constructors or record fields into scope

The syntax is nice, but comes with a risk:

module M = struct
  type t = { foo : int; bar : bool }

  let ( = ) a b = a.foo = b.foo
end

let () =
  let a = 1 in
  let b = 2 in
  let _ = M.{ foo = 5; bar = (a = b) } in
  ()

The above example won’t compile, again for the same reason as discussed in the other thread.

Another example where this causes problems:

module M = struct
  type t = { foo : int }
end

let () =
  let z = 5 in
  let x = M.{ foo = z } in
  assert (x.foo = z)

That program compiles and runs successfully. However, assume that in a new version of the module, there is a new item:

 module M = struct
   type t = { foo : int }
+  let z = "zero"
 end

Now this would lead to a compiler error. But even worse, consider:

 module M = struct
   type t = { foo : int }
+  let z = 0
 end

Now, this would cause a runtime error.

I know that a lot of these scenarios are unlikely to happen, but they still can happen, so I’d like to try to maintain some code/namespace hygiene here to minimize those risks. And I’m not sure what’s the best approach.