Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b90709a
add higher ranked assumptions v2 flag
BoxyUwU Apr 28, 2026
a4649b4
new region constraint representation
BoxyUwU Apr 28, 2026
2bee929
compute and track assumptions on entered binders
BoxyUwU Apr 28, 2026
48a0966
produce new region constraints
BoxyUwU Apr 28, 2026
045c85f
destructure in root universe
BoxyUwU Apr 27, 2026
dd9d787
rewrite region constraints to smaller universes
BoxyUwU Apr 28, 2026
e2007e8
s/solve/solver typo
BoxyUwU May 1, 2026
2b11dd5
readd comments to enter_forall
BoxyUwU May 1, 2026
9d6f728
FIXME for fast paths
BoxyUwU May 1, 2026
c31f98a
incorrect binder handling FIXME
BoxyUwU May 1, 2026
c3e191b
better where clause
BoxyUwU May 1, 2026
7568093
AliasTyOutlivesViaEnv
BoxyUwU May 1, 2026
f68d07c
s/solve/solver typo
BoxyUwU May 1, 2026
b77217a
AliasTyOutlivesViaEnv
BoxyUwU May 1, 2026
5c5f53b
handle wf(?x) assumptions
BoxyUwU May 1, 2026
4d64eb3
use Assumptions::new
BoxyUwU May 1, 2026
4366098
unreused MaxUniverse visitor
BoxyUwU May 1, 2026
fe6a810
region_assumptions_from_term
BoxyUwU May 1, 2026
7284693
s/universe assumptions/placeholder assumptions
BoxyUwU May 1, 2026
522eb7b
match not iflet
BoxyUwU May 1, 2026
07f87d2
x fmt
BoxyUwU May 1, 2026
52153f0
make region constraints in responses be an enum of old/new style
BoxyUwU May 1, 2026
8be3f42
eagerly_handle_placeholders return type fix
BoxyUwU May 1, 2026
c2ce7bf
eval_ctxt/solver_region_constraints.rs
BoxyUwU May 1, 2026
038ae08
eval_ctxt/solver_region_constraints import nits
BoxyUwU May 1, 2026
42dbf64
erased regions are cause for alarm
BoxyUwU May 1, 2026
2135f41
simpler evaluation of solver region constraints
BoxyUwU May 1, 2026
4e5e197
better diagnostics (?)
BoxyUwU May 1, 2026
2c25e21
better externregionconstraint thingy
BoxyUwU May 1, 2026
d4b3518
diagnostics finish
BoxyUwU May 4, 2026
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
22 changes: 22 additions & 0 deletions compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.next_trait_solver
}

fn higher_ranked_assumptions_v2(&self) -> bool {
self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions_v2
}

fn typing_mode(&self) -> ty::TypingMode<'tcx> {
self.typing_mode()
}
Expand All @@ -34,6 +38,12 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.create_next_universe()
}

fn get_solve_region_constraint(
Comment thread
BoxyUwU marked this conversation as resolved.
Outdated
&self,
) -> rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>> {
self.inner.borrow().solver_region_constraint_storage.get_constraint()
}

fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> {
match self.try_resolve_ty_var(vid) {
Err(universe) => Some(universe),
Expand Down Expand Up @@ -272,6 +282,18 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
);
}

fn register_solver_region_constraint(
&self,
c: rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>,
) {
let mut inner = self.inner.borrow_mut();
use rustc_data_structures::undo_log::UndoLogs;

use crate::infer::UndoLog;
inner.undo_log.push(UndoLog::PushSolverRegionConstraint);
inner.solver_region_constraint_storage.push(c);
}

fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
}
Expand Down
47 changes: 47 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ pub struct InferCtxtInner<'tcx> {
/// region constraints would've been added.
region_constraint_storage: Option<RegionConstraintStorage<'tcx>>,

/// Used by the next solver when `-Zhigher-ranked-assumptions=v2` is set.
solver_region_constraint_storage: SolverRegionConstraintStorage<'tcx>,

/// A set of constraints that regionck must validate.
///
/// Each constraint has the form `T:'a`, meaning "some type `T` must
Expand Down Expand Up @@ -170,6 +173,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
float_unification_storage: Default::default(),
float_origin_origin_storage: Default::default(),
region_constraint_storage: Some(Default::default()),
solver_region_constraint_storage: SolverRegionConstraintStorage::new(),
region_obligations: Default::default(),
region_assumptions: Default::default(),
hir_typeck_potentially_region_dependent_goals: Default::default(),
Expand Down Expand Up @@ -1721,3 +1725,46 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
}

