Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));

if cfg!(debug_assertions) {
match key.typing_env.typing_mode() {
match key.typing_env.typing_mode().assert_not_erased() {
ty::TypingMode::PostAnalysis => {}
ty::TypingMode::Coherence
| ty::TypingMode::Analysis { .. }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ pub(crate) fn eval_to_valtree<'tcx>(
cid: GlobalId<'tcx>,
) -> EvalToValTreeResult<'tcx> {
if cfg!(debug_assertions) {
match typing_env.typing_mode() {
match typing_env.typing_mode().assert_not_erased() {
ty::TypingMode::PostAnalysis => {}
ty::TypingMode::Coherence
| ty::TypingMode::Analysis { .. }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// types that are not specified in the opaque type. We also use MIR bodies whose opaque types have
// already been revealed, so we'd be able to at least partially observe the hidden types anyways.
if cfg!(debug_assertions) {
match typing_env.typing_mode() {
match typing_env.typing_mode().assert_not_erased() {
TypingMode::PostAnalysis => {}
TypingMode::Coherence
| TypingMode::Analysis { .. }
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum CallStep<'tcx> {
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[tracing::instrument(skip(self))]
pub(crate) fn check_expr_call(
&self,
call_expr: &'tcx hir::Expr<'tcx>,
Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use rustc_hir_analysis::hir_ty_lowering::{
};
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;
Expand Down Expand Up @@ -161,6 +163,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

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()
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> {
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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
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 {
Expand Down
34 changes: 28 additions & 6 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rustc_middle::ty::{
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;
Expand Down Expand Up @@ -640,14 +641,34 @@ impl<'tcx> InferCtxt<'tcx> {
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`.
Expand Down Expand Up @@ -1071,7 +1092,7 @@ impl<'tcx> InferCtxt<'tcx> {
#[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,
}
Expand Down Expand Up @@ -1402,7 +1423,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() {
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
Expand All @@ -1414,6 +1435,7 @@ impl<'tcx> InferCtxt<'tcx> {
mode @ (ty::TypingMode::Coherence
| ty::TypingMode::PostBorrowckAnalysis { .. }
| ty::TypingMode::PostAnalysis) => mode,
ty::TypingMode::ErasedNotCoherence(MayBeErased) => unreachable!(),
};
ty::TypingEnv::new(param_env, typing_mode)
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_infer/src/infer/opaque_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<'tcx> InferCtxt<'tcx> {
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 },
Expand Down Expand Up @@ -229,7 +229,9 @@ 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() {
//
// 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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/relate/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, '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);
Expand Down Expand Up @@ -736,7 +736,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()
&& !self.infcx.typing_mode().is_coherence()
&& !self.infcx.typing_mode_raw().is_coherence()
&& self.in_alias
{
variable_table.union(vid, new_var_id);
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/traits/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub type QueryResult<'tcx> = ir::solve::QueryResult<TyCtxt<'tcx>>;
pub type CandidateSource<'tcx> = ir::solve::CandidateSource<TyCtxt<'tcx>>;
pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir::solve::CanonicalInput<TyCtxt<'tcx>, P>;
pub type CanonicalResponse<'tcx> = ir::solve::CanonicalResponse<TyCtxt<'tcx>>;
pub type FetchEligibleAssocItemResponse<'tcx> =
ir::solve::FetchEligibleAssocItemResponse<TyCtxt<'tcx>>;

pub type PredefinedOpaques<'tcx> = &'tcx ty::List<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>;

Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ impl<'tcx> TypingEnv<'tcx> {
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> {
Expand All @@ -1075,19 +1075,20 @@ impl<'tcx> TypingEnv<'tcx> {
/// opaque types in the `param_env`.
pub fn with_post_analysis_normalized(self, tcx: TyCtxt<'tcx>) -> TypingEnv<'tcx> {
let TypingEnv { typing_mode, param_env } = self;
match typing_mode.0 {
TypingMode::Coherence
| TypingMode::Analysis { .. }
| TypingMode::Borrowck { .. }
| TypingMode::PostBorrowckAnalysis { .. } => {}
TypingMode::PostAnalysis => 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() {
param_env
} else {
match typing_mode.0.assert_not_erased() {
TypingMode::Coherence
| TypingMode::Analysis { .. }
| TypingMode::Borrowck { .. }
| TypingMode::PostBorrowckAnalysis { .. } => {}
TypingMode::PostAnalysis => return self,
}

ParamEnv::new(tcx.reveal_opaque_types_in_bounds(param_env.caller_bounds()))
};
TypingEnv { typing_mode: TypingModeEqWrapper(TypingMode::PostAnalysis), param_env }
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use rustc_span::{DUMMY_SP, Span, Symbol, kw, sym};
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;

Expand All @@ -41,7 +43,7 @@ pub type FnSigKind<'tcx> = ir::FnSigKind<TyCtxt<'tcx>>;
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>>;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/elaborate_drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ where
let subpath = self.elaborator.field_subpath(variant_path, field_idx);
let tcx = self.tcx();

match self.elaborator.typing_env().typing_mode() {
match self.elaborator.typing_env().typing_mode().assert_not_erased() {
ty::TypingMode::PostAnalysis => {}
ty::TypingMode::Coherence
| ty::TypingMode::Analysis { .. }
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_next_trait_solver/src/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_type_ir::inherent::*;
use rustc_type_ir::relate::solver_relating::RelateExt;
use rustc_type_ir::{
self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner,
TypeFoldable, TypingModeEqWrapper,
TypeFoldable, TypingMode, TypingModeEqWrapper,
};
use tracing::instrument;

Expand Down Expand Up @@ -54,6 +54,7 @@ pub(super) fn canonicalize_goal<D, I>(
delegate: &D,
goal: Goal<I, I::Predicate>,
opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
typing_mode: TypingMode<I>,
) -> (Vec<I::GenericArg>, CanonicalInput<I, I::Predicate>)
where
D: SolverDelegate<Interner = I>,
Expand All @@ -66,10 +67,9 @@ where
predefined_opaques_in_body: delegate.cx().mk_predefined_opaques_in_body(opaque_types),
},
);
let query_input = ty::CanonicalQueryInput {
canonical,
typing_mode: TypingModeEqWrapper(delegate.typing_mode()),
};

let query_input =
ty::CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(typing_mode) };
(orig_values, query_input)
}

Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_next_trait_solver/src/delegate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::ops::Deref;

use rustc_type_ir::solve::{Certainty, Goal, NoSolution, VisibleForLeakCheck};
use rustc_type_ir::solve::{
Certainty, FetchEligibleAssocItemResponse, Goal, NoSolution, VisibleForLeakCheck,
};
use rustc_type_ir::{self as ty, InferCtxtLike, Interner, TypeFoldable};

pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
Expand Down Expand Up @@ -79,10 +81,7 @@ pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
goal_trait_ref: ty::TraitRef<Self::Interner>,
trait_assoc_def_id: <Self::Interner as Interner>::DefId,
impl_def_id: <Self::Interner as Interner>::ImplId,
) -> Result<
Option<<Self::Interner as Interner>::DefId>,
<Self::Interner as Interner>::ErrorGuaranteed,
>;
) -> FetchEligibleAssocItemResponse<Self::Interner>;

fn is_transmutable(
&self,
Expand Down
Loading
Loading