-/// What kind of overlap check are we doing -- this exists just for testing and feature-gating
-/// purposes.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-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 {
- fn use_negative_impl(&self) -> bool {
- *self == OverlapMode::Strict || *self == OverlapMode::WithNegative
- }
-
- fn use_implicit_negative(&self) -> bool {
- *self == OverlapMode::Stable || *self == OverlapMode::WithNegative
- }
-}
-
-fn overlap_mode<'tcx>(tcx: TyCtxt<'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> OverlapMode {
- // Find the possible coherence mode override opt-in attributes for each `DefId`
- let find_coherence_attr = |attr: &Attribute| {
- let name = attr.name_or_empty();
- match name {
- sym::rustc_with_negative_coherence | sym::rustc_strict_coherence => Some(name),
- _ => None,
- }
- };
- let impl1_coherence_mode = tcx.get_attrs(impl1_def_id).iter().find_map(find_coherence_attr);
- let impl2_coherence_mode = tcx.get_attrs(impl2_def_id).iter().find_map(find_coherence_attr);
-
- // If there are any (that currently happens in tests), they need to match. Otherwise, the
- // default 1.0 rules are used.
- match (impl1_coherence_mode, impl2_coherence_mode) {
- (None, None) => OverlapMode::Stable,
- (Some(sym::rustc_with_negative_coherence), Some(sym::rustc_with_negative_coherence)) => {
- OverlapMode::WithNegative
- }
- (Some(sym::rustc_strict_coherence), Some(sym::rustc_strict_coherence)) => {
- OverlapMode::Strict
- }
- (Some(mode), _) | (_, Some(mode)) => {
- bug!("Use the same coherence mode on both impls: {}", mode)
- }
- }
-}
-