support revealing defined opaque post borrowck
This commit is contained in:
parent
18e2253e79
commit
34a8c2dbba
21 changed files with 226 additions and 58 deletions
|
@ -339,7 +339,9 @@ where
|
|||
|
||||
match self.typing_mode() {
|
||||
TypingMode::Coherence => {}
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => {
|
||||
TypingMode::Analysis { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => {
|
||||
self.discard_impls_shadowed_by_env(goal, &mut candidates);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -644,6 +644,12 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn next_region_var(&mut self) -> I::Region {
|
||||
let region = self.delegate.next_region_infer();
|
||||
self.inspect.add_var_value(region);
|
||||
region
|
||||
}
|
||||
|
||||
pub(super) fn next_ty_infer(&mut self) -> I::Ty {
|
||||
let ty = self.delegate.next_ty_infer();
|
||||
self.inspect.add_var_value(ty);
|
||||
|
|
|
@ -23,7 +23,7 @@ mod trait_goals;
|
|||
|
||||
use rustc_type_ir::inherent::*;
|
||||
pub use rustc_type_ir::solve::*;
|
||||
use rustc_type_ir::{self as ty, Interner};
|
||||
use rustc_type_ir::{self as ty, Interner, TypingMode};
|
||||
use tracing::instrument;
|
||||
|
||||
pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt};
|
||||
|
@ -321,6 +321,19 @@ where
|
|||
Ok(ct)
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool {
|
||||
match self.typing_mode() {
|
||||
// Opaques are never rigid outside of analysis mode.
|
||||
TypingMode::Coherence | TypingMode::PostAnalysis => false,
|
||||
// During analysis, opaques are rigid unless they may be defined by
|
||||
// the current body.
|
||||
TypingMode::Analysis { defining_opaque_types: non_rigid_opaques }
|
||||
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => {
|
||||
!def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn response_no_constraints_raw<I: Interner>(
|
||||
|
|
|
@ -6,7 +6,7 @@ mod weak_types;
|
|||
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::{self as ty, Interner, NormalizesTo, TypingMode, Upcast as _};
|
||||
use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
@ -71,21 +71,10 @@ where
|
|||
Ok(())
|
||||
}
|
||||
ty::AliasTermKind::OpaqueTy => {
|
||||
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.
|
||||
TypingMode::Analysis { defining_opaque_types } => {
|
||||
if rigid_alias
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| defining_opaque_types.contains(&def_id))
|
||||
{
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
if self.opaque_type_is_rigid(rigid_alias.def_id) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
}
|
||||
}
|
||||
// FIXME(generic_const_exprs): we would need to support generic consts here
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
//! behaves differently depending on the current `TypingMode`.
|
||||
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_type_ir::fold::fold_regions;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::{self as ty, Interner, TypingMode};
|
||||
|
||||
|
@ -95,6 +96,26 @@ where
|
|||
);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
TypingMode::PostBorrowckAnalysis { defined_opaque_types } => {
|
||||
let Some(def_id) = opaque_ty.def_id.as_local() else {
|
||||
return Err(NoSolution);
|
||||
};
|
||||
|
||||
if !defined_opaque_types.contains(&def_id) {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args);
|
||||
// FIXME: Actually use a proper binder here instead of relying on `ReErased`.
|
||||
//
|
||||
// This is also probably unsound or sth :shrug:
|
||||
let actual = fold_regions(cx, actual, |re, _dbi| match re.kind() {
|
||||
ty::ReErased => self.next_region_var(),
|
||||
_ => re,
|
||||
});
|
||||
self.eq(goal.param_env, expected, actual)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
TypingMode::PostAnalysis => {
|
||||
// FIXME: Add an assertion that opaque type storage is empty.
|
||||
let actual = cx.type_of(opaque_ty.def_id).instantiate(cx, opaque_ty.args);
|
||||
|
|
|
@ -69,7 +69,9 @@ where
|
|||
// it's not a real impl.
|
||||
(ty::ImplPolarity::Reservation, _) => match ecx.typing_mode() {
|
||||
TypingMode::Coherence => Certainty::AMBIGUOUS,
|
||||
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => return Err(NoSolution),
|
||||
TypingMode::Analysis { .. }
|
||||
| TypingMode::PostBorrowckAnalysis { .. }
|
||||
| TypingMode::PostAnalysis => return Err(NoSolution),
|
||||
},
|
||||
|
||||
// Impl matches polarity
|
||||
|
@ -174,20 +176,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() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
debug_assert!(ecx.opaque_type_is_rigid(opaque_ty.def_id));
|
||||
}
|
||||
|
||||
ecx.probe_and_evaluate_goal_for_constituent_tys(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue