From 3e3e70d529d8c7d7c4d7bc4fefc9f109393b9245 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:43 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_middle/src/traits/mod.rs | 48 ++++++++++------ compiler/rustc_middle/src/traits/query.rs | 4 +- compiler/rustc_middle/src/traits/solve.rs | 66 ++++++++++++++++++++++ .../src/traits/specialization_graph.rs | 12 ++-- 4 files changed, 104 insertions(+), 26 deletions(-) create mode 100644 compiler/rustc_middle/src/traits/solve.rs (limited to 'compiler/rustc_middle/src/traits') diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index d00b26a5a..6231dd9b6 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -5,6 +5,7 @@ mod chalk; pub mod query; pub mod select; +pub mod solve; pub mod specialization_graph; mod structural_impls; pub mod util; @@ -18,7 +19,8 @@ use crate::ty::{self, AdtKind, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; +use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; @@ -36,7 +38,7 @@ pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner /// Depending on the stage of compilation, we want projection to be /// more or less conservative. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)] pub enum Reveal { /// At type-checking time, we refuse to project any associated /// type that is marked `default`. Non-`default` ("final") types @@ -89,7 +91,8 @@ 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, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] pub struct ObligationCause<'tcx> { pub span: Span, @@ -99,7 +102,7 @@ pub struct ObligationCause<'tcx> { /// (in particular, closures can add new assumptions). See the /// field `region_obligations` of the `FulfillmentContext` for more /// information. - pub body_id: hir::HirId, + pub body_id: LocalDefId, code: InternedObligationCauseCode<'tcx>, } @@ -120,13 +123,13 @@ impl<'tcx> ObligationCause<'tcx> { #[inline] pub fn new( span: Span, - body_id: hir::HirId, + body_id: LocalDefId, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { ObligationCause { span, body_id, code: code.into() } } - pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { + pub fn misc(span: Span, body_id: LocalDefId) -> ObligationCause<'tcx> { ObligationCause::new(span, body_id, MiscObligation) } @@ -137,7 +140,7 @@ impl<'tcx> ObligationCause<'tcx> { #[inline(always)] pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> { - ObligationCause { span, body_id: hir::CRATE_HIR_ID, code: Default::default() } + ObligationCause { span, body_id: CRATE_DEF_ID, code: Default::default() } } pub fn span(&self) -> Span { @@ -196,14 +199,16 @@ impl<'tcx> ObligationCause<'tcx> { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] pub struct UnifyReceiverContext<'tcx> { pub assoc_item: ty::AssocItem, pub param_env: ty::ParamEnv<'tcx>, pub substs: SubstsRef<'tcx>, } -#[derive(Clone, PartialEq, Eq, Hash, Lift, Default)] +#[derive(Clone, PartialEq, Eq, Hash, Lift, Default, HashStable)] +#[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)] pub struct InternedObligationCauseCode<'tcx> { /// `None` for `ObligationCauseCode::MiscObligation` (a common case, occurs ~60% of /// the time). `Some` otherwise. @@ -238,7 +243,8 @@ impl<'tcx> std::ops::Deref for InternedObligationCauseCode<'tcx> { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from the span. MiscObligation, @@ -446,7 +452,8 @@ pub enum ObligationCauseCode<'tcx> { /// This information is used to obtain an `hir::Ty`, which /// 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(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)] +#[derive(TypeVisitable, TypeFoldable)] pub enum WellFormedLoc { /// Use the type of the provided definition. Ty(LocalDefId), @@ -463,10 +470,17 @@ pub enum WellFormedLoc { }, } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] pub struct ImplDerivedObligationCause<'tcx> { pub derived: DerivedObligationCause<'tcx>, - pub impl_def_id: DefId, + /// The `DefId` of the `impl` that gave rise to the `derived` obligation. + /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl, + /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle + /// that exceptional case where appropriate. + pub impl_or_alias_def_id: DefId, + /// The index of the derived predicate in the parent impl's predicates. + pub impl_def_predicate_index: Option, pub span: Span, } @@ -517,7 +531,8 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] pub struct MatchExpressionArmCause<'tcx> { pub arm_block_id: Option, pub arm_ty: Ty<'tcx>, @@ -533,7 +548,7 @@ pub struct MatchExpressionArmCause<'tcx> { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -#[derive(Lift, TypeFoldable, TypeVisitable)] +#[derive(Lift, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] pub struct IfExpressionCause<'tcx> { pub then_id: hir::HirId, pub else_id: hir::HirId, @@ -543,7 +558,8 @@ pub struct IfExpressionCause<'tcx> { pub opt_suggest_box_span: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift, HashStable, TyEncodable, TyDecodable)] +#[derive(TypeVisitable, TypeFoldable)] 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 615154a55..c4f871875 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -14,7 +14,7 @@ use rustc_span::source_map::Span; pub mod type_op { use crate::ty::fold::TypeFoldable; - use crate::ty::{Predicate, Ty, UserType}; + use crate::ty::{Predicate, Ty, TyCtxt, UserType}; use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] @@ -64,7 +64,7 @@ pub mod type_op { impl<'tcx, T> Normalize where - T: fmt::Debug + TypeFoldable<'tcx>, + T: fmt::Debug + TypeFoldable>, { pub fn new(value: T) -> Self { Self { value } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs new file mode 100644 index 000000000..bd43867a3 --- /dev/null +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -0,0 +1,66 @@ +use std::ops::ControlFlow; + +use rustc_data_structures::intern::Interned; + +use crate::infer::canonical::QueryRegionConstraints; +use crate::ty::{ + FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, +}; + +#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] +pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); + +impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> { + type Target = ExternalConstraintsData<'tcx>; + + fn deref(&self) -> &Self::Target { + &*self.0 + } +} + +/// Additional constraints returned on success. +#[derive(Debug, PartialEq, Eq, Clone, Hash, Default, TypeFoldable, TypeVisitable)] +pub struct ExternalConstraintsData<'tcx> { + // FIXME: implement this. + pub region_constraints: QueryRegionConstraints<'tcx>, + pub opaque_types: Vec<(Ty<'tcx>, Ty<'tcx>)>, +} + +// FIXME: Having to clone `region_constraints` for folding feels bad and +// probably isn't great wrt performance. +// +// Not sure how to fix this, maybe we should also intern `opaque_types` and +// `region_constraints` here or something. +impl<'tcx> TypeFoldable> for ExternalConstraints<'tcx> { + fn try_fold_with>>( + self, + folder: &mut F, + ) -> Result { + Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { + region_constraints: self.region_constraints.clone().try_fold_with(folder)?, + opaque_types: self + .opaque_types + .iter() + .map(|opaque| opaque.try_fold_with(folder)) + .collect::>()?, + })) + } + + fn fold_with>>(self, folder: &mut F) -> Self { + TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { + region_constraints: self.region_constraints.clone().fold_with(folder), + opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), + }) + } +} + +impl<'tcx> TypeVisitable> for ExternalConstraints<'tcx> { + fn visit_with>>( + &self, + visitor: &mut V, + ) -> std::ops::ControlFlow { + self.region_constraints.visit_with(visitor)?; + self.opaque_types.visit_with(visitor)?; + ControlFlow::Continue(()) + } +} diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index aad5b2fbe..c016f7227 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -1,6 +1,6 @@ use crate::error::StrictCoherenceNeedsNegativeCoherence; use crate::ty::fast_reject::SimplifiedType; -use crate::ty::visit::TypeVisitable; +use crate::ty::visit::TypeVisitableExt; use crate::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; @@ -133,11 +133,7 @@ impl Node { /// /// If this returns `None`, the item can potentially still be found in /// parents of this node. - pub fn item<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - trait_item_def_id: DefId, - ) -> Option<&'tcx ty::AssocItem> { + pub fn item<'tcx>(&self, tcx: TyCtxt<'tcx>, trait_item_def_id: DefId) -> Option { match *self { Node::Trait(_) => Some(tcx.associated_item(trait_item_def_id)), Node::Impl(impl_def_id) => { @@ -239,7 +235,7 @@ impl<'tcx> Ancestors<'tcx> { } } - Some(LeafDef { item: *item, defining_node: node, finalizing_node }) + Some(LeafDef { item, defining_node: node, finalizing_node }) } else { // Item not mentioned. This "finalizes" any defaulted item provided by an ancestor. finalizing_node = Some(node); @@ -263,7 +259,7 @@ pub fn ancestors( if let Some(reported) = specialization_graph.has_errored { Err(reported) - } else if let Err(reported) = tcx.type_of(start_from_impl).error_reported() { + } else if let Err(reported) = tcx.type_of(start_from_impl).subst_identity().error_reported() { Err(reported) } else { Ok(Ancestors { -- cgit v1.2.3