-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A Lifetime-generic Copy
impl can allow fields which are only Copy
when 'static
#88901
Comments
Specialization on use weird_lib::*;
struct Wrapped<'a>(Foo<'a>);
impl Clone for Wrapped<'_> {
fn clone(&self) -> Self {
panic!("please don't reach this code!")
}
}
// properly only on `'static`
impl Copy for Wrapped<'static> {}
fn main() {
let s = Foo::with_new(|ref mut foo| {
let mut x = vec![Wrapped(foo.take().unwrap())];
let mut y = x.clone(); // <- doesn't actually call `clone` on `Wrapped` due to specialization
Foo::proved_static(&mut x[0].0, &mut y[0].0)
});
println!("{}", s.into_inner());
} |
Assigning priority as discussed in the Zulip thread of the Prioritization Working Group. Also tagging T-lang as this issue could benefit from a opinion from the team (@danielhenrymantilla left some thoughts in the Zulip thread) @rustbot label -I-prioritize +P-medium +T-lang |
From PR 71321 which contains this comment block: // FIXME(matthewjasper) This allows copying a type that doesn't implement
// `Copy` because of unsatisfied lifetime bounds (copying `A<'_>` when only
// `A<'static>: Copy` and `A<'_>: Clone`).
// We have this attribute here for now only because there are quite a few
// existing specializations on `Copy` that already exist in the standard
// library, and there's no way to safely have this behavior right now.
#[rustc_unsafe_specialization_marker] |
@QuineDot my code example above goes slightly further and shows that this can (as a consequence) also allow copying a type that doesn't even implement Clone. |
We talked about this in the T-types meetup today -- I'm gonna take a stab at changing the |
…g-regions, r=lcnr Check ADT fields for copy implementations considering regions Fixes rust-lang#88901 r? `@ghost`
I tried this code:
#[derive(Clone)]
: while this simple snippet features aClone
impl for all lifetimes, it is possible to restrict the impl ofClone for Foo
to'static
as well, and yet offer aBar<'any>
which isClone
able (thanks to it beingCopy
able). See below for a more detailed example about that).I expected to see this happen:
Either the
impl Copy for Bar<'_> {}
should have failed, or, at the very least, the borrow checker ought to have complained about the actual copy ofb
(from looking at the old related issue, a "late" / on-use borrow-checker issue was deemed good enough since such a check does prevent unsoundness).Alas, we can see here that that check can be dodged by using a wrapper type.
Instead, this happened:
Meta
stable, beta and nightly are affected by this, and I suspect all versions of Rust do.
Impact
While contrived, this ought to be a
I-unsound
issue, since a library could feature a lifetime-generic typeFoo<'lt>
with an exploited safety invariant ofFoo<'not_static>
not being cloneable. DemoBonus / tangential issue 🎁
A type which is only
Copy
when'static
becomes, in practice / in non-generic context, unmoveable when non-'static
:Playground
Indeed, the
move_or_copy
heuristic decides to go for copy since the type is indeedcopy_modulo_regions
, but then the borrow checker (correctly) forbids theCopy
operation since the lifetime isn't (can't be proven to be)'static
The text was updated successfully, but these errors were encountered: