Skip to content
Open
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
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"({:?}: {:?}) due to {:?} ({:?}) ({:?})",
self.sup, self.sub, self.locations, self.variance_info, self.category,
"({:?}: {:?}) due to {:?} ({:?}) ({:?}) (span: {:?})",
self.sup, self.sub, self.locations, self.variance_info, self.category, self.span,
)
}
}
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
ConstraintCategory::OpaqueType => "opaque type ",
ConstraintCategory::ClosureUpvar(_) => "closure capture ",
ConstraintCategory::Usage => "this usage ",
ConstraintCategory::Predicate(_)
ConstraintCategory::SolverRegionConstraint(_)
| ConstraintCategory::Predicate(_)
| ConstraintCategory::Boring
| ConstraintCategory::BoringNoLocation
| ConstraintCategory::Internal
Expand Down Expand Up @@ -473,6 +474,14 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let errci = ErrorConstraintInfo { fr, outlived_fr, category, span: cause.span };

let mut diag = match (category, fr_is_local, outlived_fr_is_local) {
(ConstraintCategory::SolverRegionConstraint(span), _, _) => {
let mut d = self.dcx().struct_span_err(
span,
"unsatisfied lifetime constraint from -Zassumptions-on-binders :3",
);
d.note("meoow :c");
d
}
(ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => {
self.report_fnmut_error(&errci, kind)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// the `'region: 'static` constraints introduced by placeholder outlives.
ConstraintCategory::Internal => 7,
ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 8,
ConstraintCategory::SolverRegionConstraint(_) => 9,
};

debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) struct UniversalRegionRelations<'tcx> {
/// Stores the outlives relations that are known to hold from the
/// implied bounds, in-scope where-clauses, and that sort of
/// thing.
outlives: TransitiveRelation<RegionVid>,
pub(crate) outlives: TransitiveRelation<RegionVid>,

/// This is the `<=` relation; that is, if `a: b`, then `b <= a`,
/// and we store that here. This is useful when figuring out how
Expand Down
17 changes: 17 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,23 @@ pub(crate) fn type_check<'tcx>(

let polonius_context = typeck.polonius_context;

let mut converter = constraint_conversion::ConstraintConversion::new(
typeck.infcx,
typeck.universal_regions,
typeck.region_bound_pairs,
typeck.known_type_outlives_obligations,
Locations::All(rustc_span::DUMMY_SP),
rustc_span::DUMMY_SP,
ConstraintCategory::Boring,
typeck.constraints,
);
typeck.infcx.destructure_solver_region_constraints_for_borrowck(
&mut converter,
typeck.known_type_outlives_obligations,
universal_region_relations.outlives.clone(),
infcx.tcx.def_span(infcx.root_def_id),
);

// In case type check encountered an error region, we suppress unhelpful extra
// errors in by clearing out all outlives bounds that we may end up checking.
if let Some(guar) = universal_region_relations.universal_regions.encountered_re_error() {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ where

lint_redundant_lifetimes(tcx, body_def_id, &outlives_env);

let errors = infcx.resolve_regions_with_outlives_env(&outlives_env);
let errors = infcx.resolve_regions_with_outlives_env(&outlives_env, tcx.def_span(body_def_id));
if errors.is_empty() {
return Ok(());
}
Expand All @@ -211,7 +211,8 @@ where
// the implied bounds hack if this contains `bevy_ecs`'s `ParamSet` type.
false,
);
let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env);
let errors_compat =
infcx_compat.resolve_regions_with_outlives_env(&outlives_env, tcx.def_span(body_def_id));
if errors_compat.is_empty() {
// FIXME: Once we fix bevy, this would be the place to insert a warning
// to upgrade bevy.
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ impl<'tcx> InferCtxt<'tcx> {
reported_signature_mismatch: self.reported_signature_mismatch.clone(),
tainted_by_errors: self.tainted_by_errors.clone(),
universe: self.universe.clone(),
placeholder_assumptions_for_next_solver: self
.placeholder_assumptions_for_next_solver
.clone(),
next_trait_solver: self.next_trait_solver,
obligation_inspector: self.obligation_inspector.clone(),
}
Expand All @@ -106,6 +109,9 @@ impl<'tcx> InferCtxt<'tcx> {
reported_signature_mismatch: self.reported_signature_mismatch.clone(),
tainted_by_errors: self.tainted_by_errors.clone(),
universe: self.universe.clone(),
placeholder_assumptions_for_next_solver: self
.placeholder_assumptions_for_next_solver
.clone(),
next_trait_solver: self.next_trait_solver,
obligation_inspector: self.obligation_inspector.clone(),
};
Expand Down
50 changes: 50 additions & 0 deletions compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.typing_mode_raw()
}

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

