-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Trait bounds on associated type projections via HRTB are broken #56556
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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: