Skip to content

Commit 116d35d

Browse files
committed
const_evaluatable_unchecked to const eval
1 parent 660ca48 commit 116d35d

File tree

12 files changed

+51
-42
lines changed

12 files changed

+51
-42
lines changed

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#![feature(drain_filter)]
5656
#![feature(intra_doc_pointers)]
5757
#![feature(yeet_expr)]
58+
#![feature(result_option_inspect)]
5859
#![feature(const_option)]
5960
#![recursion_limit = "512"]
6061
#![allow(rustc::potential_query_instability)]

compiler/rustc_middle/src/mir/interpret/queries.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::mir;
44
use crate::ty::subst::InternalSubsts;
55
use crate::ty::visit::TypeVisitable;
66
use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
7+
use rustc_hir::def::DefKind;
78
use rustc_hir::def_id::DefId;
9+
use rustc_session::lint;
810
use rustc_span::{Span, DUMMY_SP};
911

1012
impl<'tcx> TyCtxt<'tcx> {
@@ -83,7 +85,29 @@ impl<'tcx> TyCtxt<'tcx> {
8385
match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
8486
Ok(Some(instance)) => {
8587
let cid = GlobalId { instance, promoted: None };
86-
self.const_eval_global_id_for_typeck(param_env, cid, span)
88+
self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
89+
// We are emitting the lint here instead of in `is_const_evaluatable`
90+
// as we normalize obligations before checking them, and normalization
91+
// uses this function to evaluate this constant.
92+
//
93+
// @lcnr believes that successfully evaluating even though there are
94+
// used generic parameters is a bug of evaluation, so checking for it
95+
// here does feel somewhat sensible.
96+
if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
97+
assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
98+
let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
99+
if mir_body.is_polymorphic {
100+
let Some(local_def_id) = ct.def.did.as_local() else { return };
101+
self.struct_span_lint_hir(
102+
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
103+
self.hir().local_def_id_to_hir_id(local_def_id),
104+
self.def_span(ct.def.did),
105+
"cannot use constants which depend on generic parameters in types",
106+
|err| err,
107+
)
108+
}
109+
}
110+
})
87111
}
88112
Ok(None) => Err(ErrorHandled::TooGeneric),
89113
Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+1-21
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@
99
//! `thir_abstract_const` which can then be checked for structural equality with other
1010
//! generic constants mentioned in the `caller_bounds` of the current environment.
1111
use rustc_errors::ErrorGuaranteed;
12-
use rustc_hir::def::DefKind;
1312
use rustc_infer::infer::InferCtxt;
1413
use rustc_middle::mir::interpret::ErrorHandled;
1514
use rustc_middle::ty::abstract_const::{
1615
walk_abstract_const, AbstractConst, FailureKind, Node, NotConstEvaluatable,
1716
};
1817
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
19-
use rustc_session::lint;
2018
use rustc_span::Span;
2119

2220
use std::iter;
@@ -262,25 +260,7 @@ pub fn is_const_evaluatable<'tcx>(
262260
Err(NotConstEvaluatable::Error(reported))
263261
}
264262
Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
265-
Ok(_) => {
266-
if uv.substs.has_non_region_param() {
267-
assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
268-
let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
269-
270-
if mir_body.is_polymorphic {
271-
let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
272-
tcx.struct_span_lint_hir(
273-
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
274-
tcx.hir().local_def_id_to_hir_id(local_def_id),
275-
span,
276-
"cannot use constants which depend on generic parameters in types",
277-
|err| err
278-
)
279-
}
280-
}
281-
282-
Ok(())
283-
},
263+
Ok(_) => Ok(()),
284264
}
285265
}
286266
}

src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: generic parameters may not be used in const operations
2-
--> $DIR/dependence_lint.rs:13:32
2+
--> $DIR/dependence_lint.rs:14:32
33
|
44
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
55
| ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
88
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
99

1010
error: generic parameters may not be used in const operations
11-
--> $DIR/dependence_lint.rs:20:37
11+
--> $DIR/dependence_lint.rs:21:37
1212
|
1313
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
1414
| ^ cannot perform const operation using `T`
@@ -17,7 +17,7 @@ LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
1717
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
1818

1919
warning: cannot use constants which depend on generic parameters in types
20-
--> $DIR/dependence_lint.rs:9:9
20+
--> $DIR/dependence_lint.rs:10:9
2121
|
2222
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
2323
| ^^^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_
2727
= note: `#[warn(const_evaluatable_unchecked)]` on by default
2828

