Skip to content

Commit 629a613

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 61fbc6a + 4cdc31b commit 629a613

File tree

9 files changed

+180
-156
lines changed

9 files changed

+180
-156
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,
@@ -1984,14 +1987,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19841987
let span = body.source_info(location).span;
19851988
let ty = operand.ty(body, tcx);
19861989
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
1990+
let ccx = ConstCx::new_with_param_env(
1991+
tcx,
1992+
self.mir_def_id,
1993+
body,
1994+
self.param_env,
1995+
);
19871996
// To determine if `const_in_array_repeat_expressions` feature gate should
19881997
// be mentioned, need to check if the rvalue is promotable.
19891998
let should_suggest =
19901999
should_suggest_const_in_array_repeat_expressions_attribute(
1991-
tcx,
1992-
self.mir_def_id,
1993-
body,
1994-
operand,
2000+
&ccx, operand,
19952001
);
19962002
debug!("check_rvalue: should_suggest={:?}", should_suggest);
19972003

src/librustc_mir/transform/check_consts/mod.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,29 @@ 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 mir::Body<'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(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'mir mir::Body<'tcx>) -> Self {
3333
let param_env = tcx.param_env(def_id);
34+
Self::new_with_param_env(tcx, def_id, body, param_env)
35+
}
36+
37+
pub fn new_with_param_env(
38+
tcx: TyCtxt<'tcx>,
39+
def_id: DefId,
40+
body: &'mir mir::Body<'tcx>,
41+
param_env: ty::ParamEnv<'tcx>,
42+
) -> Self {
3443
let const_kind = ConstKind::for_item(tcx, def_id);
3544

36-
Item { body, tcx, def_id, param_env, const_kind }
45+
ConstCx { body, tcx, def_id, param_env, const_kind }
3746
}
3847

3948
/// 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));
@@ -113,16 +113,16 @@ impl NonConstOp for FnCallUnstable {
113113
#[derive(Debug)]
114114
pub struct HeapAllocation;
115115
impl NonConstOp for HeapAllocation {
116-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
116+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
117117
let mut err = struct_span_err!(
118-
item.tcx.sess,
118+
ccx.tcx.sess,
119119
span,
120120
E0010,
121121
"allocations are not allowed in {}s",
122-
item.const_kind()
122+
ccx.const_kind()
123123
);
124-
err.span_label(span, format!("allocation not allowed in {}s", item.const_kind()));
125-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
124+
err.span_label(span, format!("allocation not allowed in {}s", ccx.const_kind()));
125+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
126126
err.note(
127127
"The value of statics and constants must be known at compile time, \
128128
and they live for the entire lifetime of a program. Creating a boxed \
@@ -141,9 +141,9 @@ impl NonConstOp for IfOrMatch {
141141
Some(sym::const_if_match)
142142
}
143143

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

@@ -154,14 +154,14 @@ impl NonConstOp for InlineAsm {}
154154
#[derive(Debug)]
155155
pub struct LiveDrop;
156156
impl NonConstOp for LiveDrop {
157-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
157+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
158158
struct_span_err!(
159-
item.tcx.sess,
159+
ccx.tcx.sess,
160160
span,
161161
E0493,
162162
"destructors cannot be evaluated at compile-time"
163163
)
164-
.span_label(span, format!("{}s cannot evaluate destructors", item.const_kind()))
164+
.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()))
165165
.emit();
166166
}
167167
}
@@ -173,18 +173,18 @@ impl NonConstOp for Loop {
173173
Some(sym::const_loop)
174174
}
175175

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

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

