diff options
| author | lcnr <rust@lcnr.de> | 2023-11-09 11:06:48 +0100 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2023-11-09 11:32:50 +0100 |
| commit | e3850f404dfdc4805f0e2b863117ff4563d5f00e (patch) | |
| tree | eb1c9e8b9116f46a9e4ad67bb241892f08056d3c /compiler/rustc_trait_selection/src/solve/mod.rs | |
| parent | 1c54494888d79ff17e03a45aeb4d944bfb181ae2 (diff) | |
| download | rust-e3850f404dfdc4805f0e2b863117ff4563d5f00e.tar.gz rust-e3850f404dfdc4805f0e2b863117ff4563d5f00e.zip | |
rework alias-relate to `norm(lhs) == norm(rhs)`
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve/mod.rs')
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/mod.rs | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 17992d72e25..5b44d396379 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -16,13 +16,14 @@ //! about it on zulip. use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::query::NoSolution; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, IsNormalizesToHack, QueryResult, Response, }; -use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex}; +use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{ CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate, }; @@ -299,12 +300,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, ) -> Option<Ty<'tcx>> { - self.try_normalize_ty_recur(param_env, 0, ty) + self.try_normalize_ty_recur(param_env, DefineOpaqueTypes::Yes, 0, ty) } fn try_normalize_ty_recur( &mut self, param_env: ty::ParamEnv<'tcx>, + define_opaque_types: DefineOpaqueTypes, depth: usize, ty: Ty<'tcx>, ) -> Option<Ty<'tcx>> { @@ -312,10 +314,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return None; } - let ty::Alias(_, projection_ty) = *ty.kind() else { + let ty::Alias(kind, projection_ty) = *ty.kind() else { return Some(ty); }; + // We do no always define opaque types eagerly to allow non-defining uses in the defining scope. + if let (DefineOpaqueTypes::No, ty::AliasKind::Opaque) = (define_opaque_types, kind) { + if let Some(def_id) = projection_ty.def_id.as_local() { + if self + .unify_existing_opaque_tys( + param_env, + OpaqueTypeKey { def_id, args: projection_ty.args }, + self.next_ty_infer(), + ) + .is_empty() + { + return Some(ty); + } + } + } + // FIXME(@lcnr): If the normalization of the alias adds an inference constraint which // causes a previously added goal to fail, then we treat the alias as rigid. // @@ -331,7 +349,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { this.add_goal(normalizes_to_goal); this.try_evaluate_added_goals()?; let ty = this.resolve_vars_if_possible(normalized_ty); - Ok(this.try_normalize_ty_recur(param_env, depth + 1, ty)) + Ok(this.try_normalize_ty_recur(param_env, define_opaque_types, depth + 1, ty)) }) { Ok(ty) => ty, Err(NoSolution) => Some(ty), |
