Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8b14b84

Browse files
skinnyBatlcnr
authored andcommitted
Assume unevaluated consts are equal to the other consts and add ConstEquate obligation. This delays
the need to evaluate consts eagerly and therefore gets around const eval query cycles.
1 parent 09739c2 commit 8b14b84

File tree

36 files changed

+371
-122
lines changed

36 files changed

+371
-122
lines changed

src/librustc_infer/infer/canonical/query_response.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc_middle::arena::ArenaAllocatable;
2525
use rustc_middle::ty::fold::TypeFoldable;
2626
use rustc_middle::ty::relate::TypeRelation;
2727
use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
28-
use rustc_middle::ty::{self, BoundVar, Ty, TyCtxt};
28+
use rustc_middle::ty::{self, BoundVar, Const, Ty, TyCtxt};
2929
use std::fmt::Debug;
3030

3131
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
@@ -671,6 +671,13 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
671671
});
672672
}
673673

674+
fn const_equate(&mut self, _a: &'tcx Const<'tcx>, _b: &'tcx Const<'tcx>) {
675+
span_bug!(
676+
self.cause.span(self.infcx.tcx),
677+
"lazy_normalization_consts: unreachable `const_equate`"
678+
);
679+
}
680+
674681
fn normalization() -> NormalizationStrategy {
675682
NormalizationStrategy::Eager
676683
}

src/librustc_infer/infer/combine.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
164164
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
165165
return self.unify_const_variable(!a_is_expected, vid, a);
166166
}
167-
168167
_ => {}
169168
}
170169

@@ -375,6 +374,20 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
375374
debug!("generalize: success {{ {:?}, {:?} }}", ty, needs_wf);
376375
Ok(Generalization { ty, needs_wf })
377376
}
377+
378+
pub fn add_const_equate_obligation(
379+
&mut self,
380+
a_is_expected: bool,
381+
a: &'tcx ty::Const<'tcx>,
382+
b: &'tcx ty::Const<'tcx>,
383+
) {
384+
let predicate = if a_is_expected {
385+
ty::Predicate::ConstEquate(a, b)
386+
} else {
387+
ty::Predicate::ConstEquate(b, a)
388+
};
389+
self.obligations.push(Obligation::new(self.trace.cause.clone(), self.param_env, predicate));
390+
}
378391
}
379392

380393
struct Generalizer<'cx, 'tcx> {
@@ -637,6 +650,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
637650
}
638651
}
639652
}
653+
ty::ConstKind::Unevaluated(..) => Ok(c),
640654
_ => relate::super_relate_consts(self, c, c),
641655
}
642656
}

src/librustc_infer/infer/equate.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::Subtype;
44
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
55
use rustc_middle::ty::subst::SubstsRef;
66
use rustc_middle::ty::TyVar;
7-
use rustc_middle::ty::{self, Ty, TyCtxt};
7+
use rustc_middle::ty::{self, ConstKind, Ty, TyCtxt};
88

99
use rustc_hir::def_id::DefId;
1010

@@ -119,7 +119,17 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
119119
a: &'tcx ty::Const<'tcx>,
120120
b: &'tcx ty::Const<'tcx>,
121121
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
122-
self.fields.infcx.super_combine_consts(self, a, b)
122+
match (a.val, b.val) {
123+
(ConstKind::Unevaluated(..), _) => {
124+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
125+
Ok(b)
126+
}
127+
(_, ConstKind::Unevaluated(..)) => {
128+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
129+
Ok(a)
130+
}
131+
_ => self.fields.infcx.super_combine_consts(self, a, b),
132+
}
123133
}
124134

125135
fn binders<T>(

src/librustc_infer/infer/glb.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,17 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
7979
a: &'tcx ty::Const<'tcx>,
8080
b: &'tcx ty::Const<'tcx>,
8181
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
82-
self.fields.infcx.super_combine_consts(self, a, b)
82+
match (a.val, b.val) {
83+
(ty::ConstKind::Unevaluated(..), _) => {
84+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
85+
Ok(b)
86+
}
87+
(_, ty::ConstKind::Unevaluated(..)) => {
88+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
89+
Ok(a)
90+
}
91+
_ => self.fields.infcx.super_combine_consts(self, a, b),
92+
}
8393
}
8494

8595
fn binders<T>(

src/librustc_infer/infer/lub.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,17 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
7979
a: &'tcx ty::Const<'tcx>,
8080
b: &'tcx ty::Const<'tcx>,
8181
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
82-
self.fields.infcx.super_combine_consts(self, a, b)
82+
match (a.val, b.val) {
83+
(ty::ConstKind::Unevaluated(..), _) => {
84+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
85+
Ok(b)
86+
}
87+
(_, ty::ConstKind::Unevaluated(..)) => {
88+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
89+
Ok(a)
90+
}
91+
_ => self.fields.infcx.super_combine_consts(self, a, b),
92+
}
8393
}
8494

8595
fn binders<T>(

src/librustc_infer/infer/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
14901490
self.report_and_explain_type_error(trace, &err)
14911491
}
14921492

