Move overlap_mode into trait level attribute + feature flag
This commit is contained in:
@@ -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)]
|
||||
|
||||
Reference in New Issue
Block a user