Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up`where_clauses_object_safety` future compatibility lint #51443
Comments
leodasvacas
added
A-typesystem
A-traits
T-compiler
B-unstable
labels
Jun 8, 2018
jkordish
added
the
C-future-compatibility
label
Jun 13, 2018
This comment has been minimized.
This comment has been minimized.
|
To clarify: we are specifically interested in getting feedback on places where this lint causes you issues, since that will help us to judge how well more precise fixes would work. |
MajorBreakfast
referenced this issue
Jun 27, 2018
Merged
`PinMut::get_mut_unchecked`, Add `Sized` bound to `poll_unpin` #1049
This comment has been minimized.
This comment has been minimized.
|
This caused a future-compat warning in the upcoming #![feature(arbitrary_self_types, pin)]
use std::marker::Unpin;
use std::mem::PinMut;
trait Future {
fn poll(self: PinMut<Self>);
}
trait FutureExt: Future {
fn poll_unpin(&mut self) where Self: Unpin {
PinMut::new(self).poll()
}
}The error:
It seems like it should be possible to permit calls to |
This comment has been minimized.
This comment has been minimized.
|
Thanks @cramertj -- that falls pretty squarely into the rules we had in mind! Let's discuss the details of those rules in #50781 I guess, I want to try and "re-sync" (but I guess I'd rather keep this thread for people to report issues). But just to summarize, the rule we had in mind is roughly this:
That applies to your example, I believe, since This is a kind of generalization of the rule around |
nikomatsakis
referenced this issue
Jun 28, 2018
Open
Trait objects can call nonexistent concrete methods #50781
rkruppe
referenced this issue
Jul 3, 2018
Open
RFC: Existential types with external definition #2492
This comment has been minimized.
This comment has been minimized.
locka99
commented
Jul 13, 2018
|
For anyone reading this, I got the warning/error on a trait that was like this:
In my case I was able to make the problem go away by requiring the thing implementing Config to also implement serde::Serialize:
|
This comment has been minimized.
This comment has been minimized.
|
This broke bindgen:
This is on this bindgen commit fwiw: rust-lang/rust-bindgen@29dad40 |
emilio
added a commit
to rust-lang/rust-bindgen
that referenced
this issue
Jul 30, 2018
This comment has been minimized.
This comment has been minimized.
|
I have an extension trait that was never supposed to be made into an object which triggers this. It only exists to add a few methods. I like this as a lint but the Edit: In fact, the lint is a false positive. The trait isn't dyn capable already because it contains generic functions. |
This comment has been minimized.
This comment has been minimized.
|
I bumped into this upcasting boxed trait objects with marker traits. There may be a way to do this safely that doesn't fall foul of this lint? use std::any::Any;
trait Trait: Any {
fn into_any(self: Box<Self>) -> Box<Any>;
fn into_any_send(self: Box<Self>) -> Box<Any+Send> where Self: Send;
fn into_any_sync(self: Box<Self>) -> Box<Any+Sync> where Self: Sync;
fn into_any_send_sync(self: Box<Self>) -> Box<Any+Send+Sync> where Self: Send+Sync;
}
impl<T> Trait for T where T: Any {
fn into_any(self: Box<Self>) -> Box<Any> {
self
}
fn into_any_send(self: Box<Self>) -> Box<Any+Send> where Self: Send {
self
}
fn into_any_sync(self: Box<Self>) -> Box<Any+Sync> where Self: Sync {
self
}
fn into_any_send_sync(self: Box<Self>) -> Box<Any+Send+Sync> where Self: Send+Sync {
self
}
}
fn main() {
let a: usize = 123;
let b: Box<Trait+Send+Sync> = Box::new(a);
let c: Box<Any+Send+Sync> = b.into_any_send_sync();
let _d: usize = *Box::<Any>::downcast(c).unwrap();
}
|
adeschamps
referenced this issue
Aug 21, 2018
Open
warn(where_clauses_object_safety) on recent nightly #4
This comment has been minimized.
This comment has been minimized.
|
This warns on
|
This comment has been minimized.
This comment has been minimized.
rodrimati1992
commented
Sep 16, 2018
•
|
I have an extension trait that i want to be usable with ?Sized types (including str) where this is causing a problem. This is the reduced version of the trait:
With the previous 2 methods I get this somewhat confusing pair of warning and error :
It seems to me that if it knows that it can't be turned into a trait object because it has a generic method, |
jonas-schievink
referenced this issue
Sep 17, 2018
Open
Future compatibility warning ("CloneToAny" cannot be made into an object) #31
This comment has been minimized.
This comment has been minimized.
|
On the AnyMap case: it’s substantially the same as what @alecmocatta is reporting. This lint causes trouble with auto traits.
AnyMap has an extension of that, a cloneable Any. That part is fine, but when you get to additional trait bounds, you need a function that will be in the vtable; and that’s where we run into trouble under this new scheme. Here’s a simplified version of some of the code (covering only the #[doc(hidden)]
pub trait CloneToAny {
/// Clone `self` into a new `Box<CloneAny>` object.
fn clone_to_any(&self) -> Box<CloneAny>;
/// Clone `self` into a new `Box<CloneAny + Send>` object.
fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send;
}
impl<T: Any + Clone> CloneToAny for T {
fn clone_to_any(&self) -> Box<CloneAny> {
Box::new(self.clone())
}
fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send {
Box::new(self.clone())
}
}
pub trait CloneAny: Any + CloneToAny { }
impl<T: Any + Clone> CloneAny for T { }
impl Clone for Box<CloneAny> {
fn clone(&self) -> Box<CloneAny> {
(**self).clone_to_any()
}
}
impl Clone for Box<CloneAny + Send> {
fn clone(&self) -> Box<CloneAny + Send> {
(**self).clone_to_any_send()
}
}Now as it stands, I know that if I have a I would like to retain the same interface: adding trait bounds is a known and sane way of handling these things—the way you’re supposed to handle it. But if necessary, I suppose the proliferation of traits can begin, with As it stands, I’m seeing a few options for me as a developer:
Expanding on the appeal: I don’t know, but my impression is that auto traits won’t trigger the memory unsafety problem. If so, is it reasonable to check whether the additional bounds on Self are all auto traits, and consider that acceptable code? And if tweaking the lint is not reasonable, is what I outline in the second item reasonable? Will Rust eat my laundry if I transmute (Quite incidentally: where I’m from “laundry” refers to the room where clothes washing is done, not to the pile of clothes, which is called the “washing”. The whole “may eat your laundry” thing was therefore much more amusing to contemplate than it would have been if it were mere clothes that were being devoured.) |
This comment has been minimized.
This comment has been minimized.
This is effectively what's done by the stdlib here: Lines 455 to 517 in f1aefb4 |
This comment has been minimized.
This comment has been minimized.
This is true, this lint can be tweaked to not fire if the bounds are all auto traits. |
nikomatsakis
referenced this issue
Dec 13, 2018
Closed
problems with trait objects with a trait projection value that contains Self #56288
pierrechevalier83
added a commit
to pierrechevalier83/rust-typemap
that referenced
this issue
Dec 27, 2018
pierrechevalier83
referenced this issue
Dec 27, 2018
Open
(fix) Fix compiler error with rust 1.31.1 #44
This comment has been minimized.
This comment has been minimized.
|
How should I deal with that warning? Does it only trigger if I create a trait object or otherwise interact with |
leodasvacas commentedJun 8, 2018
•
edited
This is the summary issue for the
WHERE_CLAUSES_OBJECT_SAFETYfuture-compatibility warning and other related errors. The goal of
this page is describe why this change was made and how you can fix
code that is affected by it. It also provides a place to ask questions
or register a complaint if you feel the change should not be made. For
more information on the policy around future-compatibility warnings,
see our breaking change policy guidelines.
What is the warning for?
As was discovered in #50781 a combination of implementing a trait directly for a
dyntype and where clauses involvingSelfcan punch a hole in our dyn-capability rules rules. See the minimization:The fix applied in #50966 is to tighten the dyn-capability rules to make
Xnot dyn-capable in this case, in general making any trait that containsSelfin where clauses not dyn-capable, much like we disallowSelfin arguments or return type. Few root regressions appeared in the crater run and those were fixable, though some crates being unmaintained complicates things.However that fix is heavy handed and disallows things we actually wish to support, still we went ahead with the warning as a stop gap while we look for a better, more targeted fix. The original issue contains some discussion of alternative fixes. With tight chalk integration, we could do some clever things.
Other alternatives discussed for the short-term:
impl Foo for dyn Bar + ..whether that impl is causing trouble. This seems to be a dead end because it's hard to tell whichdyntypes are targeted by a blanket impl such asimpl<U: ?Sized + Bounds> Trait for U.dyn Foo: Traitthen to castTintodyn Foowe require thatT: Traitmust also hold", probably for everyTraitsuch thatSelf: Traitappears in where clauses in the traits methods. This would alleviate the warning forSelf: Traitwhere clauses. This may be practical to implement now, but seems subtle, we'd need to give it more thought.When will this warning become a hard error?
Hopefully we will develop a finer-grained rule and this warning will never be an error.
How to fix this?
Either drop the where clause or stop using
dyntypes with the affected trait. If this is not viable, that's probably ok, it's very unlikely that your code is actually unsound. But please do report your case here so take we may take it into consideration and see how to better support it!