Move change to check_fn, fix up overloaded-calls-nontuple
This commit is contained in:
parent
1e9d5c70c1
commit
c825c74dc9
4 changed files with 47 additions and 27 deletions
|
@ -94,6 +94,37 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||
|
||||
fn_maybe_err(tcx, span, fn_sig.abi);
|
||||
|
||||
if fn_sig.abi == abi::Abi::RustCall {
|
||||
let expected_args = if let ImplicitSelfKind::None = decl.implicit_self { 1 } else { 2 };
|
||||
|
||||
let err = || {
|
||||
let item = match tcx.hir().get(fn_id) {
|
||||
Node::Item(hir::Item { kind: ItemKind::Fn(header, ..), .. }) => Some(header),
|
||||
Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(header, ..), ..
|
||||
}) => Some(header),
|
||||
// Closures are RustCall, but they tuple their arguments, so shouldn't be checked
|
||||
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => None,
|
||||
node => bug!("Item being checked wasn't a function/closure: {:?}", node),
|
||||
};
|
||||
|
||||
if let Some(header) = item {
|
||||
tcx.sess.span_err(header.span, "A function with the \"rust-call\" ABI must take a single non-self argument that is a tuple")
|
||||
}
|
||||
};
|
||||
|
||||
if fn_sig.inputs().len() != expected_args {
|
||||
err()
|
||||
} else {
|
||||
// FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on
|
||||
// This will probably require wide-scale changes to support a TupleKind obligation
|
||||
// We can't resolve this without knowing the type of the param
|
||||
if !matches!(fn_sig.inputs()[expected_args - 1].kind(), ty::Tuple(_) | ty::Param(_)) {
|
||||
err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if body.generator_kind.is_some() && can_be_generator.is_some() {
|
||||
let yield_ty = fcx
|
||||
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
|
||||
|
|
|
@ -521,31 +521,6 @@ fn typeck_with_fallback<'tcx>(
|
|||
|
||||
let fn_sig = fixup_opaque_types(tcx, &fn_sig);
|
||||
|
||||
if fn_sig.abi == abi::Abi::RustCall {
|
||||
let expected_args = if let ImplicitSelfKind::None = decl.implicit_self { 1 } else { 2 };
|
||||
|
||||
let err = || {
|
||||
let item = tcx.hir().expect_item(id);
|
||||
|
||||
if let hir::ItemKind::Fn(header, ..) = &item.kind {
|
||||
tcx.sess.span_err(header.span, "A function with the \"rust-call\" ABI must take a single non-self argument that is a tuple")
|
||||
} else {
|
||||
bug!("Item being checked wasn't a function")
|
||||
}
|
||||
};
|
||||
|
||||
if fn_sig.inputs().len() != expected_args {
|
||||
err()
|
||||
} else {
|
||||
// FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on
|
||||
// This will probably require wide-scale changes to support a TupleKind obligation
|
||||
// We can't resolve this without knowing the type of the param
|
||||
if !matches!(fn_sig.inputs()[expected_args - 1].kind(), ty::Tuple(_) | ty::Param(_)) {
|
||||
err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
|
||||
fcx
|
||||
} else {
|
||||
|
|
|
@ -11,11 +11,13 @@ impl FnMut<isize> for S {
|
|||
extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
|
||||
self.x + self.y + z
|
||||
}
|
||||
//~^^^ ERROR A function with the "rust-call" ABI must take a single non-self argument
|
||||
}
|
||||
|
||||
impl FnOnce<isize> for S {
|
||||
type Output = isize;
|
||||
extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
|
||||
//~^ ERROR A function with the "rust-call" ABI must take a single non-self argument
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
error: A function with the "rust-call" ABI must take a single non-self argument that is a tuple
|
||||
--> $DIR/overloaded-calls-nontuple.rs:11:5
|
||||
|
|
||||
LL | extern "rust-call" fn call_mut(&mut self, z: isize) -> isize {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: A function with the "rust-call" ABI must take a single non-self argument that is a tuple
|
||||
--> $DIR/overloaded-calls-nontuple.rs:19:5
|
||||
|
|
||||
LL | extern "rust-call" fn call_once(mut self, z: isize) -> isize { self.call_mut(z) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit
|
||||
--> $DIR/overloaded-calls-nontuple.rs:26:10
|
||||
--> $DIR/overloaded-calls-nontuple.rs:28:10
|
||||
|
|
||||
LL | drop(s(3))
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0059`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue