diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 1ea1f496e50..1d2e12ec575 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -1,9 +1,8 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{ - self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, -}; +use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath}; +use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 12cefc23233..28baa334840 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -299,37 +299,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -/// Polarity for a trait predicate. May either be negative or positive. -/// Distinguished from [`ImplPolarity`] since we never compute goals with -/// "reservation" level. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum PredicatePolarity { - /// `Type: Trait` - Positive, - /// `Type: !Trait` - Negative, -} - -impl PredicatePolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> PredicatePolarity { - match self { - PredicatePolarity::Positive => PredicatePolarity::Negative, - PredicatePolarity::Negative => PredicatePolarity::Positive, - } - } -} - -impl fmt::Display for PredicatePolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 5387036d409..80a9499e862 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -5,6 +5,7 @@ use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_type_ir::ClauseKind as IrClauseKind; use rustc_type_ir::PredicateKind as IrPredicateKind; +use rustc_type_ir::TraitPredicate as IrTraitPredicate; use rustc_type_ir::TraitRef as IrTraitRef; use std::cmp::Ordering; @@ -15,6 +16,7 @@ }; pub type TraitRef<'tcx> = IrTraitRef>; +pub type TraitPredicate<'tcx> = IrTraitPredicate>; pub type ClauseKind<'tcx> = IrClauseKind>; pub type PredicateKind<'tcx> = IrPredicateKind>; @@ -578,37 +580,8 @@ pub fn instantiate_supertrait( } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx>, - - /// If polarity is Positive: we are proving that the trait is implemented. - /// - /// If polarity is Negative: we are proving that a negative impl of this trait - /// exists. (Note that coherence also checks whether negative impls of supertraits - /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. - pub polarity: PredicatePolarity, -} - pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; -impl<'tcx> TraitPredicate<'tcx> { - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } - } - - pub fn def_id(self) -> DefId { - self.trait_ref.def_id - } - - pub fn self_ty(self) -> Ty<'tcx> { - self.trait_ref.self_ty() - } -} - impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 14a628ab064..fc42ba6fcd3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2953,8 +2953,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } +#[extension(pub trait PrintTraitPredicateExt<'tcx>)] impl<'tcx> ty::TraitPredicate<'tcx> { - pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { + fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { TraitPredPrintModifiersAndPath(self) } } @@ -3037,6 +3038,15 @@ macro_rules! define_print_and_forward_display { p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path())) } + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), ": "); + p!(pretty_print_bound_constness(self.trait_ref)); + if let ty::PredicatePolarity::Negative = self.polarity { + p!("!"); + } + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3176,15 +3186,6 @@ macro_rules! define_print_and_forward_display { p!(print(self.b)) } - ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), ": "); - p!(pretty_print_bound_constness(self.trait_ref)); - if let ty::PredicatePolarity::Negative = self.polarity { - p!("!"); - } - p!(print(self.trait_ref.print_trait_sugared())) - } - ty::ProjectionPredicate<'tcx> { p!(print(self.projection_ty), " == "); cx.reset_type_limit(); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a7770f71926..e0fbcb1a7f0 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -158,13 +158,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { } } -impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(effects) printing? - write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) - } -} - impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 51a4e910d62..ea1752a6e98 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -45,7 +45,9 @@ use crate::infer::InferCtxtExt as _; use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::print::{ + with_forced_trimmed_paths, with_no_trimmed_paths, PrintTraitPredicateExt as _, +}; use itertools::EitherOrBoth; use itertools::Itertools; diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 92fe50883d0..08ffe37b8b4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -38,7 +38,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{ - with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitRefExt as _, + with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitPredicateExt as _, + PrintTraitRefExt as _, }; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index d12052625ea..cef3f4e8ce0 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -11,10 +11,10 @@ rustc_ast_ir = { path = "../rustc_ast_ir" } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } -smallvec = { version = "1.8.1" } +rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } +smallvec = { version = "1.8.1", default-features = false } # tidy-alphabetical-end [features] diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index c8bd7fea11b..fe14836b1d5 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,9 +5,9 @@ use crate::inherent::*; use crate::ir_print::IrPrint; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{CanonicalVarInfo, DebugWithInfcx, TraitRef}; +use crate::{CanonicalVarInfo, DebugWithInfcx, TraitPredicate, TraitRef}; -pub trait Interner: Sized + Copy + IrPrint> { +pub trait Interner: Sized + Copy + IrPrint> + IrPrint> { type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type AdtDef: Copy + Debug + Hash + Eq; diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 84e889b486a..715fb317669 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,6 +1,6 @@ use std::fmt; -use crate::{Interner, TraitRef}; +use crate::{Interner, TraitPredicate, TraitRef}; pub trait IrPrint { fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; @@ -15,7 +15,13 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { >>::print(self, fmt) } } + )* + } +} +macro_rules! define_debug_via_print { + ($($ty:ident),+ $(,)?) => { + $( impl fmt::Debug for $ty { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { >>::print_debug(self, fmt) @@ -25,4 +31,6 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { } } -define_display_via_print!(TraitRef,); +define_display_via_print!(TraitRef, TraitPredicate,); + +define_debug_via_print!(TraitRef,); diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index 7dcc8851a43..f2f7b165de5 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -53,4 +53,5 @@ fn visit_with>( crate::UniverseIndex, rustc_ast_ir::Mutability, rustc_ast_ir::Movability, + crate::PredicatePolarity, } diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs index 3b37df5b39d..0aae75ebf43 100644 --- a/compiler/rustc_type_ir/src/trait_ref.rs +++ b/compiler/rustc_type_ir/src/trait_ref.rs @@ -1,3 +1,5 @@ +use std::fmt; + use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; @@ -67,3 +69,78 @@ pub fn self_ty(&self) -> I::Ty { self.args.type_at(0) } } + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitPredicate { + pub trait_ref: TraitRef, + + /// If polarity is Positive: we are proving that the trait is implemented. + /// + /// If polarity is Negative: we are proving that a negative impl of this trait + /// exists. (Note that coherence also checks whether negative impls of supertraits + /// exist via a series of predicates.) + /// + /// If polarity is Reserved: that's a bug. + pub polarity: PredicatePolarity, +} + +impl TraitPredicate { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } + + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } +} + +impl fmt::Debug for TraitPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // FIXME(effects) printing? + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) + } +} + +/// Polarity for a trait predicate. May either be negative or positive. +/// Distinguished from [`ImplPolarity`] since we never compute goals with +/// "reservation" level. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum PredicatePolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative, +} + +impl PredicatePolarity { + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. + pub fn flip(&self) -> PredicatePolarity { + match self { + PredicatePolarity::Positive => PredicatePolarity::Negative, + PredicatePolarity::Negative => PredicatePolarity::Positive, + } + } +} + +impl fmt::Display for PredicatePolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + } + } +} diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs index eb45001cc67..000bcf2d3b2 100644 --- a/compiler/rustc_type_ir_macros/src/lib.rs +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -1,6 +1,6 @@ -use synstructure::decl_derive; use quote::quote; use syn::{parse_quote, visit_mut::VisitMut}; +use synstructure::decl_derive; decl_derive!( [TypeFoldable_Generic] => type_foldable_derive @@ -156,4 +156,4 @@ fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( } }, ) -} \ No newline at end of file +}