Add a sane error for rust-call functions not taking tuples during type checking, and associated UI tests

This commit is contained in:
Rune Tynan 2020-11-11 18:15:39 -05:00
parent 9d78d1d027
commit 91eabf59d5
No known key found for this signature in database
GPG Key ID: 7ECC932F8B2C731E
5 changed files with 62 additions and 7 deletions

View File

@ -108,7 +108,7 @@ use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::intravisit::Visitor;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{HirIdMap, Node};
use rustc_hir::{HirIdMap, ImplicitSelfKind, Node};
use rustc_index::bit_set::BitSet;
use rustc_index::vec::Idx;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -137,6 +137,7 @@ use crate::util::common::indenter;
use self::coercion::DynamicCoerceMany;
pub use self::Expectation::*;
use rustc_target::spec::abi;
#[macro_export]
macro_rules! type_error_struct {
@ -520,6 +521,35 @@ 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 = || {
if let Node::Item(item) = tcx.hir().get(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!("Couldn't get span of FnHeader being checked")
}
};
if fn_sig.inputs().len() != expected_args {
err()
} else {
match fn_sig.inputs()[expected_args - 1].kind() {
ty::Tuple(_) => (),
// 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
ty::Param(_) => (),
_ => {
err()
}
}
}
}
let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
fcx
} else {

View File

@ -0,0 +1,8 @@
#![feature(unboxed_closures)]
extern "rust-call" fn b(_i: i32) {}
//~^ ERROR A function with the "rust-call" ABI must take a single non-self argument that is a tuple
fn main () {
b(10);
}

View File

@ -0,0 +1,8 @@
error: A function with the "rust-call" ABI must take a single non-self argument that is a tuple
--> $DIR/issue-22565-rust-call.rs:3:1
|
LL | extern "rust-call" fn b(_i: i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,9 @@
// check-pass
#![feature(unboxed_closures)]
extern "rust-call" fn foo<T>(_: T) {}
fn main() {
foo(());
foo((1, 2));
}

View File

@ -26,7 +26,7 @@ LL | extern "vectorcall" fn f3() {}
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:18:8
|
LL | extern "rust-call" fn f4() {}
LL | extern "rust-call" fn f4(_: ()) {}
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
@ -113,7 +113,7 @@ LL | extern "vectorcall" fn m3();
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:33:12
|
LL | extern "rust-call" fn m4();
LL | extern "rust-call" fn m4(_: ());
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
@ -183,7 +183,7 @@ LL | extern "vectorcall" fn dm3() {}
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:42:12
|
LL | extern "rust-call" fn dm4() {}
LL | extern "rust-call" fn dm4(_: ()) {}
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
@ -270,7 +270,7 @@ LL | extern "vectorcall" fn m3() {}
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:60:12
|
LL | extern "rust-call" fn m4() {}
LL | extern "rust-call" fn m4(_: ()) {}
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
@ -357,7 +357,7 @@ LL | extern "vectorcall" fn im3() {}
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:76:12
|
LL | extern "rust-call" fn im4() {}
LL | extern "rust-call" fn im4(_: ()) {}
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
@ -444,7 +444,7 @@ LL | type A3 = extern "vectorcall" fn();
error[E0658]: rust-call ABI is subject to change
--> $DIR/feature-gate-abi.rs:89:18
|
LL | type A4 = extern "rust-call" fn();
LL | type A4 = extern "rust-call" fn(_: ());
| ^^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information