204-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
204+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
205205
let mut err = feature_err(
206-
&item.tcx.sess.parse_sess,
206+
&ccx.tcx.sess.parse_sess,
207207
sym::const_mut_refs,
208208
span,
209209
&format!(
210210
"references in {}s may only refer \
211211
to immutable values",
212-
item.const_kind()
212+
ccx.const_kind()
213213
),
214214
);
215-
err.span_label(span, format!("{}s require immutable values", item.const_kind()));
216-
if item.tcx.sess.teach(&err.get_code().unwrap()) {
215+
err.span_label(span, format!("{}s require immutable values", ccx.const_kind()));
216+
if ccx.tcx.sess.teach(&err.get_code().unwrap()) {
217217
err.note(
218218
"References in statics and constants may only refer \
219219
to immutable values.\n\n\
@@ -236,12 +236,12 @@ impl NonConstOp for MutAddressOf {
236236
Some(sym::const_mut_refs)
237237
}
238238

239-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
239+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
240240
feature_err(
241-
&item.tcx.sess.parse_sess,
241+
&ccx.tcx.sess.parse_sess,
242242
sym::const_mut_refs,
243243
span,
244-
&format!("`&raw mut` is not allowed in {}s", item.const_kind()),
244+
&format!("`&raw mut` is not allowed in {}s", ccx.const_kind()),
245245
)
246246
.emit();
247247
}
@@ -262,12 +262,12 @@ impl NonConstOp for Panic {
262262
Some(sym::const_panic)
263263
}
264264

265-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
265+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
266266
feature_err(
267-
&item.tcx.sess.parse_sess,
267+
&ccx.tcx.sess.parse_sess,
268268
sym::const_panic,
269269
span,
270-
&format!("panicking in {}s is unstable", item.const_kind()),
270+
&format!("panicking in {}s is unstable", ccx.const_kind()),
271271
)
272272
.emit();
273273
}
@@ -280,12 +280,12 @@ impl NonConstOp for RawPtrComparison {
280280
Some(sym::const_compare_raw_pointers)
281281
}
282282

283-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
283+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
284284
feature_err(
285-
&item.tcx.sess.parse_sess,
285+
&ccx.tcx.sess.parse_sess,
286286
sym::const_compare_raw_pointers,
287287
span,
288-
&format!("comparing raw pointers inside {}", item.const_kind()),
288+
&format!("comparing raw pointers inside {}", ccx.const_kind()),
289289
)
290290
.emit();
291291
}
@@ -298,12 +298,12 @@ impl NonConstOp for RawPtrDeref {
298298
Some(sym::const_raw_ptr_deref)
299299
}
300300

301-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
301+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
302302
feature_err(
303-
&item.tcx.sess.parse_sess,
303+
&ccx.tcx.sess.parse_sess,
304304
sym::const_raw_ptr_deref,
305305
span,
306-
&format!("dereferencing raw pointers in {}s is unstable", item.const_kind(),),
306+
&format!("dereferencing raw pointers in {}s is unstable", ccx.const_kind(),),
307307
)
308308
.emit();
309309
}
@@ -316,12 +316,12 @@ impl NonConstOp for RawPtrToIntCast {
316316
Some(sym::const_raw_ptr_to_usize_cast)
317317
}
318318

319-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
319+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
320320
feature_err(
321-
&item.tcx.sess.parse_sess,
321+
&ccx.tcx.sess.parse_sess,
322322
sym::const_raw_ptr_to_usize_cast,
323323
span,
324-
&format!("casting pointers to integers in {}s is unstable", item.const_kind(),),
324+
&format!("casting pointers to integers in {}s is unstable", ccx.const_kind(),),
325325
)
326326
.emit();
327327
}
@@ -331,22 +331,22 @@ impl NonConstOp for RawPtrToIntCast {
331331
#[derive(Debug)]
332332
pub struct StaticAccess;
333333
impl NonConstOp for StaticAccess {
334-
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
335-
item.const_kind().is_static()
334+
fn is_allowed_in_item(&self, ccx: &ConstCx<'_, '_>) -> bool {
335+
ccx.const_kind().is_static()
336336
}
337337

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

366-
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
366+
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
367367
struct_span_err!(
368-
item.tcx.sess,
368+
ccx.tcx.sess,
369369
span,
370370
E0625,
371371
"thread-local statics cannot be \
@@ -378,19 +378,19 @@ impl NonConstOp for ThreadLocalAccess {
378378
#[derive(Debug)]
379379
pub struct UnionAccess;
380380
impl NonConstOp for UnionAccess {
381-
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
381+
fn is_allowed_in_item(&self, ccx: &ConstCx<'_, '_>) -> bool {
382382
// Union accesses are stable in all contexts except `const fn`.
383-
item.const_kind() != ConstKind::ConstFn
384-
|| item.tcx.features().enabled(Self::feature_gate().unwrap())
383+
ccx.const_kind() != ConstKind::ConstFn
384+
|| ccx.tcx.features().enabled(Self::feature_gate().unwrap())
385385
}
386386

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

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

0 commit comments

Comments
 (0)