about summary refs log tree commit diff
path: root/compiler/rustc_middle
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2022-01-30 18:55:22 -0300
committerSantiago Pastorino <spastorino@gmail.com>2022-01-31 11:50:43 -0300
commita9bfb5d83754710a8cb7da2f7d17f62ec3cafdcc (patch)
tree3fd1b7a15b4aabb631434f71d896376c760721dc /compiler/rustc_middle
parent427eba2f0bacdeaebc992a78eb2889564de7d7cf (diff)
Move overlap_mode into trait level attribute + feature flag
Diffstat (limited to 'compiler/rustc_middle')
-rw-r--r--compiler/rustc_middle/src/traits/specialization_graph.rs50
1 files changed, 49 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs
index 087be313b26..36025ea637f 100644
--- a/compiler/rustc_middle/src/traits/specialization_graph.rs
+++ b/compiler/rustc_middle/src/traits/specialization_graph.rs
@@ -4,6 +4,7 @@ use crate::ty::{self, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::ErrorReported;
 use rustc_hir::def_id::{DefId, DefIdMap};
+use rustc_span::symbol::sym;
 
 /// A per-trait graph of impls in specialization order. At the moment, this
 /// graph forms a tree rooted with the trait itself, with all other nodes
@@ -31,11 +32,23 @@ pub struct Graph {
 
     /// Whether an error was emitted while constructing the graph.
     pub has_errored: bool,
+
+    /// Overlap mode to be used
+    pub overlap_mode: OverlapMode,
 }
 
 impl Graph {
     pub fn new() -> Graph {
-        Graph { parent: Default::default(), children: Default::default(), has_errored: false }
+        Graph {
+            parent: Default::default(),
+            children: Default::default(),
+            has_errored: false,
+            overlap_mode: OverlapMode::Stable,
+        }
+    }
+
+    pub fn set_overlap_mode(&mut self, overlap_mode: OverlapMode) {
+        self.overlap_mode = overlap_mode;
     }
 
     /// The parent of a given impl, which is the `DefId` of the trait when the
@@ -45,6 +58,41 @@ impl Graph {
     }
 }
 
+/// What kind of overlap check are we doing -- this exists just for testing and feature-gating
+/// purposes.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable, Debug, TyEncodable, TyDecodable)]
+pub enum OverlapMode {
+    /// The 1.0 rules (either types fail to unify, or where clauses are not implemented for crate-local types)
+    Stable,
+    /// Feature-gated test: Stable, *or* there is an explicit negative impl that rules out one of the where-clauses.
+    WithNegative,
+    /// Just check for negative impls, not for "where clause not implemented": used for testing.
+    Strict,
+}
+
+impl OverlapMode {
+    pub fn get<'tcx>(tcx: TyCtxt<'tcx>, trait_id: DefId) -> OverlapMode {
+        let with_negative_coherence = tcx.features().with_negative_coherence;
+        let strict_coherence = tcx.has_attr(trait_id, sym::rustc_strict_coherence);
+
+        if with_negative_coherence {
+            if strict_coherence { OverlapMode::Strict } else { OverlapMode::WithNegative }
+        } else if strict_coherence {
+            bug!("To use strict_coherence you need to set with_negative_coherence feature flag");
+        } else {
+            OverlapMode::Stable
+        }
+    }
+
+    pub fn use_negative_impl(&self) -> bool {
+        *self == OverlapMode::Strict || *self == OverlapMode::WithNegative
+    }
+
+    pub fn use_implicit_negative(&self) -> bool {
+        *self == OverlapMode::Stable || *self == OverlapMode::WithNegative
+    }
+}
+
 /// Children of a given impl, grouped into blanket/non-blanket varieties as is
 /// done in `TraitDef`.
 #[derive(Default, TyEncodable, TyDecodable, Debug, HashStable)]