-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Trait bounds on associated type projections via HRTB are broken #56556
Comments
It does seem like it should compile... cc @rust-lang/wg-traits |
Another instance of this from #57671: trait Bar<T> {
type Assoc;
}
impl<'a> Bar<&'a ()> for () {
type Assoc = Box<Send>;
}
fn oops<C>()
where
for<'a> C: Bar<&'a ()>,
for<'a> <C as Bar<&'a ()>>::Assoc: Send,
{
}
fn main() {
oops::<()>();
} fails with
|
@sfackler do you know of a workaround for this bug? It's currently blocking me and I'm not entirely sure how else to structure my code. |
The only workaround I know of is to remove the lifetime parameter
On Thu, Jan 17, 2019 at 10:02 AM Jon Gjengset ***@***.***> wrote:
@sfackler <https://github.com/sfackler> do you know of a workaround for
this bug? It's currently blocking me and I'm not entirely sure how else to
structure my code.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#56556 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABY2UW0Y2cj6SRaHA6WUrpeo6C4gM1jLks5vELqegaJpZM4ZF3D3>
.
--
Steven Fackler
|
I believe this issue I ran in to might be related - StackOverflow. I was trying to put a bound on an associated type |
Another example, when trying to bind |
Ran into this in one of my own projects, and used this odd workaround (suggested on satck overflow): https://github.com/Lucretiel/joinery/blob/master/src/join.rs#L174-L188 |
This is a workaround for a Rust compiler bug/limitation: rust-lang/rust#56556
Another variation of this issue (as far as I can tell): trait Bar<'a> {
type Assoc;
}
impl<'a> Bar<'a> for () {
type Assoc = ();
}
fn oops<C>()
where
for<'a> C: Bar<'a>,
for<'a> <C as Bar<'a>>::Assoc: Send,
{
}
fn main() {
oops::<()>();
} Fails with:
|
I just ran into this (playground): #[derive(Clone, Copy, Debug)]
struct Value<'a> {
num: NonZeroU64,
marker: PhantomData<&'a ()>,
}
impl<'a> TryFrom<u64> for Value<'a> {
type Error = TryFromIntError;
fn try_from(value: u64) -> Result<Self, Self::Error> {
NonZeroU64::try_from(value).map(|num| Value { num, marker: PhantomData })
}
}
trait ToValue {
fn to_value(&self) -> Result<Value, ValueError>;
}
#[derive(Clone, Copy, Default, Debug)]
struct ValueError;
impl From<TryFromIntError> for ValueError {
fn from(_: TryFromIntError) -> Self {
ValueError
}
}
impl<T> ToValue for T
where
T: Clone,
T: for<'a> TryInto<Value<'a>>,
ValueError: for<'a> From<<T as TryInto<Value<'a>>>::Error>,
{
fn to_value(&self) -> Result<Value, ValueError> {
self.clone().try_into().map_err(Into::into)
}
}
fn main() {
let v: Value = 42_u64.to_value().unwrap();
println!("{:#?}", v);
} I get the following error on latest stable (1.52.1):
The workaround in my case was to pull out the associated type into a type parameter, and require that it be invariant w.r.t. the universally quantified lifetime parameter (playground): impl<T, E> ToValue for T
where
T: Clone,
T: for<'a> TryInto<Value<'a>, Error = E>,
ValueError: From<E>,
{
fn to_value(&self) -> Result<Value, ValueError> {
self.clone().try_into().map_err(Into::into)
}
} |
…komatsakis Normalize projections under binders Fixes rust-lang#70243 Fixes rust-lang#70120 Fixes rust-lang#62529 Fixes rust-lang#87219 Issues to followup on after (probably fixed, but no test added here): rust-lang#76956 rust-lang#56556 rust-lang#79207 rust-lang#85636 r? `@nikomatsakis`
Fixed by #85499, marking as needs-test because wasn't an ICE and a simple enough example I'd like to have a test for. |
This bug might not be completely fixed. Here is another test case that still fails on nightly and beta: EDIT: Made the case a bit smaller: |
this is the smallest example I can find: This below works: fn test<T>()
where
for<'a> &'a T: IntoIterator,
for<'a> <&'a T as IntoIterator>::IntoIter: Clone,
{
}
fn main() {
test::<Vec<u8>>();
} While this doesn't: use std::ops::Deref;
fn test<T, TDeref>()
where
T: Deref<Target = TDeref>,
TDeref: ?Sized,
for<'a> &'a TDeref: IntoIterator,
for<'a> <&'a TDeref as IntoIterator>::IntoIter: Clone,
{
}
fn main() {
test::<Vec<u8>, _>();
} @jackh726 Can you confirm that the second case works in your PR as well? |
Add a couple tests for normalize under binder issues Closes rust-lang#56556 Closes rust-lang#76956 r? `@nikomatsakis`
Another bug of this kind: #90950 |
Add a couple tests for rust-lang#90887 fixes closes rust-lang#56556 closes rust-lang#90875 These are confirmed fixes by rust-lang#90887, so r? `@jackh726`
I believe this should successfully compile, but it currently fails claiming that vec's iterator isn't ExactSizeIterator:
Things compile correctly if the bounds are changed to
T
rather thanfor<'a> &'a T
.https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=c96139308ad1602c281e71c4c54c73ec
The text was updated successfully, but these errors were encountered: