Skip to content

Commit f63798a

Browse files
authored
Rollup merge of rust-lang#70319 - lcnr:issue63695, r=eddyb
correctly normalize constants closes rust-lang#70317 implements rust-lang#70125 (comment) r? eddyb cc @varkor
2 parents 3c1d9ad + f8e3da5 commit f63798a

File tree

16 files changed

+105
-40
lines changed

16 files changed

+105
-40
lines changed

src/librustc/dep_graph/dep_node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use crate::traits::query::{
5757
CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
5858
CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal,
5959
};
60-
use crate::ty::subst::SubstsRef;
60+
use crate::ty::subst::{GenericArg, SubstsRef};
6161
use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
6262

6363
use rustc_data_structures::fingerprint::Fingerprint;

src/librustc/query/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::traits::query::{
99
};
1010
use crate::ty::query::queries;
1111
use crate::ty::query::QueryDescription;
12-
use crate::ty::subst::SubstsRef;
12+
use crate::ty::subst::{GenericArg, SubstsRef};
1313
use crate::ty::{self, ParamEnvAnd, Ty, TyCtxt};
1414
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1515

@@ -1114,10 +1114,10 @@ rustc_queries! {
11141114
}
11151115

11161116
/// Do not call this query directly: invoke `normalize_erasing_regions` instead.
1117-
query normalize_ty_after_erasing_regions(
1118-
goal: ParamEnvAnd<'tcx, Ty<'tcx>>
1119-
) -> Ty<'tcx> {
1120-
desc { "normalizing `{:?}`", goal }
1117+
query normalize_generic_arg_after_erasing_regions(
1118+
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>
1119+
) -> GenericArg<'tcx> {
1120+
desc { "normalizing `{}`", goal.value }
11211121
}
11221122

11231123
query implied_outlives_bounds(

src/librustc/traits/structural_impls.rs

+14
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,20 @@ impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
273273
t.super_visit_with(self)
274274
}
275275

276+
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
277+
match c.val {
278+
ty::ConstKind::Bound(debruijn, bound_var) if debruijn == self.binder_index => {
279+
self.types.insert(
280+
bound_var.as_u32(),
281+
Symbol::intern(&format!("^{}", bound_var.as_u32())),
282+
);
283+
}
284+
_ => (),
285+
}
286+
287+
c.super_visit_with(self)
288+
}
289+
276290
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
277291
match r {
278292
ty::ReLateBound(index, br) if *index == self.binder_index => match br {

src/librustc/ty/fold.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -978,17 +978,27 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
978978
// ignore the inputs to a projection, as they may not appear
979979
// in the normalized form
980980
if self.just_constrained {
981-
match t.kind {
982-
ty::Projection(..) | ty::Opaque(..) => {
983-
return false;
984-
}
985-
_ => {}
981+
if let ty::Projection(..) | ty::Opaque(..) = t.kind {
982+
return false;
986983
}
987984
}
988985

989986
t.super_visit_with(self)
990987
}
991988

989+
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
990+
// if we are only looking for "constrained" region, we have to
991+
// ignore the inputs of an unevaluated const, as they may not appear
992+
// in the normalized form
993+
if self.just_constrained {
994+
if let ty::ConstKind::Unevaluated(..) = c.val {
995+
return false;
996+
}
997+
}
998+
999+
c.super_visit_with(self)
1000+
}
1001+
9921002
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
9931003
if let ty::ReLateBound(debruijn, br) = *r {
9941004
if debruijn == self.current_index {

src/librustc/ty/normalize_erasing_regions.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
//!
55
//! The methods in this file use a `TypeFolder` to recursively process
66
//! contents, invoking the underlying
7-
//! `normalize_ty_after_erasing_regions` query for each type found
8-
//! within. (This underlying query is what is cached.)
7+
//! `normalize_generic_arg_after_erasing_regions` query for each type
8+
//! or constant found within. (This underlying query is what is cached.)
99
1010
use crate::ty::fold::{TypeFoldable, TypeFolder};
1111
use crate::ty::subst::{Subst, SubstsRef};
@@ -94,6 +94,12 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
9494
}
9595

9696
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
97-
self.tcx.normalize_ty_after_erasing_regions(self.param_env.and(ty))
97+
let arg = self.param_env.and(ty.into());
98+
self.tcx.normalize_generic_arg_after_erasing_regions(arg).expect_ty()
99+
}
100+
101+
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
102+
let arg = self.param_env.and(c.into());
103+
self.tcx.normalize_generic_arg_after_erasing_regions(arg).expect_const()
98104
}
99105
}

src/librustc/ty/query/keys.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::mir;
55
use crate::traits;
66
use crate::ty::fast_reject::SimplifiedType;
77
use crate::ty::query::caches::DefaultCacheSelector;
8-
use crate::ty::subst::SubstsRef;
8+
use crate::ty::subst::{GenericArg, SubstsRef};
99
use crate::ty::{self, Ty, TyCtxt};
1010
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
1111
use rustc_span::symbol::Symbol;
@@ -194,6 +194,17 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
194194
}
195195
}
196196

197+
impl<'tcx> Key for GenericArg<'tcx> {
198+
type CacheSelector = DefaultCacheSelector;
199+
200+
fn query_crate(&self) -> CrateNum {
201+
LOCAL_CRATE
202+
}
203+
fn default_span(&self, _: TyCtxt<'_>) -> Span {
204+
DUMMY_SP
205+
}
206+
}
207+
197208
impl<'tcx> Key for &'tcx ty::Const<'tcx> {
198209
type CacheSelector = DefaultCacheSelector;
199210

src/librustc/ty/query/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::traits::specialization_graph;
3131
use crate::traits::Clauses;
3232
use crate::traits::{self, Vtable};
3333
use crate::ty::steal::Steal;
34-
use crate::ty::subst::SubstsRef;
34+
use crate::ty::subst::{GenericArg, SubstsRef};
3535
use crate::ty::util::AlwaysRequiresDrop;
3636
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
3737
use crate::util::common::ErrorReported;

src/librustc/ty/subst.rs

+8
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ impl<'tcx> GenericArg<'tcx> {
128128
_ => bug!("expected a type, but found another kind"),
129129
}
130130
}
131+
132+
/// Unpack the `GenericArg` as a const when it is known certainly to be a const.
133+
pub fn expect_const(self) -> &'tcx ty::Const<'tcx> {
134+
match self.unpack() {
135+
GenericArgKind::Const(c) => c,
136+
_ => bug!("expected a const, but found another kind"),
137+
}
138+
}
131139
}
132140

133141
impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {

src/librustc_session/session.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub struct PerfStats {
150150
/// Total number of values canonicalized queries constructed.
151151
pub queries_canonicalized: AtomicUsize,
152152
/// Number of times this query is invoked.
153-
pub normalize_ty_after_erasing_regions: AtomicUsize,
153+
pub normalize_generic_arg_after_erasing_regions: AtomicUsize,
154154
/// Number of times this query is invoked.
155155
pub normalize_projection_ty: AtomicUsize,
156156
}
@@ -707,8 +707,8 @@ impl Session {
707707
self.perf_stats.queries_canonicalized.load(Ordering::Relaxed)
708708
);
709709
println!(
710-
"normalize_ty_after_erasing_regions: {}",
711-
self.perf_stats.normalize_ty_after_erasing_regions.load(Ordering::Relaxed)
710+
"normalize_generic_arg_after_erasing_regions: {}",
711+
self.perf_stats.normalize_generic_arg_after_erasing_regions.load(Ordering::Relaxed)
712712
);
713713
println!(
714714
"normalize_projection_ty: {}",
@@ -1080,7 +1080,7 @@ fn build_session_(
10801080
symbol_hash_time: Lock::new(Duration::from_secs(0)),
10811081
decode_def_path_tables_time: Lock::new(Duration::from_secs(0)),
10821082
queries_canonicalized: AtomicUsize::new(0),
1083-
normalize_ty_after_erasing_regions: AtomicUsize::new(0),
1083+
normalize_generic_arg_after_erasing_regions: AtomicUsize::new(0),
10841084
normalize_projection_ty: AtomicUsize::new(0),
10851085
},
10861086
code_stats: Default::default(),

src/librustc_trait_selection/traits/project.rs

+1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
387387
}
388388

389389
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
390+
let constant = constant.super_fold_with(self);
390391
constant.eval(self.selcx.tcx(), self.param_env)
391392
}
392393
}

src/librustc_trait_selection/traits/query/normalize.rs

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
191191
}
192192

193193
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
194+
let constant = constant.super_fold_with(self);
194195
constant.eval(self.infcx.tcx, self.param_env)
195196
}
196197
}

src/librustc_traits/normalize_erasing_regions.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
use rustc::traits::query::NoSolution;
22
use rustc::ty::query::Providers;
3-
use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt};
3+
use rustc::ty::subst::GenericArg;
4+
use rustc::ty::{self, ParamEnvAnd, TyCtxt};
45
use rustc_infer::infer::TyCtxtInferExt;
56
use rustc_trait_selection::traits::query::normalize::AtExt;
67
use rustc_trait_selection::traits::{Normalized, ObligationCause};
78
use std::sync::atomic::Ordering;
89

910
crate fn provide(p: &mut Providers<'_>) {
10-
*p = Providers { normalize_ty_after_erasing_regions, ..*p };
11+
*p = Providers { normalize_generic_arg_after_erasing_regions, ..*p };
1112
}
1213

13-
fn normalize_ty_after_erasing_regions<'tcx>(
14+
fn normalize_generic_arg_after_erasing_regions<'tcx>(
1415
tcx: TyCtxt<'tcx>,
15-
goal: ParamEnvAnd<'tcx, Ty<'tcx>>,
16-
) -> Ty<'tcx> {
17-
debug!("normalize_ty_after_erasing_regions(goal={:#?})", goal);
16+
goal: ParamEnvAnd<'tcx, GenericArg<'tcx>>,
17+
) -> GenericArg<'tcx> {
18+
debug!("normalize_generic_arg_after_erasing_regions(goal={:#?})", goal);
1819

