|
1 | 1 | use super::OverlapError;
|
2 | 2 |
|
3 |
| -use crate::ich::{self, StableHashingContext}; |
4 | 3 | use crate::traits;
|
5 |
| -use crate::ty::fast_reject::{self, SimplifiedType}; |
6 |
| -use crate::ty::{self, TyCtxt, TypeFoldable}; |
7 |
| -use rustc_data_structures::fx::FxHashMap; |
8 |
| -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; |
9 |
| -use rustc_hir::def_id::{DefId, DefIdMap}; |
10 |
| -use syntax::ast::Ident; |
11 |
| - |
12 |
| -/// A per-trait graph of impls in specialization order. At the moment, this |
13 |
| -/// graph forms a tree rooted with the trait itself, with all other nodes |
14 |
| -/// representing impls, and parent-child relationships representing |
15 |
| -/// specializations. |
16 |
| -/// |
17 |
| -/// The graph provides two key services: |
18 |
| -/// |
19 |
| -/// - Construction. This implicitly checks for overlapping impls (i.e., impls |
20 |
| -/// that overlap but where neither specializes the other -- an artifact of the |
21 |
| -/// simple "chain" rule. |
22 |
| -/// |
23 |
| -/// - Parent extraction. In particular, the graph can give you the *immediate* |
24 |
| -/// parents of a given specializing impl, which is needed for extracting |
25 |
| -/// default items amongst other things. In the simple "chain" rule, every impl |
26 |
| -/// has at most one parent. |
27 |
| -#[derive(RustcEncodable, RustcDecodable, HashStable)] |
28 |
| -pub struct Graph { |
29 |
| - // All impls have a parent; the "root" impls have as their parent the `def_id` |
30 |
| - // of the trait. |
31 |
| - parent: DefIdMap<DefId>, |
32 |
| - |
33 |
| - // The "root" impls are found by looking up the trait's def_id. |
34 |
| - children: DefIdMap<Children>, |
35 |
| -} |
| 4 | +use rustc::ty::fast_reject::{self, SimplifiedType}; |
| 5 | +use rustc::ty::{self, TyCtxt, TypeFoldable}; |
| 6 | +use rustc_hir::def_id::DefId; |
36 | 7 |
|
37 |
| -/// Children of a given impl, grouped into blanket/non-blanket varieties as is |
38 |
| -/// done in `TraitDef`. |
39 |
| -#[derive(Default, RustcEncodable, RustcDecodable)] |
40 |
| -struct Children { |
41 |
| - // Impls of a trait (or specializations of a given impl). To allow for |
42 |
| - // quicker lookup, the impls are indexed by a simplified version of their |
43 |
| - // `Self` type: impls with a simplifiable `Self` are stored in |
44 |
| - // `nonblanket_impls` keyed by it, while all other impls are stored in |
45 |
| - // `blanket_impls`. |
46 |
| - // |
47 |
| - // A similar division is used within `TraitDef`, but the lists there collect |
48 |
| - // together *all* the impls for a trait, and are populated prior to building |
49 |
| - // the specialization graph. |
50 |
| - /// Impls of the trait. |
51 |
| - nonblanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>, |
52 |
| - |
53 |
| - /// Blanket impls associated with the trait. |
54 |
| - blanket_impls: Vec<DefId>, |
55 |
| -} |
| 8 | +pub use rustc::traits::types::specialization_graph::*; |
56 | 9 |
|
57 | 10 | #[derive(Copy, Clone, Debug)]
|
58 | 11 | pub enum FutureCompatOverlapErrorKind {
|
@@ -269,10 +222,6 @@ where
|
269 | 222 | }
|
270 | 223 |
|
271 | 224 | impl<'tcx> Graph {
|
272 |
| - pub fn new() -> Graph { |
273 |
| - Graph { parent: Default::default(), children: Default::default() } |
274 |
| - } |
275 |
| - |
276 | 225 | /// Insert a local impl into the specialization graph. If an existing impl
|
277 | 226 | /// conflicts with it (has overlap, but neither specializes the other),
|
278 | 227 | /// information about the area of overlap is returned in the `Err`.
|
@@ -383,145 +332,4 @@ impl<'tcx> Graph {
|
383 | 332 |
|
384 | 333 | self.children.entry(parent).or_default().insert_blindly(tcx, child);
|
385 | 334 | }
|
386 |
| - |
387 |
| - /// The parent of a given impl, which is the `DefId` of the trait when the |
388 |
| - /// impl is a "specialization root". |
389 |
| - pub fn parent(&self, child: DefId) -> DefId { |
390 |
| - *self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {:?}", child)) |
391 |
| - } |
392 |
| -} |
393 |
| - |
394 |
| -/// A node in the specialization graph is either an impl or a trait |
395 |
| -/// definition; either can serve as a source of item definitions. |
396 |
| -/// There is always exactly one trait definition node: the root. |
397 |
| -#[derive(Debug, Copy, Clone)] |
398 |
| -pub enum Node { |
399 |
| - Impl(DefId), |
400 |
| - Trait(DefId), |
401 |
| -} |
402 |
| - |
403 |
| -impl<'tcx> Node { |
404 |
| - pub fn is_from_trait(&self) -> bool { |
405 |
| - match *self { |
406 |
| - Node::Trait(..) => true, |
407 |
| - _ => false, |
408 |
| - } |
409 |
| - } |
410 |
| - |
411 |
| - /// Iterate over the items defined directly by the given (impl or trait) node. |
412 |
| - pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> { |
413 |
| - tcx.associated_items(self.def_id()) |
414 |
| - } |
415 |
| - |
416 |
| - /// Finds an associated item defined in this node. |
417 |
| - /// |
418 |
| - /// If this returns `None`, the item can potentially still be found in |
419 |
| - /// parents of this node. |
420 |
| - pub fn item( |
421 |
| - &self, |
422 |
| - tcx: TyCtxt<'tcx>, |
423 |
| - trait_item_name: Ident, |
424 |
| - trait_item_kind: ty::AssocKind, |
425 |
| - trait_def_id: DefId, |
426 |
| - ) -> Option<ty::AssocItem> { |
427 |
| - use crate::ty::AssocKind::*; |
428 |
| - |
429 |
| - tcx.associated_items(self.def_id()).find(move |impl_item| { |
430 |
| - match (trait_item_kind, impl_item.kind) { |
431 |
| - | (Const, Const) |
432 |
| - | (Method, Method) |
433 |
| - | (Type, Type) |
434 |
| - | (Type, OpaqueTy) // assoc. types can be made opaque in impls |
435 |
| - => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), |
436 |
| - |
437 |
| - | (Const, _) |
438 |
| - | (Method, _) |
439 |
| - | (Type, _) |
440 |
| - | (OpaqueTy, _) |
441 |
| - => false, |
442 |
| - } |
443 |
| - }) |
444 |
| - } |
445 |
| - |
446 |
| - pub fn def_id(&self) -> DefId { |
447 |
| - match *self { |
448 |
| - Node::Impl(did) => did, |
449 |
| - Node::Trait(did) => did, |
450 |
| - } |
451 |
| - } |
452 |
| -} |
453 |
| - |
454 |
| -#[derive(Copy, Clone)] |
455 |
| -pub struct Ancestors<'tcx> { |
456 |
| - trait_def_id: DefId, |
457 |
| - specialization_graph: &'tcx Graph, |
458 |
| - current_source: Option<Node>, |
459 |
| -} |
460 |
| - |
461 |
| -impl Iterator for Ancestors<'_> { |
462 |
| - type Item = Node; |
463 |
| - fn next(&mut self) -> Option<Node> { |
464 |
| - let cur = self.current_source.take(); |
465 |
| - if let Some(Node::Impl(cur_impl)) = cur { |
466 |
| - let parent = self.specialization_graph.parent(cur_impl); |
467 |
| - |
468 |
| - self.current_source = if parent == self.trait_def_id { |
469 |
| - Some(Node::Trait(parent)) |
470 |
| - } else { |
471 |
| - Some(Node::Impl(parent)) |
472 |
| - }; |
473 |
| - } |
474 |
| - cur |
475 |
| - } |
476 |
| -} |
477 |
| - |
478 |
| -pub struct NodeItem<T> { |
479 |
| - pub node: Node, |
480 |
| - pub item: T, |
481 |
| -} |
482 |
| - |
483 |
| -impl<T> NodeItem<T> { |
484 |
| - pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> NodeItem<U> { |
485 |
| - NodeItem { node: self.node, item: f(self.item) } |
486 |
| - } |
487 |
| -} |
488 |
| - |
489 |
| -impl<'tcx> Ancestors<'tcx> { |
490 |
| - /// Finds the bottom-most (ie. most specialized) definition of an associated |
491 |
| - /// item. |
492 |
| - pub fn leaf_def( |
493 |
| - mut self, |
494 |
| - tcx: TyCtxt<'tcx>, |
495 |
| - trait_item_name: Ident, |
496 |
| - trait_item_kind: ty::AssocKind, |
497 |
| - ) -> Option<NodeItem<ty::AssocItem>> { |
498 |
| - let trait_def_id = self.trait_def_id; |
499 |
| - self.find_map(|node| { |
500 |
| - node.item(tcx, trait_item_name, trait_item_kind, trait_def_id) |
501 |
| - .map(|item| NodeItem { node, item }) |
502 |
| - }) |
503 |
| - } |
504 |
| -} |
505 |
| - |
506 |
| -/// Walk up the specialization ancestors of a given impl, starting with that |
507 |
| -/// impl itself. |
508 |
| -pub fn ancestors( |
509 |
| - tcx: TyCtxt<'tcx>, |
510 |
| - trait_def_id: DefId, |
511 |
| - start_from_impl: DefId, |
512 |
| -) -> Ancestors<'tcx> { |
513 |
| - let specialization_graph = tcx.specialization_graph_of(trait_def_id); |
514 |
| - Ancestors { |
515 |
| - trait_def_id, |
516 |
| - specialization_graph, |
517 |
| - current_source: Some(Node::Impl(start_from_impl)), |
518 |
| - } |
519 |
| -} |
520 |
| - |
521 |
| -impl<'a> HashStable<StableHashingContext<'a>> for Children { |
522 |
| - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
523 |
| - let Children { ref nonblanket_impls, ref blanket_impls } = *self; |
524 |
| - |
525 |
| - ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); |
526 |
| - } |
527 | 335 | }
|
0 commit comments