mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Stabilize const_fn_fn_ptr_basics and const_fn_trait_bound
This commit is contained in:
parent
d137c3a7bd
commit
7723506d13
@ -359,7 +359,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
match *ty.kind() {
|
||||
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
|
||||
ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
|
||||
ty::FnPtr(..) => self.check_op(ops::ty::FnPtr(kind)),
|
||||
|
||||
ty::Dynamic(preds, _) => {
|
||||
for pred in preds.iter() {
|
||||
@ -395,6 +394,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
| ty::PredicateKind::Projection(_)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::Trait(..)
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
||||
ty::PredicateKind::ObjectSafe(_) => {
|
||||
bug!("object safe predicate on function: {:#?}", predicate)
|
||||
@ -405,27 +405,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
|
||||
bug!("subtype/coerce predicate on function: {:#?}", predicate)
|
||||
}
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
||||
continue;
|
||||
}
|
||||
match pred.self_ty().kind() {
|
||||
ty::Param(p) => {
|
||||
let generics = tcx.generics_of(current);
|
||||
let def = generics.type_param(p, tcx);
|
||||
let span = tcx.def_span(def.def_id);
|
||||
|
||||
// These are part of the function signature, so treat them like
|
||||
// arguments when determining importance.
|
||||
let kind = LocalKind::Arg;
|
||||
|
||||
self.check_op_spanned(ops::ty::TraitBound(kind), span);
|
||||
}
|
||||
// other kinds of bounds are either tautologies
|
||||
// or cause errors in other passes
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match predicates.parent {
|
||||
@ -613,7 +592,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
),
|
||||
_,
|
||||
_,
|
||||
) => self.check_op(ops::FnPtrCast),
|
||||
) => {
|
||||
// Nothing to do here. Function pointer casts are allowed now.
|
||||
}
|
||||
|
||||
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
|
||||
// Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
|
||||
|
@ -355,31 +355,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FnPtrCast;
|
||||
impl<'tcx> NonConstOp<'tcx> for FnPtrCast {
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
} else {
|
||||
Status::Unstable(sym::const_fn_fn_ptr_basics)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(
|
||||
&self,
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_fn_ptr_basics,
|
||||
span,
|
||||
&format!("function pointer casts are not allowed in {}s", ccx.const_kind()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Generator(pub hir::GeneratorKind);
|
||||
impl<'tcx> NonConstOp<'tcx> for Generator {
|
||||
@ -821,40 +796,6 @@ pub mod ty {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FnPtr(pub mir::LocalKind);
|
||||
impl<'tcx> NonConstOp<'tcx> for FnPtr {
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
match self.0 {
|
||||
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
} else {
|
||||
Status::Unstable(sym::const_fn_fn_ptr_basics)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(
|
||||
&self,
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_fn_ptr_basics,
|
||||
span,
|
||||
&format!("function pointers cannot appear in {}s", ccx.const_kind()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplTrait;
|
||||
impl<'tcx> NonConstOp<'tcx> for ImplTrait {
|
||||
@ -876,49 +817,6 @@ pub mod ty {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TraitBound(pub mir::LocalKind);
|
||||
impl<'tcx> NonConstOp<'tcx> for TraitBound {
|
||||
fn importance(&self) -> DiagnosticImportance {
|
||||
match self.0 {
|
||||
mir::LocalKind::Var | mir::LocalKind::Temp => DiagnosticImportance::Secondary,
|
||||
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => {
|
||||
DiagnosticImportance::Primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_in_item(&self, ccx: &ConstCx<'_, 'tcx>) -> Status {
|
||||
if ccx.const_kind() != hir::ConstContext::ConstFn {
|
||||
Status::Allowed
|
||||
} else {
|
||||
Status::Unstable(sym::const_fn_trait_bound)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error(
|
||||
&self,
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let mut err = feature_err(
|
||||
&ccx.tcx.sess.parse_sess,
|
||||
sym::const_fn_trait_bound,
|
||||
span,
|
||||
"trait bounds other than `Sized` on const fn parameters are unstable",
|
||||
);
|
||||
|
||||
match ccx.fn_sig() {
|
||||
Some(fn_sig) if !fn_sig.span.contains(span) => {
|
||||
err.span_label(fn_sig.span, "function declared as const here");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DynTrait(pub mir::LocalKind);
|
||||
impl<'tcx> NonConstOp<'tcx> for DynTrait {
|
||||
|
@ -86,6 +86,10 @@ declare_features! (
|
||||
(accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
|
||||
/// Allows calling constructor functions in `const fn`.
|
||||
(accepted, const_constructor, "1.40.0", Some(61456), None),
|
||||
/// Allows using and casting function pointers in a `const fn`.
|
||||
(accepted, const_fn_fn_ptr_basics, "1.60.0", Some(57563), None),
|
||||
/// Allows trait bounds in `const fn`.
|
||||
(accepted, const_fn_trait_bound, "1.60.0", Some(93706), None),
|
||||
/// Allows calling `transmute` in const fn
|
||||
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
|
||||
/// Allows accessing fields of unions inside `const` functions.
|
||||
|
@ -338,10 +338,6 @@ declare_features! (
|
||||
(active, const_extern_fn, "1.40.0", Some(64926), None),
|
||||
/// Allows basic arithmetic on floating point types in a `const fn`.
|
||||
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
|
||||
/// Allows using and casting function pointers in a `const fn`.
|
||||
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
|
||||
/// Allows trait bounds in `const fn`.
|
||||
(active, const_fn_trait_bound, "1.53.0", Some(93706), None),
|
||||
/// Allows `for _ in _` loops in const contexts.
|
||||
(active, const_for, "1.56.0", Some(87575), None),
|
||||
/// Allows argument and return position `impl Trait` in a `const fn`.
|
||||
|
@ -140,7 +140,7 @@
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cfg_sanitize)]
|
||||
#![feature(const_deref)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(const_ptr_write)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
|
@ -158,8 +158,8 @@
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(cfg_target_has_atomic_equal_alignment)]
|
||||
#![feature(const_fn_floating_point_arithmetic)]
|
||||
#![feature(const_fn_fn_ptr_basics)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||
#![feature(const_impl_trait)]
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(const_precise_live_drops)]
|
||||
|
@ -20,8 +20,8 @@
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
#![feature(nll)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![feature(const_fn_fn_ptr_basics)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(extern_types)]
|
||||
|
@ -242,8 +242,8 @@
|
||||
#![feature(char_internals)]
|
||||
#![feature(concat_bytes)]
|
||||
#![feature(concat_idents)]
|
||||
#![feature(const_fn_fn_ptr_basics)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||
#![feature(const_format_args)]
|
||||
#![feature(const_io_structs)]
|
||||
#![feature(const_ip)]
|
||||
|
@ -32,32 +32,12 @@ pub fn is_min_const_fn<'a, 'tcx>(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, msrv:
|
||||
| ty::PredicateKind::Projection(_)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..)
|
||||
| ty::PredicateKind::Trait(..)
|
||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
||||
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
|
||||
ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
|
||||
ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
|
||||
ty::PredicateKind::Coerce(_) => panic!("coerce predicate on function: {:#?}", predicate),
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
|
||||
continue;
|
||||
}
|
||||
match pred.self_ty().kind() {
|
||||
ty::Param(ref p) => {
|
||||
let generics = tcx.generics_of(current);
|
||||
let def = generics.type_param(p, tcx);
|
||||
let span = tcx.def_span(def.def_id);
|
||||
return Err((
|
||||
span,
|
||||
"trait bounds other than `Sized` \
|
||||
on const fn parameters are unstable"
|
||||
.into(),
|
||||
));
|
||||
},
|
||||
// other kinds of bounds are either tautologies
|
||||
// or cause errors in other passes
|
||||
_ => continue,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
match predicates.parent {
|
||||
|
Loading…
Reference in New Issue
Block a user