Skip to content

Commit 93d15b9

Browse files
skinnyBatlcnr
authored andcommitted
Put lazy normalization behind a feature gate
1 parent 3ef8310 commit 93d15b9

26 files changed

+207
-67
lines changed

src/librustc_feature/active.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,9 @@ declare_features! (
558558

559559
/// Allow negative trait implementations.
560560
(active, negative_impls, "1.44.0", Some(68318), None),
561+
562+
/// Lazily evaluate constants. Which allows constants to depend on type parameters.
563+
(active, lazy_normalization_consts, "1.44.0", Some(60471), None),
561564

562565
/// Allows the use of `#[target_feature]` on safe functions.
563566
(active, target_feature_11, "1.45.0", Some(69098), None),
@@ -581,4 +584,5 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
581584
sym::raw_dylib,
582585
sym::const_trait_impl,
583586
sym::const_trait_bound_opt_out,
587+
sym::lazy_normalization_consts,
584588
];

src/librustc_infer/infer/combine.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,15 @@ 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-
(ty::ConstKind::Unevaluated(..), _) => {
167+
(ty::ConstKind::Unevaluated(..), _)
168+
if self.tcx.features().lazy_normalization_consts =>
169+
{
168170
relation.const_equate_obligation(a, b);
169171
return Ok(b);
170172
}
171-
(_, ty::ConstKind::Unevaluated(..)) => {
173+
(_, ty::ConstKind::Unevaluated(..))
174+
if self.tcx.features().lazy_normalization_consts =>
175+
{
172176
relation.const_equate_obligation(a, b);
173177
return Ok(a);
174178
}
@@ -658,14 +662,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
658662
}
659663
}
660664
}
661-
ty::ConstKind::Unevaluated(..) => Ok(c),
665+
ty::ConstKind::Unevaluated(..) if self.tcx().features().lazy_normalization_consts => {
666+
Ok(c)
667+
}
662668
_ => relate::super_relate_consts(self, c, c),
663669
}
664670
}
665671
}
666672

667673
pub trait ConstEquateRelation<'tcx>: TypeRelation<'tcx> {
668-
/// Register am obligation that both constants must be equal to each other.
674+
/// Register an obligation that both constants must be equal to each other.
669675
///
670676
/// If they aren't equal then the relation doesn't hold.
671677
fn const_equate_obligation(&mut self, a: &'tcx ty::Const<'tcx>, b: &'tcx ty::Const<'tcx>);

src/librustc_infer/infer/equate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::combine::{CombineFields, RelationDir, ConstEquateRelation};
1+
use super::combine::{CombineFields, ConstEquateRelation, RelationDir};
22
use super::Subtype;
33

44
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};

src/librustc_infer/infer/nll_relate/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,9 @@ where
988988
}
989989
}
990990
}
991-
ty::ConstKind::Unevaluated(..) => Ok(a),
991+
ty::ConstKind::Unevaluated(..) if self.tcx().features().lazy_normalization_consts => {
992+
Ok(a)
993+
}
992994
_ => relate::super_relate_consts(self, a, a),
993995
}
994996
}

src/librustc_middle/ty/relate.rs

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -431,18 +431,20 @@ pub fn super_relate_tys<R: TypeRelation<'tcx>>(
431431
let t = relation.relate(&a_t, &b_t)?;
432432
match relation.relate(&sz_a, &sz_b) {
433433
Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
434+
// FIXME(lazy_normalization_consts) Implement improved diagnostics for mismatched array
435+
// length?
436+
Err(err) if relation.tcx().features().lazy_normalization_consts => Err(err),
434437
Err(err) => {
435-
// // Check whether the lengths are both concrete/known values,
436-
// // but are unequal, for better diagnostics.
437-
// let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
438-
// let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
439-
// match (sz_a, sz_b) {
440-
// (Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize(
441-
// expected_found(relation, &sz_a_val, &sz_b_val),
442-
// )),
443-
// _ => Err(err),
444-
// }
445-
Err(err)
438+
// Check whether the lengths are both concrete/known values,
439+
// but are unequal, for better diagnostics.
440+
let sz_a = sz_a.try_eval_usize(tcx, relation.param_env());
441+
let sz_b = sz_b.try_eval_usize(tcx, relation.param_env());
442+
match (sz_a, sz_b) {
443+
(Some(sz_a_val), Some(sz_b_val)) => Err(TypeError::FixedArraySize(
444+
expected_found(relation, &sz_a_val, &sz_b_val),
445+
)),
446+
_ => Err(err),
447+
}
446448
}
447449
}
448450
}
@@ -605,14 +607,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
605607
}
606608

