31 January 2018
In my last Chalk post, I talked about an experimental, SLG-based
solver that I wrote for Chalk. That particular design was based very
closely on the excellent paper
“Efficient top-down computation of queries under the well-founded semantics”, by W. Chen, T. Swift, and D. Warren. It
followed a traditional Prolog execution model: this has a lot of
strengths, but it probably wasn’t really suitable for use in rustc.
The single biggest reason for this was that it didn’t really know when
to stop: given a query like exists<T> { T: Sized }
, it would happily
try to enumerate all sized types in the system. It was also pretty
non-obvious to me how to extend that system with things like
co-inductive predicates (needed for auto traits) and a few other
peculiarities of Rust.
read more →
21 October 2017
read more →
12 September 2017
In my last post about chalk queries, I discussed how the query
model in chalk. Since that writing, there have been some updates, and
I thought it’d be nice to do a new post covering the current model.
This post will also cover the tabling technique that scalexm
implemented for handling cyclic relations and show how that enables us
to implement implied bounds and other long-desired features in an
elegant way. (Nice work, scalexm!)
read more →
25 May 2017
For my next post discussing chalk, I want to take kind of a
different turn. I want to talk about the general struct of chalk
queries and how chalk handles them right now. (If you’ve never heard
of chalk, it’s sort of “reference implementation” for Rust’s trait
system, as well as an attempt to describe Rust’s trait system in terms
of its logical underpinnings; see
this post for an introduction to the big idea.)
read more →
23 April 2017
In my previous post, I talked over the basics of how
unification works and showed how that “mathematical version” winds
up being expressed in chalk. I want to go a bit further now and extend
that base system to cover associated types. These turn out to be a
pretty non-trival extension.
What is an associated type?
If you’re not a Rust programmer, you may not be familiar with the term
“associated type” (although many langages have equivalents). The basic
idea is that traits can have type members associated with them. I
find the most intuitive example to be the Iterator
trait, which has
an associated type Item
. This type corresponds to kind of elements
that are produced by the iterator:
read more →
25 March 2017
So in my first post on chalk, I mentioned that unification and
normalization of associated types were interesting topics. I’m going
to write a two-part blog post series covering that. This first part
begins with an overview of how ordinary type unification works during
compilation. The next post will add in associated types and we can see
what kinds of mischief they bring with them.
What is unification?
Let’s start with a brief overview of what unification is. When you are
doing type-checking or trait-checking, it often happens that you wind
up with types that you don’t know yet. For example, the user might
write None
– you know that this has type Option<T>
, but you don’t
know what that type T
is. To handle this, the compiler will create a
type variable. This basically represents an unknown,
to-be-determined type. To denote this, I’ll write Option<?T>
, where
the leading question mark indicates a variable.
read more →
26 January 2017
Over the last year or two (man, it’s scary how time flies), I’ve been
doing quite a lot of thinking about Rust’s trait system. I’ve been
looking for a way to correct a number of flaws and shortcomings in the
current implementation, not the least of which is that it’s
performance is not that great. But also, I’ve been wanting to get a
relatively clear, normative definition of how the trait system works,
so that we can better judge possible extensions. After a number of
false starts, I think I’m finally getting somewhere, so I wanted to
start writing about it.
read more →