From a9bfb5d83754710a8cb7da2f7d17f62ec3cafdcc Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sun, 30 Jan 2022 18:55:22 -0300 Subject: Move overlap_mode into trait level attribute + feature flag --- .../src/traits/specialization_graph.rs | 50 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'compiler/rustc_middle') 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)] -- cgit 1.4.1-3-g733a5