-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Associated type projections don't play well with HRTBs and normalization #30472
Comments
HRTBs (I've been using the wrong nomenclature the whole time!) make projections sad. ///////////////
// HRTB setup
//
trait A {
type S;
}
trait B<'self_> {
type T;
}
trait C: for<'self_> B<'self_> {
type U: for<'self_> A<S=<Self as B<'self_>>::T>; // requires normalizing through an HRTB
}
//////////////////////
// Problematic impls
//
impl A for usize {
type S = usize;
}
impl<'self_> B<'self_> for usize {
type T = usize;
}
impl C for usize {
type U = usize;
}
fn main() {}
Very likely a dupe of #28994. |
Known issue. |
@arielb1 (or @nikomatsakis? Still a bit unclear on y'all's role separation) |
@soltanmm actually, I'm not entirely sure. There are a serious of refactorings that I have in mind for the type system / trait resolver, and I've been figuring that after those are done, I would come back to revisit some of these issues, if they still occur, but it may be worth digging into this example (or #28994) in detail. Honestly it's not all fresh in my mind. The refactorings I am thinking of are, first, lazy normalization (as described in this discuss thread), which may indeed help here, though I've not thought it through very deeply. Second, I'd like to generally rework how the trait checker is working to make it easier to extend the environment as you go -- the current setup, where the set of assumptions etc is semi-fixed when the inference context is created -- makes it hard to "descend through" a binder like |
So, potentially w.r.t. lazy normalization, I've been playing with another bit of code (trying to shrink it a bit): trait Hkt<'a> { type Output; }
trait A where for<'s> <Self::B as Hkt<'s>>::Output: Clone {
type B: for<'s> Hkt<'s>;
}
trait C: A
where for<'s> <Self::B as Hkt<'s>>::Output: Clone
{}
impl<'a> Hkt<'a> for usize { type Output = usize; }
struct S;
impl A for S {
type B = usize;
} From reading the debug logs, it seems that when checking the well-formed-ness of An aside: does lazy normalization have something to do with this asterisk in |
Is this #30867? It looks similar, but uncertain. |
What's the state of this now? I fairly frequently run into problems with associated types involved with HRTBs not projecting/unifying. |
I'm working on data-parallelism library, heavily inspired by Rayon but focused on describing certain computations on a dataset in an SQL-like manner, somewhat akin to Diesel. One part of this combines HRTBs with associated types. I've bumped into a few issues that have made things a bit tricky ([#30472](rust-lang/rust#30472), [#30867](rust-lang/rust#30867), [#53943](rust-lang/rust#53943), and similar), the hardest to work around however has been that I don't believe it's currently possible to write this: ```rust type Task = for<'a> <B as Abc<&'a A::Item>>::Task; ``` Currently I've resorted to a dummy trait, manually reimplemented on various structs without the reference, such that I can do: ```rust type Task = <B as AbcDummy<A::Item>>::Task; ``` and (horribly) transmute between the two. I'd be very interested to discuss 1) issues I've bumped into combining HRTBs and associated types; 2) how to get rid of this transmute and the dummy trait; 3) any feedback on the library before I publish and promote it, given it's heavily inspired by your work on Rayon! I can do any of the Monday or Friday times listed, though I have a preference for the 16 - 16.30 slots. Again, much appreciation for you doing this, I think it's awesome!
Triage: last two comments asking for clarification, no replies. Given @nikomatsakis's comments earlier in the thread, I imagine this issue is "post-chalk". |
This is one of the things that the traits working group is kind of actively working towards. It's blocked to some extent on the universes work, see e.g. #65232 which tries to unblock that effort, plus lazy norm. I think we'll be making active progress though over the next few months. |
…atsakis Make GATs less ICE-prone. After this PR simple lifetime-generic associated types can now be used in a compiling program. There are two big limitations: * rust-lang#30472 has not been addressed in any way (see src/test/ui/generic-associated-types/iterable.rs) * Using type- and const-generic associated types errors because bound types and constants aren't handled by trait solving. * The errors are technically non-fatal, but they happen in a [part of the compiler](https://github.com/rust-lang/rust/blob/4abb0ad2731e9ac6fd5d64d4cf15b7c82e4b5a81/src/librustc_typeck/lib.rs#L298) that fairly aggressively stops compiling on errors. closes rust-lang#47206 closes rust-lang#49362 closes rust-lang#62521 closes rust-lang#63300 closes rust-lang#64755 closes rust-lang#67089
…atsakis Make GATs less ICE-prone. After this PR simple lifetime-generic associated types can now be used in a compiling program. There are two big limitations: * rust-lang#30472 has not been addressed in any way (see src/test/ui/generic-associated-types/iterable.rs) * Using type- and const-generic associated types errors because bound types and constants aren't handled by trait solving. * The errors are technically non-fatal, but they happen in a [part of the compiler](https://github.com/rust-lang/rust/blob/4abb0ad2731e9ac6fd5d64d4cf15b7c82e4b5a81/src/librustc_typeck/lib.rs#L298) that fairly aggressively stops compiling on errors. closes rust-lang#47206 closes rust-lang#49362 closes rust-lang#62521 closes rust-lang#63300 closes rust-lang#64755 closes rust-lang#67089
Triage: According to #30472 (comment), this should get tagged |
I think this issue is related to an error I encountered when trying to use the The trait is defined as follow: trait Iterable {
type Item<'a>;
type Iter<'a>: Iterator<Item = Self::Item<'a>>;
fn iter<'a>(&'a self) -> Self::Iter<'a>;
} I implemented it for a vector of booleans: struct BoolVec(Vec<bool>);
impl Iterable for BoolVec {
type Item<'a> = &'a bool;
type Iter<'a> = core::slice::Iter<'a, bool>;
fn iter<'a>(&'a self) -> Self::Iter<'a> {
self.0.iter()
}
} I believe this should compile, but it errors. See full error
It does not recognize that |
@demurgos You example compiles now. |
Triage: The original issue seems to have been fixed, the example from the issue description compiles just fine now. |
Add tests for some old fixed issues Closes rust-lang#30867 Closes rust-lang#30472 Closes rust-lang#28994 Closes rust-lang#26719 (and migrates the relevant test to the new run-make) Closes rust-lang#23600 cc `@jieyouxu` for the run-make-support changes try-job: x86_64-msvc
Rollup merge of rust-lang#131355 - clubby789:old-tests, r=jieyouxu Add tests for some old fixed issues Closes rust-lang#30867 Closes rust-lang#30472 Closes rust-lang#28994 Closes rust-lang#26719 (and migrates the relevant test to the new run-make) Closes rust-lang#23600 cc `@jieyouxu` for the run-make-support changes try-job: x86_64-msvc
playpen link
This could've been written with
MyInto
written asInto
and similarly forMyFrom
/From
. It was written this way only to make explicit the necessity of one blanket impl for satisfying the other.I'm guessing that extensional equality is not judged, even though it is possible to make such a judgment and such a judgment must be made to compile code that compiles today.
<Self as A<'self_>>::T
on line 12 ought to be equated tousize
(which must be detected at some other point in time else line 13 wouldn't be able to compile).EDIT: Playing around a bit, it looks more and more like it's all about the HKL bounds...
The text was updated successfully, but these errors were encountered: