Skip to content

Commit 2c556f5

Browse files
committed
group ty::coherence in one file
1 parent 3c941b2 commit 2c556f5

File tree

7 files changed

+116
-123
lines changed

7 files changed

+116
-123
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::fmt;
2+
3+
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
5+
6+
use crate::ty::{Predicate, SimplifiedType, TraitRef, Ty};
7+
8+
/// A map for the local crate mapping each type to a vector of its
9+
/// inherent impls. This is not meant to be used outside of coherence;
10+
/// rather, you should request the vector for a specific type via
11+
/// `tcx.inherent_impls(def_id)` so as to minimize your dependencies
12+
/// (constructing this map requires touching the entire crate).
13+
#[derive(Clone, Debug, Default, HashStable)]
14+
pub struct CrateInherentImpls {
15+
pub inherent_impls: LocalDefIdMap<Vec<DefId>>,
16+
pub incoherent_impls: FxHashMap<SimplifiedType, Vec<LocalDefId>>,
17+
}
18+
19+
#[derive(Debug, PartialEq, Eq)]
20+
pub enum ImplOverlapKind {
21+
/// These impls are always allowed to overlap.
22+
Permitted {
23+
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
24+
marker: bool,
25+
},
26+
/// These impls are allowed to overlap, but that raises
27+
/// an issue #33140 future-compatibility warning.
28+
///
29+
/// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
30+
/// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
31+
///
32+
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
33+
/// that difference, making what reduces to the following set of impls:
34+
///
35+
/// ```compile_fail,(E0119)
36+
/// trait Trait {}
37+
/// impl Trait for dyn Send + Sync {}
38+
/// impl Trait for dyn Sync + Send {}
39+
/// ```
40+
///
41+
/// Obviously, once we made these types be identical, that code causes a coherence
42+
/// error and a fairly big headache for us. However, luckily for us, the trait
43+
/// `Trait` used in this case is basically a marker trait, and therefore having
44+
/// overlapping impls for it is sound.
45+
///
46+
/// To handle this, we basically regard the trait as a marker trait, with an additional
47+
/// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
48+
/// it has the following restrictions:
49+
///
50+
/// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
51+
/// positive impls.
52+
/// 2. The trait-ref of both impls must be equal.
53+
/// 3. The trait-ref of both impls must be a trait object type consisting only of
54+
/// marker traits.
55+
/// 4. Neither of the impls can have any where-clauses.
56+
///
57+
/// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
58+
Issue33140,
59+
}
60+
61+
/// The "header" of an impl is everything outside the body: a Self type, a trait
62+
/// ref (in the case of a trait impl), and a set of predicates (from the
63+
/// bounds / where-clauses).
64+
#[derive(Clone, Debug, TypeFoldable, TypeVisitable)]
65+
pub struct ImplHeader<'tcx> {
66+
pub impl_def_id: DefId,
67+
pub self_ty: Ty<'tcx>,
68+
pub trait_ref: Option<TraitRef<'tcx>>,
69+
pub predicates: Vec<Predicate<'tcx>>,
70+
}
71+
72+
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
73+
pub enum ImplSubject<'tcx> {
74+
Trait(TraitRef<'tcx>),
75+
Inherent(Ty<'tcx>),
76+
}
77+
78+
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
79+
#[derive(TypeFoldable, TypeVisitable)]
80+
pub enum ImplPolarity {
81+
/// `impl Trait for Type`
82+
Positive,
83+
/// `impl !Trait for Type`
84+
Negative,
85+
/// `#[rustc_reservation_impl] impl Trait for Type`
86+
///
87+
/// This is a "stability hack", not a real Rust feature.
88+
/// See #64631 for details.
89+
Reservation,
90+
}
91+
92+
impl ImplPolarity {
93+
/// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`.
94+
pub fn flip(&self) -> Option<ImplPolarity> {
95+
match self {
96+
ImplPolarity::Positive => Some(ImplPolarity::Negative),
97+
ImplPolarity::Negative => Some(ImplPolarity::Positive),
98+
ImplPolarity::Reservation => None,
99+
}
100+
}
101+
}
102+
103+
impl fmt::Display for ImplPolarity {
104+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105+
match self {
106+
Self::Positive => f.write_str("positive"),
107+
Self::Negative => f.write_str("negative"),
108+
Self::Reservation => f.write_str("reservation"),
109+
}
110+
}
111+
}

compiler/rustc_middle/src/ty/crate_inherent_impls.rs

Lines changed: 0 additions & 15 deletions
This file was deleted.

compiler/rustc_middle/src/ty/impl_header.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

compiler/rustc_middle/src/ty/impl_overlap_kind.rs

Lines changed: 0 additions & 41 deletions
This file was deleted.

compiler/rustc_middle/src/ty/impl_polarity.rs

Lines changed: 0 additions & 36 deletions
This file was deleted.

compiler/rustc_middle/src/ty/impl_subject.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,13 @@ mod closure;
6565
mod closure_size_profile_data;
6666
mod consts;
6767
mod context;
68-
mod crate_inherent_impls;
6968
mod crate_variances_map;
7069
mod destructor;
7170
mod destructured_const;
7271
mod diagnostics;
7372
mod erase_regions;
7473
mod field_def;
7574
mod generics;
76-
mod impl_header;
77-
mod impl_overlap_kind;
78-
mod impl_polarity;
79-
mod impl_subject;
8075
mod impl_trait_in_trait_data;
8176
mod impls_ty;
8277
mod infer_var_info;
@@ -103,6 +98,8 @@ mod variant_discr;
10398
mod variant_flags;
10499
mod visibility;
105100

101+
mod coherence;
102+
106103
pub use rustc_session::lint::RegisteredTools;
107104
pub use rustc_target::abi::{ReprFlags, ReprOptions};
108105
pub use rustc_type_ir::AliasKind::*;
@@ -127,24 +124,22 @@ pub use self::closure::{
127124
CAPTURE_STRUCT_LOCAL,
128125
};
129126
pub use self::closure_size_profile_data::ClosureSizeProfileData;
127+
pub use self::coherence::{
128+
CrateInherentImpls, ImplHeader, ImplOverlapKind, ImplPolarity, ImplSubject,
129+
};
130130
pub use self::consts::{
131131
Const, ConstData, ConstInt, ConstKind, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,
132132
};
133133
pub use self::context::{
134134
tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed,
135135
};
136-
pub use self::crate_inherent_impls::CrateInherentImpls;
137136
pub use self::crate_variances_map::CrateVariancesMap;
138137
pub use self::destructor::Destructor;
139138
pub use self::destructured_const::DestructuredConst;
140139
pub use self::diagnostics::*;
141140
pub use self::field_def::FieldDef;
142141
pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
143142
pub use self::generics::*;
144-
pub use self::impl_header::ImplHeader;
145-
pub use self::impl_overlap_kind::ImplOverlapKind;
146-
pub use self::impl_polarity::ImplPolarity;
147-
pub use self::impl_subject::ImplSubject;
148143
pub use self::impl_trait_in_trait_data::ImplTraitInTraitData;
149144
pub use self::infer_var_info::InferVarInfo;
150145
pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams};

0 commit comments

Comments
 (0)