no more Reveal :(
This commit is contained in:
parent
f4b516b10c
commit
319843d8cd
46 changed files with 112 additions and 299 deletions
|
@ -26,7 +26,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
|
|||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal,
|
||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
@ -223,7 +223,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
|||
}
|
||||
|
||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
|
||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
||||
debug!(caller_bounds=?param_env.caller_bounds());
|
||||
|
||||
|
@ -508,7 +508,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||
.into_iter()
|
||||
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args))
|
||||
.map(|(clause, _)| clause);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
|
||||
let param_env = traits::normalize_param_env_or_error(
|
||||
tcx,
|
||||
param_env,
|
||||
|
@ -1793,7 +1793,7 @@ fn compare_const_predicate_entailment<'tcx>(
|
|||
.map(|(predicate, _)| predicate),
|
||||
);
|
||||
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
|
||||
let param_env = traits::normalize_param_env_or_error(
|
||||
tcx,
|
||||
param_env,
|
||||
|
@ -1946,7 +1946,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
|||
);
|
||||
}
|
||||
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds));
|
||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
||||
debug!(caller_bounds=?param_env.caller_bounds());
|
||||
|
||||
|
@ -2306,7 +2306,7 @@ fn param_env_with_gat_bounds<'tcx>(
|
|||
};
|
||||
}
|
||||
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates))
|
||||
}
|
||||
|
||||
/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_infer::infer::TyCtxtInferExt;
|
|||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::{ObligationCause, Reveal};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor, TypingMode,
|
||||
|
@ -134,7 +134,7 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
|||
.into_iter()
|
||||
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_m_to_impl_m_args))
|
||||
.map(|(clause, _)| clause);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds));
|
||||
let param_env = normalize_param_env_or_error(tcx, param_env, ObligationCause::dummy());
|
||||
|
||||
let ref infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
|
|
|
@ -604,7 +604,7 @@ fn augment_param_env<'tcx>(
|
|||
);
|
||||
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
|
||||
// i.e. traits::normalize_param_env_or_error
|
||||
ty::ParamEnv::new(bounds, param_env.reveal())
|
||||
ty::ParamEnv::new(bounds)
|
||||
}
|
||||
|
||||
/// We use the following trait as an example throughout this function.
|
||||
|
|
|
@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
query_state,
|
||||
)
|
||||
.unchecked_map(|(param_env, value)| param_env.and(value));
|
||||
CanonicalQueryInput { canonical, typing_mode: self.typing_mode(param_env) }
|
||||
CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }
|
||||
}
|
||||
|
||||
/// Canonicalizes a query *response* `V`. When we canonicalize a
|
||||
|
|
|
@ -20,11 +20,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
|
|||
self.next_trait_solver
|
||||
}
|
||||
|
||||
fn typing_mode(
|
||||
&self,
|
||||
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
|
||||
) -> ty::TypingMode<'tcx> {
|
||||
self.typing_mode(param_env_for_debug_assertion)
|
||||
fn typing_mode(&self) -> ty::TypingMode<'tcx> {
|
||||
self.typing_mode()
|
||||
}
|
||||
|
||||
fn universe(&self) -> ty::UniverseIndex {
|
||||
|
|
|
@ -43,7 +43,6 @@ use rustc_middle::ty::{
|
|||
};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_type_ir::solve::Reveal;
|
||||
use snapshot::undo_log::InferCtxtUndoLogs;
|
||||
use tracing::{debug, instrument};
|
||||
use type_variable::TypeVariableOrigin;
|
||||
|
@ -624,22 +623,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn typing_mode(
|
||||
&self,
|
||||
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
|
||||
) -> TypingMode<'tcx> {
|
||||
if cfg!(debug_assertions) {
|
||||
match (param_env_for_debug_assertion.reveal(), self.typing_mode) {
|
||||
(Reveal::All, TypingMode::PostAnalysis)
|
||||
| (Reveal::UserFacing, TypingMode::Coherence | TypingMode::Analysis { .. }) => {}
|
||||
(r, t) => unreachable!("TypingMode x Reveal mismatch: {r:?} {t:?}"),
|
||||
}
|
||||
}
|
||||
self.typing_mode
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn typing_mode_unchecked(&self) -> TypingMode<'tcx> {
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx> {
|
||||
self.typing_mode
|
||||
}
|
||||
|
||||
|
@ -1005,7 +989,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
#[inline(always)]
|
||||
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
|
||||
match self.typing_mode_unchecked() {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Analysis { defining_opaque_types } => {
|
||||
id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
|
||||
}
|
||||
|
@ -1290,7 +1274,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// which contains the necessary information to use the trait system without
|
||||
/// using canonicalization or carrying this inference context around.
|
||||
pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
|
||||
let typing_mode = match self.typing_mode(param_env) {
|
||||
let typing_mode = match self.typing_mode() {
|
||||
ty::TypingMode::Coherence => ty::TypingMode::Coherence,
|
||||
// FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
|
||||
// to handle them without proper canonicalization. This means we may cause cycle
|
||||
|
|
|
@ -101,7 +101,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
|
||||
let def_id = def_id.expect_local();
|
||||
if let ty::TypingMode::Coherence = self.typing_mode(param_env) {
|
||||
if let ty::TypingMode::Coherence = self.typing_mode() {
|
||||
// See comment on `insert_hidden_type` for why this is sufficient in coherence
|
||||
return Some(self.register_hidden_type(
|
||||
OpaqueTypeKey { def_id, args },
|
||||
|
@ -522,7 +522,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// value being folded. In simple cases like `-> impl Foo`,
|
||||
// these are the same span, but not in cases like `-> (impl
|
||||
// Foo, impl Bar)`.
|
||||
match self.typing_mode(param_env) {
|
||||
match self.typing_mode() {
|
||||
ty::TypingMode::Coherence => {
|
||||
// During intercrate we do not define opaque types but instead always
|
||||
// force ambiguity unless the hidden type is known to not implement
|
||||
|
|
|
@ -520,10 +520,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
|||
//
|
||||
// cc trait-system-refactor-initiative#108
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !matches!(
|
||||
self.infcx.typing_mode_unchecked(),
|
||||
TypingMode::Coherence
|
||||
)
|
||||
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
|
||||
&& self.in_alias
|
||||
{
|
||||
inner.type_variables().equate(vid, new_var_id);
|
||||
|
@ -654,10 +651,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
|||
// See the comment for type inference variables
|
||||
// for more details.
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !matches!(
|
||||
self.infcx.typing_mode_unchecked(),
|
||||
TypingMode::Coherence
|
||||
)
|
||||
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
|
||||
&& self.in_alias
|
||||
{
|
||||
variable_table.union(vid, new_var_id);
|
||||
|
|
|
@ -14,7 +14,6 @@ use rustc_feature::Features;
|
|||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
|
||||
use rustc_infer::traits::Reveal;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::privacy::EffectiveVisibilities;
|
||||
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
|
||||
|
@ -702,7 +701,6 @@ impl<'tcx> LateContext<'tcx> {
|
|||
/// The typing mode of the currently visited node. Use this when
|
||||
/// building a new `InferCtxt`.
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx> {
|
||||
debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
|
||||
// FIXME(#132279): In case we're in a body, we should use a typing
|
||||
// mode which reveals the opaque types defined by that body.
|
||||
TypingMode::non_body_analysis()
|
||||
|
|
|
@ -105,8 +105,10 @@ impl<'tcx> ConstValue<'tcx> {
|
|||
typing_env: ty::TypingEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<u128> {
|
||||
let size =
|
||||
tcx.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(ty)).ok()?.size;
|
||||
let size = tcx
|
||||
.layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(ty))
|
||||
.ok()?
|
||||
.size;
|
||||
self.try_to_bits(size)
|
||||
}
|
||||
|
||||
|
@ -376,7 +378,7 @@ impl<'tcx> Const<'tcx> {
|
|||
) -> Option<u128> {
|
||||
let int = self.try_eval_scalar_int(tcx, typing_env)?;
|
||||
let size = tcx
|
||||
.layout_of(typing_env.with_reveal_all_normalized(tcx).as_query_input(self.ty()))
|
||||
.layout_of(typing_env.with_post_analysis_normalized(tcx).as_query_input(self.ty()))
|
||||
.ok()?
|
||||
.size;
|
||||
Some(int.to_bits(size))
|
||||
|
|
|
@ -162,7 +162,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
// improve caching of queries.
|
||||
let inputs =
|
||||
self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
|
||||
self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
|
||||
if !span.is_dummy() {
|
||||
// The query doesn't know where it is being invoked, so we need to fix the span.
|
||||
self.at(span).eval_to_const_value_raw(inputs).map_err(|e| e.with_span(span))
|
||||
|
@ -182,7 +182,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
// improve caching of queries.
|
||||
let inputs =
|
||||
self.erase_regions(typing_env.with_reveal_all_normalized(self).as_query_input(cid));
|
||||
self.erase_regions(typing_env.with_post_analysis_normalized(self).as_query_input(cid));
|
||||
debug!(?inputs);
|
||||
if !span.is_dummy() {
|
||||
// The query doesn't know where it is being invoked, so we need to fix the span.
|
||||
|
|
|
@ -1381,10 +1381,10 @@ rustc_queries! {
|
|||
feedable
|
||||
}
|
||||
|
||||
/// Like `param_env`, but returns the `ParamEnv` in `Reveal::All` mode.
|
||||
/// Prefer this over `tcx.param_env(def_id).with_reveal_all_normalized(tcx)`,
|
||||
/// as this method is more efficient.
|
||||
query param_env_reveal_all_normalized(def_id: DefId) -> ty::ParamEnv<'tcx> {
|
||||
/// Like `param_env`, but returns the `ParamEnv` after all opaque types have been
|
||||
/// replaced with their hidden type. This is used in the old trait solver
|
||||
/// when in `PostAnalysis` mode and should not be called directly.
|
||||
query param_env_normalized_for_post_analysis(def_id: DefId) -> ty::ParamEnv<'tcx> {
|
||||
desc { |tcx| "computing revealed normalized predicates of `{}`", tcx.def_path_str(def_id) }
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
|
|||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
// FIXME: Remove this import and import via `solve::`
|
||||
pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal};
|
||||
pub use rustc_type_ir::solve::BuiltinImplSource;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
|
|
|
@ -174,7 +174,6 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for CtfeProvenance {
|
|||
impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> {
|
||||
fn encode(&self, e: &mut E) {
|
||||
self.caller_bounds().encode(e);
|
||||
self.reveal().encode(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,8 +309,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::SymbolName<'tcx>
|
|||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> {
|
||||
fn decode(d: &mut D) -> Self {
|
||||
let caller_bounds = Decodable::decode(d);
|
||||
let reveal = Decodable::decode(d);
|
||||
ty::ParamEnv::new(caller_bounds, reveal)
|
||||
ty::ParamEnv::new(caller_bounds)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ impl<'tcx> Const<'tcx> {
|
|||
pub fn try_to_bits(self, tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>) -> Option<u128> {
|
||||
let (scalar, ty) = self.try_to_scalar()?;
|
||||
let scalar = scalar.try_to_scalar_int().ok()?;
|
||||
let input = typing_env.with_reveal_all_normalized(tcx).as_query_input(ty);
|
||||
let input = typing_env.with_post_analysis_normalized(tcx).as_query_input(ty);
|
||||
let size = tcx.layout_of(input).ok()?.size;
|
||||
Some(scalar.to_bits(size))
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
|||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
|
||||
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
||||
|
@ -104,7 +103,6 @@ use crate::metadata::ModChild;
|
|||
use crate::middle::privacy::EffectiveVisibilities;
|
||||
use crate::mir::{Body, CoroutineLayout};
|
||||
use crate::query::{IntoQueryParam, Providers};
|
||||
use crate::traits::{self, Reveal};
|
||||
use crate::ty;
|
||||
pub use crate::ty::diagnostics::*;
|
||||
use crate::ty::fast_reject::SimplifiedType;
|
||||
|
@ -960,147 +958,50 @@ impl<'tcx> rustc_type_ir::visit::Flags for Clauses<'tcx> {
|
|||
/// [dev guide chapter][param_env_guide] for more information.
|
||||
///
|
||||
/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(HashStable, TypeVisitable, TypeFoldable)]
|
||||
pub struct ParamEnv<'tcx> {
|
||||
/// This packs both caller bounds and the reveal enum into one pointer.
|
||||
///
|
||||
/// Caller bounds are `Obligation`s that the caller must satisfy. This is
|
||||
/// basically the set of bounds on the in-scope type parameters, translated
|
||||
/// into `Obligation`s, and elaborated and normalized.
|
||||
///
|
||||
/// Use the `caller_bounds()` method to access.
|
||||
///
|
||||
/// Typically, this is `Reveal::UserFacing`, but during codegen we
|
||||
/// want `Reveal::All`.
|
||||
///
|
||||
/// Note: This is packed, use the reveal() method to access it.
|
||||
packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>,
|
||||
caller_bounds: Clauses<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||
fn reveal(self) -> Reveal {
|
||||
self.reveal()
|
||||
}
|
||||
|
||||
fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
|
||||
self.caller_bounds()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct ParamTag {
|
||||
reveal: traits::Reveal,
|
||||
}
|
||||
|
||||
rustc_data_structures::impl_tag! {
|
||||
impl Tag for ParamTag;
|
||||
ParamTag { reveal: traits::Reveal::UserFacing },
|
||||
ParamTag { reveal: traits::Reveal::All },
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ParamEnv")
|
||||
.field("caller_bounds", &self.caller_bounds())
|
||||
.field("reveal", &self.reveal())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
self.caller_bounds().hash_stable(hcx, hasher);
|
||||
self.reveal().hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||
fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
Ok(ParamEnv::new(
|
||||
self.caller_bounds().try_fold_with(folder)?,
|
||||
self.reveal().try_fold_with(folder)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||
try_visit!(self.caller_bounds().visit_with(visitor));
|
||||
self.reveal().visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ParamEnv<'tcx> {
|
||||
/// Construct a trait environment suitable for contexts where
|
||||
/// there are no where-clauses in scope. Hidden types (like `impl
|
||||
/// Trait`) are left hidden. In majority of cases it is incorrect
|
||||
/// Construct a trait environment suitable for contexts where there are
|
||||
/// no where-clauses in scope. In the majority of cases it is incorrect
|
||||
/// to use an empty environment. See the [dev guide section][param_env_guide]
|
||||
/// for information on what a `ParamEnv` is and how to acquire one.
|
||||
///
|
||||
/// [param_env_guide]: https://rustc-dev-guide.rust-lang.org/param_env/param_env_summary.html
|
||||
#[inline]
|
||||
pub fn empty() -> Self {
|
||||
Self::new(ListWithCachedTypeInfo::empty(), Reveal::UserFacing)
|
||||
Self::new(ListWithCachedTypeInfo::empty())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn caller_bounds(self) -> Clauses<'tcx> {
|
||||
self.packed.pointer()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reveal(self) -> traits::Reveal {
|
||||
self.packed.tag().reveal
|
||||
}
|
||||
|
||||
/// Construct a trait environment with no where-clauses in scope
|
||||
/// where the values of all `impl Trait` and other hidden types
|
||||
/// are revealed. This is suitable for monomorphized, post-typeck
|
||||
/// environments like codegen or doing optimizations.
|
||||
///
|
||||
/// N.B., if you want to have predicates in scope, use `ParamEnv::new`,
|
||||
/// or invoke `param_env.with_reveal_all()`.
|
||||
#[inline]
|
||||
pub fn reveal_all() -> Self {
|
||||
Self::new(ListWithCachedTypeInfo::empty(), Reveal::All)
|
||||
self.caller_bounds
|
||||
}
|
||||
|
||||
/// Construct a trait environment with the given set of predicates.
|
||||
#[inline]
|
||||
pub fn new(caller_bounds: Clauses<'tcx>, reveal: Reveal) -> Self {
|
||||
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
|
||||
}
|
||||
|
||||
/// Returns a new parameter environment with the same clauses, but
|
||||
/// which "reveals" the true results of projections in all cases
|
||||
/// (even for associated types that are specializable). This is
|
||||
/// the desired behavior during codegen and certain other special
|
||||
/// contexts; normally though we want to use `Reveal::UserFacing`,
|
||||
/// which is the default.
|
||||
/// All opaque types in the caller_bounds of the `ParamEnv`
|
||||
/// will be normalized to their underlying types.
|
||||
/// See PR #65989 and issue #65918 for more details
|
||||
pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> Self {
|
||||
if self.packed.tag().reveal == traits::Reveal::All {
|
||||
return self;
|
||||
}
|
||||
|
||||
// No need to reveal opaques with the new solver enabled,
|
||||
// since we have lazy norm.
|
||||
if tcx.next_trait_solver_globally() {
|
||||
return ParamEnv::new(self.caller_bounds(), Reveal::All);
|
||||
}
|
||||
|
||||
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
|
||||
pub fn new(caller_bounds: Clauses<'tcx>) -> Self {
|
||||
ParamEnv { caller_bounds }
|
||||
}
|
||||
|
||||
/// Returns this same environment but with no caller bounds.
|
||||
#[inline]
|
||||
pub fn without_caller_bounds(self) -> Self {
|
||||
Self::new(ListWithCachedTypeInfo::empty(), self.reveal())
|
||||
Self::new(ListWithCachedTypeInfo::empty())
|
||||
}
|
||||
|
||||
/// Creates a pair of param-env and value for use in queries.
|
||||
|
@ -1148,7 +1049,7 @@ impl<'tcx> TypingEnv<'tcx> {
|
|||
/// use `TypingMode::PostAnalysis`, they may still have where-clauses
|
||||
/// in scope.
|
||||
pub fn fully_monomorphized() -> TypingEnv<'tcx> {
|
||||
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::reveal_all() }
|
||||
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env: ParamEnv::empty() }
|
||||
}
|
||||
|
||||
/// Create a typing environment for use during analysis outside of a body.
|
||||
|
@ -1166,15 +1067,25 @@ impl<'tcx> TypingEnv<'tcx> {
|
|||
pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryParam<DefId>) -> TypingEnv<'tcx> {
|
||||
TypingEnv {
|
||||
typing_mode: TypingMode::PostAnalysis,
|
||||
param_env: tcx.param_env_reveal_all_normalized(def_id),
|
||||
param_env: tcx.param_env_normalized_for_post_analysis(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify the `typing_mode` to `PostAnalysis` and eagerly reveal all
|
||||
/// opaque types in the `param_env`.
|
||||
pub fn with_reveal_all_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
|
||||
let TypingEnv { typing_mode: _, param_env } = self;
|
||||
let param_env = param_env.with_reveal_all_normalized(tcx);
|
||||
pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
|
||||
let TypingEnv { typing_mode, param_env } = self;
|
||||
if let TypingMode::PostAnalysis = typing_mode {
|
||||
return self;
|
||||
}
|
||||
|
||||
// No need to reveal opaques with the new solver enabled,
|
||||
// since we have lazy norm.
|
||||
let param_env = if tcx.next_trait_solver_globally() {
|
||||
ParamEnv::new(param_env.caller_bounds())
|
||||
} else {
|
||||
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
|
||||
};
|
||||
TypingEnv { typing_mode: TypingMode::PostAnalysis, param_env }
|
||||
}
|
||||
|
||||
|
|
|
@ -237,7 +237,6 @@ TrivialTypeTraversalImpls! {
|
|||
crate::mir::coverage::ConditionId,
|
||||
crate::mir::Local,
|
||||
crate::mir::Promoted,
|
||||
crate::traits::Reveal,
|
||||
crate::ty::adjustment::AutoBorrowMutability,
|
||||
crate::ty::AdtKind,
|
||||
crate::ty::BoundRegion,
|
||||
|
|
|
@ -1053,7 +1053,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
|
|||
// This is because for default trait methods with RPITITs, we
|
||||
// install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))`
|
||||
// predicate, which would trivially cause a cycle when we do
|
||||
// anything that requires `ParamEnv::with_reveal_all_normalized`.
|
||||
// anything that requires `TypingEnv::with_post_analysis_normalized`.
|
||||
term: projection_pred.term,
|
||||
})
|
||||
.upcast(self.tcx)
|
||||
|
|
|
@ -87,7 +87,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
|
||||
// instead of having this logic here
|
||||
let typing_env =
|
||||
self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx);
|
||||
self.tcx.erase_regions(self.typing_env).with_post_analysis_normalized(self.tcx);
|
||||
let uv = self.tcx.erase_regions(uv);
|
||||
|
||||
// try to resolve e.g. associated constants to their definition on an impl, and then
|
||||
|
|
|
@ -321,7 +321,7 @@ where
|
|||
|
||||
let mut candidates = vec![];
|
||||
|
||||
if let TypingMode::Coherence = self.typing_mode(goal.param_env) {
|
||||
if let TypingMode::Coherence = self.typing_mode() {
|
||||
if let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal) {
|
||||
return vec![candidate];
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ where
|
|||
|
||||
self.assemble_param_env_candidates(goal, &mut candidates);
|
||||
|
||||
match self.typing_mode(goal.param_env) {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Coherence => {}
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => {
|
||||
self.discard_impls_shadowed_by_env(goal, &mut candidates);
|
||||
|
|
|
@ -55,7 +55,6 @@ where
|
|||
&self,
|
||||
goal: Goal<I, T>,
|
||||
) -> (Vec<I::GenericArg>, CanonicalInput<I, T>) {
|
||||
let param_env_for_debug_assertion = goal.param_env;
|
||||
let opaque_types = self.delegate.clone_opaque_types_for_query_response();
|
||||
let (goal, opaque_types) =
|
||||
(goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate));
|
||||
|
@ -72,10 +71,7 @@ where
|
|||
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
|
||||
},
|
||||
);
|
||||
let query_input = ty::CanonicalQueryInput {
|
||||
canonical,
|
||||
typing_mode: self.typing_mode(param_env_for_debug_assertion),
|
||||
};
|
||||
let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() };
|
||||
(orig_values, query_input)
|
||||
}
|
||||
|
||||
|
|
|
@ -214,8 +214,8 @@ where
|
|||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn typing_mode(&self, param_env_for_debug_assertion: I::ParamEnv) -> TypingMode<I> {
|
||||
self.delegate.typing_mode(param_env_for_debug_assertion)
|
||||
pub(super) fn typing_mode(&self) -> TypingMode<I> {
|
||||
self.delegate.typing_mode()
|
||||
}
|
||||
|
||||
pub(super) fn set_is_normalizes_to_goal(&mut self) {
|
||||
|
|
|
@ -71,7 +71,7 @@ where
|
|||
Ok(())
|
||||
}
|
||||
ty::AliasTermKind::OpaqueTy => {
|
||||
match self.typing_mode(param_env) {
|
||||
match self.typing_mode() {
|
||||
// Opaques are never rigid outside of analysis mode.
|
||||
TypingMode::Coherence | TypingMode::PostAnalysis => Err(NoSolution),
|
||||
// During analysis, opaques are only rigid if we may not define it.
|
||||
|
|
|
@ -22,7 +22,7 @@ where
|
|||
let opaque_ty = goal.predicate.alias;
|
||||
let expected = goal.predicate.term.as_type().expect("no such thing as an opaque const");
|
||||
|
||||
match self.typing_mode(goal.param_env) {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Coherence => {
|
||||
// An impossible opaque type bound is the only way this goal will fail
|
||||
// e.g. assigning `impl Copy := NotCopy`
|
||||
|
|
|
@ -67,7 +67,7 @@ where
|
|||
let maximal_certainty = match (impl_polarity, goal.predicate.polarity) {
|
||||
// In intercrate mode, this is ambiguous. But outside of intercrate,
|
||||
// it's not a real impl.
|
||||
(ty::ImplPolarity::Reservation, _) => match ecx.typing_mode(goal.param_env) {
|
||||
(ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() {
|
||||
TypingMode::Coherence => Certainty::AMBIGUOUS,
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution),
|
||||
},
|
||||
|
@ -174,7 +174,7 @@ where
|
|||
// ideally we want to avoid, since we can make progress on this goal
|
||||
// via an alias bound or a locally-inferred hidden type instead.
|
||||
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
|
||||
match ecx.typing_mode(goal.param_env) {
|
||||
match ecx.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::PostAnalysis => {
|
||||
unreachable!("rigid opaque outside of analysis: {goal:?}");
|
||||
}
|
||||
|
|
|
@ -111,6 +111,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
|||
/// Type inference occasionally gives us opaque types in places where corresponding patterns
|
||||
/// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
|
||||
/// types, we use the corresponding concrete type if possible.
|
||||
// FIXME(#132279): This will be unnecessary once we have a TypingMode which supports revealing
|
||||
// opaque types defined in a body.
|
||||
#[inline]
|
||||
pub fn reveal_opaque_ty(&self, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
|
||||
fn reveal_inner<'tcx>(cx: &RustcPatCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> RevealedTy<'tcx> {
|
||||
|
|
|
@ -204,7 +204,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
// and the obligation is monomorphic, otherwise passes such as
|
||||
// transmute checking and polymorphic MIR optimizations could
|
||||
// get a result which isn't correct for all monomorphizations.
|
||||
match self.typing_mode_unchecked() {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::Analysis { .. } => false,
|
||||
TypingMode::PostAnalysis => {
|
||||
let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref);
|
||||
|
|
|
@ -318,13 +318,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||
elaborate(tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()));
|
||||
new_env = ty::ParamEnv::new(
|
||||
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
|
||||
param_env.reveal(),
|
||||
);
|
||||
}
|
||||
|
||||
let final_user_env = ty::ParamEnv::new(
|
||||
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
|
||||
user_env.reveal(),
|
||||
);
|
||||
debug!(
|
||||
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
|
||||
|
|
|
@ -707,7 +707,7 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
let caller_bounds =
|
||||
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
||||
|
||||
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal())
|
||||
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds))
|
||||
};
|
||||
|
||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||
|
|
|
@ -20,7 +20,7 @@ pub fn evaluate_host_effect_obligation<'tcx>(
|
|||
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||
obligation: &HostEffectObligation<'tcx>,
|
||||
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
|
||||
if matches!(selcx.infcx.typing_mode(obligation.param_env), TypingMode::Coherence) {
|
||||
if matches!(selcx.infcx.typing_mode(), TypingMode::Coherence) {
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
"should not select host obligation in old solver in intercrate mode"
|
||||
|
|
|
@ -768,8 +768,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
|
|||
stalled_on: &mut Vec<TyOrConstInferVar>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let infcx = self.selcx.infcx;
|
||||
if obligation.predicate.is_global()
|
||||
&& !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
|
||||
if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
|
||||
{
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
|
@ -824,8 +823,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
|
|||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let tcx = self.selcx.tcx();
|
||||
let infcx = self.selcx.infcx;
|
||||
if obligation.predicate.is_global()
|
||||
&& !matches!(infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
|
||||
if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
|
||||
{
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
|
|
|
@ -423,7 +423,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
|
||||
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));
|
||||
if !elaborated_env.has_aliases() {
|
||||
return elaborated_env;
|
||||
}
|
||||
|
@ -470,8 +470,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
// here. I believe they should not matter, because we are ignoring TypeOutlives param-env
|
||||
// predicates here anyway. Keeping them here anyway because it seems safer.
|
||||
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
|
||||
let outlives_env =
|
||||
ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal());
|
||||
let outlives_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env));
|
||||
let Ok(outlives_predicates) =
|
||||
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
|
||||
else {
|
||||
|
@ -484,7 +483,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
let mut predicates = non_outlives_predicates;
|
||||
predicates.extend(outlives_predicates);
|
||||
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -612,7 +611,7 @@ pub fn try_evaluate_const<'tcx>(
|
|||
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
|
||||
// instead of having this logic here
|
||||
let typing_env =
|
||||
tcx.erase_regions(infcx.typing_env(param_env)).with_reveal_all_normalized(tcx);
|
||||
tcx.erase_regions(infcx.typing_env(param_env)).with_post_analysis_normalized(tcx);
|
||||
let erased_uv = tcx.erase_regions(uv);
|
||||
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
|
|
|
@ -111,14 +111,13 @@ where
|
|||
|
||||
pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
|
||||
value: &T,
|
||||
) -> bool {
|
||||
let mut flags = ty::TypeFlags::HAS_ALIAS;
|
||||
|
||||
// Opaques are treated as rigid with `Reveal::UserFacing`,
|
||||
// so we can ignore those.
|
||||
match infcx.typing_mode(param_env_for_debug_assertion) {
|
||||
match infcx.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||
flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
|
||||
}
|
||||
|
@ -158,11 +157,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
"Normalizing {value:?} without wrapping in a `Binder`"
|
||||
);
|
||||
|
||||
if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
|
||||
value
|
||||
} else {
|
||||
value.fold_with(self)
|
||||
}
|
||||
if !needs_normalization(self.selcx.infcx, &value) { value } else { value.fold_with(self) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +177,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
|
||||
if !needs_normalization(self.selcx.infcx, &ty) {
|
||||
return ty;
|
||||
}
|
||||
|
||||
|
@ -217,7 +212,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
match kind {
|
||||
ty::Opaque => {
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.selcx.infcx.typing_mode(self.param_env) {
|
||||
match self.selcx.infcx.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
|
@ -407,8 +402,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
let tcx = self.selcx.tcx();
|
||||
if tcx.features().generic_const_exprs()
|
||||
|| !needs_normalization(self.selcx.infcx, self.param_env, &constant)
|
||||
if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &constant)
|
||||
{
|
||||
constant
|
||||
} else {
|
||||
|
@ -426,7 +420,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
|||
|
||||
#[inline]
|
||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
|
||||
if p.allow_normalization() && needs_normalization(self.selcx.infcx, &p) {
|
||||
p.super_fold_with(self)
|
||||
} else {
|
||||
p
|
||||
|
|
|
@ -10,7 +10,6 @@ use rustc_hir::lang_items::LangItem;
|
|||
use rustc_infer::infer::DefineOpaqueTypes;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::traits::{ObligationCauseCode, PredicateObligations};
|
||||
pub use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
|
@ -975,7 +974,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// and the obligation is monomorphic, otherwise passes such as
|
||||
// transmute checking and polymorphic MIR optimizations could
|
||||
// get a result which isn't correct for all monomorphizations.
|
||||
match selcx.infcx.typing_mode(obligation.param_env) {
|
||||
match selcx.infcx.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::Analysis { .. } => {
|
||||
debug!(
|
||||
assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
|
||||
|
|
|
@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
if !needs_normalization(self.infcx, self.param_env, &value) {
|
||||
if !needs_normalization(self.infcx, &value) {
|
||||
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))]
|
||||
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !needs_normalization(self.infcx, self.param_env, &ty) {
|
||||
if !needs_normalization(self.infcx, &ty) {
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
|||
let res = match kind {
|
||||
ty::Opaque => {
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.infcx.typing_mode(self.param_env) {
|
||||
match self.infcx.typing_mode() {
|
||||
TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
|
||||
ty.try_super_fold_with(self)?
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
|||
&mut self,
|
||||
constant: ty::Const<'tcx>,
|
||||
) -> Result<ty::Const<'tcx>, Self::Error> {
|
||||
if !needs_normalization(self.infcx, self.param_env, &constant) {
|
||||
if !needs_normalization(self.infcx, &constant) {
|
||||
return Ok(constant);
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
|
|||
&mut self,
|
||||
p: ty::Predicate<'tcx>,
|
||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||
if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
|
||||
if p.allow_normalization() && needs_normalization(self.infcx, &p) {
|
||||
p.try_super_fold_with(self)
|
||||
} else {
|
||||
Ok(p)
|
||||
|
|
|
@ -760,9 +760,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
//
|
||||
// Note that this is only sound as projection candidates of opaque types
|
||||
// are always applicable for auto traits.
|
||||
} else if let TypingMode::Coherence =
|
||||
self.infcx.typing_mode(obligation.param_env)
|
||||
{
|
||||
} else if let TypingMode::Coherence = self.infcx.typing_mode() {
|
||||
// We do not emit auto trait candidates for opaque types in coherence.
|
||||
// Doing so can result in weird dependency cycles.
|
||||
candidates.ambiguous = true;
|
||||
|
@ -905,7 +903,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
//
|
||||
// FIXME(@lcnr): This should probably only trigger during analysis,
|
||||
// disabling candidates during codegen is also questionable.
|
||||
if let TypingMode::Coherence = self.infcx.typing_mode(param_env) {
|
||||
if let TypingMode::Coherence = self.infcx.typing_mode() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
/// Enables tracking of intercrate ambiguity causes. See
|
||||
/// the documentation of [`Self::intercrate_ambiguity_causes`] for more.
|
||||
pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
|
||||
assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
|
||||
assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
|
||||
assert!(self.intercrate_ambiguity_causes.is_none());
|
||||
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
|
||||
debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
|
||||
|
@ -234,7 +234,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
pub fn take_intercrate_ambiguity_causes(
|
||||
&mut self,
|
||||
) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>> {
|
||||
assert_matches!(self.infcx.typing_mode_unchecked(), TypingMode::Coherence);
|
||||
assert_matches!(self.infcx.typing_mode(), TypingMode::Coherence);
|
||||
self.intercrate_ambiguity_causes.take().unwrap_or_default()
|
||||
}
|
||||
|
||||
|
@ -1027,7 +1027,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
||||
mut obligation: PolyTraitObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
if !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
|
||||
if !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
|
||||
&& obligation.is_global()
|
||||
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param())
|
||||
{
|
||||
|
@ -1459,7 +1459,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
|
||||
let obligation = &stack.obligation;
|
||||
match self.infcx.typing_mode(obligation.param_env) {
|
||||
match self.infcx.typing_mode() {
|
||||
TypingMode::Coherence => {}
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Ok(()),
|
||||
}
|
||||
|
@ -1489,7 +1489,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
return false;
|
||||
}
|
||||
|
||||
match self.infcx.typing_mode(param_env) {
|
||||
match self.infcx.typing_mode() {
|
||||
// Avoid using the global cache during coherence and just rely
|
||||
// on the local cache. It is really just a simplification to
|
||||
// avoid us having to fear that coherence results "pollute"
|
||||
|
@ -2518,7 +2518,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
nested_obligations.extend(obligations);
|
||||
|
||||
if impl_trait_header.polarity == ty::ImplPolarity::Reservation
|
||||
&& !matches!(self.infcx.typing_mode(obligation.param_env), TypingMode::Coherence)
|
||||
&& !matches!(self.infcx.typing_mode(), TypingMode::Coherence)
|
||||
{
|
||||
debug!("reservation impls only apply in intercrate mode");
|
||||
return Err(());
|
||||
|
|
|
@ -155,7 +155,7 @@ fn resolve_associated_item<'tcx>(
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
let typing_env = typing_env.with_reveal_all_normalized(tcx);
|
||||
let typing_env = typing_env.with_post_analysis_normalized(tcx);
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let args = rcvr_args.rebase_onto(tcx, trait_def_id, impl_data.args);
|
||||
let args = translate_args(
|
||||
|
|
|
@ -49,7 +49,7 @@ fn layout_of<'tcx>(
|
|||
// Optimization: We convert to RevealAll and convert opaque types in the where bounds
|
||||
// to their hidden types. This reduces overall uncached invocations of `layout_of` and
|
||||
// is thus a small performance improvement.
|
||||
let typing_env = typing_env.with_reveal_all_normalized(tcx);
|
||||
let typing_env = typing_env.with_post_analysis_normalized(tcx);
|
||||
let unnormalized_ty = ty;
|
||||
|
||||
// FIXME: We might want to have two different versions of `layout_of`:
|
||||
|
|
|
@ -158,8 +158,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
|||
|
||||
let local_did = def_id.as_local();
|
||||
|
||||
let unnormalized_env =
|
||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing);
|
||||
let unnormalized_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates));
|
||||
|
||||
let body_id = local_did.unwrap_or(CRATE_DEF_ID);
|
||||
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
||||
|
@ -249,8 +248,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||
tcx.param_env(def_id).with_reveal_all_normalized(tcx)
|
||||
fn param_env_normalized_for_post_analysis(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||
// This is a bit ugly but the easiest way to avoid code duplication.
|
||||
let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id);
|
||||
typing_env.with_post_analysis_normalized(tcx).param_env
|
||||
}
|
||||
|
||||
/// If the given trait impl enables exploiting the former order dependence of trait objects,
|
||||
|
@ -362,7 +363,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
asyncness,
|
||||
adt_sized_constraint,
|
||||
param_env,
|
||||
param_env_reveal_all_normalized,
|
||||
param_env_normalized_for_post_analysis,
|
||||
self_ty_of_trait_impl_enabling_order_dep_trait_object_hack,
|
||||
defaultness,
|
||||
unsizing_params_for_adt,
|
||||
|
|
|
@ -70,10 +70,7 @@ pub trait InferCtxtLike: Sized {
|
|||
true
|
||||
}
|
||||
|
||||
fn typing_mode(
|
||||
&self,
|
||||
param_env_for_debug_assertion: <Self::Interner as Interner>::ParamEnv,
|
||||
) -> TypingMode<Self::Interner>;
|
||||
fn typing_mode(&self) -> TypingMode<Self::Interner>;
|
||||
|
||||
fn universe(&self) -> ty::UniverseIndex;
|
||||
fn create_next_universe(&self) -> ty::UniverseIndex;
|
||||
|
|
|
@ -11,7 +11,7 @@ use rustc_ast_ir::Mutability;
|
|||
use crate::elaborate::Elaboratable;
|
||||
use crate::fold::{TypeFoldable, TypeSuperFoldable};
|
||||
use crate::relate::Relate;
|
||||
use crate::solve::{AdtDestructorKind, Reveal};
|
||||
use crate::solve::AdtDestructorKind;
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||
use crate::{self as ty, CollectAndApply, Interner, UpcastFrom};
|
||||
|
||||
|
@ -542,8 +542,6 @@ pub trait AdtDef<I: Interner>: Copy + Debug + Hash + Eq {
|
|||
}
|
||||
|
||||
pub trait ParamEnv<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
|
||||
fn reveal(self) -> Reveal;
|
||||
|
||||
fn caller_bounds(self) -> impl IntoIterator<Item = I::Clause>;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ where
|
|||
|
||||
(ty::Alias(ty::Opaque, _), _) | (_, ty::Alias(ty::Opaque, _)) => {
|
||||
assert!(!infcx.next_trait_solver());
|
||||
match infcx.typing_mode(relation.param_env()) {
|
||||
match infcx.typing_mode() {
|
||||
// During coherence, opaque types should be treated as *possibly*
|
||||
// equal to any other type. This is an
|
||||
// extremely heavy hammer, but can be relaxed in a forwards-compatible
|
||||
|
|
|
@ -10,54 +10,6 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen
|
|||
|
||||
use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
|
||||
|
||||
/// Depending on the stage of compilation, we want projection to be
|
||||
/// more or less conservative.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum Reveal {
|
||||
/// At type-checking time, we refuse to project any associated
|
||||
/// type that is marked `default`. Non-`default` ("final") types
|
||||
/// are always projected. This is necessary in general for
|
||||
/// soundness of specialization. However, we *could* allow
|
||||
/// projections in fully-monomorphic cases. We choose not to,
|
||||
/// because we prefer for `default type` to force the type
|
||||
/// definition to be treated abstractly by any consumers of the
|
||||
/// impl. Concretely, that means that the following example will
|
||||
/// fail to compile:
|
||||
///
|
||||
/// ```compile_fail,E0308
|
||||
/// #![feature(specialization)]
|
||||
/// trait Assoc {
|
||||
/// type Output;
|
||||
/// }
|
||||
///
|
||||
/// impl<T> Assoc for T {
|
||||
/// default type Output = bool;
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let x: <() as Assoc>::Output = true;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// We also do not reveal the hidden type of opaque types during
|
||||
/// type-checking.
|
||||
UserFacing,
|
||||
|
||||
/// At codegen time, all monomorphic projections will succeed.
|
||||
/// Also, `impl Trait` is normalized to the concrete type,
|
||||
/// which has to be already collected by type-checking.
|
||||
///
|
||||
/// NOTE: as `impl Trait`'s concrete type should *never*
|
||||
/// be observable directly by the user, `Reveal::All`
|
||||
/// should not be used by checks which may expose
|
||||
/// type equality or type contents to the user.
|
||||
/// There are some exceptions, e.g., around auto traits and
|
||||
/// transmute-checking, which expose some details, but
|
||||
/// not the whole concrete type of the `impl Trait`.
|
||||
All,
|
||||
}
|
||||
|
||||
pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
|
||||
ty::CanonicalQueryInput<I, QueryInput<I, T>>;
|
||||
pub type CanonicalResponse<I> = Canonical<I, Response<I>>;
|
||||
|
|
|
@ -11,7 +11,6 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::ty::{
|
||||
self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast,
|
||||
};
|
||||
|
@ -516,7 +515,6 @@ fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId
|
|||
.upcast(tcx)
|
||||
}),
|
||||
)),
|
||||
Reveal::UserFacing,
|
||||
);
|
||||
ty::TypingEnv {
|
||||
typing_mode: ty::TypingMode::non_body_analysis(),
|
||||
|
|
|
@ -575,7 +575,7 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
|
|||
|
||||
/// Checks if a given type looks safe to be uninitialized.
|
||||
pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
let typing_env = cx.typing_env().with_reveal_all_normalized(cx.tcx);
|
||||
let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx);
|
||||
cx.tcx
|
||||
.check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty)))
|
||||
.unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty))
|
||||
|
|
Loading…
Add table
Reference in a new issue