Skip to content

Commit ef6100e

Browse files
committed
convert to future compat lint
1 parent c81935e commit ef6100e

File tree

6 files changed

+65
-39
lines changed

6 files changed

+65
-39
lines changed

compiler/rustc_session/src/lint/builtin.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,16 @@ declare_lint! {
539539
};
540540
}
541541

542+
declare_lint! {
543+
pub CONST_EVALUATABLE_UNCHECKED,
544+
Warn,
545+
"detects a generic constant is used in a type without a emitting a warning",
546+
@future_incompatible = FutureIncompatibleInfo {
547+
reference: "TODO",
548+
edition: None,
549+
};
550+
}
551+
542552
declare_lint_pass! {
543553
/// Does nothing as a lint pass, but registers some `Lint`s
544554
/// that are used by other parts of the compiler.
@@ -612,6 +622,7 @@ declare_lint_pass! {
612622
UNSAFE_OP_IN_UNSAFE_FN,
613623
INCOMPLETE_INCLUDE,
614624
CENUM_IMPL_DROP_CAST,
625+
CONST_EVALUATABLE_UNCHECKED,
615626
]
616627
}
617628

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,43 @@
1-
use rustc_middle::ty::{self, TypeFoldable};
1+
use rustc_hir::def::DefKind;
22
use rustc_infer::infer::InferCtxt;
3+
use rustc_middle::mir::interpret::ErrorHandled;
34
use rustc_middle::ty::subst::SubstsRef;
4-
use rustc_span::Span;
5+
use rustc_middle::ty::{self, TypeFoldable};
6+
use rustc_session::lint;
57
use rustc_span::def_id::DefId;
6-
use rustc_middle::mir::interpret::ErrorHandled;
7-
use rustc_hir::def::DefKind;
8+
use rustc_span::Span;
89

910
pub fn is_const_evaluatable<'cx, 'tcx>(
1011
infcx: &InferCtxt<'cx, 'tcx>,
1112
def: ty::WithOptConstParam<DefId>,
1213
substs: SubstsRef<'tcx>,
1314
param_env: ty::ParamEnv<'tcx>,
1415
span: Span,
15-
) -> Result<(), ErrorHandled>
16-
{
16+
) -> Result<(), ErrorHandled> {
17+
let future_compat_lint = || {
18+
if let Some(local_def_id) = def.did.as_local() {
19+
infcx.tcx.struct_span_lint_hir(
20+
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
21+
infcx.tcx.hir().as_local_hir_id(local_def_id),
22+
span,
23+
|err| {
24+
err.build("cannot use constants which depend on generic parameters in types")
25+
.emit();
26+
},
27+
);
28+
}
29+
};
30+
31+
// FIXME: We should only try to evaluate a given constant here if it is fully concrete
32+
// as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
33+
//
34+
// We previously did not check this, so we only emit a future compat warning if
35+
// const evaluation succeeds and the given constant is still polymorphic for now
36+
// and hopefully soon change this to an error.
37+
//
38+
// See #74595 for more details about this.
39+
let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
40+
1741
let def_kind = infcx.tcx.def_kind(def.did);
1842
match def_kind {
1943
DefKind::AnonConst => {
@@ -22,33 +46,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
2246
} else {
2347
infcx.tcx.optimized_mir(def.did)
2448
};
25-
if mir_body.is_polymorphic {
26-
return Err(ErrorHandled::TooGeneric);
49+
if mir_body.is_polymorphic && concrete.is_ok() {
50+
future_compat_lint();
2751
}
2852
}
2953
_ => {
30-
if substs.has_param_types_or_consts() {
31-
return Err(ErrorHandled::TooGeneric);
54+
if substs.has_param_types_or_consts() && concrete.is_ok() {
55+
future_compat_lint();
3256
}
3357
}
3458
}
3559

36-
match infcx.const_eval_resolve(
37-
param_env,
38-
def,
39-
substs,
40-
None,
41-
Some(span),
42-
) {
43-
Ok(_) => Ok(()),
44-
Err(err) => {
45-
if matches!(err, ErrorHandled::TooGeneric) {
46-
infcx.tcx.sess.delay_span_bug(
47-
span,
48-
&format!("ConstEvaluatable too generic: {:?}, {:?}, {:?}", def, substs, param_env),
49-
);
50-
}
51-
Err(err)
52-
}
53-
}
54-
}
60+
concrete.map(drop)
61+
}

src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-pass
12
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
23

34
extern crate core;
@@ -7,7 +8,8 @@ use core::intrinsics::discriminant_value;
78
enum MyWeirdOption<T> {
89
None = 0,
910
Some(T) = core::mem::size_of::<*mut T>(),
10-
//~^ ERROR constant expression depends on a generic parameter
11+
//~^ WARN cannot use constants which depend on generic parameters in types
12+
//~| WARN this was previously accepted by the compiler but is being phased out
1113
}
1214

1315
fn main() {
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
error: constant expression depends on a generic parameter
2-
--> $DIR/issue-70453-polymorphic-ctfe.rs:9:15
1+
warning: cannot use constants which depend on generic parameters in types
2+
--> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
33
|
44
LL | Some(T) = core::mem::size_of::<*mut T>(),
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: this may fail depending on what value the parameter takes
7+
= note: `#[warn(const_evaluatable_unchecked)]` on by default
8+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9+
= note: for more information, see TODO
810

9-
error: aborting due to previous error
11+
warning: 1 warning emitted
1012

src/test/ui/lazy_normalization_consts/issue-73980.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// check-pass
12
#![feature(lazy_normalization_consts)]
23
#![allow(incomplete_features)]
34

@@ -9,6 +10,7 @@ impl<T: ?Sized> L<T> {
910
}
1011

1112
impl<T> X<T, [u8; L::<T>::S]> {}
12-
//~^ ERROR constant expression depends on a generic parameter
13+
//~^ WARN cannot use constants which depend on generic parameters
14+
//~| WARN this was previously accepted by the compiler but is being phased out
1315

1416
fn main() {}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
error: constant expression depends on a generic parameter
2-
--> $DIR/issue-73980.rs:11:9
1+
warning: cannot use constants which depend on generic parameters in types
2+
--> $DIR/issue-73980.rs:12:9
33
|
44
LL | impl<T> X<T, [u8; L::<T>::S]> {}
55
| ^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: this may fail depending on what value the parameter takes
7+
= note: `#[warn(const_evaluatable_unchecked)]` on by default
8+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9+
= note: for more information, see TODO
810

9-
error: aborting due to previous error
11+
warning: 1 warning emitted
1012

0 commit comments

Comments
 (0)