diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index de786c38326..3d4e5caa9b2 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -110,7 +110,7 @@ macro_rules! arena_types { rustc_hir::def_id::DefId, rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>> >, - [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>, + [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData>, [] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>, [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, [] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem, diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index fea673eed77..9e979620a44 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -1,6 +1,6 @@ use rustc_ast_ir::try_visit; use rustc_data_structures::intern::Interned; -use rustc_macros::{HashStable, TypeFoldable, TypeVisitable}; +use rustc_macros::HashStable; use rustc_type_ir as ir; pub use rustc_type_ir::solve::*; @@ -37,37 +37,18 @@ impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> { } #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)] -pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>); +pub struct ExternalConstraints<'tcx>( + pub(crate) Interned<'tcx, ExternalConstraintsData>>, +); impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> { - type Target = ExternalConstraintsData<'tcx>; + type Target = ExternalConstraintsData>; fn deref(&self) -> &Self::Target { &self.0 } } -/// Additional constraints returned on success. -#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)] -pub struct ExternalConstraintsData<'tcx> { - // FIXME: implement this. - pub region_constraints: Vec>>, - pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>, - pub normalization_nested_goals: NestedNormalizationGoals<'tcx>, -} - -#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)] -pub struct NestedNormalizationGoals<'tcx>(pub Vec<(GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>); -impl<'tcx> NestedNormalizationGoals<'tcx> { - pub fn empty() -> Self { - NestedNormalizationGoals(vec![]) - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } -} - // FIXME: Having to clone `region_constraints` for folding feels bad and // probably isn't great wrt performance. // diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 3651c990c97..e2f15dac019 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -88,6 +88,7 @@ use std::ops::{Bound, Deref}; #[allow(rustc::usage_of_ty_tykind)] impl<'tcx> Interner for TyCtxt<'tcx> { type DefId = DefId; + type LocalDefId = LocalDefId; type AdtDef = ty::AdtDef<'tcx>; type GenericArgs = ty::GenericArgsRef<'tcx>; @@ -382,7 +383,7 @@ pub struct CtxtInterners<'tcx> { bound_variable_kinds: InternedSet<'tcx, List>, layout: InternedSet<'tcx, LayoutS>, adt_def: InternedSet<'tcx, AdtDefData>, - external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, + external_constraints: InternedSet<'tcx, ExternalConstraintsData>>, predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>, fields: InternedSet<'tcx, List>, local_def_ids: InternedSet<'tcx, List>, @@ -2093,7 +2094,7 @@ direct_interners! { const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, - external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): + external_constraints: pub mk_external_constraints(ExternalConstraintsData>): ExternalConstraints -> ExternalConstraints<'tcx>, predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>): PredefinedOpaques -> PredefinedOpaques<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index ffbdc639f08..2e020b03c5d 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -14,6 +14,7 @@ use crate::solve::{ inspect, response_no_constraints_raw, CanonicalResponse, QueryResult, Response, }; use rustc_data_structures::fx::FxHashSet; +use rustc_hir::def_id::LocalDefId; use rustc_index::IndexVec; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; @@ -178,8 +179,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { fn compute_external_query_constraints( &self, certainty: Certainty, - normalization_nested_goals: NestedNormalizationGoals<'tcx>, - ) -> ExternalConstraintsData<'tcx> { + normalization_nested_goals: NestedNormalizationGoals>, + ) -> ExternalConstraintsData> { // We only return region constraints once the certainty is `Yes`. This // is necessary as we may drop nested goals on ambiguity, which may result // in unconstrained inference variables in the region constraints. It also @@ -213,13 +214,20 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { Default::default() }; - let mut opaque_types = self.infcx.clone_opaque_types_for_query_response(); - // Only return opaque type keys for newly-defined opaques - opaque_types.retain(|(a, _)| { - self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a) - }); - - ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals } + ExternalConstraintsData { + region_constraints, + opaque_types: self + .infcx + .clone_opaque_types_for_query_response() + .into_iter() + // Only return *newly defined* opaque types. + .filter(|(a, _)| { + self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a) + }) + .map(|(key, value)| (key.def_id, key.args, value)) + .collect(), + normalization_nested_goals, + } } /// After calling a canonical query, we apply the constraints returned @@ -235,7 +243,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { param_env: ty::ParamEnv<'tcx>, original_values: Vec>, response: CanonicalResponse<'tcx>, - ) -> (NestedNormalizationGoals<'tcx>, Certainty) { + ) -> (NestedNormalizationGoals>, Certainty) { let instantiation = Self::compute_query_response_instantiation_values( self.infcx, &original_values, @@ -385,10 +393,14 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { } } - fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)]) { - for &(key, ty) in opaque_types { + fn register_new_opaque_types( + &mut self, + opaque_types: &[(LocalDefId, ty::GenericArgsRef<'tcx>, Ty<'tcx>)], + ) { + for &(def_id, args, ty) in opaque_types { let hidden_ty = ty::OpaqueHiddenType { ty, span: DUMMY_SP }; - self.infcx.inject_new_hidden_type_unchecked(key, hidden_ty); + self.infcx + .inject_new_hidden_type_unchecked(ty::OpaqueTypeKey { def_id, args }, hidden_ty); } } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 8dc6b31f8d1..74938d2bbd7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -337,7 +337,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { goal_evaluation_kind: GoalEvaluationKind, _source: GoalSource, goal: Goal<'tcx, ty::Predicate<'tcx>>, - ) -> Result<(NestedNormalizationGoals<'tcx>, bool, Certainty), NoSolution> { + ) -> Result<(NestedNormalizationGoals>, bool, Certainty), NoSolution> { let (orig_values, canonical_goal) = self.canonicalize_goal(goal); let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind); @@ -380,7 +380,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { param_env: ty::ParamEnv<'tcx>, original_values: Vec>, response: CanonicalResponse<'tcx>, - ) -> (NestedNormalizationGoals<'tcx>, Certainty, bool) { + ) -> (NestedNormalizationGoals>, Certainty, bool) { if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty { return (NestedNormalizationGoals::empty(), response.value.certainty, false); } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index a2b71e1fc25..30beb4480e9 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -29,6 +29,7 @@ pub trait Interner: + IrPrint> { type DefId: Copy + Debug + Hash + Eq + TypeFoldable; + type LocalDefId: Copy + Debug + Hash + Eq + TypeFoldable; type AdtDef: AdtDef; type GenericArgs: GenericArgs; diff --git a/compiler/rustc_type_ir/src/solve.rs b/compiler/rustc_type_ir/src/solve.rs index cff62ee3d1e..d4e43716c17 100644 --- a/compiler/rustc_type_ir/src/solve.rs +++ b/compiler/rustc_type_ir/src/solve.rs @@ -7,7 +7,7 @@ use std::hash::Hash; use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; -use crate::{Canonical, CanonicalVarValues, Interner, Upcast}; +use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast}; /// Depending on the stage of compilation, we want projection to be /// more or less conservative. @@ -254,6 +254,47 @@ pub struct Response { pub external_constraints: I::ExternalConstraints, } +/// Additional constraints returned on success. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = ""), + Default(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub struct ExternalConstraintsData { + pub region_constraints: Vec>, + pub opaque_types: Vec<(I::LocalDefId, I::GenericArgs, I::Ty)>, + pub normalization_nested_goals: NestedNormalizationGoals, +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = ""), + Default(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] +pub struct NestedNormalizationGoals(pub Vec<(GoalSource, Goal)>); + +impl NestedNormalizationGoals { + pub fn empty() -> Self { + NestedNormalizationGoals(vec![]) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + #[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum Certainty {