fn universe(&self) -> ty::UniverseIndex {
self.universe()
}
Expand All @@ -38,6 +42,40 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.create_next_universe()
}

fn insert_placeholder_assumptions(
&self,
u: ty::UniverseIndex,
assumptions: Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>>,
) {
self.placeholder_assumptions_for_next_solver.borrow_mut().insert(u, assumptions);
}

fn get_placeholder_assumptions(
&self,
u: ty::UniverseIndex,
) -> Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>> {
self.placeholder_assumptions_for_next_solver.borrow().get(&u).unwrap().as_ref().cloned()
}

fn get_solver_region_constraint(
&self,
) -> rustc_type_ir::region_constraint::RegionConstraint<TyCtxt<'tcx>> {
self.inner.borrow().solver_region_constraint_storage.get_constraint()
}

fn overwrite_solver_region_constraint(
&self,
constraint: 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;
let old_constraint = inner.solver_region_constraint_storage.get_constraint();
inner.undo_log.push(UndoLog::OverwriteSolverRegionConstraint { old_constraint });
inner.solver_region_constraint_storage.overwrite_solver_region_constraint(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 @@ -290,6 +328,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
76 changes: 76 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,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 @@ -171,6 +174,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 @@ -315,6 +319,19 @@ pub struct InferCtxt<'tcx> {
/// bound.
universe: Cell<ty::UniverseIndex>,

/// List of assumed wellformed types which we can derive implied
/// bounds on a `for<...>` from. Only used unstabley and by the
/// new solver.
//
// FIXME(-Zassumptions-on-binders): This and `universe` should probably be
// in `InferCtxtInner` so they can participate in rollbacks and whatnot
placeholder_assumptions_for_next_solver: RefCell<
Comment thread
BoxyUwU marked this conversation as resolved.
FxIndexMap<
ty::UniverseIndex,
Option<rustc_type_ir::region_constraint::Assumptions<TyCtxt<'tcx>>>,
>,
>,

next_trait_solver: bool,

pub obligation_inspector: Cell<Option<ObligationInspector<'tcx>>>,
Expand Down Expand Up @@ -397,6 +414,10 @@ pub enum SubregionOrigin<'tcx> {
},

AscribeUserTypeProvePredicate(Span),

// FIXME(-Zassumptions-on-binders): this is a temporary hack until we support
// proper diagnostics for solver region constraints.
SolverRegionConstraint(Span),
}

// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
Expand All @@ -408,6 +429,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
match self {
Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(),
Self::AscribeUserTypeProvePredicate(span) => ConstraintCategory::Predicate(*span),
Self::SolverRegionConstraint(span) => ConstraintCategory::SolverRegionConstraint(*span),
_ => ConstraintCategory::BoringNoLocation,
}
}
Expand Down Expand Up @@ -607,6 +629,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
reported_signature_mismatch: Default::default(),
tainted_by_errors: Cell::new(None),
universe: Cell::new(ty::UniverseIndex::ROOT),
placeholder_assumptions_for_next_solver: RefCell::new(Default::default()),
next_trait_solver,
obligation_inspector: Cell::new(None),
}
Expand Down Expand Up @@ -1661,6 +1684,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
SubregionOrigin::CompareImplItemObligation { span, .. } => span,
SubregionOrigin::AscribeUserTypeProvePredicate(span) => span,
SubregionOrigin::CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
SubregionOrigin::SolverRegionConstraint(a) => a,
}
}

Expand Down Expand Up @@ -1750,3 +1774,55 @@ 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!(),
}
}

#[instrument(level = "debug", skip(self))]
fn overwrite_solver_region_constraint(&mut self, constraint: SolverRegionConstraint<'tcx>) {
if !constraint.is_and() {
self.0 = SolverRegionConstraint::And(vec![constraint].into_boxed_slice())
} else {
self.0 = constraint;
}
}
}
4 changes: 3 additions & 1 deletion compiler/rustc_infer/src/infer/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::iter;
use rustc_data_structures::undo_log::UndoLogs;
use rustc_middle::traits::query::{NoSolution, OutlivesBound};
use rustc_middle::ty;
use rustc_span::Span;
use tracing::instrument;

use self::env::OutlivesEnvironment;
Expand Down Expand Up @@ -49,8 +50,9 @@ impl<'tcx> InferCtxt<'tcx> {
ty::PolyTypeOutlivesPredicate<'tcx>,
SubregionOrigin<'tcx>,
) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
span: Span,
) -> Vec<RegionResolutionError<'tcx>> {
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty, span) {
Ok(()) => {}
Err((clause, origin)) => {
return vec![RegionResolutionError::CannotNormalize(clause, origin)];
Expand Down
Loading
Loading