diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 2f0eadce631e2..af2eb4d10a6b8 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -1,4 +1,5 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::TypeVisitable; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; use super::type_variable::TypeVariableOrigin; @@ -99,69 +100,74 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { where F: FnOnce() -> Result, T: TypeFoldable<'tcx>, + E: TypeVisitable<'tcx>, { let variable_lengths = self.variable_lengths(); - let (mut fudger, value) = self.probe(|_| { - match f() { - Ok(value) => { - let value = self.resolve_vars_if_possible(value); - - // At this point, `value` could in principle refer - // to inference variables that have been created during - // the snapshot. Once we exit `probe()`, those are - // going to be popped, so we will have to - // eliminate any references to them. - - let mut inner = self.inner.borrow_mut(); - let type_vars = - inner.type_variables().vars_since_snapshot(variable_lengths.type_var_len); - let int_vars = vars_since_snapshot( - &mut inner.int_unification_table(), - variable_lengths.int_var_len, - ); - let float_vars = vars_since_snapshot( - &mut inner.float_unification_table(), - variable_lengths.float_var_len, - ); - let region_vars = inner - .unwrap_region_constraints() - .vars_since_snapshot(variable_lengths.region_constraints_len); - let const_vars = const_vars_since_snapshot( - &mut inner.const_unification_table(), - variable_lengths.const_var_len, - ); - let fudger = InferenceFudger { + let snapshot = self.start_snapshot(); + + match f() { + Ok(value) => { + let value = self.resolve_vars_if_possible(value); + + // At this point, `value` could in principle refer + // to inference variables that have been created during + // the snapshot. Once we exit the snapshot, those are + // going to be popped, so we will have to + // eliminate any references to them. + + let mut inner = self.inner.borrow_mut(); + let type_vars = + inner.type_variables().vars_since_snapshot(variable_lengths.type_var_len); + let int_vars = vars_since_snapshot( + &mut inner.int_unification_table(), + variable_lengths.int_var_len, + ); + let float_vars = vars_since_snapshot( + &mut inner.float_unification_table(), + variable_lengths.float_var_len, + ); + let region_vars = inner + .unwrap_region_constraints() + .vars_since_snapshot(variable_lengths.region_constraints_len); + let const_vars = const_vars_since_snapshot( + &mut inner.const_unification_table(), + variable_lengths.const_var_len, + ); + drop(inner); + + self.rollback_to("fudge_inference_if_ok -- ok", snapshot); + + // At this point, we need to replace any of the now-popped + // type/region variables that appear in `value` with a fresh + // variable of the appropriate kind. We can't do this during + // the probe because they would just get popped then too. =) + + // Micro-optimization: if no variables have been created, then + // `value` can't refer to any of them. =) So we can just return it. + if type_vars.0.is_empty() + && int_vars.is_empty() + && float_vars.is_empty() + && region_vars.0.is_empty() + && const_vars.0.is_empty() + { + Ok(value) + } else { + Ok(value.fold_with(&mut InferenceFudger { infcx: self, type_vars, int_vars, float_vars, region_vars, const_vars, - }; - - Ok((fudger, value)) + })) } - Err(e) => Err(e), } - })?; - - // At this point, we need to replace any of the now-popped - // type/region variables that appear in `value` with a fresh - // variable of the appropriate kind. We can't do this during - // the probe because they would just get popped then too. =) - - // Micro-optimization: if no variables have been created, then - // `value` can't refer to any of them. =) So we can just return it. - if fudger.type_vars.0.is_empty() - && fudger.int_vars.is_empty() - && fudger.float_vars.is_empty() - && fudger.region_vars.0.is_empty() - && fudger.const_vars.0.is_empty() - { - Ok(value) - } else { - Ok(value.fold_with(&mut fudger)) + Err(e) => { + debug_assert!(!e.needs_infer(), "fudge_inference_if_ok: leaking infer vars: {e:?}"); + self.rollback_to("fudge_inference_if_ok -- error", snapshot); + return Err(e); + } } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 444817f396e56..6f304949b7b3f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -71,14 +71,13 @@ pub mod type_variable; mod undo_log; #[must_use] -#[derive(Debug)] +#[derive(Debug, Clone, TypeFoldable, TypeVisitable)] pub struct InferOk<'tcx, T> { pub value: T, pub obligations: PredicateObligations<'tcx>, } pub type InferResult<'tcx, T> = Result, TypeError<'tcx>>; -pub type Bound = Option; pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result" pub type FixupResult<'tcx, T> = Result>; // "fixup result" @@ -845,6 +844,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn commit_if_ok(&self, f: F) -> Result where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> Result, + E: TypeVisitable<'tcx>, { let snapshot = self.start_snapshot(); let r = f(&snapshot); @@ -853,7 +853,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { Ok(_) => { self.commit_from(snapshot); } - Err(_) => { + Err(ref e) => { + debug_assert!(!e.needs_infer(), "commit_if_ok: leaking infer vars: {e:?}"); self.rollback_to("commit_if_ok -- error", snapshot); } } @@ -865,9 +866,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn probe(&self, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, + R: TypeVisitable<'tcx>, { let snapshot = self.start_snapshot(); + let r = f(&snapshot); + + debug_assert!(!r.needs_infer(), "probe: leaking infer vars: {r:?}"); self.rollback_to("probe", snapshot); r } @@ -877,6 +882,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn probe_maybe_skip_leak_check(&self, should_skip: bool, f: F) -> R where F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> R, + R: TypeVisitable<'tcx>, { let snapshot = self.start_snapshot(); let was_skip_leak_check = self.skip_leak_check.get(); @@ -884,6 +890,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.skip_leak_check.set(true); } let r = f(&snapshot); + + debug_assert!(!r.needs_infer(), "probe_maybe_skip_leak_check: leaking infer vars: {r:?}"); self.rollback_to("probe", snapshot); self.skip_leak_check.set(was_skip_leak_check); r diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index 5d22f9f972e10..c7ea02f9287c2 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -15,7 +15,7 @@ pub use rustc_middle::traits::{EvaluationResult, Reveal}; pub(crate) type UndoLog<'tcx> = snapshot_map::UndoLog, ProjectionCacheEntry<'tcx>>; -#[derive(Clone)] +#[derive(Clone, TypeFoldable, TypeVisitable)] pub struct MismatchedProjectionTypes<'tcx> { pub err: ty::error::TypeError<'tcx>, } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 200de9079c218..3b810aed327df 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -301,9 +301,12 @@ TrivialTypeTraversalAndLiftImpls! { } } -TrivialTypeTraversalImpls! { - for <'tcx> { - crate::infer::canonical::CanonicalVarInfos<'tcx>, +impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { + fn try_fold_with>( + self, + _: &mut F, + ) -> ::std::result::Result, F::Error> { + Ok(self) } } diff --git a/compiler/rustc_middle/src/mir/type_visitable.rs b/compiler/rustc_middle/src/mir/type_visitable.rs index 6a0801cb0dd25..c3cfb2a313b61 100644 --- a/compiler/rustc_middle/src/mir/type_visitable.rs +++ b/compiler/rustc_middle/src/mir/type_visitable.rs @@ -1,7 +1,6 @@ //! `TypeVisitable` implementations for MIR types use super::*; -use crate::ty; impl<'tcx> TypeVisitable<'tcx> for Terminator<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -67,12 +66,6 @@ impl<'tcx> TypeVisitable<'tcx> for Place<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> { fn visit_with>(&self, visitor: &mut V) -> ControlFlow { use crate::mir::Rvalue::*; diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 72b848c3ee2dd..cb2548ca934e8 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -88,7 +88,7 @@ pub enum Reveal { /// /// We do not want to intern this as there are a lot of obligation causes which /// only live for a short period of time. -#[derive(Clone, Debug, PartialEq, Eq, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Lift, TypeVisitable)] pub struct ObligationCause<'tcx> { pub span: Span, @@ -186,6 +186,7 @@ impl<'tcx> ObligationCause<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(TypeVisitable)] pub struct UnifyReceiverContext<'tcx> { pub assoc_item: ty::AssocItem, pub param_env: ty::ParamEnv<'tcx>, @@ -193,6 +194,7 @@ pub struct UnifyReceiverContext<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, Default)] +#[derive(TypeVisitable)] pub struct InternedObligationCauseCode<'tcx> { /// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of /// the time). `Some` otherwise. @@ -221,6 +223,7 @@ impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(TypeVisitable)] pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from the span. MiscObligation, @@ -415,6 +418,7 @@ pub enum ObligationCauseCode<'tcx> { /// we can walk in order to obtain precise spans for any /// 'nested' types (e.g. `Foo` in `Option`). #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(TypeVisitable)] pub enum WellFormedLoc { /// Use the type of the provided definition. Ty(LocalDefId), @@ -432,6 +436,7 @@ pub enum WellFormedLoc { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(TypeVisitable)] pub struct ImplDerivedObligationCause<'tcx> { pub derived: DerivedObligationCause<'tcx>, pub impl_def_id: DefId, @@ -479,6 +484,7 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(TypeVisitable)] pub struct MatchExpressionArmCause<'tcx> { pub arm_block_id: Option, pub arm_ty: Ty<'tcx>, @@ -505,6 +511,7 @@ pub struct IfExpressionCause<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(TypeVisitable)] pub struct DerivedObligationCause<'tcx> { /// The trait predicate of the parent obligation that led to the /// current obligation. Note that only trait obligations lead to diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 1f9b474ade12b..a8ab801c5c9ff 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -97,7 +97,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; -#[derive(Copy, Clone, Debug, HashStable)] +#[derive(Copy, Clone, Debug, HashStable, TypeVisitable)] pub struct NoSolution; pub type Fallible = Result; @@ -178,7 +178,7 @@ impl<'tcx> FromIterator> for DropckConstraint<'tcx> { } } -#[derive(Debug, HashStable)] +#[derive(Debug, HashStable, TypeVisitable)] pub struct CandidateStep<'tcx> { pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, pub autoderefs: usize, @@ -191,7 +191,7 @@ pub struct CandidateStep<'tcx> { pub unsize: bool, } -#[derive(Copy, Clone, Debug, HashStable)] +#[derive(Copy, Clone, Debug, HashStable, TypeVisitable)] pub struct MethodAutoderefStepsResult<'tcx> { /// The valid autoderef steps that could be find. pub steps: &'tcx [CandidateStep<'tcx>], @@ -202,7 +202,7 @@ pub struct MethodAutoderefStepsResult<'tcx> { pub reached_recursion_limit: bool, } -#[derive(Debug, HashStable)] +#[derive(Debug, HashStable, TypeVisitable)] pub struct MethodAutoderefBadTy<'tcx> { pub reached_raw_pointer: bool, pub ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index e836ba47eed7a..a551d62cac2fc 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -175,6 +175,7 @@ pub enum SelectionCandidate<'tcx> { /// so they are noops when unioned with a definite error, and within /// the categories it's easy to see that the unions are correct. #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, HashStable)] +#[derive(TypeVisitable)] pub enum EvaluationResult { /// Evaluation successful. EvaluatedToOk, diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 5e96e278b9cad..bf980b2ba1bef 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -55,7 +55,7 @@ use std::collections::BTreeMap; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeFoldable<'tcx>: TypeVisitable<'tcx> { +pub trait TypeFoldable<'tcx>: TypeVisitable<'tcx> + Clone { /// The entry point for folding. To fold a value `t` with a folder `f` /// call: `t.try_fold_with(f)`. /// diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 7660a2f3af60a..c85826478c803 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -9,10 +9,11 @@ use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use crate::ty::{self, InferConst, Lift, Term, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; - +use smallvec::SmallVec; use std::fmt; use std::mem::ManuallyDrop; use std::ops::ControlFlow; @@ -189,6 +190,7 @@ TrivialTypeTraversalAndLiftImpls! { bool, usize, ::rustc_target::abi::VariantIdx, + u16, u32, u64, String, @@ -198,7 +200,9 @@ TrivialTypeTraversalAndLiftImpls! { ::rustc_ast::InlineAsmTemplatePiece, ::rustc_ast::NodeId, ::rustc_span::symbol::Symbol, + ::rustc_span::symbol::Ident, ::rustc_hir::def::Res, + ::rustc_hir::def::DefKind, ::rustc_hir::def_id::DefId, ::rustc_hir::def_id::LocalDefId, ::rustc_hir::HirId, @@ -844,6 +848,30 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for Vec { } } +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &T { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + T::visit_with(self, visitor) + } +} + +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &[T] { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &ty::List { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + +impl<'tcx, T: TypeVisitable<'tcx>, const N: usize> TypeVisitable<'tcx> for SmallVec<[T; N]> { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|t| t.try_fold_with(folder)) @@ -901,26 +929,12 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List TypeVisitable<'tcx> - for &'tcx ty::List>> -{ - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|p| p.visit_with(visitor)) - } -} - impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List { fn try_fold_with>(self, folder: &mut F) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } } -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { use crate::ty::InstanceDef::*; @@ -1156,12 +1170,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|p| p.visit_with(visitor)) - } -} - impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec { fn try_fold_with>(self, folder: &mut F) -> Result { self.try_map_id(|x| x.try_fold_with(folder)) @@ -1174,6 +1182,12 @@ impl<'tcx, T: TypeVisitable<'tcx>, I: Idx> TypeVisitable<'tcx> for IndexVec> TypeVisitable<'tcx> for FxIndexSet { + fn visit_with>(&self, visitor: &mut V) -> ControlFlow { + self.iter().try_for_each(|t| t.visit_with(visitor)) + } +} + impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> { fn try_fold_with>(self, folder: &mut F) -> Result { folder.try_fold_const(self) diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 6262aa1807577..b07e271b2d4da 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -459,12 +459,6 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for SubstsRef<'tcx> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { fn try_fold_with>(self, folder: &mut F) -> Result { // This code is fairly hot, though not as hot as `SubstsRef`. @@ -497,12 +491,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeVisitable<'tcx> for &'tcx ty::List> { - fn visit_with>(&self, visitor: &mut V) -> ControlFlow { - self.iter().try_for_each(|t| t.visit_with(visitor)) - } -} - // Just call `foo.subst(tcx, substs)` to perform a substitution across `foo`. #[rustc_on_unimplemented(message = "Calling `subst` must now be done through an `EarlyBinder`")] pub trait Subst<'tcx>: Sized { diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 5365067209af9..8b7c7a41016cd 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -53,7 +53,7 @@ use std::ops::ControlFlow; /// /// To implement this conveniently, use the derive macro located in /// `rustc_macros`. -pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { +pub trait TypeVisitable<'tcx>: fmt::Debug { /// The entry point for visiting. To visit a value `t` with a visitor `v` /// call: `t.visit_with(v)`. /// diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 985600d9ebcc2..e15c20e4bf691 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -43,6 +43,7 @@ pub enum Conflict { Downstream, } +#[derive(Debug, TypeVisitable)] pub struct OverlapResult<'tcx> { pub impl_header: ty::ImplHeader<'tcx>, pub intercrate_ambiguity_causes: FxIndexSet, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 715b97492683b..31185938a1e38 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -154,6 +154,7 @@ impl<'tcx> ProjectionCandidateSet<'tcx> { /// MismatchedProjectionTypes<'tcx>, /// > /// ``` +#[derive(Debug, Clone, TypeVisitable)] pub(super) enum ProjectAndUnifyResult<'tcx> { /// The projection bound holds subject to the given obligations. If the /// projection cannot be normalized because the required trait bound does diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 46b50dd92f1ef..66f4719819939 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -53,6 +53,7 @@ mod candidate_assembly; mod confirmation; #[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(TypeVisitable)] pub enum IntercrateAmbiguityCause { DownstreamCrate { trait_desc: String, self_desc: Option }, UpstreamCrateUpdate { trait_desc: String, self_desc: Option }, @@ -2691,6 +2692,7 @@ impl<'o, 'tcx> fmt::Debug for TraitObligationStack<'o, 'tcx> { } } +#[derive(Debug, Clone, TypeVisitable)] pub enum ProjectionMatchesProjection { Yes, Ambiguous, diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 0e678c41f8b40..2f63e84ca9d41 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -47,7 +47,7 @@ pub struct MethodCallee<'tcx> { pub sig: ty::FnSig<'tcx>, } -#[derive(Debug)] +#[derive(Debug, TypeVisitable)] pub enum MethodError<'tcx> { // Did not find an applicable method, but we did find various near-misses that may work. NoMatch(NoMatchData<'tcx>), @@ -69,7 +69,7 @@ pub enum MethodError<'tcx> { // Contains a list of static methods that may apply, a list of unsatisfied trait predicates which // could lead to matches if satisfied, and a list of not-in-scope traits which may work. -#[derive(Debug)] +#[derive(Debug, TypeVisitable)] pub struct NoMatchData<'tcx> { pub static_candidates: Vec, pub unsatisfied_predicates: @@ -82,6 +82,7 @@ pub struct NoMatchData<'tcx> { // A pared down enum describing just the places from which a method // candidate can arise. Used for error reporting only. #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive(TypeVisitable)] pub enum CandidateSource { Impl(DefId), Trait(DefId /* trait id */), diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index efe15fec7cbfa..1ebddb7ead792 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -152,6 +152,7 @@ enum CandidateKind<'tcx> { } #[derive(Debug, PartialEq, Eq, Copy, Clone)] +#[derive(TypeVisitable)] enum ProbeResult { NoMatch, BadReturnType, @@ -171,6 +172,7 @@ enum ProbeResult { /// (at most) one of these. Either the receiver has type `T` and we convert it to `&T` (or with /// `mut`), or it has type `*mut T` and we convert it to `*const T`. #[derive(Debug, PartialEq, Copy, Clone)] +#[derive(TypeVisitable)] pub enum AutorefOrPtrAdjustment { /// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it. /// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing. @@ -195,6 +197,7 @@ impl AutorefOrPtrAdjustment { } #[derive(Debug, PartialEq, Clone)] +#[derive(TypeVisitable)] pub struct Pick<'tcx> { pub item: ty::AssocItem, pub kind: PickKind<'tcx>, @@ -213,6 +216,7 @@ pub struct Pick<'tcx> { } #[derive(Clone, Debug, PartialEq, Eq)] +#[derive(TypeVisitable)] pub enum PickKind<'tcx> { InherentImplPick, ObjectPick, @@ -226,6 +230,7 @@ pub enum PickKind<'tcx> { pub type PickResult<'tcx> = Result, MethodError<'tcx>>; #[derive(PartialEq, Eq, Copy, Clone, Debug)] +#[derive(TypeVisitable)] pub enum Mode { // An expression of the form `receiver.method_name(...)`. // Autoderefs are performed on `receiver`, lookup is done based on the @@ -327,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn probe_op( + fn probe_op>( &'a self, span: Span, mode: Mode, diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 76599721e586f..1976b9cc58425 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -1,6 +1,5 @@ //! Errors emitted by typeck. use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed}; -use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic}; use rustc_middle::ty::Ty; use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 8c6fb6a77181d..b0c863bd97ee2 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -80,6 +80,9 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +#[macro_use] +extern crate rustc_macros; + // These are used by Clippy. pub mod check; pub mod expr_use_visitor;