region-bound is expected to change in Rust 1.3, but don't use it for
anything in this commit. Note that this is not a "significant" part of
the type (it's not part of the formal model) so we have to normalize
this away or trans starts to get confused because two equal types wind
up with distinct LLVM types.
This patch implements the next chunk of flattening out the type checking context. In a series of patches I moved around the necessary state and logic in order to delete the `Typer` and `ClosureTyper` traits. My next goal is to clean the interfaces and start to move the normalization code behind them.
r? @nrc I hope my PR is coherent, doing this too late at night ;)
This commit finalizes the work of the past commits by fully moving the fulfillment context into
the InferCtxt, cleaning up related context interfaces, removing the Typer and ClosureTyper
traits and cleaning up related intefaces
Update all uses of FulfillmentContext to be ones obtained via
an InferCtxt. This is another step of flattening the type
checking context into a single piece of state.
This first patch starts by moving around pieces of state related to
type checking. The goal is to slowly unify the type checking state
into a single typing context. This initial patch moves the
ParameterEnvironment into the InferCtxt and moves shared tables
from Inherited and ty::ctxt into their own struct Tables. This
is the foundational work to refactoring the type checker to
enable future evolution of the language and tooling.
When we successfully resolve a trait reference with no type/lifetime parameters, like `i32: Foo` or `Box<u32>: Sized`, this is in fact globally true. This patch adds a simple global to the tcx to cache such cases. The main advantage of this is really about caching things like `Box<Vec<Foo>>: Sized`. It also points to the need to revamp our caching infrastructure -- the current caches make selection cost cheaper, but we still wind up paying a high cost in the confirmation process, and in particular unrolling out dependent obligations. Moreover, we should probably do caching more uniformly and with a key that takes the where-clauses into account. But that's for later.
For me, this shows up as a reasonably nice win (20%) on Servo's script crate (when built in dev mode). This is not as big as my initial measurements suggested, I think because I was building my rustc with more debugging enabled at the time. I've not yet done follow-up profiling and so forth to see where the new hot spots are. Bootstrap times seem to be largely unaffected.
cc @pcwalton
This is technically a [breaking-change] in that functions with unsatisfiable where-clauses may now yield errors where before they may have been accepted. Even before, these functions could never have been *called* by actual code. In the future, such functions will probably become illegal altogether, but in this commit they are still accepted, so long as they do not rely on the unsatisfiable where-clauses. As before, the functions still cannot be called in any case.
again, do it once and then just remember the expanded form. At the same
time, filter globally nameable predicates out of the environment, since
they can cause cache errors (and they are not necessary in any case).
that are known to have been satisfied *somewhere*. This means that if
one fn finds that `SomeType: Foo`, then every other fn can just consider
that to hold.
Unfortunately, there are some complications:
1. If `SomeType: Foo` includes dependent conditions, those conditions
may trigger an error. This error will be repored in the first fn
where `SomeType: Foo` is evaluated, but not in the other fns, which
can lead to uneven error reporting (which is sometimes confusing).
2. This kind of caching can be unsound in the presence of
unsatisfiable where clauses. For example, suppose that the first fn
has a where-clause like `i32: Bar<u32>`, which in fact does not
hold. This will "fool" trait resolution into thinking that `i32:
Bar<u32>` holds. This is ok currently, because it means that the
first fn can never be calle (since its where clauses cannot be
satisfied), but if the first fn's successful resolution is cached, it
can allow other fns to compile that should not. This problem is fixed
in the next commit.
There is no subtyping relationship between the types (or their non-freshened
variants), so they can not be merged.
Fixes#22645Fixes#24352Fixes#23825
Should fix#25235 (no test in issue).
Should fix#19976 (test is outdated).
There is no subtyping relationship between the types (or their non-freshened
variants), so they can not be merged.
Fixes#22645Fixes#24352Fixes#23825
Should fix#25235 (no test in issue).
Should fix#19976 (test is outdated).
There were still some mentions of `~[T]` and `~T`, mostly in comments and debugging statements. I tried to do my best to preserve meaning, but I might have gotten some wrong-- I'm happy to fix anything :)