type SolverRegionConstraint<'tcx> =
rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>>;

#[derive(Clone, Debug)]
struct SolverRegionConstraintStorage<'tcx>(SolverRegionConstraint<'tcx>);

impl<'tcx> SolverRegionConstraintStorage<'tcx> {
fn new() -> Self {
SolverRegionConstraintStorage(SolverRegionConstraint::And(Box::new([])))
}

fn get_constraint(&self) -> SolverRegionConstraint<'tcx> {
self.0.clone()
}

fn pop(&mut self) -> Option<SolverRegionConstraint<'tcx>> {
match &mut self.0 {
SolverRegionConstraint::And(and) => {
let mut and = core::mem::take(and).into_iter().collect::<Vec<_>>();
let popped = and.pop()?;
self.0 = SolverRegionConstraint::And(and.into_boxed_slice());
Some(popped)
}
_ => unreachable!(),
}
}

#[instrument(level = "debug")]
fn push(&mut self, constraint: SolverRegionConstraint<'tcx>) {
match &mut self.0 {
SolverRegionConstraint::And(and) => {
let and = core::mem::take(and)
.into_iter()
.chain([constraint])
.collect::<Vec<_>>()
.into_boxed_slice();
self.0 = SolverRegionConstraint::And(and);
}
_ => unreachable!(),
}
}
}
9 changes: 9 additions & 0 deletions compiler/rustc_infer/src/infer/snapshot/undo_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) enum UndoLog<'tcx> {
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
ProjectionCache(traits::UndoLog<'tcx>),
PushTypeOutlivesConstraint,
PushSolverRegionConstraint,
PushRegionAssumption,
PushHirTypeckPotentiallyRegionDependentGoal,
}
Expand Down Expand Up @@ -77,6 +78,14 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
self.region_constraint_storage.as_mut().unwrap().unification_table.reverse(undo)
}
UndoLog::ProjectionCache(undo) => self.projection_cache.reverse(undo),
UndoLog::PushSolverRegionConstraint => {
let popped = self.solver_region_constraint_storage.pop();
assert_matches!(
popped,
Some(_),
"pushed solver region constraint but could not pop it"
);
}
UndoLog::PushTypeOutlivesConstraint => {
let popped = self.region_obligations.pop();
assert_matches!(popped, Some(_), "pushed region constraint but could not pop it");
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/traits/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
}

Ok(FallibleTypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
solver_region_constraint: self
.solver_region_constraint
.clone()
.try_fold_with(folder)?,
region_constraints: self.region_constraints.clone().try_fold_with(folder)?,
opaque_types: self
.opaque_types
Expand All @@ -70,6 +74,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> {
}

TypeFolder::cx(folder).mk_external_constraints(ExternalConstraintsData {
solver_region_constraint: self.solver_region_constraint.clone().fold_with(folder),
region_constraints: self.region_constraints.clone().fold_with(folder),
opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(),
normalization_nested_goals: self.normalization_nested_goals.clone().fold_with(folder),
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_next_trait_solver/src/canonical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,14 @@ where

unify_query_var_values(delegate, param_env, &original_values, var_values, span);

let ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals } =
&*external_constraints;
let ExternalConstraintsData {
solver_region_constraint,
region_constraints,
opaque_types,
normalization_nested_goals,
} = &*external_constraints;

delegate.register_solver_region_constraint(solver_region_constraint.clone());
register_region_constraints(delegate, region_constraints, span);
register_new_opaque_types(delegate, opaque_types, span);

Expand Down
35 changes: 28 additions & 7 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
use std::mem;
use std::ops::ControlFlow;

use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
#[cfg(feature = "nightly")]
use rustc_macros::HashStable_NoContext;
use rustc_type_ir::data_structures::{HashMap, HashSet};
use rustc_type_ir::ClauseKind::*;
use rustc_type_ir::data_structures::{HashMap, HashSet, IndexMap};
use rustc_type_ir::inherent::*;
use rustc_type_ir::outlives::Component;
use rustc_type_ir::region_constraint::RegionConstraint;
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::OpaqueTypesJank;
use rustc_type_ir::{
self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
TypingMode,
self as ty, AliasTy, Binder, CanonicalVarValues, InferCtxtLike, Interner, OutlivesPredicate,
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt, TypeVisitor, TypingMode, UniverseIndex,
};
use tracing::{debug, instrument, trace};

Expand Down Expand Up @@ -1092,6 +1096,14 @@ where
args
}

pub(super) fn higher_ranked_assumptions_v2(&self) -> bool {
self.delegate.higher_ranked_assumptions_v2()
}

pub(super) fn register_solver_region_constraint(&self, c: RegionConstraint<I>) {
self.delegate.register_solver_region_constraint(c);
}

pub(super) fn register_ty_outlives(&self, ty: I::Ty, lt: I::Region) {
self.delegate.register_ty_outlives(ty, lt, self.origin_span);
}
Expand Down Expand Up @@ -1287,8 +1299,11 @@ where
return Ok(self.make_ambiguous_response_no_constraints(cause, opaque_types_jank));
}