1493+
pub fn report_mismatched_consts(
1494+
&self,
1495+
cause: &ObligationCause<'tcx>,
1496+
expected: &'tcx ty::Const<'tcx>,
1497+
actual: &'tcx ty::Const<'tcx>,
1498+
err: TypeError<'tcx>,
1499+
) -> DiagnosticBuilder<'tcx> {
1500+
let trace = TypeTrace::consts(cause, true, expected, actual);
1501+
self.report_and_explain_type_error(trace, &err)
1502+
}
1503+
14931504
pub fn replace_bound_vars_with_fresh_vars<T>(
14941505
&self,
14951506
span: Span,
@@ -1777,6 +1788,15 @@ impl<'tcx> TypeTrace<'tcx> {
17771788
TypeTrace { cause: cause.clone(), values: Types(ExpectedFound::new(a_is_expected, a, b)) }
17781789
}
17791790

1791+
pub fn consts(
1792+
cause: &ObligationCause<'tcx>,
1793+
a_is_expected: bool,
1794+
a: &'tcx ty::Const<'tcx>,
1795+
b: &'tcx ty::Const<'tcx>,
1796+
) -> TypeTrace<'tcx> {
1797+
TypeTrace { cause: cause.clone(), values: Consts(ExpectedFound::new(a_is_expected, a, b)) }
1798+
}
1799+
17801800
pub fn dummy(tcx: TyCtxt<'tcx>) -> TypeTrace<'tcx> {
17811801
TypeTrace {
17821802
cause: ObligationCause::dummy(),

src/librustc_infer/infer/nll_relate/mod.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ pub trait TypeRelatingDelegate<'tcx> {
7777
/// delegate.
7878
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
7979

80+
fn const_equate(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);
81+
8082
/// Creates a new universe index. Used when instantiating placeholders.
8183
fn create_next_universe(&mut self) -> ty::UniverseIndex;
8284

@@ -592,8 +594,16 @@ where
592594
b = self.infcx.shallow_resolve(b);
593595
}
594596

595-
match b.val {
596-
ty::ConstKind::Infer(InferConst::Var(_)) if D::forbid_inference_vars() => {
597+
match (a.val, b.val) {
598+
(ty::ConstKind::Unevaluated(..), _) => {
599+
self.delegate.const_equate(a, b);
600+
Ok(b)
601+
}
602+
(_, ty::ConstKind::Unevaluated(..)) => {
603+
self.delegate.const_equate(a, b);
604+
Ok(a)
605+
}
606+
(_, ty::ConstKind::Infer(InferConst::Var(_))) if D::forbid_inference_vars() => {
597607
// Forbid inference variables in the RHS.
598608
bug!("unexpected inference var {:?}", b)
599609
}
@@ -976,6 +986,7 @@ where
976986
}
977987
}
978988
}
989+
ty::ConstKind::Unevaluated(..) => Ok(a),
979990
_ => relate::super_relate_consts(self, a, a),
980991
}
981992
}

src/librustc_infer/infer/outlives/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ pub fn explicit_outlives_bounds<'tcx>(
1919
| ty::Predicate::ObjectSafe(..)
2020
| ty::Predicate::ClosureKind(..)
2121
| ty::Predicate::TypeOutlives(..)
22-
| ty::Predicate::ConstEvaluatable(..) => None,
22+
| ty::Predicate::ConstEvaluatable(..)
23+
| ty::Predicate::ConstEquate(..) => None,
2324
ty::Predicate::RegionOutlives(ref data) => data
2425
.no_bound_vars()
2526
.map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a)),

src/librustc_infer/infer/sub.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,17 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
155155
a: &'tcx ty::Const<'tcx>,
156156
b: &'tcx ty::Const<'tcx>,
157157
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
158-
self.fields.infcx.super_combine_consts(self, a, b)
158+
match (a.val, b.val) {
159+
(ty::ConstKind::Unevaluated(..), _) => {
160+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
161+
Ok(b)
162+
}
163+
(_, ty::ConstKind::Unevaluated(..)) => {
164+
self.fields.add_const_equate_obligation(self.a_is_expected, a, b);
165+
Ok(a)
166+
}
167+
_ => self.fields.infcx.super_combine_consts(self, a, b),
168+
}
159169
}
160170

161171
fn binders<T>(

src/librustc_infer/traits/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub mod util;
1010

1111
use rustc_hir as hir;
1212
use rustc_middle::ty::error::{ExpectedFound, TypeError};
13-
use rustc_middle::ty::{self, Ty};
13+
use rustc_middle::ty::{self, Const, Ty};
1414
use rustc_span::Span;
1515

1616
pub use self::FulfillmentErrorCode::*;
@@ -81,6 +81,7 @@ pub enum FulfillmentErrorCode<'tcx> {
8181
CodeSelectionError(SelectionError<'tcx>),
8282
CodeProjectionError(MismatchedProjectionTypes<'tcx>),
8383
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
84+
CodeConstEquateError(ExpectedFound<&'tcx Const<'tcx>>, TypeError<'tcx>),
8485
CodeAmbiguity,
8586
}
8687

0 commit comments

Comments
 (0)