607609
// FIXME(const_generics): this is wrong, as it is a projection
608-
// (
609-
// ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
610-
// ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
611-
// ) if a_def_id == b_def_id && a_promoted == b_promoted => {
612-
// let substs =
613-
// relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
614-
// Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted))
615-
// }
610+
(
611+
ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
612+
ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
613+
) if a_def_id == b_def_id && a_promoted == b_promoted => {
614+
let substs =
615+
relation.relate_with_variance(ty::Variance::Invariant, &a_substs, &b_substs)?;
616+
Ok(ty::ConstKind::Unevaluated(a_def_id, &substs, a_promoted))
617+
}
616618
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
617619
};
618620
new_const_val.map(|val| tcx.mk_const(ty::Const { val, ty: a.ty }))

src/librustc_session/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
870870
instrument_mcount: bool = (false, parse_bool, [TRACKED],
871871
"insert function instrument code for mcount-based tracing (default: no)"),
872872
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
873-
"keep hygiene data after analysis (default: no)"),
873+
"lazily evaluate constants (experimental)"),
874874
link_native_libraries: bool = (true, parse_bool, [UNTRACKED],
875875
"link native libraries in the linker invocation (default: yes)"),
876876
link_only: bool = (false, parse_bool, [TRACKED],

src/librustc_span/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ symbols! {
411411
label_break_value,
412412
lang,
413413
lang_items,
414+
lazy_normalization_consts,
414415
let_chains,
415416
lhs,
416417
lib,

src/librustc_trait_selection/traits/project.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,15 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
386386
_ => ty,
387387
}
388388
}
389+
390+
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
391+
if self.selcx.tcx().features().lazy_normalization_consts {
392+
constant
393+
} else {
394+
let constant = constant.super_fold_with(self);
395+
constant.eval(self.selcx.tcx(), self.param_env)
396+
}
397+
}
389398
}
390399

391400
/// The guts of `normalize`: normalize a specific projection like `<T

src/librustc_trait_selection/traits/query/normalize.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
201201
_ => ty,
202202
}
203203
}
204+
205+
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
206+
let constant = constant.super_fold_with(self);
207+
constant.eval(self.infcx.tcx, self.param_env)
208+
}
204209
}

src/librustc_typeck/collect.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,8 +1156,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
11561156

11571157
let node = tcx.hir().get(hir_id);
11581158
let parent_def_id = match node {
1159-
Node::AnonConst(_)
1160-
| Node::ImplItem(_)
1159+
Node::ImplItem(_)
11611160
| Node::TraitItem(_)
11621161
| Node::Variant(_)
11631162
| Node::Ctor(..)
@@ -1166,6 +1165,15 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
11661165
Some(tcx.hir().local_def_id(parent_id).to_def_id())
11671166
}
11681167

1168+
Node::AnonConst(_) => {
1169+
if tcx.features().lazy_normalization_consts {
1170+
let parent_id = tcx.hir().get_parent_item(hir_id);
1171+
Some(tcx.hir().local_def_id(parent_id))
1172+
} else {
1173+
None
1174+
}
1175+
}
1176+
11691177
Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => {
11701178
Some(tcx.closure_base_def_id(def_id))
11711179
}

0 commit comments

Comments
 (0)