Auto merge of #96964 - oli-obk:const_trait_mvp, r=compiler-errors
Replace `#[default_method_body_is_const]` with `#[const_trait]` pulled out of #96077 related issues: #67792 and #92158 cc `@fee1-dead` This is groundwork to only allowing `impl const Trait` for traits that are marked with `#[const_trait]`. This is necessary to prevent adding a new default method from becoming a breaking change (as it could be a non-const fn).
This commit is contained in:
commit
5c780b98d1
32 changed files with 82 additions and 260 deletions
|
@ -277,8 +277,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if !ecx.tcx.is_const_fn_raw(def.did) {
|
||||
// allow calling functions marked with #[default_method_body_is_const].
|
||||
if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) {
|
||||
// allow calling functions inside a trait marked with #[const_trait].
|
||||
if !ecx.tcx.is_const_default_method(def.did) {
|
||||
// We certainly do *not* want to actually call the fn
|
||||
// though, so be sure we return here.
|
||||
throw_unsup_format!("calling non-const function `{}`", instance)
|
||||
|
|
|
@ -9,6 +9,7 @@ Rust MIR: a lowered representation of Rust.
|
|||
#![feature(control_flow_enum)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(min_specialization)]
|
||||
|
|
|
@ -711,8 +711,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
let mut nonconst_call_permission = false;
|
||||
|
||||
// Attempting to call a trait method?
|
||||
if let Some(trait_id) = tcx.trait_of_item(callee) {
|
||||
trace!("attempting to call a trait method");
|
||||
|
@ -774,13 +772,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
_ if !tcx.is_const_fn_raw(callee) => {
|
||||
// At this point, it is only legal when the caller is marked with
|
||||
// #[default_method_body_is_const], and the callee is in the same
|
||||
// trait.
|
||||
let callee_trait = tcx.trait_of_item(callee);
|
||||
if callee_trait.is_some()
|
||||
&& tcx.has_attr(caller.to_def_id(), sym::default_method_body_is_const)
|
||||
&& callee_trait == tcx.trait_of_item(caller)
|
||||
// At this point, it is only legal when the caller is in a trait
|
||||
// marked with #[const_trait], and the callee is in the same trait.
|
||||
let mut nonconst_call_permission = false;
|
||||
if let Some(callee_trait) = tcx.trait_of_item(callee)
|
||||
&& tcx.has_attr(callee_trait, sym::const_trait)
|
||||
&& Some(callee_trait) == tcx.trait_of_item(caller)
|
||||
// Can only call methods when it's `<Self as TheTrait>::f`.
|
||||
&& tcx.types.self_param == substs.type_at(0)
|
||||
{
|
||||
|
@ -874,16 +871,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
let is_intrinsic = tcx.is_intrinsic(callee);
|
||||
|
||||
if !tcx.is_const_fn_raw(callee) {
|
||||
if tcx.trait_of_item(callee).is_some() {
|
||||
if tcx.has_attr(callee, sym::default_method_body_is_const) {
|
||||
// To get to here we must have already found a const impl for the
|
||||
// trait, but for it to still be non-const can be that the impl is
|
||||
// using default method bodies.
|
||||
nonconst_call_permission = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !nonconst_call_permission {
|
||||
if !tcx.is_const_default_method(callee) {
|
||||
// To get to here we must have already found a const impl for the
|
||||
// trait, but for it to still be non-const can be that the impl is
|
||||
// using default method bodies.
|
||||
self.check_op(ops::FnCallNonConst {
|
||||
caller,
|
||||
callee,
|
||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir as hir;
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::{sym, Symbol};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
pub use self::qualifs::Qualif;
|
||||
|
||||
|
@ -84,10 +84,10 @@ pub fn rustc_allow_const_fn_unstable(
|
|||
// functions are subject to more stringent restrictions than "const-unstable" functions: They
|
||||
// cannot use unstable features and can only call other "const-stable" functions.
|
||||
pub fn is_const_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||
// A default body marked const is not const-stable because const
|
||||
// A default body in a `#[const_trait]` is not const-stable because const
|
||||
// trait fns currently cannot be const-stable. We shouldn't
|
||||
// restrict default bodies to only call const-stable functions.
|
||||
if tcx.has_attr(def_id, sym::default_method_body_is_const) {
|
||||
if tcx.is_const_default_method(def_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue