mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-16 13:05:18 +03:00
type safety for typing mode outside trait solver which can't be erased-not-coherence
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, MayBeErased, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, throw_inval};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
@@ -384,7 +384,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
"Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
|
||||
)
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
|
||||
// Make sure we format the instance even if we do not print it.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::layout::{LayoutCx, TyAndLayout};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, MayBeErased, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, mir};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use tracing::{debug, instrument, trace};
|
||||
@@ -247,7 +247,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
|
||||
"Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
|
||||
)
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
|
||||
}
|
||||
}
|
||||
let const_alloc = tcx.eval_to_allocation_raw(typing_env.as_query_input(cid))?;
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
LayoutOfHelpers, TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv, TypingMode,
|
||||
Variance,
|
||||
self, GenericArgsRef, MayBeErased, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingEnv,
|
||||
TypingMode, Variance,
|
||||
};
|
||||
use rustc_middle::{bug, mir, span_bug};
|
||||
use rustc_span::Span;
|
||||
@@ -251,7 +251,7 @@ pub fn new(
|
||||
| TypingMode::PostBorrowckAnalysis { .. } => {
|
||||
bug!("Const eval should always happens in PostAnalysis mode.");
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
};
|
||||
use rustc_infer::infer::{self, RegionVariableOrigin};
|
||||
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
|
||||
use rustc_middle::ty::{self, Const, Flags, Ty, TyCtxt, TypeVisitableExt, Unnormalized};
|
||||
use rustc_middle::ty::{
|
||||
self, CantBeErased, Const, Flags, Ty, TyCtxt, TypeVisitableExt, TypingMode, Unnormalized,
|
||||
};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span};
|
||||
use rustc_trait_selection::error_reporting::TypeErrCtxt;
|
||||
@@ -161,6 +163,12 @@ pub(crate) fn new(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn typing_mode(&self) -> TypingMode<'tcx, CantBeErased> {
|
||||
// `FnCtxt` is never constructed in the trait solver, so we can safely use
|
||||
// `assert_not_erased`.
|
||||
self.infcx.typing_mode_raw().assert_not_erased()
|
||||
}
|
||||
|
||||
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'a> {
|
||||
self.root_ctxt.infcx.dcx()
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ pub fn canonicalize_query<V>(
|
||||
query_state,
|
||||
)
|
||||
.unchecked_map(|(param_env, value)| param_env.and(value));
|
||||
CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(self.typing_mode()) }
|
||||
CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(self.typing_mode_raw()) }
|
||||
}
|
||||
|
||||
/// Canonicalizes a query *response* `V`. When we canonicalize a
|
||||
|
||||
@@ -26,8 +26,8 @@ fn disable_trait_solver_fast_paths(&self) -> bool {
|
||||
self.disable_trait_solver_fast_paths()
|
||||
}
|
||||
|
||||
fn typing_mode(&self) -> ty::TypingMode<'tcx> {
|
||||
self.typing_mode()
|
||||
fn typing_mode_raw(&self) -> ty::TypingMode<'tcx> {
|
||||
self.typing_mode_raw()
|
||||
}
|
||||
|
||||
fn universe(&self) -> ty::UniverseIndex {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
TypeSuperFoldable, TypeVisitable, TypeVisitableExt, TypingEnv, TypingMode, fold_regions,
|
||||
};
|
||||
use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use rustc_type_ir::MayBeErased;
|
||||
use snapshot::undo_log::InferCtxtUndoLogs;
|
||||
use tracing::{debug, instrument};
|
||||
use type_variable::TypeVariableOrigin;
|
||||
@@ -640,14 +641,34 @@ pub fn next_trait_solver(&self) -> bool {
|
||||
self.next_trait_solver
|
||||
}
|
||||
|
||||
/// This method is deliberately called `..._raw`,
|
||||
/// since the output may possibly include [`TypingMode::ErasedNotCoherence`](TypingMode::ErasedNotCoherence).
|
||||
/// `ErasedNotCoherence` is an implementation detail of the next trait solver, see its docs for
|
||||
/// more information.
|
||||
///
|
||||
/// `InferCtxt` has two uses: the trait solver calls some methods on it, because the `InferCtxt`
|
||||
/// works as a kind of store for for example type unification information.
|
||||
/// `InferCtxt` is also often used outside the trait solver during typeck.
|
||||
/// There, we don't care about the `ErasedNotCoherence` case and should never encounter it.
|
||||
/// To make sure these two uses are never confused, we want to statically encode this information.
|
||||
///
|
||||
/// The `FnCtxt`, for example, is only used in the outside-trait-solver case. It has a non-raw
|
||||
/// version of the `typing_mode` method available that asserts `ErasedNotCoherence` is
|
||||
/// impossible, and returns a `TypingMode` where `ErasedNotCoherence` is made uninhabited using
|
||||
/// the [`CantBeErased`](rustc_type_ir::CantBeErased) enum. That way you don't even have to
|
||||
/// match on the variant and can safely ignore it.
|
||||
///
|
||||
/// Prefer non-raw apis if available. e.g.,
|
||||
/// - On the `FnCtxt`
|
||||
/// - on the `SelectionCtxt`
|
||||
#[inline(always)]
|
||||
pub fn disable_trait_solver_fast_paths(&self) -> bool {
|
||||
self.tcx.disable_trait_solver_fast_paths()
|
||||
pub fn typing_mode_raw(&self) -> TypingMode<'tcx> {
|
||||
self.typing_mode
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx> {
|
||||
self.typing_mode
|
||||
pub fn disable_trait_solver_fast_paths(&self) -> bool {
|
||||
self.tcx.disable_trait_solver_fast_paths()
|
||||
}
|
||||
|
||||
/// Returns the origin of the type variable identified by `vid`.
|
||||
@@ -1071,7 +1092,7 @@ pub fn opaques_with_sub_unified_hidden_type(&self, ty_vid: TyVid) -> Vec<ty::Ali
|
||||
#[inline(always)]
|
||||
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
|
||||
debug_assert!(!self.next_trait_solver());
|
||||
match self.typing_mode() {
|
||||
match self.typing_mode_raw().assert_not_erased() {
|
||||
TypingMode::Analysis {
|
||||
defining_opaque_types_and_generators: defining_opaque_types,
|
||||
}
|
||||
@@ -1084,7 +1105,7 @@ pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
|
||||
TypingMode::Coherence
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => false,
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1403,7 +1424,7 @@ pub fn create_next_universe(&self) -> ty::UniverseIndex {
|
||||
/// 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() {
|
||||
let typing_mode = match self.typing_mode_raw() {
|
||||
// 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
|
||||
// errors and fail to reveal opaques while inside of bodies. We should rename this
|
||||
@@ -1415,7 +1436,7 @@ pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
|
||||
mode @ (ty::TypingMode::Coherence
|
||||
| ty::TypingMode::PostBorrowckAnalysis { .. }
|
||||
| ty::TypingMode::PostAnalysis) => mode,
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
};
|
||||
ty::TypingEnv::new(param_env, typing_mode)
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ pub fn handle_opaque_type(
|
||||
if def_id.is_local() =>
|
||||
{
|
||||
let def_id = def_id.expect_local();
|
||||
if self.typing_mode().is_coherence() {
|
||||
if self.typing_mode_raw().is_coherence() {
|
||||
// See comment on `insert_hidden_type` for why this is sufficient in coherence
|
||||
return Some(self.register_hidden_type(
|
||||
OpaqueTypeKey { def_id, args },
|
||||
@@ -229,7 +229,9 @@ pub fn insert_hidden_type(
|
||||
// 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() {
|
||||
//
|
||||
// Note: we don't use this function in the next solver so we can safely call `assert_not_erased`
|
||||
match self.typing_mode_raw().assert_not_erased() {
|
||||
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
|
||||
@@ -284,7 +286,6 @@ pub fn insert_hidden_type(
|
||||
mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => {
|
||||
bug!("insert hidden type in {mode:?}")
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -604,7 +604,7 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
//
|
||||
// cc trait-system-refactor-initiative#108
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !self.infcx.typing_mode().is_coherence()
|
||||
&& !self.infcx.typing_mode_raw().is_coherence()
|
||||
&& self.in_alias
|
||||
{
|
||||
inner.type_variables().equate(vid, new_var_id);
|
||||
@@ -736,7 +736,7 @@ fn consts(
|
||||
// See the comment for type inference variables
|
||||
// for more details.
|
||||
if self.infcx.next_trait_solver()
|
||||
&& !self.infcx.typing_mode().is_coherence()
|
||||
&& !self.infcx.typing_mode_raw().is_coherence()
|
||||
&& self.in_alias
|
||||
{
|
||||
variable_table.union(vid, new_var_id);
|
||||
|
||||
@@ -1063,7 +1063,7 @@ pub fn non_body_analysis(
|
||||
def_id: impl IntoQueryKey<DefId>,
|
||||
) -> TypingEnv<'tcx> {
|
||||
let def_id = def_id.into_query_key();
|
||||
Self::new(tcx.param_env(def_id), TypingMode::non_body_analysis())
|
||||
Self::new(tcx.param_env(def_id), TypingMode::non_body_analysis().into())
|
||||
}
|
||||
|
||||
pub fn post_analysis(tcx: TyCtxt<'tcx>, def_id: impl IntoQueryKey<DefId>) -> TypingEnv<'tcx> {
|
||||
@@ -1081,7 +1081,7 @@ pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx>
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. } => {}
|
||||
TypingMode::PostAnalysis => return self,
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
|
||||
// No need to reveal opaques with the new solver enabled,
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
use rustc_type_ir::TyKind::*;
|
||||
use rustc_type_ir::solve::SizedTraitKind;
|
||||
use rustc_type_ir::walk::TypeWalker;
|
||||
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, TypeVisitableExt, elaborate};
|
||||
use rustc_type_ir::{
|
||||
self as ir, BoundVar, CollectAndApply, MayBeErased, TypeVisitableExt, elaborate,
|
||||
};
|
||||
use tracing::instrument;
|
||||
use ty::util::IntTypeExt;
|
||||
|
||||
@@ -41,7 +43,7 @@
|
||||
pub type Binder<'tcx, T> = ir::Binder<TyCtxt<'tcx>, T>;
|
||||
pub type EarlyBinder<'tcx, T> = ir::EarlyBinder<TyCtxt<'tcx>, T>;
|
||||
pub type Unnormalized<'tcx, T> = ir::Unnormalized<TyCtxt<'tcx>, T>;
|
||||
pub type TypingMode<'tcx> = ir::TypingMode<TyCtxt<'tcx>>;
|
||||
pub type TypingMode<'tcx, S = MayBeErased> = ir::TypingMode<TyCtxt<'tcx>, S>;
|
||||
pub type TypingModeEqWrapper<'tcx> = ir::TypingModeEqWrapper<TyCtxt<'tcx>>;
|
||||
pub type Placeholder<'tcx, T> = ir::Placeholder<TyCtxt<'tcx>, T>;
|
||||
pub type PlaceholderRegion<'tcx> = ir::PlaceholderRegion<TyCtxt<'tcx>>;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt, Unnormalized};
|
||||
use rustc_middle::ty::{self, GenericArg, GenericArgsRef, MayBeErased, Ty, TyCtxt, Unnormalized};
|
||||
use rustc_middle::{bug, span_bug, traits};
|
||||
use rustc_span::{DUMMY_SP, Spanned, dummy_spanned};
|
||||
use tracing::{debug, instrument};
|
||||
@@ -555,7 +555,7 @@ fn move_paths_for_fields(
|
||||
| ty::TypingMode::PostBorrowckAnalysis { .. } => {
|
||||
bug!()
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
|
||||
}
|
||||
|
||||
let field_ty = field.ty(tcx, args);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use rustc_type_ir::relate::solver_relating::RelateExt;
|
||||
use rustc_type_ir::{
|
||||
self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner,
|
||||
TypeFoldable, TypingMode, TypingModeEqWrapper,
|
||||
MayBeErased, TypeFoldable, TypingMode, TypingModeEqWrapper,
|
||||
};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -65,16 +65,16 @@ pub(super) fn canonicalize_goal<D, I>(
|
||||
D: SolverDelegate<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
let (opaque_types, typing_mode) = match (erase_opaque_types, delegate.typing_mode()) {
|
||||
let (opaque_types, typing_mode) = match (erase_opaque_types, delegate.typing_mode_raw()) {
|
||||
// In `TypingMode::Coherence` there should not be any opaques, and we also don't change typing mode.
|
||||
(_, TypingMode::Coherence) => {
|
||||
assert!(opaque_types.is_empty());
|
||||
(&[][..], TypingMode::Coherence)
|
||||
}
|
||||
// Make sure we're not recursively in `ErasedNotCoherence`.
|
||||
(_, TypingMode::ErasedNotCoherence) => {
|
||||
(_, TypingMode::ErasedNotCoherence(MayBeErased)) => {
|
||||
assert!(opaque_types.is_empty());
|
||||
(&[][..], TypingMode::ErasedNotCoherence)
|
||||
(&[][..], TypingMode::ErasedNotCoherence(MayBeErased))
|
||||
}
|
||||
// If we're supposed to erase opaque types, and we're in any typing mode other than coherence,
|
||||
// do the erasing and change typing mode.
|
||||
@@ -84,7 +84,7 @@ pub(super) fn canonicalize_goal<D, I>(
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis,
|
||||
) => (&[][..], TypingMode::ErasedNotCoherence),
|
||||
) => (&[][..], TypingMode::ErasedNotCoherence(MayBeErased)),
|
||||
(EraseOpaqueTypes::No, typing_mode) => (opaque_types, typing_mode),
|
||||
};
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
use rustc_type_ir::search_graph::CandidateHeadUsages;
|
||||
use rustc_type_ir::solve::{AliasBoundKind, MaybeInfo, SizedTraitKind, StalledOnCoroutines};
|
||||
use rustc_type_ir::{
|
||||
self as ty, AliasTy, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||
TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized,
|
||||
Upcast, elaborate,
|
||||
self as ty, AliasTy, Interner, MayBeErased, TypeFlags, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
TypingMode, Unnormalized, Upcast, elaborate,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
@@ -478,7 +478,7 @@ pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
|
||||
| CandidateSource::AliasBound(_)
|
||||
) && has_no_inference_or_external_constraints(c.result)
|
||||
}),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
};
|
||||
if assemble_impls {
|
||||
self.assemble_impl_candidates(goal, &mut candidates);
|
||||
@@ -970,7 +970,7 @@ pub(super) fn filter_specialized_impls(
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => {}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
@@ -1034,7 +1034,7 @@ fn try_assemble_bounds_via_registered_opaques<G: GoalKind<D>>(
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => vec![],
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
};
|
||||
|
||||
if opaque_types.is_empty() {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use rustc_type_ir::lang_items::SolverTraitLangItem;
|
||||
use rustc_type_ir::solve::inspect::ProbeKind;
|
||||
use rustc_type_ir::solve::{AliasBoundKind, SizedTraitKind};
|
||||
use rustc_type_ir::{self as ty, Interner, TypingMode, Unnormalized, elaborate};
|
||||
use rustc_type_ir::{self as ty, Interner, Unnormalized, elaborate};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::assembly::{Candidate, structural_traits};
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
use rustc_type_ir::relate::Relate;
|
||||
use rustc_type_ir::relate::solver_relating::RelateExt;
|
||||
use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind};
|
||||
use rustc_type_ir::solve::{AccessedOpaques, AccessedOpaquesInfo, MaybeInfo, OpaqueTypesJank};
|
||||
use rustc_type_ir::solve::{AccessedOpaques, MaybeInfo, OpaqueTypesJank};
|
||||
use rustc_type_ir::{
|
||||
self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
|
||||
TypingMode,
|
||||
};
|
||||
use tracing::{Level, debug, instrument, trace, warn};
|
||||
use tracing::{debug, instrument, trace, warn};
|
||||
|
||||
use super::has_only_region_constraints;
|
||||
use crate::canonical::{
|
||||
@@ -272,7 +272,7 @@ impl<'a, D, I> EvalCtxt<'a, D>
|
||||
I: Interner,
|
||||
{
|
||||
pub(super) fn typing_mode(&self) -> TypingMode<I> {
|
||||
self.delegate.typing_mode()
|
||||
self.delegate.typing_mode_raw()
|
||||
}
|
||||
|
||||
/// Computes the `PathKind` for the step from the current goal to the
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir::inherent::*;
|
||||
pub use rustc_type_ir::solve::*;
|
||||
use rustc_type_ir::{self as ty, Interner, TyVid, TypingMode};
|
||||
use rustc_type_ir::{self as ty, Interner, MayBeErased, TyVid, TypingMode};
|
||||
use tracing::instrument;
|
||||
|
||||
pub use self::eval_ctxt::{
|
||||
@@ -368,7 +368,7 @@ fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool {
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => {
|
||||
!def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id))
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
|
||||
use rustc_type_ir::{
|
||||
self as ty, FieldInfo, Interner, NormalizesTo, PredicateKind, Unnormalized, Upcast as _,
|
||||
self as ty, FieldInfo, Interner, MayBeErased, NormalizesTo, PredicateKind, Unnormalized,
|
||||
Upcast as _,
|
||||
};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -311,7 +312,7 @@ fn consider_impl_candidate(
|
||||
return ecx
|
||||
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
};
|
||||
}
|
||||
Err(guar) => return error_response(ecx, guar),
|
||||
@@ -349,7 +350,7 @@ fn consider_impl_candidate(
|
||||
);
|
||||
return then(ecx, Certainty::Yes);
|
||||
}
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
} else {
|
||||
return error_response(ecx, cx.delay_bug("missing item"));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::solve::GoalSource;
|
||||
use rustc_type_ir::{self as ty, Interner, TypingMode, fold_regions};
|
||||
use rustc_type_ir::{self as ty, Interner, MayBeErased, TypingMode, fold_regions};
|
||||
|
||||
use crate::delegate::SolverDelegate;
|
||||
use crate::solve::{Certainty, EvalCtxt, Goal, QueryResult};
|
||||
@@ -97,7 +97,7 @@ pub(super) fn normalize_opaque_type(
|
||||
TypingMode::Coherence
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => unreachable!(),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ pub(super) fn normalize_opaque_type(
|
||||
self.eq(goal.param_env, expected, actual)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
|
||||
use rustc_type_ir::data_structures::ensure_sufficient_stack;
|
||||
use rustc_type_ir::search_graph::{self, PathKind};
|
||||
use rustc_type_ir::solve::{
|
||||
AccessedOpaques, AccessedOpaquesInfo, CanonicalInput, Certainty, NoSolution, QueryResult,
|
||||
};
|
||||
use rustc_type_ir::{Interner, TypingMode};
|
||||
use rustc_type_ir::solve::{AccessedOpaques, CanonicalInput, Certainty, NoSolution, QueryResult};
|
||||
use rustc_type_ir::{Interner, MayBeErased, TypingMode};
|
||||
|
||||
use crate::canonical::response_no_constraints_raw;
|
||||
use crate::delegate::SolverDelegate;
|
||||
@@ -72,7 +70,7 @@ fn initial_provisional_result(
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => (Err(NoSolution), AccessedOpaques::default()),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
SizedTraitKind,
|
||||
};
|
||||
use rustc_type_ir::{
|
||||
self as ty, FieldInfo, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
|
||||
TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _, elaborate,
|
||||
self as ty, FieldInfo, Interner, MayBeErased, Movability, PredicatePolarity, TraitPredicate,
|
||||
TraitRef, TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _, elaborate,
|
||||
};
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
@@ -1396,7 +1396,7 @@ pub(super) fn unsound_prefer_builtin_dyn_impl(&mut self, candidates: &mut Vec<Ca
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => {}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
|
||||
if candidates
|
||||
@@ -1575,7 +1575,7 @@ fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>,
|
||||
| TypingMode::PostAnalysis
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::Certainty;
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
|
||||
self, MayBeErased, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
|
||||
};
|
||||
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
|
||||
|
||||
@@ -288,7 +288,7 @@ fn fetch_eligible_assoc_item(
|
||||
// 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() {
|
||||
match self.typing_mode_raw() {
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
@@ -297,7 +297,7 @@ fn fetch_eligible_assoc_item(
|
||||
let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref);
|
||||
!poly_trait_ref.still_further_specializable()
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ fn drain_stalled_obligations_for_coroutines(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
) -> PredicateObligations<'tcx> {
|
||||
let stalled_coroutines = match infcx.typing_mode() {
|
||||
let stalled_coroutines = match infcx.typing_mode_raw().assert_not_erased() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
defining_opaque_types_and_generators
|
||||
}
|
||||
@@ -284,7 +284,6 @@ fn drain_stalled_obligations_for_coroutines(
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ }
|
||||
| TypingMode::PostAnalysis => return Default::default(),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
};
|
||||
|
||||
if stalled_coroutines.is_empty() {
|
||||
|
||||
@@ -25,7 +25,7 @@ pub fn evaluate_host_effect_obligation<'tcx>(
|
||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||
obligation: &HostEffectObligation<'tcx>,
|
||||
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
|
||||
if selcx.infcx.typing_mode().is_coherence() {
|
||||
if selcx.typing_mode().is_coherence() {
|
||||
span_bug!(
|
||||
obligation.cause.span,
|
||||
"should not select host obligation in old solver in intercrate mode"
|
||||
|
||||
@@ -171,7 +171,7 @@ fn drain_stalled_obligations_for_coroutines(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
) -> PredicateObligations<'tcx> {
|
||||
let stalled_coroutines = match infcx.typing_mode() {
|
||||
let stalled_coroutines = match infcx.typing_mode_raw().assert_not_erased() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
defining_opaque_types_and_generators
|
||||
}
|
||||
@@ -179,7 +179,6 @@ fn drain_stalled_obligations_for_coroutines(
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ }
|
||||
| TypingMode::PostAnalysis => return Default::default(),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
};
|
||||
|
||||
if stalled_coroutines.is_empty() {
|
||||
@@ -879,7 +878,7 @@ fn process_trait_obligation(
|
||||
stalled_on: &mut Vec<TyOrConstInferVar>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let infcx = self.selcx.infcx;
|
||||
if obligation.predicate.is_global() && !infcx.typing_mode().is_coherence() {
|
||||
if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
if infcx.predicate_must_hold_considering_regions(obligation) {
|
||||
@@ -933,7 +932,7 @@ fn process_projection_obligation(
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let tcx = self.selcx.tcx();
|
||||
let infcx = self.selcx.infcx;
|
||||
if obligation.predicate.is_global() && !infcx.typing_mode().is_coherence() {
|
||||
if obligation.predicate.is_global() && !self.selcx.typing_mode().is_coherence() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
if infcx.predicate_must_hold_considering_regions(obligation) {
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::{
|
||||
self, AliasTerm, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||
TypeVisitableExt, TypingMode, Unnormalized,
|
||||
self, AliasTerm, MayBeErased, Term, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
|
||||
TypeVisitable, TypeVisitableExt, TypingMode, Unnormalized,
|
||||
};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
@@ -138,14 +138,14 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
|
||||
// Opaques are treated as rigid outside of `TypingMode::PostAnalysis`,
|
||||
// so we can ignore those.
|
||||
match infcx.typing_mode() {
|
||||
match infcx.typing_mode_raw() {
|
||||
// FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. } => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
|
||||
TypingMode::PostAnalysis => {}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
|
||||
}
|
||||
|
||||
value.has_type_flags(flags)
|
||||
@@ -411,7 +411,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match data.kind {
|
||||
ty::Opaque { def_id } => {
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.selcx.infcx.typing_mode() {
|
||||
match self.selcx.typing_mode() {
|
||||
// FIXME(#132279): We likely want to reveal opaques during post borrowck analysis
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
@@ -436,7 +436,6 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.depth -= 1;
|
||||
folded_ty
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -950,7 +950,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() {
|
||||
match selcx.typing_mode() {
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
@@ -969,7 +969,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
selcx.infcx.resolve_vars_if_possible(trait_ref);
|
||||
!poly_trait_ref.still_further_specializable()
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
let res = match data.kind {
|
||||
ty::Opaque { def_id } => {
|
||||
// Only normalize `impl Trait` outside of type inference, usually in codegen.
|
||||
match self.infcx.typing_mode() {
|
||||
match self.infcx.typing_mode_raw().assert_not_erased() {
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
@@ -253,7 +253,6 @@ fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
self.anon_depth -= 1;
|
||||
folded_ty?
|
||||
}
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ fn assemble_candidates_from_auto_impls(
|
||||
//
|
||||
// Note that this is only sound as projection candidates of opaque types
|
||||
// are always applicable for auto traits.
|
||||
} else if self.infcx.typing_mode().is_coherence() {
|
||||
} else if self.typing_mode().is_coherence() {
|
||||
// We do not emit auto trait candidates for opaque types in coherence.
|
||||
// Doing so can result in weird dependency cycles.
|
||||
candidates.ambiguous = true;
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
use rustc_middle::ty::error::TypeErrorToStringExt;
|
||||
use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
|
||||
use rustc_middle::ty::{
|
||||
self, CandidatePreferenceMode, DeepRejectCtxt, GenericArgsRef, PolyProjectionPredicate,
|
||||
SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, TypingMode, Unnormalized, Upcast,
|
||||
elaborate, may_use_unstable_feature,
|
||||
self, CandidatePreferenceMode, CantBeErased, DeepRejectCtxt, GenericArgsRef,
|
||||
PolyProjectionPredicate, SizedTraitKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
|
||||
TypingMode, Unnormalized, Upcast, elaborate, may_use_unstable_feature,
|
||||
};
|
||||
use rustc_next_trait_solver::solve::AliasBoundKind;
|
||||
use rustc_span::Symbol;
|
||||
@@ -199,6 +199,10 @@ pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn typing_mode(&self) -> TypingMode<'tcx, CantBeErased> {
|
||||
self.infcx.typing_mode_raw().assert_not_erased()
|
||||
}
|
||||
|
||||
pub fn with_query_mode(
|
||||
infcx: &'cx InferCtxt<'tcx>,
|
||||
query_mode: TraitQueryMode,
|
||||
@@ -210,7 +214,7 @@ pub fn with_query_mode(
|
||||
/// 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!(self.infcx.typing_mode().is_coherence());
|
||||
assert!(self.typing_mode().is_coherence());
|
||||
assert!(self.intercrate_ambiguity_causes.is_none());
|
||||
|
||||
self.intercrate_ambiguity_causes = Some(FxIndexSet::default());
|
||||
@@ -223,7 +227,7 @@ pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
|
||||
pub fn take_intercrate_ambiguity_causes(
|
||||
&mut self,
|
||||
) -> FxIndexSet<IntercrateAmbiguityCause<'tcx>> {
|
||||
assert!(self.infcx.typing_mode().is_coherence());
|
||||
assert!(self.typing_mode().is_coherence());
|
||||
|
||||
self.intercrate_ambiguity_causes.take().unwrap_or_default()
|
||||
}
|
||||
@@ -1022,7 +1026,7 @@ fn evaluate_trait_predicate_recursively<'o>(
|
||||
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
||||
mut obligation: PolyTraitObligation<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
if !self.infcx.typing_mode().is_coherence()
|
||||
if !self.typing_mode().is_coherence()
|
||||
&& obligation.is_global()
|
||||
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.has_param())
|
||||
{
|
||||
@@ -1479,13 +1483,12 @@ fn filter_reservation_impls(
|
||||
|
||||
fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> {
|
||||
let obligation = &stack.obligation;
|
||||
match self.infcx.typing_mode() {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Coherence => {}
|
||||
TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => return Ok(()),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
|
||||
debug!("is_knowable()");
|
||||
@@ -1513,7 +1516,7 @@ fn can_use_global_caches(
|
||||
return false;
|
||||
}
|
||||
|
||||
match self.infcx.typing_mode() {
|
||||
match self.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"
|
||||
@@ -1545,7 +1548,6 @@ fn can_use_global_caches(
|
||||
// FIXME(#132279): This is still incorrect as we treat opaque types
|
||||
// and default associated items differently between these two modes.
|
||||
TypingMode::PostAnalysis => true,
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2567,7 +2569,7 @@ fn match_impl(
|
||||
nested_obligations.extend(obligations);
|
||||
|
||||
if impl_trait_header.polarity == ty::ImplPolarity::Reservation
|
||||
&& !self.infcx.typing_mode().is_coherence()
|
||||
&& !self.typing_mode().is_coherence()
|
||||
{
|
||||
debug!("reservation impls only apply in intercrate mode");
|
||||
return Err(());
|
||||
@@ -2906,7 +2908,7 @@ fn impl_or_trait_obligations(
|
||||
}
|
||||
|
||||
pub(super) fn should_stall_coroutine(&self, def_id: DefId) -> bool {
|
||||
match self.infcx.typing_mode() {
|
||||
match self.typing_mode() {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
|
||||
def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
|
||||
}
|
||||
@@ -2914,7 +2916,6 @@ pub(super) fn should_stall_coroutine(&self, def_id: DefId) -> bool {
|
||||
| TypingMode::PostAnalysis
|
||||
| TypingMode::Borrowck { defining_opaque_types: _ }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false,
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError};
|
||||
use rustc_middle::ty::{
|
||||
self, ClosureKind, GenericArgsRef, Instance, PseudoCanonicalInput, TyCtxt, TypeVisitableExt,
|
||||
Unnormalized,
|
||||
self, ClosureKind, GenericArgsRef, Instance, MayBeErased, PseudoCanonicalInput, TyCtxt,
|
||||
TypeVisitableExt, Unnormalized,
|
||||
};
|
||||
use rustc_span::sym;
|
||||
use rustc_trait_selection::traits;
|
||||
@@ -161,7 +161,7 @@ fn resolve_associated_item<'tcx>(
|
||||
| ty::TypingMode::Borrowck { .. }
|
||||
| ty::TypingMode::PostBorrowckAnalysis { .. } => false,
|
||||
ty::TypingMode::PostAnalysis => !trait_ref.still_further_specializable(),
|
||||
ty::TypingMode::ErasedNotCoherence => todo!(),
|
||||
ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
|
||||
}
|
||||
};
|
||||
if !eligible {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use core::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use derive_where::derive_where;
|
||||
@@ -11,6 +12,26 @@
|
||||
use crate::solve::VisibleForLeakCheck;
|
||||
use crate::{self as ty, Interner, TyVid};
|
||||
|
||||
mod private {
|
||||
pub trait Sealed {}
|
||||
|
||||
impl Sealed for super::CantBeErased {}
|
||||
impl Sealed for super::MayBeErased {}
|
||||
}
|
||||
pub trait TypingModeErasedStatus: private::Sealed + Clone + Copy + Hash + fmt::Debug {}
|
||||
|
||||
#[derive(Clone, Copy, Hash, Debug)]
|
||||
pub enum CantBeErased {}
|
||||
#[derive(Clone, Copy, Hash, Debug)]
|
||||
#[cfg_attr(
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
|
||||
)]
|
||||
pub struct MayBeErased;
|
||||
|
||||
impl TypingModeErasedStatus for CantBeErased {}
|
||||
impl TypingModeErasedStatus for MayBeErased {}
|
||||
|
||||
/// The current typing mode of an inference context. We unfortunately have some
|
||||
/// slightly different typing rules depending on the current context. See the
|
||||
/// doc comment for each variant for how and why they are used.
|
||||
@@ -42,8 +63,7 @@
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext)
|
||||
)]
|
||||
#[cfg_attr(feature = "nightly", rustc_must_match_exhaustively)]
|
||||
pub enum TypingMode<I: Interner> {
|
||||
pub enum TypingMode<I: Interner, S: TypingModeErasedStatus = MayBeErased> {
|
||||
/// When checking whether impls overlap, we check whether any obligations
|
||||
/// are guaranteed to never hold when unifying the impls. This requires us
|
||||
/// to be complete: we must never fail to prove something which may actually
|
||||
@@ -121,7 +141,7 @@ pub enum TypingMode<I: Interner> {
|
||||
/// rerun in the original typing mode.
|
||||
///
|
||||
/// `TypingMode::Coherence` is not replaced by this and is always kept as-is.
|
||||
ErasedNotCoherence,
|
||||
ErasedNotCoherence(S),
|
||||
}
|
||||
|
||||
/// We want to highly discourage using equality checks on typing modes.
|
||||
@@ -134,7 +154,7 @@ pub enum TypingMode<I: Interner> {
|
||||
feature = "nightly",
|
||||
derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext)
|
||||
)]
|
||||
pub struct TypingModeEqWrapper<I: Interner>(pub TypingMode<I>);
|
||||
pub struct TypingModeEqWrapper<I: Interner>(pub TypingMode<I, MayBeErased>);
|
||||
|
||||
impl<I: Interner> Hash for TypingModeEqWrapper<I> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
@@ -159,14 +179,17 @@ fn eq(&self, other: &Self) -> bool {
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types: r },
|
||||
) => l == r,
|
||||
(TypingMode::PostAnalysis, TypingMode::PostAnalysis) => true,
|
||||
(TypingMode::ErasedNotCoherence, TypingMode::ErasedNotCoherence) => true,
|
||||
(
|
||||
TypingMode::ErasedNotCoherence(MayBeErased),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased),
|
||||
) => true,
|
||||
(
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis
|
||||
| TypingMode::ErasedNotCoherence,
|
||||
| TypingMode::ErasedNotCoherence(MayBeErased),
|
||||
_,
|
||||
) => false,
|
||||
}
|
||||
@@ -175,7 +198,7 @@ fn eq(&self, other: &Self) -> bool {
|
||||
|
||||
impl<I: Interner> Eq for TypingModeEqWrapper<I> {}
|
||||
|
||||
impl<I: Interner> TypingMode<I> {
|
||||
impl<I: Interner, S: TypingModeErasedStatus> TypingMode<I, S> {
|
||||
/// There are a bunch of places in the compiler where we single out `Coherence`,
|
||||
/// and alter behavior. We'd like to *always* match on `TypingMode` exhaustively,
|
||||
/// but not having this method leads to a bunch of noisy code.
|
||||
@@ -188,10 +211,37 @@ pub fn is_coherence(&self) -> bool {
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis
|
||||
| TypingMode::ErasedNotCoherence => false,
|
||||
| TypingMode::ErasedNotCoherence(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypingMode<I, MayBeErased> {
|
||||
/// Only call this when you're sure you're outside the next trait solver!
|
||||
/// That means either not in the trait solver, or in code that is old-solver only.
|
||||
///
|
||||
/// See the comment on `InferCtxt::typing_mode_raw`
|
||||
pub fn assert_not_erased(self) -> TypingMode<I, CantBeErased> {
|
||||
match self {
|
||||
TypingMode::Coherence => TypingMode::Coherence,
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators }
|
||||
}
|
||||
TypingMode::Borrowck { defining_opaque_types } => {
|
||||
TypingMode::Borrowck { defining_opaque_types }
|
||||
}
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types }
|
||||
}
|
||||
TypingMode::PostAnalysis => TypingMode::PostAnalysis,
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => panic!(
|
||||
"Called `assert_not_erased` from a place that can be called by the trait solver in `TypingMode::ErasedNotCoherence`. `TypingMode` is `ErasedNotCoherence` in a place where that should be impossible"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> TypingMode<I, CantBeErased> {
|
||||
/// Analysis outside of a body does not define any opaque types.
|
||||
pub fn non_body_analysis() -> TypingMode<I> {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators: Default::default() }
|
||||
@@ -234,6 +284,24 @@ pub fn post_borrowck_analysis(cx: I, body_def_id: I::LocalDefId) -> TypingMode<I
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner> From<TypingMode<I, CantBeErased>> for TypingMode<I, MayBeErased> {
|
||||
fn from(value: TypingMode<I, CantBeErased>) -> Self {
|
||||
match value {
|
||||
TypingMode::Coherence => TypingMode::Coherence,
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators } => {
|
||||
TypingMode::Analysis { defining_opaque_types_and_generators }
|
||||
}
|
||||
TypingMode::Borrowck { defining_opaque_types } => {
|
||||
TypingMode::Borrowck { defining_opaque_types }
|
||||
}
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types }
|
||||
}
|
||||
TypingMode::PostAnalysis => TypingMode::PostAnalysis,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "type_ir_infer_ctxt_like")]
|
||||
pub trait InferCtxtLike: Sized {
|
||||
type Interner: Interner;
|
||||
@@ -249,7 +317,7 @@ fn next_trait_solver(&self) -> bool {
|
||||
|
||||
fn disable_trait_solver_fast_paths(&self) -> bool;
|
||||
|
||||
fn typing_mode(&self) -> TypingMode<Self::Interner>;
|
||||
fn typing_mode_raw(&self) -> TypingMode<Self::Interner>;
|
||||
|
||||
fn universe(&self) -> ty::UniverseIndex;
|
||||
fn create_next_universe(&self) -> ty::UniverseIndex;
|
||||
@@ -425,7 +493,7 @@ pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
|
||||
// Note: `feature_bound_holds_in_crate` does not consider a feature to be enabled
|
||||
// if we are in std/core even if there is a corresponding `feature` attribute on the crate.
|
||||
|
||||
match infcx.typing_mode() {
|
||||
match infcx.typing_mode_raw().assert_not_erased() {
|
||||
TypingMode::Coherence
|
||||
| TypingMode::Analysis { .. }
|
||||
| TypingMode::Borrowck { .. }
|
||||
@@ -433,6 +501,5 @@ pub fn may_use_unstable_feature<'a, I: Interner, Infcx>(
|
||||
infcx.cx().features().feature_bound_holds_in_crate(symbol)
|
||||
}
|
||||
TypingMode::PostAnalysis => true,
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ pub fn super_combine_tys<Infcx, I, R>(
|
||||
(ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }), _)
|
||||
| (_, ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })) => {
|
||||
assert!(!infcx.next_trait_solver());
|
||||
match infcx.typing_mode() {
|
||||
match infcx.typing_mode_raw().assert_not_erased() {
|
||||
// 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
|
||||
@@ -144,7 +144,7 @@ pub fn super_combine_tys<Infcx, I, R>(
|
||||
| TypingMode::Borrowck { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => structurally_relate_tys(relation, a, b),
|
||||
TypingMode::ErasedNotCoherence => todo!(),
|
||||
TypingMode::ErasedNotCoherence(MayBeErased) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user