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() {
|
match *ty.kind() {
|
||||||
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
|
ty::Ref(_, _, hir::Mutability::Mut) => self.check_op(ops::ty::MutRef(kind)),
|
||||||
ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
|
ty::Opaque(..) => self.check_op(ops::ty::ImplTrait),
|
||||||
ty::FnPtr(..) => self.check_op(ops::ty::FnPtr(kind)),
|
|
||||||
|
|
||||||
ty::Dynamic(preds, _) => {
|
ty::Dynamic(preds, _) => {
|
||||||
for pred in preds.iter() {
|
for pred in preds.iter() {
|
||||||
@ -395,6 +394,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||||||
| ty::PredicateKind::Projection(_)
|
| ty::PredicateKind::Projection(_)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Trait(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
||||||
ty::PredicateKind::ObjectSafe(_) => {
|
ty::PredicateKind::ObjectSafe(_) => {
|
||||||
bug!("object safe predicate on function: {:#?}", predicate)
|
bug!("object safe predicate on function: {:#?}", predicate)
|
||||||
@ -405,27 +405,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
|||||||
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
|
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_) => {
|
||||||
bug!("subtype/coerce predicate on function: {:#?}", predicate)
|
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 {
|
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), _, _) => {
|
Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), _, _) => {
|
||||||
// Nothing to check here (`check_local_or_return_ty` ensures no trait objects occur
|
// 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)]
|
#[derive(Debug)]
|
||||||
pub struct Generator(pub hir::GeneratorKind);
|
pub struct Generator(pub hir::GeneratorKind);
|
||||||
impl<'tcx> NonConstOp<'tcx> for Generator {
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct ImplTrait;
|
pub struct ImplTrait;
|
||||||
impl<'tcx> NonConstOp<'tcx> for 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)]
|
#[derive(Debug)]
|
||||||
pub struct DynTrait(pub mir::LocalKind);
|
pub struct DynTrait(pub mir::LocalKind);
|
||||||
impl<'tcx> NonConstOp<'tcx> for DynTrait {
|
impl<'tcx> NonConstOp<'tcx> for DynTrait {
|
||||||
|
@ -86,6 +86,10 @@ declare_features! (
|
|||||||
(accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
|
(accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
|
||||||
/// Allows calling constructor functions in `const fn`.
|
/// Allows calling constructor functions in `const fn`.
|
||||||
(accepted, const_constructor, "1.40.0", Some(61456), None),
|
(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
|
/// Allows calling `transmute` in const fn
|
||||||
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
|
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
|
||||||
/// Allows accessing fields of unions inside `const` functions.
|
/// Allows accessing fields of unions inside `const` functions.
|
||||||
|
@ -338,10 +338,6 @@ declare_features! (
|
|||||||
(active, const_extern_fn, "1.40.0", Some(64926), None),
|
(active, const_extern_fn, "1.40.0", Some(64926), None),
|
||||||
/// Allows basic arithmetic on floating point types in a `const fn`.
|
/// Allows basic arithmetic on floating point types in a `const fn`.
|
||||||
(active, const_fn_floating_point_arithmetic, "1.48.0", Some(57241), None),
|
(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.
|
/// Allows `for _ in _` loops in const contexts.
|
||||||
(active, const_for, "1.56.0", Some(87575), None),
|
(active, const_for, "1.56.0", Some(87575), None),
|
||||||
/// Allows argument and return position `impl Trait` in a `const fn`.
|
/// Allows argument and return position `impl Trait` in a `const fn`.
|
||||||
|
@ -140,7 +140,7 @@
|
|||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(cfg_sanitize)]
|
#![feature(cfg_sanitize)]
|
||||||
#![feature(const_deref)]
|
#![feature(const_deref)]
|
||||||
#![feature(const_fn_trait_bound)]
|
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_ptr_write)]
|
#![feature(const_ptr_write)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
|
@ -158,8 +158,8 @@
|
|||||||
#![feature(cfg_target_has_atomic)]
|
#![feature(cfg_target_has_atomic)]
|
||||||
#![feature(cfg_target_has_atomic_equal_alignment)]
|
#![feature(cfg_target_has_atomic_equal_alignment)]
|
||||||
#![feature(const_fn_floating_point_arithmetic)]
|
#![feature(const_fn_floating_point_arithmetic)]
|
||||||
#![feature(const_fn_fn_ptr_basics)]
|
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||||
#![feature(const_fn_trait_bound)]
|
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||||
#![feature(const_impl_trait)]
|
#![feature(const_impl_trait)]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
#![feature(rustc_allow_const_fn_unstable)]
|
#![feature(rustc_allow_const_fn_unstable)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(const_fn_trait_bound)]
|
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||||
#![feature(const_fn_fn_ptr_basics)]
|
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||||
#![feature(allow_internal_unstable)]
|
#![feature(allow_internal_unstable)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
|
@ -242,8 +242,8 @@
|
|||||||
#![feature(char_internals)]
|
#![feature(char_internals)]
|
||||||
#![feature(concat_bytes)]
|
#![feature(concat_bytes)]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
#![feature(const_fn_fn_ptr_basics)]
|
#![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))]
|
||||||
#![feature(const_fn_trait_bound)]
|
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
|
||||||
#![feature(const_format_args)]
|
#![feature(const_format_args)]
|
||||||
#![feature(const_io_structs)]
|
#![feature(const_io_structs)]
|
||||||
#![feature(const_ip)]
|
#![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::Projection(_)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::ConstEvaluatable(..)
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Trait(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
||||||
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
|
ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
|
||||||
ty::PredicateKind::ClosureKind(..) => panic!("closure kind 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::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
|
||||||
ty::PredicateKind::Coerce(_) => panic!("coerce 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 {
|
match predicates.parent {
|
||||||
|
Loading…
Reference in New Issue
Block a user