1920
let ParamEnvAnd { param_env, value } = goal;
20-
tcx.sess.perf_stats.normalize_ty_after_erasing_regions.fetch_add(1, Ordering::Relaxed);
21+
tcx.sess.perf_stats.normalize_generic_arg_after_erasing_regions.fetch_add(1, Ordering::Relaxed);
2122
tcx.infer_ctxt().enter(|infcx| {
2223
let cause = ObligationCause::dummy();
2324
match infcx.at(&cause, param_env).normalize(&value) {

src/test/mir-opt/inline/inline-into-box-place.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ignore-tidy-linelength
22
// ignore-wasm32-bare compiled with panic=abort by default
33
// compile-flags: -Z mir-opt-level=3
4+
// only-64bit FIXME: the mir representation of RawVec depends on ptr size
45
#![feature(box_syntax)]
56

67
fn main() {
@@ -55,7 +56,7 @@ fn main() {
5556
// StorageLive(_2);
5657
// _2 = Box(std::vec::Vec<u32>);
5758
// _4 = &mut (*_2);
58-
// ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32>::NEW;
59+
// ((*_4).0: alloc::raw_vec::RawVec<u32>) = const ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>;
5960
// ((*_4).1: usize) = const 0usize;
6061
// _1 = move _2;
6162
// StorageDead(_2);

src/test/ui/associated-const/defaults-cyclic-fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// build-fail
2+
//~^ ERROR cycle detected when normalizing `<() as Tr>::A`
23

34
// Cyclic assoc. const defaults don't error unless *used*
45
trait Tr {
56
const A: u8 = Self::B;
6-
//~^ ERROR cycle detected when const-evaluating + checking `Tr::A`
77

88
const B: u8 = Self::A;
99
}

src/test/ui/associated-const/defaults-cyclic-fail.stderr

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,42 @@
1-
error[E0391]: cycle detected when const-evaluating + checking `Tr::A`
2-
--> $DIR/defaults-cyclic-fail.rs:5:5
1+
error[E0391]: cycle detected when normalizing `<() as Tr>::A`
2+
|
3+
note: ...which requires const-evaluating + checking `Tr::A`...
4+
--> $DIR/defaults-cyclic-fail.rs:6:5
35
|
46
LL | const A: u8 = Self::B;
57
| ^^^^^^^^^^^^^^^^^^^^^^
8+
note: ...which requires const-evaluating + checking `Tr::A`...
9+
--> $DIR/defaults-cyclic-fail.rs:6:5
610
|
11+
LL | const A: u8 = Self::B;
12+
| ^^^^^^^^^^^^^^^^^^^^^^
713
note: ...which requires const-evaluating `Tr::A`...
8-
--> $DIR/defaults-cyclic-fail.rs:5:19
14+
--> $DIR/defaults-cyclic-fail.rs:6:5
915
|
1016
LL | const A: u8 = Self::B;
11-
| ^^^^^^^
17+
| ^^^^^^^^^^^^^^^^^^^^^^
18+
= note: ...which requires normalizing `<() as Tr>::B`...
19+
note: ...which requires const-evaluating + checking `Tr::B`...
20+
--> $DIR/defaults-cyclic-fail.rs:8:5
21+
|
22+
LL | const B: u8 = Self::A;
23+
| ^^^^^^^^^^^^^^^^^^^^^^
1224
note: ...which requires const-evaluating + checking `Tr::B`...
1325
--> $DIR/defaults-cyclic-fail.rs:8:5
1426
|
1527
LL | const B: u8 = Self::A;
1628
| ^^^^^^^^^^^^^^^^^^^^^^
1729
note: ...which requires const-evaluating `Tr::B`...
18-
--> $DIR/defaults-cyclic-fail.rs:8:19
30+
--> $DIR/defaults-cyclic-fail.rs:8:5
1931
|
2032
LL | const B: u8 = Self::A;
21-
| ^^^^^^^
22-
= note: ...which again requires const-evaluating + checking `Tr::A`, completing the cycle
33+
| ^^^^^^^^^^^^^^^^^^^^^^
34+
= note: ...which again requires normalizing `<() as Tr>::A`, completing the cycle
2335
note: cycle used when const-evaluating `main`
24-
--> $DIR/defaults-cyclic-fail.rs:16:16
36+
--> $DIR/defaults-cyclic-fail.rs:14:1
2537
|
26-
LL | assert_eq!(<() as Tr>::A, 0);
27-
| ^^^^^^^^^^^^^
38+
LL | fn main() {
39+
| ^^^^^^^^^
2840

2941
error: aborting due to previous error
3042

src/test/ui/consts/const-size_of-cycle.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ note: ...which requires const-evaluating + checking `std::intrinsics::size_of`..
2525
LL | pub fn size_of<T>() -> usize;
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2727
= note: ...which requires computing layout of `Foo`...
28-
= note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
28+
= note: ...which requires normalizing `[u8; _]`...
2929
= note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
3030
note: cycle used when processing `Foo`
3131
--> $DIR/const-size_of-cycle.rs:7:1

0 commit comments

Comments
 (0)