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

[wg-traits] pass around interned refs to goals and not goals #50580

Closed
nikomatsakis opened this issue May 9, 2018 · 3 comments
Closed

[wg-traits] pass around interned refs to goals and not goals #50580

nikomatsakis opened this issue May 9, 2018 · 3 comments
Assignees
Labels
C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-traits Working group: Traits, https://internals.rust-lang.org/t/announcing-traits-working-group/6804

Comments

@nikomatsakis
Copy link
Contributor

Currently we have a setup where we have an enum Goal:

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum Goal<'tcx> {
Implies(Clauses<'tcx>, &'tcx Goal<'tcx>),
And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>),
Not(&'tcx Goal<'tcx>),
DomainGoal(DomainGoal<'tcx>),
Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>),
CannotProve,
}

This enum contains interned goals (&'tcx Goal<'tcx>). We also have slices of goals:

pub type Goals<'tcx> = &'tcx Slice<Goal<'tcx>>;

This works ok as long as we pass around Goal<'tcx> enum values. But I suspect we might rather pass around pointers to interned goals, rather like Ty<'tcx> is a reference. This would also allow us to do cheap equality testing, hashing and so forth if we cared to.

Therefore, we probably ought to:

  1. Rename the enum Goal to GoalKind
  2. Add a type alias Goal<'tcx> = &'tcx GoalKind<'tcx>
  3. And thus change Goals<'tcx> to a slice of interned refs.
@nikomatsakis nikomatsakis added C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-traits Working group: Traits, https://internals.rust-lang.org/t/announcing-traits-working-group/6804 labels May 9, 2018
@iancormac84
Copy link
Contributor

I'd like to try my hand at this, please.

@iancormac84
Copy link
Contributor

@nikomatsakis I'm having some problems eliminating all errors. I'm fairly confident that I'm going in the right direction, but the lingering uncertainty has me wondering if this is why my code refuses to compile.

My implementation of the mk_goal and mk_goals methods is frustrating the compiler. I'm receiving the error:

error[E0277]: the trait bound traits::GoalKind<'_>: ty::context::InternIteratorElement<&traits::GoalKind<'_>, &ty::Slice<&traits::GoalKind<'_>>> is not satisfied
--> librustc\ty\context.rs:2614:15
|
2614 | &self.mk_goals(iter::once(goal_kind))[0]
| ^^^^^^^^ the trait ty::context::InternIteratorElement<&traits::GoalKind<'_>, &ty::Slice<&traits::GoalKind<'_>>> is not implemented for traits::GoalKind<'_>
|
= note: required because of the requirements on the impl of ty::context::InternAs<[&traits::GoalKind<'_>], &ty::Slice<&traits::GoalKind<'_>>> for std::iter::Once<traits::GoalKind<'_>>

The slice_interners and intern_method macros are spitting out the following errors:

error[E0308]: mismatched types
--> librustc\ty\context.rs:2135:72
|
2135 | if let Some(i) = self.interners.$name.borrow().get(key) {
| ^^^ expected struct ty::context::Interned, found slice
...
2216 | / slice_interners!(
2217 | | existential_predicates: _intern_existential_predicates(ExistentialPredicate),
2218 | | predicates: _intern_predicates(Predicate),
2219 | | type_list: _intern_type_list(Ty),
... |
2222 | | goals: _intern_goals(Goal)
2223 | | );
| |__- in this macro invocation
|
= note: expected type &ty::context::Interned<'_, ty::Slice<traits::GoalKind<'_>>>
found type &[&traits::GoalKind<'_>]

error[E0308]: mismatched types
--> librustc\ty\context.rs:2136:32
|
2136 | return i.0;
| ^^^ expected reference, found enum traits::GoalKind
...
2216 | / slice_interners!(
2217 | | existential_predicates: _intern_existential_predicates(ExistentialPredicate),
2218 | | predicates: _intern_predicates(Predicate),
2219 | | type_list: _intern_type_list(Ty),
... |
2222 | | goals: _intern_goals(Goal)
2223 | | );
| |__- in this macro invocation
|
= note: expected type &'tcx ty::Slice<&'tcx traits::GoalKind<'tcx>>
found type &ty::Slice<traits::GoalKind<'_>>

error[E0308]: mismatched types
--> librustc\ty\context.rs:2139:83
|
2139 | if let Some(i) = self.global_interners.$name.borrow().get(key) {
| ^^^ expected struct ty::context::Interned, found slice
...
2216 | / slice_interners!(
2217 | | existential_predicates: _intern_existential_predicates(ExistentialPredicate),
2218 | | predicates: _intern_predicates(Predicate),
2219 | | type_list: _intern_type_list(Ty),
... |
2222 | | goals: _intern_goals(Goal)
2223 | | );
| |__- in this macro invocation
|
= note: expected type &ty::context::Interned<'_, ty::Slice<traits::GoalKind<'_>>>
found type &[&traits::GoalKind<'_>]

error[E0308]: mismatched types
--> librustc\ty\context.rs:2154:82
|
2154 | self.global_interners.$name.borrow_mut().insert(Interned(i));
| ^ expected enum traits::GoalKind, found reference
...
2216 | / slice_interners!(
2217 | | existential_predicates: _intern_existential_predicates(ExistentialPredicate),
2218 | | predicates: _intern_predicates(Predicate),
2219 | | type_list: _intern_type_list(Ty),
... |
2222 | | goals: _intern_goals(Goal)
2223 | | );
| |__- in this macro invocation
|
= note: expected type &ty::Slice<traits::GoalKind<'_>>
found type &ty::Slice<&traits::GoalKind<'_>>

error[E0308]: mismatched types
--> librustc\ty\context.rs:2168:67
|
2168 | self.interners.$name.borrow_mut().insert(Interned(i));
| ^ expected enum traits::GoalKind, found reference
...
2216 | / slice_interners!(
2217 | | existential_predicates: _intern_existential_predicates(ExistentialPredicate),
2218 | | predicates: _intern_predicates(Predicate),
2219 | | type_list: _intern_type_list(Ty),
... |
2222 | | goals: _intern_goals(Goal)
2223 | | );
| |__- in this macro invocation
|
= note: expected type &ty::Slice<traits::GoalKind<'_>>
found type &ty::Slice<&traits::GoalKind<'_>>

Am I even on the right track? I'm fairly sure that - along with the other edits to different sections of code - this code is correct, but the compiler begs to differ.

@nikomatsakis
Copy link
Contributor Author

@iancormac84 omg! I missed this comment completely. Sorry for the total radio silence! You still around? I'll take a look, but best would be if you can hop onto #wg-traits in the rust-lang discord and we can discuss there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-traits Working group: Traits, https://internals.rust-lang.org/t/announcing-traits-working-group/6804
Projects
None yet
Development

No branches or pull requests

3 participants