1
Fork 0

Remove #[default..] and add #[const_trait]

This commit is contained in:
Deadbeef 2022-03-16 20:49:54 +11:00 committed by Oli Scherer
parent f558990814
commit 257f06587c
30 changed files with 74 additions and 250 deletions

View file

@ -277,8 +277,9 @@ 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 !matches!(ecx.tcx.trait_of_item(def.did), Some(trait_id) if ecx.tcx.has_attr(trait_id, sym::const_trait))
{
// 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)

View file

@ -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)]

View file

@ -774,13 +774,11 @@ 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.
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)
{
@ -875,7 +873,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
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) {
if let Some(callee_trait) = tcx.trait_of_item(callee) && tcx.has_attr(callee_trait, sym::const_trait) {
// 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.

View file

@ -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 let Some(trait_id) = tcx.trait_of_item(def_id) && tcx.has_attr(trait_id, sym::const_trait) {
return false;
}