convert to future compat lint
This commit is contained in:
parent
c81935e6df
commit
ef6100e846
6 changed files with 67 additions and 41 deletions
|
@ -539,6 +539,16 @@ declare_lint! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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! {
|
declare_lint_pass! {
|
||||||
/// Does nothing as a lint pass, but registers some `Lint`s
|
/// Does nothing as a lint pass, but registers some `Lint`s
|
||||||
/// that are used by other parts of the compiler.
|
/// that are used by other parts of the compiler.
|
||||||
|
@ -612,6 +622,7 @@ declare_lint_pass! {
|
||||||
UNSAFE_OP_IN_UNSAFE_FN,
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
INCOMPLETE_INCLUDE,
|
INCOMPLETE_INCLUDE,
|
||||||
CENUM_IMPL_DROP_CAST,
|
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_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>(
|
pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
infcx: &InferCtxt<'cx, 'tcx>,
|
infcx: &InferCtxt<'cx, 'tcx>,
|
||||||
|
@ -12,8 +13,31 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
span: Span,
|
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);
|
let def_kind = infcx.tcx.def_kind(def.did);
|
||||||
match def_kind {
|
match def_kind {
|
||||||
DefKind::AnonConst => {
|
DefKind::AnonConst => {
|
||||||
|
@ -22,33 +46,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||||
} else {
|
} else {
|
||||||
infcx.tcx.optimized_mir(def.did)
|
infcx.tcx.optimized_mir(def.did)
|
||||||
};
|
};
|
||||||
if mir_body.is_polymorphic {
|
if mir_body.is_polymorphic && concrete.is_ok() {
|
||||||
return Err(ErrorHandled::TooGeneric);
|
future_compat_lint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if substs.has_param_types_or_consts() {
|
if substs.has_param_types_or_consts() && concrete.is_ok() {
|
||||||
return Err(ErrorHandled::TooGeneric);
|
future_compat_lint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match infcx.const_eval_resolve(
|
concrete.map(drop)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
// run-pass
|
||||||
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
|
#![feature(arbitrary_enum_discriminant, core_intrinsics)]
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
@ -7,7 +8,8 @@ use core::intrinsics::discriminant_value;
|
||||||
enum MyWeirdOption<T> {
|
enum MyWeirdOption<T> {
|
||||||
None = 0,
|
None = 0,
|
||||||
Some(T) = core::mem::size_of::<*mut T>(),
|
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() {
|
fn main() {
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
error: constant expression depends on a generic parameter
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/issue-70453-polymorphic-ctfe.rs:9:15
|
--> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
|
||||||
|
|
|
|
||||||
LL | Some(T) = core::mem::size_of::<*mut T>(),
|
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)]
|
#![feature(lazy_normalization_consts)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ impl<T: ?Sized> L<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> X<T, [u8; L::<T>::S]> {}
|
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() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
error: constant expression depends on a generic parameter
|
warning: cannot use constants which depend on generic parameters in types
|
||||||
--> $DIR/issue-73980.rs:11:9
|
--> $DIR/issue-73980.rs:12:9
|
||||||
|
|
|
|
||||||
LL | impl<T> X<T, [u8; L::<T>::S]> {}
|
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…
Add table
Add a link
Reference in a new issue