Move overlap_mode into trait level attribute + feature flag

This commit is contained in:
Santiago Pastorino
2022-01-30 18:55:22 -03:00
parent 427eba2f0b
commit a9bfb5d837
17 changed files with 121 additions and 75 deletions

View File

@@ -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)]