Skip to content

Handle bound vars in builtin trait impls #463

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

Merged
merged 1 commit into from
May 21, 2020

Conversation

flodiebold
Copy link
Member

The builtin impls have the same problem that the dyn trait impl did, which is
that they reuse the trait ref as given. The problem with that is that the
recursive solver calls program_clauses with trait refs that contain bound vars
from the original goal. So the builtin impls returned clauses with free bound
vars, which is a problem. The solution is the same as for the dyn trait impls:
Use the Generalize folder to collect those free bound vars and basically put a
forall around them. To give an example:

Looking for

Implemented((^0.0, ^0.1): Sized)

previously returned something like

if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) }

as a clause; now it returns

forall<type, type> if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) }

(The SLG solver instantiates goals before asking for program clauses, so it has
inference variables instead of bound vars in those places.)

Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this end up being more work for SLG? This seems right. But an alternative solution might be to make the recursive solver "generalize" all the program clauses.

The builtin impls have the same problem that the dyn trait impl did, which is
that they reuse the trait ref as given. The problem with that is that the
recursive solver calls `program_clauses` with trait refs that contain bound vars
from the original goal. So the builtin impls returned clauses with free bound
vars, which is a problem. The solution is the same as for the dyn trait impls:
Use the `Generalize` folder to collect those free bound vars and basically put a
`forall` around them. To give an example:

Looking for

```
Implemented((^0.0, ^0.1): Sized)
```

previously returned something like

```
if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) }
```

as a clause; now it returns

```
forall<type, type> if (Implemented(^0.1: Sized)) { Implemented((^0.0, ^0.1): Sized) }
```

(The SLG solver instantiates goals before asking for program clauses, so it has
inference variables instead of bound vars in those places.)
@flodiebold flodiebold force-pushed the generalize-for-builtin-impls branch from 99fcb47 to 35a0647 Compare May 21, 2020 08:46
@flodiebold
Copy link
Member Author

It might be slightly more work, but it's just a no-op fold instead of a clone, which I would think should not be much slower.

Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the code here looks right to me. Can you file an issue for the builtin type enumeration for followup?

I'm still a bit wary on whether this is a better solution compared to the alternative I suggested. So maybe @nikomatsakis can take a quick look?

@flodiebold
Copy link
Member Author

I'm not a fan of doing this for all program clauses because most program clauses don't actually need it. It's only when we take full types from the goal that it becomes necessary. It would actually be possible to write the builtin clauses code in a way that doesn't require this either (instead of a clause for e.g. the specific tuple type always generate a clause for all tuples of the given cardinality), this is just a bit easier.

@jackh726
Copy link
Member

I'm convinced.

@jackh726 jackh726 merged commit 1927311 into rust-lang:master May 21, 2020
@flodiebold flodiebold deleted the generalize-for-builtin-impls branch May 21, 2020 21:07
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.

2 participants