diff options
| author | Aaron Turon <aturon@mozilla.com> | 2015-12-30 15:57:49 -0800 |
|---|---|---|
| committer | Aaron Turon <aturon@mozilla.com> | 2016-03-14 15:04:39 -0700 |
| commit | c1df41e776c5a65ce8345d34a7e22296a99abd5e (patch) | |
| tree | 66a6d269c8129db180ba3593a19adfce27b64abe | |
| parent | ed8d059d8d49491b736ea88edd8f2b57a866c44a (diff) | |
| download | rust-c1df41e776c5a65ce8345d34a7e22296a99abd5e.tar.gz rust-c1df41e776c5a65ce8345d34a7e22296a99abd5e.zip | |
Add some basic comments about how specialization fits into the rest of the trait machinery
| -rw-r--r-- | src/librustc/middle/traits/README.md | 40 | ||||
| -rw-r--r-- | src/librustc/middle/traits/specialize.rs | 3 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/librustc/middle/traits/README.md b/src/librustc/middle/traits/README.md index 92982af92dc..ff72f9dd07e 100644 --- a/src/librustc/middle/traits/README.md +++ b/src/librustc/middle/traits/README.md @@ -428,3 +428,43 @@ We used to try and draw finer-grained distinctions, but that led to a serious of annoying and weird bugs like #22019 and #18290. This simple rule seems to be pretty clearly safe and also still retains a very high hit rate (~95% when compiling rustc). + +# Specialization + +Defined in the `specialize` module. + +The basic strategy is to build up a *specialization graph* during +coherence checking. Insertion into the graph locates the right place +to put an impl in the specialization hierarchy; if there is no right +place (due to partial overlap but no containment), you get an overlap +error. Specialization is consulted when selecting an impl (of course), +and the graph is consulted when propagating defaults down the +specialization hierarchy. + +You might expect that the specialization graph would be used during +selection -- i.e., when actually performing specialization. This is +not done for two reasons: + +- It's merely an optimization: given a set of candidates that apply, + we can determine the most specialized one by comparing them directly + for specialization, rather than consulting the graph. Given that we + also cache the results of selection, the benefit of this + optimization is questionable. + +- To build the specialization graph in the first place, we need to use + selection (because we need to determine whether one impl specializes + another). Dealing with this reentrancy would require some additional + mode switch for selection. Given that there seems to be no strong + reason to use the graph anyway, we stick with a simpler approach in + selection, and use the graph only for propagating default + implementations. + +Trait impl selection can succeed even when multiple impls can apply, +as long as they are part of the same specialization family. In that +case, it returns a *single* impl on success -- this is the most +specialized impl *known* to apply. However, if there are any inference +variables in play, the returned impl may not be the actual impl we +will use at trans time. Thus, we take special care to avoid projecting +associated types unless either (1) the associated type does not use +`default` and thus cannot be overridden or (2) all input types are +known concretely. diff --git a/src/librustc/middle/traits/specialize.rs b/src/librustc/middle/traits/specialize.rs index 0f47e19eaf3..30897e9289d 100644 --- a/src/librustc/middle/traits/specialize.rs +++ b/src/librustc/middle/traits/specialize.rs @@ -13,6 +13,9 @@ // // At the moment, this implementation support only the simple "chain" rule: // If any two impls overlap, one must be a strict subset of the other. +// +// See traits/README.md for a bit more detail on how specialization +// fits together with the rest of the trait machinery. use super::util; use super::SelectionContext; |
