support revealing defined opaque post borrowck

This commit is contained in:
lcnr 2024-11-26 16:01:08 +01:00
parent 18e2253e79
commit 34a8c2dbba
21 changed files with 226 additions and 58 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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