diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2022-01-30 18:55:22 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2022-01-31 11:50:43 -0300 |
| commit | a9bfb5d83754710a8cb7da2f7d17f62ec3cafdcc (patch) | |
| tree | 3fd1b7a15b4aabb631434f71d896376c760721dc /compiler/rustc_middle | |
| parent | 427eba2f0bacdeaebc992a78eb2889564de7d7cf (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.rs | 50 |
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)] |