let external_constraints =
self.compute_external_query_constraints(certainty, normalization_nested_goals);
let external_constraints = self.compute_external_query_constraints(
certainty,
normalization_nested_goals,
RegionConstraint::new_true(),
);
let (var_values, mut external_constraints) =
eager_resolve_vars(self.delegate, (self.var_values, external_constraints));

Expand Down Expand Up @@ -1340,6 +1355,7 @@ where
&self,
certainty: Certainty,
normalization_nested_goals: NestedNormalizationGoals<I>,
solver_region_constraint: RegionConstraint<I>,
) -> ExternalConstraintsData<I> {
// We only return region constraints once the certainty is `Yes`. This
// is necessary as we may drop nested goals on ambiguity, which may result
Expand All @@ -1363,7 +1379,12 @@ where
.delegate
.clone_opaque_types_added_since(self.initial_opaque_types_storage_num_entries);

ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
ExternalConstraintsData {
solver_region_constraint,
region_constraints,
Comment thread
BoxyUwU marked this conversation as resolved.
Outdated
opaque_types,
normalization_nested_goals,
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_next_trait_solver/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,21 @@ fn has_no_inference_or_external_constraints<I: Interner>(
response: ty::Canonical<I, Response<I>>,
) -> bool {
let ExternalConstraintsData {
ref solver_region_constraint,
ref region_constraints,
ref opaque_types,
ref normalization_nested_goals,
} = *response.value.external_constraints;
response.value.var_values.is_identity()
&& solver_region_constraint.is_true()
&& region_constraints.is_empty()
&& opaque_types.is_empty()
&& normalization_nested_goals.is_empty()
}

fn has_only_region_constraints<I: Interner>(response: ty::Canonical<I, Response<I>>) -> bool {
let ExternalConstraintsData {
solver_region_constraint: _,
region_constraints: _,
ref opaque_types,
ref normalization_nested_goals,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2355,6 +2355,8 @@ options! {
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),
higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED],
"allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"),
higher_ranked_assumptions_v2: bool = (false, parse_bool, [TRACKED],
"allow deducing higher-ranked outlives assumptions from all binders (`for<'a>`)"),
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],
"hint that most of this crate will go unused, to minimize work for uncalled functions"),
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_type_ir/src/infer_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ pub trait InferCtxtLike: Sized {
fn universe(&self) -> ty::UniverseIndex;
fn create_next_universe(&self) -> ty::UniverseIndex;

fn higher_ranked_assumptions_v2(&self) -> bool {
false
}

fn get_solve_region_constraint(
&self,
) -> crate::region_constraint::RegionConstraint<Self::Interner>;

fn universe_of_ty(&self, ty: ty::TyVid) -> Option<ty::UniverseIndex>;
fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex>;
fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex>;
Expand Down Expand Up @@ -333,6 +341,11 @@ pub trait InferCtxtLike: Sized {
span: <Self::Interner as Interner>::Span,
);

fn register_solver_region_constraint(
&self,
c: crate::region_constraint::RegionConstraint<Self::Interner>,
);

fn register_ty_outlives(
&self,
ty: <Self::Interner as Interner>::Ty,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_type_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod ir_print;
pub mod lang_items;
pub mod lift;
pub mod outlives;
pub mod region_constraint;
Copy link
Copy Markdown
Member Author

@BoxyUwU BoxyUwU Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird module name

View changes since the review

pub mod relate;
pub mod search_graph;
pub mod solve;
Expand Down
Loading