| Age | Commit message (Collapse) | Author | Lines |
|
|
|
|
|
|
|
This hack has long since outlived its usefulness; the transition to
trans passing around full substitutions is basically done. Instead of
`ErasedRegions`, just supply substitutions with a suitable number of
`'static` entries, and invoke `erase_regions` when needed (the latter of
which we already do).
|
|
|
|
Automated conversion using the untry tool [1] and the following command:
```
$ find -name '*.rs' -type f | xargs untry
```
at the root of the Rust repo.
[1]: https://github.com/japaric/untry
|
|
|
|
#32205
|
|
|
|
|
|
|
|
chance of bugs
|
|
|
|
|
|
danger of inference variables floating around without their inference
context.
The main insight here is that, when we are translating substitutions
between two impls, *we already know that the more specific impl holds*,
so we do not need to add its obligations to the parameter
environment. Instead, we can just thread through the inference context
we used to show select the more specific impl in the first place.
|
|
|
|
projection sensitive to "mode" (most importantly, trans vs middle).
This commit introduces several pieces of iteration infrastructure in the
specialization graph data structure, as well as various helpers for
finding the definition of a given item, given its kind and name.
In addition, associated type projection is now *mode-sensitive*, with
three possible modes:
- **Topmost**. This means that projection is only possible if there is a
non-`default` definition of the associated type directly on the
selected impl. This mode is a bit of a hack: it's used during early
coherence checking before we have built the specialization
graph (and therefore before we can walk up the specialization
parents to find other definitions). Eventually, this should be
replaced with a less "staged" construction of the specialization
graph.
- **AnyFinal**. Projection succeeds for any non-`default` associated
type definition, even if it is defined by a parent impl. Used
throughout typechecking.
- **Any**. Projection always succeeds. Used by trans.
The lasting distinction here is between `AnyFinal` and `Any` -- we wish
to treat `default` associated types opaquely for typechecking purposes.
In addition to the above, the commit includes a few other minor review fixes.
|
|
|
|
|
|
trait machinery
|
|
|
|
This commit leverages the specialization graph infrastructure to allow
specializing trait implementations to leave off associated types for
which their parents have provided defaults.
It also modifies the type projection code to avoid projecting associated
types unless either (1) all input types are fully known or (2) the
available associated type is "final", i.e. not marked `default`.
This restriction is required for soundness, due to examples like:
```rust
trait Foo {
type Assoc;
}
impl<T> Foo for T {
default type Assoc = ();
}
impl Foo for u8 {
type Assoc = String;
}
fn generic<T>() -> <T as Foo>::Assoc {
() //~ ERROR
}
fn main() {
let s: String = generic::<u8>();
println!("{}", s); // bad news
}
```
|
|
|
|
This commit leverages the specialization graph infrastructure to allow
specializing trait implementations to leave off methods for which their
parents have provided defaults.
It does not yet check that the `default` keyword is appropriately used
in such cases.
|
|
- Rewrites the overlap checker to instead build up a specialization
graph, checking for overlap errors in the process.
- Use the specialization order during impl selection.
This commit does not yet handle associated types correctly, and assumes
that all items are `default` and are overridden.
|
|
The module contains a few important components:
- The `specialize` function, which determines whether one impl is a
specialization of another.
- The `SpecializationGraph`, a per-trait graph recording the
specialization tree. The main purpose of the graph is to allow
traversals upwards (to less specialized impls) for discovering
un-overridden defaults, and for ensuring that overridden items are
allowed to be overridden.
|
|
|
|
|
|
impl blocks.
For example, the following is now correctly illegal:
```rust
struct Foo;
impl Foo {
fn id() {}
}
impl Foo {
fn id() {}
}
```
"Overlapping" here is determined the same way it is for traits (and in
fact shares the same code path): roughly, there must be some way of
substituting any generic types to unify the impls, such that none of the
`where` clauses are provably unsatisfiable under such a unification.
Closes #22889
|
|
This commit introduces the idea of an "impl header", which consists of
everything outside the impl body: the Self type, the trait
reference (when applicable), and predicates from `where` clauses. This
type is usable with the type folding machinery, making it possible to
work with impl headers at a higher and more generic level.
|
|
|
|
|
|
There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
|
|
|
|
this improves typeck performance by 5% (LLVM times are still huge).
Basically fixes #25916 (still O(n^2), but the example takes <1s to
compile).
|
|
<sup>**context:** moving back to a layered approach to type checking.</sup>
It looks like they'd not ended up tightly coupled in the time one was owned by the other. Every instance outside of `FnCtxt.inh` was from an `InferCtxt` created and dropped in the same function body.
This conflicts slightly with #30652, but there too it looks like the `FulfillmentContext` is from an `InferCtxt` that is created and dropped within the same function body (across one call to a module-private function).
That said, I heard that the PR that originally moved `FulfillmentContext` into `InferCtxt` was big, which leaves me concerned that I'm missing something.
r? @nikomatsakis
|
|
|
|
|
|
|
|
|
|
|
|
was the major use-case, and to update the dep-graph. Other kinds of
predicates are now excluded from the cache because there is no easy way
to make a good dep-graph node for them, and because they are not
believed to be that useful. :)
Fixes #30741. (However, the test still gives wrong result for trans,
for an independent reason which is fixed in the next commit.)
|
|
size of `DepNode` smaller and because we are not that fine-grained yet
anyhow
|
|
|
|
|
|
|
|
a FIXME for later.
|
|
to get the `Sized` error usable, since that hits new users
frequently. Further work is needed for the error reporting for non-Sized
cycle cases; those currently just fallback to the old path. Also adjust tests.
|
|
Better safe than sorry.
|
|
too.
|