Code change:
<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // RFC 736 (and Issue 21407): functional struct update should respect privacy. // The `foo` module attempts to maintains an invariant that each `S` // has a unique `u64` id. use self::foo::S; mod foo { use std::cell::{UnsafeCell}; static mut count : UnsafeCell<u64> = UnsafeCell { value: 1 }; pub struct S { pub a: u8, pub b: String, secret_uid: u64 } pub fn make_secrets(a: u8, b: String) -> S { let val = unsafe { let p = count.get(); let val = *p; *p = val + 1; val }; println!("creating {}, uid {}", b, val); S { a: a, b: b, secret_uid: val } } impl Drop for S { fn drop(&mut self) { println!("dropping {}, uid {}", self.b, self.secret_uid); } } } fn main() { let s_1 = foo::make_secrets(3, format!("ess one")); let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ... //~^ ERROR field `secret_uid` of struct `foo::S` is private println!("main forged an S named: {}", s_2.b); // at end of scope, ... both s_1 *and* s_2 get dropped.  Boom! } </ins>

Related discussion:
text: That out of the way, an additional possibility, let's call it 6., for list: We could just make the "abstract type" vs. "data type" distinction based on "does or doesn't the type have a private field". This doesn't entirely fill me with satisfaction (as with "worse is better" solutions in general), with specific drawbacks being that it doesn't extend cleanly to the nullary case (no fields at all), and that in terms of UX a change of semantics based on the presence or absence of a private field may be unexpected, but on the plus side, it's simpler, and would, I think, work.
Sure, hypothetical show-stopper issues could cause us to revisit our self-imposed schedule. I personally don't think that this issue, on its own at least, provides sufficient motivation for schedule revision. I admit that your draft RFC seems like it addresses a host of issues, so maybe all of them taken in unison would be a different story. (But then again, that's not even my call to make.)
There were a couple more options that I should have put on the list, for completeness, but overlooked. 6 note, the "has any private fields ==abstract-type; all public fields ==data-type", is one of them. This would (probably) be less work than adopting the draft RFC in full, but I am not sure what the other Advantages/Disadvantages are. I invite others to write an Advantages/Drawbacks for this approach (perhaps in an RFC PR). 7 We could add a way for a struct to opt-out of FRU support entirely. So in this approach, one would attach the appropriate attribute to , , etc. Advantages: won't break any existing code Drawbacks: Seems quite fragile; we may be good about auditing our own stdlib, but clients who are not aware of the attribute may inadvertently expose themselves to the same bug that currently plagues .
Also, I just wanted to mention: when I wrote my comment 6 hours ago, I came to the keyboard thinking that the FRU support for adding new private fields to and having still work was an important use case. But after some reflection in the hours since, supporting that use case does not seem as important to me.