1
Fork 0

Stabilize const_fn_fn_ptr_basics and const_fn_trait_bound

This commit is contained in:
Eric Holk 2022-02-08 16:33:15 -08:00
parent d137c3a7bd
commit 7723506d13
9 changed files with 16 additions and 157 deletions

View file

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

View file

@ -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 {