diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty/mod.rs')
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e95493acbb7..cf47da157d1 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -38,7 +38,7 @@ use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_session::cstore::CrateStoreDyn; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_target::abi::Align; use std::cmp::Ordering; @@ -92,7 +92,6 @@ pub mod fold; pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; -pub mod outlives; pub mod print; pub mod query; pub mod relate; @@ -165,7 +164,18 @@ pub struct ImplHeader<'tcx> { pub predicates: Vec<Predicate<'tcx>>, } -#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] +#[derive( + Copy, + Clone, + PartialEq, + Eq, + Hash, + TyEncodable, + TyDecodable, + HashStable, + Debug, + TypeFoldable +)] pub enum ImplPolarity { /// `impl Trait for Type` Positive, @@ -178,6 +188,27 @@ pub enum ImplPolarity { Reservation, } +impl ImplPolarity { + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. + pub fn flip(&self) -> Option<ImplPolarity> { + match self { + ImplPolarity::Positive => Some(ImplPolarity::Negative), + ImplPolarity::Negative => Some(ImplPolarity::Positive), + ImplPolarity::Reservation => None, + } + } +} + +impl fmt::Display for ImplPolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + Self::Reservation => f.write_str("reservation"), + } + } +} + #[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)] pub enum Visibility { /// Visible everywhere (including in other crates). @@ -460,6 +491,29 @@ impl<'tcx> Predicate<'tcx> { pub fn kind(self) -> Binder<'tcx, PredicateKind<'tcx>> { self.inner.kind } + + /// Flips the polarity of a Predicate. + /// + /// Given `T: Trait` predicate it returns `T: !Trait` and given `T: !Trait` returns `T: Trait`. + pub fn flip_polarity(&self, tcx: TyCtxt<'tcx>) -> Option<Predicate<'tcx>> { + let kind = self + .inner + .kind + .map_bound(|kind| match kind { + PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) => { + Some(PredicateKind::Trait(TraitPredicate { + trait_ref, + constness, + polarity: polarity.flip()?, + })) + } + + _ => None, + }) + .transpose()?; + + Some(tcx.mk_predicate(kind)) + } } impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> { @@ -655,6 +709,8 @@ pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx>, pub constness: BoundConstness, + + pub polarity: ImplPolarity, } pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; @@ -789,7 +845,11 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.value .map_bound(|trait_ref| { - PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: self.constness }) + PredicateKind::Trait(ty::TraitPredicate { + trait_ref, + constness: self.constness, + polarity: ty::ImplPolarity::Positive, + }) }) .to_predicate(tcx) } @@ -1900,6 +1960,14 @@ impl<'tcx> TyCtxt<'tcx> { self.sess.contains_name(&self.get_attrs(did), attr) } + /// Determines whether an item is annotated with `doc(hidden)`. + pub fn is_doc_hidden(self, did: DefId) -> bool { + self.get_attrs(did) + .iter() + .filter_map(|attr| if attr.has_name(sym::doc) { attr.meta_item_list() } else { None }) + .any(|items| items.iter().any(|item| item.has_name(sym::hidden))) + } + /// Returns `true` if this is an `auto trait`. pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { self.trait_def(trait_def_id).has_auto_impl |
