rework alias-relate to norm(lhs) == norm(rhs)

This commit is contained in:
lcnr 2023-11-09 11:06:48 +01:00
parent 1c54494888
commit e3850f404d
4 changed files with 164 additions and 167 deletions

View file

@ -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),