Skip to content

Commit c1df41e

Browse files
committed
Add some basic comments about how specialization fits into the rest of the trait machinery
1 parent ed8d059 commit c1df41e

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/librustc/middle/traits/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,43 @@ We used to try and draw finer-grained distinctions, but that led to a
428428
serious of annoying and weird bugs like #22019 and #18290. This simple
429429
rule seems to be pretty clearly safe and also still retains a very
430430
high hit rate (~95% when compiling rustc).
431+
432+
# Specialization
433+
434+
Defined in the `specialize` module.
435+
436+
The basic strategy is to build up a *specialization graph* during
437+
coherence checking. Insertion into the graph locates the right place
438+
to put an impl in the specialization hierarchy; if there is no right
439+
place (due to partial overlap but no containment), you get an overlap
440+
error. Specialization is consulted when selecting an impl (of course),
441+
and the graph is consulted when propagating defaults down the
442+
specialization hierarchy.
443+
444+
You might expect that the specialization graph would be used during
445+
selection -- i.e., when actually performing specialization. This is
446+
not done for two reasons:
447+
448+
- It's merely an optimization: given a set of candidates that apply,
449+
we can determine the most specialized one by comparing them directly
450+
for specialization, rather than consulting the graph. Given that we
451+
also cache the results of selection, the benefit of this
452+
optimization is questionable.
453+
454+
- To build the specialization graph in the first place, we need to use
455+
selection (because we need to determine whether one impl specializes
456+
another). Dealing with this reentrancy would require some additional
457+
mode switch for selection. Given that there seems to be no strong
458+
reason to use the graph anyway, we stick with a simpler approach in
459+
selection, and use the graph only for propagating default
460+
implementations.
461+
462+
Trait impl selection can succeed even when multiple impls can apply,
463+
as long as they are part of the same specialization family. In that
464+
case, it returns a *single* impl on success -- this is the most
465+
specialized impl *known* to apply. However, if there are any inference
466+
variables in play, the returned impl may not be the actual impl we
467+
will use at trans time. Thus, we take special care to avoid projecting
468+
associated types unless either (1) the associated type does not use
469+
`default` and thus cannot be overridden or (2) all input types are
470+
known concretely.

src/librustc/middle/traits/specialize.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
//
1414
// At the moment, this implementation support only the simple "chain" rule:
1515
// If any two impls overlap, one must be a strict subset of the other.
16+
//
17+
// See traits/README.md for a bit more detail on how specialization
18+
// fits together with the rest of the trait machinery.
1619

1720
use super::util;
1821
use super::SelectionContext;

0 commit comments

Comments
 (0)