1
Fork 0

Auto merge of #133242 - lcnr:questionable-uwu, r=compiler-errors,BoxyUwU

finish `Reveal` removal

After #133212 changed the `TypingMode` to be the only source of truth, this entirely rips out `Reveal`.

cc #132279

r? `@compiler-errors`
This commit is contained in:
bors 2024-11-23 18:01:21 +00:00
commit 386a7c7ae2
82 changed files with 344 additions and 529 deletions

View file

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

View file

@ -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.

View file

@ -629,8 +629,7 @@ impl<'tcx> Body<'tcx> {
) -> Option<(u128, &'a SwitchTargets)> {
// There are two places here we need to evaluate a constant.
let eval_mono_const = |constant: &ConstOperand<'tcx>| {
// FIXME(#132279): what is this, why are we using an empty environment with
// `RevealAll` here.
// FIXME(#132279): what is this, why are we using an empty environment here.
let typing_env = ty::TypingEnv::fully_monomorphized();
let mono_literal = instance.instantiate_mir_and_normalize_erasing_regions(
tcx,

View file

@ -1373,18 +1373,20 @@ rustc_queries! {
/// Gets the ParameterEnvironment for a given item; this environment
/// will be in "user-facing" mode, meaning that it is suitable for
/// type-checking etc, and it does not normalize specializable
/// associated types. This is almost always what you want,
/// unless you are doing MIR optimizations, in which case you
/// might want to use `reveal_all()` method to change modes.
/// associated types.
///
/// You should almost certainly not use this. If you already have an InferCtxt, then
/// you should also probably have a `ParamEnv` from when it was built. If you don't,
/// then you should take a `TypingEnv` to ensure that you handle opaque types correctly.
query param_env(def_id: DefId) -> ty::ParamEnv<'tcx> {
desc { |tcx| "computing normalized predicates of `{}`", tcx.def_path_str(def_id) }
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) }
}
@ -1465,13 +1467,13 @@ rustc_queries! {
/// *IMPORTANT*: *DO NOT* run this query before promoted MIR body is constructed,
/// because this query partially depends on that query.
/// Otherwise, there is a risk of query cycles.
query list_significant_drop_tys(ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> {
query list_significant_drop_tys(ty: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> &'tcx ty::List<Ty<'tcx>> {
desc { |tcx| "computing when `{}` has a significant destructor", ty.value }
cache_on_disk_if { false }
}
/// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode, and will normalize the input type.
/// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
query layout_of(
key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>
) -> Result<ty::layout::TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {

View file

@ -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;
@ -551,7 +551,7 @@ pub struct DerivedCause<'tcx> {
pub parent_code: InternedObligationCauseCode<'tcx>,
}
#[derive(Clone, Debug, TypeVisitable)]
#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
pub enum SelectionError<'tcx> {
/// The trait is not implemented.
Unimplemented,
@ -573,7 +573,7 @@ pub enum SelectionError<'tcx> {
ConstArgHasWrongType { ct: ty::Const<'tcx>, ct_ty: Ty<'tcx>, expected_ty: Ty<'tcx> },
}
#[derive(Clone, Debug, TypeVisitable)]
#[derive(Clone, Debug, PartialEq, Eq, TypeVisitable)]
pub struct SignatureMismatchData<'tcx> {
pub found_trait_ref: ty::TraitRef<'tcx>,
pub expected_trait_ref: ty::TraitRef<'tcx>,

View file

@ -11,20 +11,10 @@ use self::EvaluationResult::*;
use super::{SelectionError, SelectionResult};
use crate::ty;
pub type SelectionCache<'tcx> = Cache<
// This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace
// caller bounds with an empty list if the `TraitPredicate` looks global, which may happen
// after erasing lifetimes from the predicate.
(ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
>;
pub type SelectionCache<'tcx, ENV> =
Cache<(ENV, ty::TraitPredicate<'tcx>), SelectionResult<'tcx, SelectionCandidate<'tcx>>>;
pub type EvaluationCache<'tcx> = Cache<
// See above: this cache does not use `ParamEnvAnd` in its keys due to sometimes incorrectly
// caching with the wrong `ParamEnv`.
(ty::ParamEnv<'tcx>, ty::PolyTraitPredicate<'tcx>),
EvaluationResult,
>;
pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>), EvaluationResult>;
/// The selection process begins by considering all impls, where
/// clauses, and so forth that might resolve an obligation. Sometimes

View file

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

View file

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

View file

@ -1326,12 +1326,12 @@ pub struct GlobalCtxt<'tcx> {
/// Caches the results of trait selection. This cache is used
/// for things that do not have to do with the parameters in scope.
pub selection_cache: traits::SelectionCache<'tcx>,
pub selection_cache: traits::SelectionCache<'tcx, ty::TypingEnv<'tcx>>,
/// Caches the results of trait evaluation. This cache is used
/// for things that do not have to do with the parameters in scope.
/// Merge this with `selection_cache`?
pub evaluation_cache: traits::EvaluationCache<'tcx>,
pub evaluation_cache: traits::EvaluationCache<'tcx, ty::TypingEnv<'tcx>>,
/// Caches the results of goal evaluation in the new solver.
pub new_solver_evaluation_cache: Lock<search_graph::GlobalCache<TyCtxt<'tcx>>>,

View file

@ -504,8 +504,8 @@ impl<'tcx> Instance<'tcx> {
/// ```
///
/// trying to resolve `Debug::fmt` applied to `T` will yield `Ok(None)`, because we do not
/// know what code ought to run. (Note that this setting is also affected by the
/// `RevealMode` in the parameter environment.)
/// know what code ought to run. This setting is also affected by the current `TypingMode`
/// of the environment.
///
/// Presuming that coherence and type-check have succeeded, if this method is invoked
/// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return

View file

@ -682,14 +682,14 @@ pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasTypingEnv<
/// Blanket extension trait for contexts that can compute layouts of types.
pub trait LayoutOf<'tcx>: LayoutOfHelpers<'tcx> {
/// Computes the layout of a type. Note that this implicitly
/// executes in "reveal all" mode, and will normalize the input type.
/// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
#[inline]
fn layout_of(&self, ty: Ty<'tcx>) -> Self::LayoutOfResult {
self.spanned_layout_of(ty, DUMMY_SP)
}
/// Computes the layout of a type, at `span`. Note that this implicitly
/// executes in "reveal all" mode, and will normalize the input type.
/// executes in `TypingMode::PostAnalysis`, and will normalize the input type.
// FIXME(eddyb) avoid passing information like this, and instead add more
// `TyCtxt::at`-like APIs to be able to do e.g. `cx.at(span).layout_of(ty)`.
#[inline]

View file

@ -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 }
}

View file

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

View file

@ -423,8 +423,8 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn async_drop_glue_morphology(self, did: DefId) -> AsyncDropGlueMorphology {
let ty: Ty<'tcx> = self.type_of(did).instantiate_identity();
// Async drop glue morphology is an internal detail, so reveal_all probably
// should be fine
// Async drop glue morphology is an internal detail, so
// using `TypingMode::PostAnalysis` probably should be fine.
let typing_env = ty::TypingEnv::fully_monomorphized();
if ty.needs_async_drop(self, typing_env) {
AsyncDropGlueMorphology::Custom
@ -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)