Skip to content
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

Elaborate predicates on associated types' associated types (and so on) #30704

Closed
wants to merge 1 commit into from

Conversation

soltanmm
Copy link

@soltanmm soltanmm commented Jan 4, 2016

This elaborates predicates of the form <<<Self as S>::A as X>::B as Y>: Z for traits with supertrait S (and naturally the chain of projections can go on to the recursion limit).

I don't know if the overall way I wrote this is koscher or not, so I've not tidied up yet. I've left a few comments in the code directed at reviewers (those will of course be cleaned up).

I would have liked to tackle predicates of the form <Self as Super>::A: X for traits with supertraits that are subtraits (wc?) of Super, but after playing around with it I couldn't see how to do it.

Specifically, given the following (where --> is the usual implication):

<Self as B> --> <Self as A>
<Self as B> --> <<Self as A>::T as U>

I couldn't figure out how to prove <<Self as A>::T as U> whenever <Self as B>, because it looks like obligations passed into librustc/middle/traits/select.rs code only keep track of one notion of Self (so when proving <<Self as A>::T as U>: <Self as A> is known and accessible but <Self as B> is not accessible despite being known somewhere in the aether). I'd love for someone to tell me that I'm horribly wrong. :-D

All tests appear to be passing on my local machine, save for some run-pass-valgrind ones and one run-pass dealing with LTO, but those never passed on my machine to begin with so meh.

cc #20671

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @alexcrichton (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@eddyb
Copy link
Member

eddyb commented Jan 4, 2016

r? @nikomatsakis

@nikomatsakis
Copy link
Contributor

Hmm. I have to think about this more deeply. This may be the right way to go about things, but it does feel a bit frightening.

@soltanmm
Copy link
Author

soltanmm commented Jan 5, 2016

I feel like if I knew more about how the compiler internals were organized (in particular, the semantics of InferCtxt and FulfillmentContext), I could come up with something more palatable.

The code in this PR is the product of only a few days of poking around the compiler and frankly isn't what I wanted to write. I wanted to be able to differentiate between the different notions of Self, e.g. the fresh type Self in <Self as Trait> (as in a trait reference), the Self type variable for which multiple predicates may apply (as in a single type variable for which many predicates apply and many are being inferred), and those Selfs just described but for projections. The second notion may be considered a superset of the first.

Being able to pluck out both major notions of Self (and being able to access the predicates the second notion participates in) would probably allow this to at least dodge the scariness of the Elaborator utility's newfound hard recursion limit and some of the cross-cutting penetration all over the place (along with perhaps being able to elaborate more predicate forms). Unfortunately, I don't have enough knowledge of the compiler's internals to think through that.

I'd love to discuss it, though!

EDIT: In this edit, in which I learn that ParameterEnvironment is what I've been looking for, and that I've been again munging nomenclature (type variable vs. parameter)...

@sanxiyn
Copy link
Member

sanxiyn commented Jan 5, 2016

Travis failure is for missing license boilerplate in the new test.

@soltanmm
Copy link
Author

soltanmm commented Jan 5, 2016

@sanxiyn Yes - I'll tidy up preferably after making sure whatever approach ends up in the PR is okay. :-)

@jroesch
Copy link
Member

jroesch commented Jan 5, 2016

cc me

@soltanmm
Copy link
Author

soltanmm commented Jan 6, 2016

Maybe it'd be better if the expanded scope of elaboration happens only when the ParameterEnvironment is constructed? That feels more 'correct', except that doing that gives me inexplicable type mismatch errors when building libserialize (which also occur when elaborating in assemble_candidates_from_caller_bounds)...

@bors
Copy link
Contributor

bors commented Feb 5, 2016

☔ The latest upstream changes (presumably #31304) made this pull request unmergeable. Please resolve the merge conflicts.

@soltanmm
Copy link
Author

soltanmm commented Feb 8, 2016

This take is not the take to take, probably.

@soltanmm soltanmm closed this Feb 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants