convert to future compat lint
This commit is contained in:
parent
c81935e6df
commit
ef6100e846
@ -539,6 +539,16 @@
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub CONST_EVALUATABLE_UNCHECKED,
|
||||
Warn,
|
||||
"detects a generic constant is used in a type without a emitting a warning",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "TODO",
|
||||
edition: None,
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint_pass! {
|
||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||
/// that are used by other parts of the compiler.
|
||||
@ -612,6 +622,7 @@
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
INCOMPLETE_INCLUDE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
CONST_EVALUATABLE_UNCHECKED,
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
use rustc_middle::ty::{self, TypeFoldable};
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, TypeFoldable};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
|
||||
pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||
infcx: &InferCtxt<'cx, 'tcx>,
|
||||
@ -12,8 +13,31 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||
substs: SubstsRef<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<(), ErrorHandled>
|
||||
{
|
||||
) -> Result<(), ErrorHandled> {
|
||||
let future_compat_lint = || {
|
||||
if let Some(local_def_id) = def.did.as_local() {
|
||||
infcx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
|
||||
infcx.tcx.hir().as_local_hir_id(local_def_id),
|
||||
span,
|
||||
|err| {
|
||||
err.build("cannot use constants which depend on generic parameters in types")
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: We should only try to evaluate a given constant here if it is fully concrete
|
||||
// as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
|
||||
//
|
||||
// We previously did not check this, so we only emit a future compat warning if
|
||||
// const evaluation succeeds and the given constant is still polymorphic for now
|
||||
// and hopefully soon change this to an error.
|
||||
//
|
||||
// See #74595 for more details about this.
|
||||
let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
|
||||
|
||||
let def_kind = infcx.tcx.def_kind(def.did);
|
||||
match def_kind {
|
||||
DefKind::AnonConst => {
|
||||
@ -22,33 +46,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||
} else {
|
||||
infcx.tcx.optimized_mir(def.did)
|
||||
};
|
||||
if mir_body.is_polymorphic {
|
||||
return Err(ErrorHandled::TooGeneric);
|
||||
if mir_body.is_polymorphic && concrete.is_ok() {
|
||||
future_compat_lint();
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if substs.has_param_types_or_consts() {
|
||||
return Err(ErrorHandled::TooGeneric);
|
||||
if substs.has_param_types_or_consts() && concrete.is_ok() {
|
||||
future_compat_lint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match infcx.const_eval_resolve(
|
||||
param_env,
|
||||
def,
|
||||
substs,
|
||||
None,
|
||||
Some(span),
|
||||
) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
if matches!(err, ErrorHandled::TooGeneric) {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!("ConstEvaluatable too generic: {:?}, {:?}, {:?}", def, substs, param_env),
|
||||
);
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
concrete.map(drop)
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
// run-pass
|
||||
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
|
||||
|
||||
extern crate core;
|
||||
@ -7,7 +8,8 @@
|
||||
enum MyWeirdOption<T> {
|
||||
None = 0,
|
||||
Some(T) = core::mem::size_of::<*mut T>(),
|
||||
//~^ ERROR constant expression depends on a generic parameter
|
||||
//~^ WARN cannot use constants which depend on generic parameters in types
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -1,10 +1,12 @@
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/issue-70453-polymorphic-ctfe.rs:9:15
|
||||
warning: cannot use constants which depend on generic parameters in types
|
||||
--> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
|
||||
|
|
||||
LL | Some(T) = core::mem::size_of::<*mut T>(),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see TODO
|
||||
|
||||
error: aborting due to previous error
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// check-pass
|
||||
#![feature(lazy_normalization_consts)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
@ -9,6 +10,7 @@ impl<T: ?Sized> L<T> {
|
||||
}
|
||||
|
||||
impl<T> X<T, [u8; L::<T>::S]> {}
|
||||
//~^ ERROR constant expression depends on a generic parameter
|
||||
//~^ WARN cannot use constants which depend on generic parameters
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,10 +1,12 @@
|
||||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/issue-73980.rs:11:9
|
||||
warning: cannot use constants which depend on generic parameters in types
|
||||
--> $DIR/issue-73980.rs:12:9
|
||||
|
|
||||
LL | impl<T> X<T, [u8; L::<T>::S]> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
= note: `#[warn(const_evaluatable_unchecked)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see TODO
|
||||
|
||||
error: aborting due to previous error
|
||||
warning: 1 warning emitted
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user