normalization folders, yeet ParamEnv::reveal
This commit is contained in:
parent
2cde638ac0
commit
dc750665ae
3 changed files with 31 additions and 24 deletions
|
@ -411,7 +411,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
||||||
|
|
||||||
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
|
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
|
||||||
if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) {
|
if !elaborated_env.has_aliases() {
|
||||||
return elaborated_env;
|
return elaborated_env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
//! Deeply normalize types using the old trait solver.
|
//! Deeply normalize types using the old trait solver.
|
||||||
|
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_infer::infer::InferOk;
|
|
||||||
use rustc_infer::infer::at::At;
|
use rustc_infer::infer::at::At;
|
||||||
|
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||||
use rustc_infer::traits::{
|
use rustc_infer::traits::{
|
||||||
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
|
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
|
||||||
};
|
};
|
||||||
use rustc_macros::extension;
|
use rustc_macros::extension;
|
||||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
|
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
|
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
|
||||||
|
TypingMode,
|
||||||
};
|
};
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
|
@ -109,16 +110,19 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||||
|
infcx: &InferCtxt<'tcx>,
|
||||||
|
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
|
||||||
value: &T,
|
value: &T,
|
||||||
reveal: Reveal,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut flags = ty::TypeFlags::HAS_ALIAS;
|
let mut flags = ty::TypeFlags::HAS_ALIAS;
|
||||||
|
|
||||||
// Opaques are treated as rigid with `Reveal::UserFacing`,
|
// Opaques are treated as rigid with `Reveal::UserFacing`,
|
||||||
// so we can ignore those.
|
// so we can ignore those.
|
||||||
match reveal {
|
match infcx.typing_mode(param_env_for_debug_assertion) {
|
||||||
Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
|
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||||
Reveal::All => {}
|
flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
|
||||||
|
}
|
||||||
|
TypingMode::PostAnalysis => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
value.has_type_flags(flags)
|
value.has_type_flags(flags)
|
||||||
|
@ -154,7 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
"Normalizing {value:?} without wrapping in a `Binder`"
|
"Normalizing {value:?} without wrapping in a `Binder`"
|
||||||
);
|
);
|
||||||
|
|
||||||
if !needs_normalization(&value, self.param_env.reveal()) {
|
if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
value.fold_with(self)
|
value.fold_with(self)
|
||||||
|
@ -178,7 +182,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,10 +217,11 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||||
match kind {
|
match kind {
|
||||||
ty::Opaque => {
|
ty::Opaque => {
|
||||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||||
match self.param_env.reveal() {
|
match self.selcx.infcx.typing_mode(self.param_env) {
|
||||||
Reveal::UserFacing => ty.super_fold_with(self),
|
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||||
|
ty.super_fold_with(self)
|
||||||
Reveal::All => {
|
}
|
||||||
|
TypingMode::PostAnalysis => {
|
||||||
let recursion_limit = self.cx().recursion_limit();
|
let recursion_limit = self.cx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.depth) {
|
if !recursion_limit.value_within_limit(self.depth) {
|
||||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||||
|
@ -403,7 +408,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||||
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
let tcx = self.selcx.tcx();
|
let tcx = self.selcx.tcx();
|
||||||
if tcx.features().generic_const_exprs()
|
if tcx.features().generic_const_exprs()
|
||||||
|| !needs_normalization(&constant, self.param_env.reveal())
|
|| !needs_normalization(self.selcx.infcx, self.param_env, &constant)
|
||||||
{
|
{
|
||||||
constant
|
constant
|
||||||
} else {
|
} else {
|
||||||
|
@ -420,7 +425,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||||
if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
|
if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
|
||||||
p.super_fold_with(self)
|
p.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
p
|
p
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_macros::extension;
|
||||||
pub use rustc_middle::traits::query::NormalizationResult;
|
pub use rustc_middle::traits::query::NormalizationResult;
|
||||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
||||||
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
|
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor, TypingMode};
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use tracing::{debug, info, instrument};
|
use tracing::{debug, info, instrument};
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ use crate::infer::canonical::OriginalQueryValues;
|
||||||
use crate::infer::{InferCtxt, InferOk};
|
use crate::infer::{InferCtxt, InferOk};
|
||||||
use crate::traits::normalize::needs_normalization;
|
use crate::traits::normalize::needs_normalization;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError,
|
BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[extension(pub trait QueryNormalizeExt<'tcx>)]
|
#[extension(pub trait QueryNormalizeExt<'tcx>)]
|
||||||
|
@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !needs_normalization(&value, self.param_env.reveal()) {
|
if !needs_normalization(self.infcx, self.param_env, &value) {
|
||||||
return Ok(Normalized { value, obligations: PredicateObligations::new() });
|
return Ok(Normalized { value, obligations: PredicateObligations::new() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
if !needs_normalization(self.infcx, self.param_env, &ty) {
|
||||||
return Ok(ty);
|
return Ok(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,10 +215,12 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
||||||
let res = match kind {
|
let res = match kind {
|
||||||
ty::Opaque => {
|
ty::Opaque => {
|
||||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||||
match self.param_env.reveal() {
|
match self.infcx.typing_mode(self.param_env) {
|
||||||
Reveal::UserFacing => ty.try_super_fold_with(self)?,
|
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||||
|
ty.try_super_fold_with(self)?
|
||||||
|
}
|
||||||
|
|
||||||
Reveal::All => {
|
TypingMode::PostAnalysis => {
|
||||||
let args = data.args.try_fold_with(self)?;
|
let args = data.args.try_fold_with(self)?;
|
||||||
let recursion_limit = self.cx().recursion_limit();
|
let recursion_limit = self.cx().recursion_limit();
|
||||||
|
|
||||||
|
@ -332,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
constant: ty::Const<'tcx>,
|
constant: ty::Const<'tcx>,
|
||||||
) -> Result<ty::Const<'tcx>, Self::Error> {
|
) -> Result<ty::Const<'tcx>, Self::Error> {
|
||||||
if !needs_normalization(&constant, self.param_env.reveal()) {
|
if !needs_normalization(self.infcx, self.param_env, &constant) {
|
||||||
return Ok(constant);
|
return Ok(constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: ty::Predicate<'tcx>,
|
p: ty::Predicate<'tcx>,
|
||||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||||
if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
|
if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
|
||||||
p.try_super_fold_with(self)
|
p.try_super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(p)
|
Ok(p)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue