TypingMode 🤔
This commit is contained in:
@@ -6,7 +6,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::visit::TypeVisitableExt as _;
|
||||
use rustc_type_ir::{self as ty, Interner, TraitPredicate, Upcast as _, elaborate};
|
||||
use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::delegate::SolverDelegate;
|
||||
@@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
|
||||
use crate::solve::inspect::ProbeKind;
|
||||
use crate::solve::{
|
||||
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
|
||||
NoSolution, QueryResult, Reveal, SolverMode,
|
||||
NoSolution, QueryResult,
|
||||
};
|
||||
|
||||
impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
|
||||
@@ -67,9 +67,9 @@ 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.solver_mode() {
|
||||
SolverMode::Coherence => Certainty::AMBIGUOUS,
|
||||
SolverMode::Normal => return Err(NoSolution),
|
||||
(ty::ImplPolarity::Reservation, _) => match ecx.typing_mode(goal.param_env) {
|
||||
TypingMode::Coherence => Certainty::AMBIGUOUS,
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution),
|
||||
},
|
||||
|
||||
// Impl matches polarity
|
||||
@@ -167,33 +167,32 @@ where
|
||||
return result;
|
||||
}
|
||||
|
||||
// Don't call `type_of` on a local TAIT that's in the defining scope,
|
||||
// since that may require calling `typeck` on the same item we're
|
||||
// We only look into opaque types during analysis for opaque types
|
||||
// outside of their defining scope. Doing so for opaques in the
|
||||
// defining scope may require calling `typeck` on the same item we're
|
||||
// currently type checking, which will result in a fatal cycle that
|
||||
// ideally we want to avoid, since we can make progress on this goal
|
||||
// via an alias bound or a locally-inferred hidden type instead.
|
||||
//
|
||||
// Also, don't call `type_of` on a TAIT in `Reveal::All` mode, since
|
||||
// we already normalize the self type in
|
||||
// `assemble_candidates_after_normalizing_self_ty`, and we'd
|
||||
// just be registering an identical candidate here.
|
||||
//
|
||||
// We always return `Err(NoSolution)` here in `SolverMode::Coherence`
|
||||
// since we'll always register an ambiguous candidate in
|
||||
// `assemble_candidates_after_normalizing_self_ty` due to normalizing
|
||||
// the TAIT.
|
||||
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
|
||||
if matches!(goal.param_env.reveal(), Reveal::All)
|
||||
|| matches!(ecx.solver_mode(), SolverMode::Coherence)
|
||||
|| opaque_ty
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| ecx.can_define_opaque_ty(def_id))
|
||||
{
|
||||
return Err(NoSolution);
|
||||
match ecx.typing_mode(goal.param_env) {
|
||||
TypingMode::Coherence | TypingMode::PostAnalysis => {
|
||||
unreachable!("rigid opaque outside of analysis: {goal:?}");
|
||||
}
|
||||
TypingMode::Analysis { defining_opaque_types } => {
|
||||
if opaque_ty
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| defining_opaque_types.contains(&def_id))
|
||||
{
|
||||
return Err(NoSolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We want to make sure
|
||||
debug_assert!(!matches!(ecx.typing_mode(), TypingMode::Coherence));
|
||||
|
||||
ecx.probe_and_evaluate_goal_for_constituent_tys(
|
||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||
goal,
|
||||
|
||||
Reference in New Issue
Block a user