2929
warning: cannot use constants which depend on generic parameters in types
30-
--> $DIR/dependence_lint.rs:16:9
30+
--> $DIR/dependence_lint.rs:17:9
3131
|
3232
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
error: overly complex generic constant
2-
--> $DIR/dependence_lint.rs:16:9
2+
--> $DIR/dependence_lint.rs:17:9
33
|
44
LL | [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
66
|
77
= help: consider moving this anonymous constant into a `const` function
88

99
error: overly complex generic constant
10-
--> $DIR/dependence_lint.rs:20:17
10+
--> $DIR/dependence_lint.rs:21:17
1111
|
1212
LL | let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
1414
|
1515
= help: consider moving this anonymous constant into a `const` function
1616

1717
error: unconstrained generic constant
18-
--> $DIR/dependence_lint.rs:13:12
18+
--> $DIR/dependence_lint.rs:14:12
1919
|
2020
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^
2222
|
2323
= help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
2424

2525
error: unconstrained generic constant
26-
--> $DIR/dependence_lint.rs:9:9
26+
--> $DIR/dependence_lint.rs:10:9
2727
|
2828
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
2929
| ^^^^^^^^^^^^^^^^^^^

src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// revisions: full gce
2+
// compile-flags: -Zdeduplicate-diagnostics=yes
23

34
#![cfg_attr(gce, feature(generic_const_exprs))]
45
#![allow(incomplete_features)]

src/test/ui/const-generics/generic_const_exprs/function-call.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// check-pass
2+
// compile-flags: -Zdeduplicate-diagnostics=yes
23

34
const fn foo<T>() -> usize {
45
// We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,

src/test/ui/const-generics/generic_const_exprs/function-call.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: cannot use constants which depend on generic parameters in types
2-
--> $DIR/function-call.rs:14:17
2+
--> $DIR/function-call.rs:15:17
33
|
44
LL | let _ = [0; foo::<T>()];
55
| ^^^^^^^^^^

src/test/ui/const-generics/min_const_generics/complex-expression.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// compile-flags: -Zdeduplicate-diagnostics=yes
12
use std::mem::size_of;
23

34
fn test<const N: usize>() {}

src/test/ui/const-generics/min_const_generics/complex-expression.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: generic parameters may not be used in const operations
2-
--> $DIR/complex-expression.rs:9:38
2+
--> $DIR/complex-expression.rs:10:38
33
|
44
LL | struct Break0<const N: usize>([u8; { N + 1 }]);
55
| ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
88
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
99

1010
error: generic parameters may not be used in const operations
11-
--> $DIR/complex-expression.rs:12:40
11+
--> $DIR/complex-expression.rs:13:40
1212
|
1313
LL | struct Break1<const N: usize>([u8; { { N } }]);
1414
| ^ cannot perform const operation using `N`
@@ -17,7 +17,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
1717
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
1818

1919
error: generic parameters may not be used in const operations
20-
--> $DIR/complex-expression.rs:16:17
20+
--> $DIR/complex-expression.rs:17:17
2121
|
2222
LL | let _: [u8; N + 1];
2323
| ^ cannot perform const operation using `N`
@@ -26,7 +26,7 @@ LL | let _: [u8; N + 1];
2626
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
2727

2828
error: generic parameters may not be used in const operations
29-
--> $DIR/complex-expression.rs:21:17
29+
--> $DIR/complex-expression.rs:22:17
3030
|
3131
LL | let _ = [0; N + 1];
3232
| ^ cannot perform const operation using `N`
@@ -35,7 +35,7 @@ LL | let _ = [0; N + 1];
3535
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
3636

3737
error: generic parameters may not be used in const operations
38-
--> $DIR/complex-expression.rs:25:45
38+
--> $DIR/complex-expression.rs:26:45
3939
|
4040
LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
4141
| ^ cannot perform const operation using `T`
@@ -44,7 +44,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
4444
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
4545

4646
error: generic parameters may not be used in const operations
47-
--> $DIR/complex-expression.rs:28:47
47+
--> $DIR/complex-expression.rs:29:47
4848
|
4949
LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
5050
| ^ cannot perform const operation using `T`
@@ -53,7 +53,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
5353
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
5454

5555
error: generic parameters may not be used in const operations
56-
--> $DIR/complex-expression.rs:32:32
56+
--> $DIR/complex-expression.rs:33:32
5757
|
5858
LL | let _: [u8; size_of::<*mut T>() + 1];
5959
| ^ cannot perform const operation using `T`
@@ -62,7 +62,7 @@ LL | let _: [u8; size_of::<*mut T>() + 1];
6262
= help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
6363

6464
warning: cannot use constants which depend on generic parameters in types
65-
--> $DIR/complex-expression.rs:37:17
65+
--> $DIR/complex-expression.rs:38:17
6666
|
6767
LL | let _ = [0; size_of::<*mut T>() + 1];
6868
| ^^^^^^^^^^^^^^^^^^^^^^^

src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// check-pass
2+
// compile-flags: -Zdeduplicate-diagnostics=yes
23
#![allow(dead_code)]
34

45
fn foo<T>() {

src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: cannot use constants which depend on generic parameters in types
2-
--> $DIR/const-evaluatable-unchecked.rs:5:9
2+
--> $DIR/const-evaluatable-unchecked.rs:6:9
33
|
44
LL | [0; std::mem::size_of::<*mut T>()];
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | [0; std::mem::size_of::<*mut T>()];
99
= note: `#[warn(const_evaluatable_unchecked)]` on by default
1010

1111
warning: cannot use constants which depend on generic parameters in types
12-
--> $DIR/const-evaluatable-unchecked.rs:16:21
12+
--> $DIR/const-evaluatable-unchecked.rs:17:21
1313
|
1414
LL | let _ = [0; Self::ASSOC];
1515
| ^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL | let _ = [0; Self::ASSOC];
1818
= note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
1919

2020
warning: cannot use constants which depend on generic parameters in types
21-
--> $DIR/const-evaluatable-unchecked.rs:28:21
21+
--> $DIR/const-evaluatable-unchecked.rs:29:21
2222
|
2323
LL | let _ = [0; Self::ASSOC];
2424
| ^^^^^^^^^^^

0 commit comments

Comments
 (0)