Skip to content

Commit f800965

Browse files
authored
Rollup merge of rust-lang#71198 - oli-obk:const_check_cleanup, r=RalfJung
Const check/promotion cleanup and sanity assertion r? @RalfJung This is just the part of rust-lang#70042 (comment) that does not change behaviour
2 parents 339a938 + 316a401 commit f800965

File tree

9 files changed

+184
-157
lines changed

9 files changed

+184
-157
lines changed

src/librustc_mir/borrow_check/type_check/mod.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations}
4242
use crate::dataflow::move_paths::MoveData;
4343
use crate::dataflow::MaybeInitializedPlaces;
4444
use crate::dataflow::ResultsCursor;
45-
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
45+
use crate::transform::{
46+
check_consts::ConstCx,
47+
promote_consts::should_suggest_const_in_array_repeat_expressions_attribute,
48+
};
4649

4750
use crate::borrow_check::{
4851
borrow_set::BorrowSet,
@@ -1998,14 +2001,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19982001
let span = body.source_info(location).span;
19992002
let ty = operand.ty(*body, tcx);
20002003
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
2004+
let ccx = ConstCx::new_with_param_env(
2005+
tcx,
2006+
self.mir_def_id,
2007+
body,
2008+
self.param_env,
2009+
);
20012010
// To determine if `const_in_array_repeat_expressions` feature gate should
20022011
// be mentioned, need to check if the rvalue is promotable.
20032012
let should_suggest =
20042013
should_suggest_const_in_array_repeat_expressions_attribute(
2005-
tcx,
2006-
self.mir_def_id,
2007-
body,
2008-
operand,
2014+
&ccx, operand,
20092015
);
20102016
debug!("check_rvalue: should_suggest={:?}", should_suggest);
20112017

src/librustc_mir/transform/check_consts/mod.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,33 @@ pub mod validation;
2020

2121
/// Information about the item currently being const-checked, as well as a reference to the global
2222
/// context.
23-
pub struct Item<'mir, 'tcx> {
23+
pub struct ConstCx<'mir, 'tcx> {
2424
pub body: mir::ReadOnlyBodyAndCache<'mir, 'tcx>,
2525
pub tcx: TyCtxt<'tcx>,
2626
pub def_id: DefId,
2727
pub param_env: ty::ParamEnv<'tcx>,
2828
pub const_kind: Option<ConstKind>,
2929
}
3030

31-
impl Item<'mir, 'tcx> {
31+
impl ConstCx<'mir, 'tcx> {
3232
pub fn new(
3333
tcx: TyCtxt<'tcx>,
3434
def_id: DefId,
3535
body: mir::ReadOnlyBodyAndCache<'mir, 'tcx>,
3636
) -> Self {
3737
let param_env = tcx.param_env(def_id);
38+
Self::new_with_param_env(tcx, def_id, body, param_env)
39+
}
40+
41+
pub fn new_with_param_env(
42+
tcx: TyCtxt<'tcx>,
43+
def_id: DefId,
44+
body: mir::ReadOnlyBodyAndCache<'mir, 'tcx>,
45+
param_env: ty::ParamEnv<'tcx>,
46+
) -> Self {
3847
let const_kind = ConstKind::for_item(tcx, def_id);
3948

40-
Item { body, tcx, def_id, param_env, const_kind }
49+
ConstCx { body, tcx, def_id, param_env, const_kind }
4150
}
4251

4352
/// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).

src/librustc_mir/transform/check_consts/ops.rs

+62-62
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_session::parse::feature_err;
77
use rustc_span::symbol::sym;
88
use rustc_span::{Span, Symbol};
99

10-
use super::{ConstKind, Item};
10+
use super::{ConstCx, ConstKind};
1111

1212
/// An operation that is not *always* allowed in a const context.
1313
pub trait NonConstOp: std::fmt::Debug {
@@ -27,19 +27,19 @@ pub trait NonConstOp: std::fmt::Debug {
2727
///
2828
/// By default, it returns `true` if and only if this operation has a corresponding feature
2929
/// gate and that gate is enabled.
30-
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
31-
Self::feature_gate().map_or(false, |gate| item.tcx.features().enabled(gate))
30+
fn is_allowed_in_item(&self, ccx: &ConstCx<'_, '_>) -> bool {
31+
Self::feature_gate().map_or(false, |gate| ccx.tcx.features().enabled(gate))
3232
}
3333

34-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
34+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
3535
let mut err = struct_span_err!(
36-
item.tcx.sess,
36+
ccx.tcx.sess,
3737
span,
3838
E0019,
3939
"{} contains unimplemented expression type",
40-
item.const_kind()
40+
ccx.const_kind()
4141
);
42-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
42+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
4343
err.note(
4444
"A function call isn't allowed in the const's initialization expression \
4545
because the expression's value must be known at compile-time.",
@@ -66,9 +66,9 @@ impl NonConstOp for Downcast {
6666
#[derive(Debug)]
6767
pub struct FnCallIndirect;
6868
impl NonConstOp for FnCallIndirect {
69-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
69+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
7070
let mut err =
71-
item.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn");
71+
ccx.tcx.sess.struct_span_err(span, "function pointers are not allowed in const fn");
7272
err.emit();
7373
}
7474
}
@@ -77,14 +77,14 @@ impl NonConstOp for FnCallIndirect {
7777
#[derive(Debug)]
7878
pub struct FnCallNonConst(pub DefId);
7979
impl NonConstOp for FnCallNonConst {
80-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
80+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
8181
let mut err = struct_span_err!(
82-
item.tcx.sess,
82+
ccx.tcx.sess,
8383
span,
8484
E0015,
8585
"calls in {}s are limited to constant functions, \
8686
tuple structs and tuple variants",
87-
item.const_kind(),
87+
ccx.const_kind(),
8888
);
8989
err.emit();
9090
}
@@ -96,12 +96,12 @@ impl NonConstOp for FnCallNonConst {
9696
#[derive(Debug)]
9797
pub struct FnCallUnstable(pub DefId, pub Symbol);
9898
impl NonConstOp for FnCallUnstable {
99-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
99+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
100100
let FnCallUnstable(def_id, feature) = *self;
101101

102-
let mut err = item.tcx.sess.struct_span_err(
102+
let mut err = ccx.tcx.sess.struct_span_err(
103103
span,
104-
&format!("`{}` is not yet stable as a const fn", item.tcx.def_path_str(def_id)),
104+
&format!("`{}` is not yet stable as a const fn", ccx.tcx.def_path_str(def_id)),
105105
);
106106
if nightly_options::is_nightly_build() {
107107
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
@@ -115,16 +115,16 @@ pub struct HeapAllocation;
115115
impl NonConstOp for HeapAllocation {
116116
const IS_SUPPORTED_IN_MIRI: bool = false;
117117

118-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
118+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
119119
let mut err = struct_span_err!(
120-
item.tcx.sess,
120+
ccx.tcx.sess,
121121
span,
122122
E0010,
123123
"allocations are not allowed in {}s",
124-
item.const_kind()
124+
ccx.const_kind()
125125
);
126-
err.span_label(span, format!("allocation not allowed in {}s", item.const_kind()));
127-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
126+
err.span_label(span, format!("allocation not allowed in {}s", ccx.const_kind()));
127+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
128128
err.note(
129129
"The value of statics and constants must be known at compile time, \
130130
and they live for the entire lifetime of a program. Creating a boxed \
@@ -143,23 +143,23 @@ impl NonConstOp for IfOrMatch {
143143
Some(sym::const_if_match)
144144
}
145145

146-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
146+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
147147
// This should be caught by the HIR const-checker.
148-
item.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context");
148+
ccx.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context");
149149
}
150150
}
151151

152152
#[derive(Debug)]
153153
pub struct LiveDrop;
154154
impl NonConstOp for LiveDrop {
155-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
155+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
156156
struct_span_err!(
157-
item.tcx.sess,
157+
ccx.tcx.sess,
158158
span,
159159
E0493,
160160
"destructors cannot be evaluated at compile-time"
161161
)
162-
.span_label(span, format!("{}s cannot evaluate destructors", item.const_kind()))
162+
.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()))
163163
.emit();
164164
}
165165
}
@@ -171,18 +171,18 @@ impl NonConstOp for Loop {
171171
Some(sym::const_loop)
172172
}
173173

174-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
174+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
175175
// This should be caught by the HIR const-checker.
176-
item.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context");
176+
ccx.tcx.sess.delay_span_bug(span, "complex control flow is forbidden in a const context");
177177
}
178178
}
179179

180180
#[derive(Debug)]
181181
pub struct CellBorrow;
182182
impl NonConstOp for CellBorrow {
183-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
183+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
184184
struct_span_err!(
185-
item.tcx.sess,
185+
ccx.tcx.sess,
186186
span,
187187
E0492,
188188
"cannot borrow a constant which may contain \
@@ -199,19 +199,19 @@ impl NonConstOp for MutBorrow {
199199
Some(sym::const_mut_refs)
200200
}
201201

202-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
202+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
203203
let mut err = feature_err(
204-
&item.tcx.sess.parse_sess,
204+
&ccx.tcx.sess.parse_sess,
205205
sym::const_mut_refs,
206206
span,
207207
&format!(
208208
"references in {}s may only refer \
209209
to immutable values",
210-
item.const_kind()
210+
ccx.const_kind()
211211
),
212212
);
213-
err.span_label(span, format!("{}s require immutable values", item.const_kind()));
214-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
213+
err.span_label(span, format!("{}s require immutable values", ccx.const_kind()));
214+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
215215
err.note(
216216
"References in statics and constants may only refer \
217217
to immutable values.\n\n\
@@ -234,12 +234,12 @@ impl NonConstOp for MutAddressOf {
234234
Some(sym::const_mut_refs)
235235
}
236236

237-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
237+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
238238
feature_err(
239-
&item.tcx.sess.parse_sess,
239+
&ccx.tcx.sess.parse_sess,
240240
sym::const_mut_refs,
241241
span,
242-
&format!("`&raw mut` is not allowed in {}s", item.const_kind()),
242+
&format!("`&raw mut` is not allowed in {}s", ccx.const_kind()),
243243
)
244244
.emit();
245245
}
@@ -260,12 +260,12 @@ impl NonConstOp for Panic {
260260
Some(sym::const_panic)
261261
}
262262

263-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
263+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
264264
feature_err(
265-
&item.tcx.sess.parse_sess,
265+
&ccx.tcx.sess.parse_sess,
266266
sym::const_panic,
267267
span,
268-
&format!("panicking in {}s is unstable", item.const_kind()),
268+
&format!("panicking in {}s is unstable", ccx.const_kind()),
269269
)
270270
.emit();
271271
}
@@ -278,12 +278,12 @@ impl NonConstOp for RawPtrComparison {
278278
Some(sym::const_compare_raw_pointers)
279279
}
280280

281-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
281+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
282282
feature_err(
283-
&item.tcx.sess.parse_sess,
283+
&ccx.tcx.sess.parse_sess,
284284
sym::const_compare_raw_pointers,
285285
span,
286-
&format!("comparing raw pointers inside {}", item.const_kind()),
286+
&format!("comparing raw pointers inside {}", ccx.const_kind()),
287287
)
288288
.emit();
289289
}
@@ -296,12 +296,12 @@ impl NonConstOp for RawPtrDeref {
296296
Some(sym::const_raw_ptr_deref)
297297
}
298298

299-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
299+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
300300
feature_err(
301-
&item.tcx.sess.parse_sess,
301+
&ccx.tcx.sess.parse_sess,
302302
sym::const_raw_ptr_deref,
303303
span,
304-
&format!("dereferencing raw pointers in {}s is unstable", item.const_kind(),),
304+
&format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
305305
)
306306
.emit();
307307
}
@@ -314,12 +314,12 @@ impl NonConstOp for RawPtrToIntCast {
314314
Some(sym::const_raw_ptr_to_usize_cast)
315315
}
316316

317-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
317+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
318318
feature_err(
319-
&item.tcx.sess.parse_sess,
319+
&ccx.tcx.sess.parse_sess,
320320
sym::const_raw_ptr_to_usize_cast,
321321
span,
322-
&format!("casting pointers to integers in {}s is unstable", item.const_kind(),),
322+
&format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
323323
)
324324
.emit();
325325
}
@@ -329,22 +329,22 @@ impl NonConstOp for RawPtrToIntCast {
329329
#[derive(Debug)]
330330
pub struct StaticAccess;
331331
impl NonConstOp for StaticAccess {
332-
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
333-
item.const_kind().is_static()
332+
fn is_allowed_in_item(&self, ccx: &ConstCx<'_, '_>) -> bool {
333+
ccx.const_kind().is_static()
334334
}
335335

336-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
336+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
337337
let mut err = struct_span_err!(
338-
item.tcx.sess,
338+
ccx.tcx.sess,
339339
span,
340340
E0013,
341341
"{}s cannot refer to statics",
342-
item.const_kind()
342+
ccx.const_kind()
343343
);
344344
err.help(
345345
"consider extracting the value of the `static` to a `const`, and referring to that",
346346
);
347-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
347+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
348348
err.note(
349349
"`static` and `const` variables can refer to other `const` variables. \
350350
A `const` variable, however, cannot refer to a `static` variable.",
@@ -361,9 +361,9 @@ pub struct ThreadLocalAccess;
361361
impl NonConstOp for ThreadLocalAccess {
362362
const IS_SUPPORTED_IN_MIRI: bool = false;
363363

364-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
364+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
365365
struct_span_err!(
366-
item.tcx.sess,
366+
ccx.tcx.sess,
367367
span,
368368
E0625,
369369
"thread-local statics cannot be \
@@ -376,19 +376,19 @@ impl NonConstOp for ThreadLocalAccess {
376376
#[derive(Debug)]
377377
pub struct UnionAccess;
378378
impl NonConstOp for UnionAccess {
379-
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
379+
fn is_allowed_in_item(&self, ccx: &ConstCx<'_, '_>) -> bool {
380380
// Union accesses are stable in all contexts except `const fn`.
381-
item.const_kind() != ConstKind::ConstFn
382-
|| item.tcx.features().enabled(Self::feature_gate().unwrap())
381+
ccx.const_kind() != ConstKind::ConstFn
382+
|| ccx.tcx.features().enabled(Self::feature_gate().unwrap())
383383
}
384384

385385
fn feature_gate() -> Option<Symbol> {
386386
Some(sym::const_fn_union)
387387
}
388388

389-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
389+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
390390
feature_err(
391-
&item.tcx.sess.parse_sess,
391+
&ccx.tcx.sess.parse_sess,
392392
sym::const_fn_union,
393393
span,
394394
"unions in const fn are unstable",

0 commit comments

Comments
 (0)