Make const_eval_select
a real intrinsic
This commit is contained in:
parent
8521a8c92d
commit
075084f772
27 changed files with 432 additions and 287 deletions
|
@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitable;
|
|||
use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{self, Span};
|
||||
use rustc_span::{self, sym, Span};
|
||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
|
||||
|
||||
use std::iter;
|
||||
|
@ -224,6 +224,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let minimum_input_count = expected_input_tys.len();
|
||||
let provided_arg_count = provided_args.len();
|
||||
|
||||
let is_const_eval_select = matches!(fn_def_id, Some(def_id) if
|
||||
self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
|
||||
&& self.tcx.is_intrinsic(def_id)
|
||||
&& self.tcx.item_name(def_id) == sym::const_eval_select);
|
||||
|
||||
// We introduce a helper function to demand that a given argument satisfy a given input
|
||||
// This is more complicated than just checking type equality, as arguments could be coerced
|
||||
// This version writes those types back so further type checking uses the narrowed types
|
||||
|
@ -259,6 +264,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
return Compatibility::Incompatible(coerce_error);
|
||||
}
|
||||
|
||||
// Check that second and third argument of `const_eval_select` must be `FnDef`, and additionally that
|
||||
// the second argument must be `const fn`. The first argument must be a tuple, but this is already expressed
|
||||
// in the function signature (`F: FnOnce<ARG>`), so I did not bother to add another check here.
|
||||
//
|
||||
// This check is here because there is currently no way to express a trait bound for `FnDef` types only.
|
||||
if is_const_eval_select && (1..=2).contains(&idx) {
|
||||
if let ty::FnDef(def_id, _) = checked_ty.kind() {
|
||||
if idx == 1 && !self.tcx.is_const_fn_raw(*def_id) {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(provided_arg.span, "this argument must be a `const fn`")
|
||||
.help("consult the documentation on `const_eval_select` for more information")
|
||||
.emit();
|
||||
}
|
||||
} else {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(provided_arg.span, "this argument must be a function item")
|
||||
.note(format!("expected a function item, found {checked_ty}"))
|
||||
.help(
|
||||
"consult the documentation on `const_eval_select` for more information",
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Check if the formal type is a supertype of the checked one
|
||||
// and register any such obligations for future type checks
|
||||
let supertype_error = self
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue