Auto merge of #99943 - compiler-errors:tuple-trait, r=jackh726
Implement `std::marker::Tuple`, use it in `extern "rust-call"` and `Fn`-family traits Implements rust-lang/compiler-team#537 I made a few opinionated decisions in this implementation, specifically: 1. Enforcing `extern "rust-call"` on fn items during wfcheck, 2. Enforcing this for all functions (not just ones that have bodies), 3. Gating this `Tuple` marker trait behind its own feature, instead of grouping it into (e.g.) `unboxed_closures`. Still needing to be done: 1. Enforce that `extern "rust-call"` `fn`-ptrs are well-formed only if they have 1/2 args and the second one implements `Tuple`. (Doing this would fix ICE in #66696.) 2. Deny all explicit/user `impl`s of the `Tuple` trait, kinda like `Sized`. 3. Fixing `Tuple` trait built-in impl for chalk, so that chalkification tests are un-broken. Open questions: 1. Does this need t-lang or t-libs signoff? Fixes #99820
This commit is contained in:
commit
7eef946fc0
53 changed files with 843 additions and 244 deletions
|
@ -700,6 +700,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
|
||||
match obligation.cause.code().peel_derives() {
|
||||
ObligationCauseCode::RustCall => {
|
||||
err.set_primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument");
|
||||
}
|
||||
ObligationCauseCode::BindingObligation(def_id, _)
|
||||
| ObligationCauseCode::ItemObligation(def_id)
|
||||
if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() =>
|
||||
{
|
||||
err.code(rustc_errors::error_code!(E0059));
|
||||
err.set_primary_message(format!(
|
||||
"type parameter to bare `{}` trait must be a tuple",
|
||||
tcx.def_path_str(*def_id)
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
|
||||
&& predicate_is_const
|
||||
{
|
||||
|
@ -848,12 +867,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
let is_fn_trait = [
|
||||
self.tcx.lang_items().fn_trait(),
|
||||
self.tcx.lang_items().fn_mut_trait(),
|
||||
self.tcx.lang_items().fn_once_trait(),
|
||||
]
|
||||
.contains(&Some(trait_ref.def_id()));
|
||||
let is_fn_trait =
|
||||
ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some();
|
||||
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
|
||||
*trait_ref.skip_binder().self_ty().kind()
|
||||
{
|
||||
|
|
|
@ -2407,7 +2407,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
| ObligationCauseCode::CheckAssociatedTypeBounds { .. }
|
||||
| ObligationCauseCode::LetElse
|
||||
| ObligationCauseCode::BinOp { .. }
|
||||
| ObligationCauseCode::AscribeUserTypeProvePredicate(..) => {}
|
||||
| ObligationCauseCode::AscribeUserTypeProvePredicate(..)
|
||||
| ObligationCauseCode::RustCall => {}
|
||||
ObligationCauseCode::SliceOrArrayElem => {
|
||||
err.note("slice and array elements must have `Sized` type");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue