-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
DispatchFromDyn: require additional checks #149068
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
base: main
Are you sure you want to change the base?
DispatchFromDyn: require additional checks #149068
Conversation
|
rustbot has assigned @WaffleLapkin. Use |
This comment has been minimized.
This comment has been minimized.
|
@theemathas What do you think? Can we break |
75de383 to
88de0f9
Compare
This comment has been minimized.
This comment has been minimized.
88de0f9 to
b7f84d2
Compare
This comment has been minimized.
This comment has been minimized.
|
The documentation for DispatchFromDyn also needs to be changed. |
I am not sure. We have an option to make it possible. The question is, would it be a bad idea? In any case, let me add a stop-gap to disallow this case. |
b7f84d2 to
8c95fd8
Compare
This comment has been minimized.
This comment has been minimized.
8c95fd8 to
fdf32a0
Compare
|
r? types |
|
Discussion under t-lang: #t-lang > Should we support dyn dispatch on `&Adt<_>`? I think we are quite convinced that |
| impl<'a, T: ?Sized, U: ?Sized> DispatchFromDyn<&'a Ptr<U>> for &'a Ptr<T> {} | ||
| //~^ ERROR the trait `DispatchFromDyn` does not allow dispatch through references |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mentioning references here seems awfully specific. What about Box<Ptr<U>> or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in the middle of updating the documentation on this trait.
Box<Ptr<U>> falls in the second case of the new documentation. We would foremost require Ptr<T>: DispatchFromDyn<Ptr<U>> among the other requirements.
| .label = can't implement cross-crate trait for type in another crate | ||
| hir_analysis_dispatch_from_dyn_multiple_refs = the trait `DispatchFromDyn` does not allow dispatch through references | ||
| .note = the trait `DispatchFromDyn` may only be implemented when dispatch goes through at most one reference to a generic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this text not show up in the test error output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot about a #[note] attribute on the error type. Now it should work.
|
This code doesn't compile with this PR. Should it? #![feature(dispatch_from_dyn, arbitrary_self_types, unsize)]
use std::marker::{PhantomData, Unsize};
use std::ops::{DispatchFromDyn, Receiver};
pub struct Inner<T: ?Sized>(T);
#[repr(transparent)]
pub struct Outer<T: ?Sized>(PhantomData<T>, Inner<T>);
fn wrap<T: ?Sized>(x: &Inner<T>) -> &Outer<T> {
// SAFETY: We're using repr(transparent)
unsafe { &*(x as *const Inner<T> as *const Outer<T>) }
}
impl<'a, T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<&'a Outer<U>> for &'a Outer<T> {}
impl<T: ?Sized> Receiver for Outer<T> {
type Target = T;
}
pub trait Trait {
fn method(self: &Outer<Self>);
}
struct Thing(i32);
impl Trait for Thing {
fn method(self: &Outer<Self>) {
println!("{}", self.1.0.0);
}
}
fn main() {
let inner: &Inner<dyn Trait> = &Inner(Thing(1));
let x: &Outer<dyn Trait> = wrap(inner);
x.method();
} |
fdf32a0 to
e0eee5f
Compare
This comment has been minimized.
This comment has been minimized.
|
To answer the comment I have jotted down the reason that we do not want to compile the example in the trait documentation. |
This comment has been minimized.
This comment has been minimized.
|
@dingxiangfei2009 Your comment in the code unfortunately does not answer my latest comment in this PR. My comment does not involve a double pointer indirection. |
The new checks are we check the pair of constituent types for same shapes structurally, and demand capability for dispatch for ADTs as usual; and we demand source generic parameter to be unsized of another for sanity. Signed-off-by: Xiangfei Ding <dingxiangfei2009@protonmail.ch>
1a2dd94 to
af90725
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
Quote @theemathas
I don't think my text articulates my thoughts right. Maybe I should reword it. The pre-requisite of a valid
The last bullet point will answer the important question...
... which is no, because we don't know how to "downcast" The I hope that this would be a better answer to the earlier question. I am not sure how much this content could go into the documentation. Please advise. |
|
This impl should be illegal: impl<'a, T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<&'a Outer<U>> for &'a Outer<T> {}It compiles because it falls into the
case in the built-in check. But the reference / raw pointer types are supposed to only have the impls found in the stdlib. If they can have more, there's going to be all sorts of problems. We need to reject all downstream impls of Probably |
The new checks are we check the pair of constituent types for same shapes structurally, and demand capability for dispatch for ADTs as usual; and we demand source generic parameter to be unsized of another for sanity.
Fix #148727
cc @theemathas