Explicitly reject const C-variadic functions
Trying to use C-variadics in a const function would previously fail with an error like "destructor of `VaListImpl<'_>` cannot be evaluated at compile-time". Add an explicit check for const C-variadics to provide a clearer error: "functions cannot be both `const` and C-variadic".
This commit is contained in:
parent
8508e65895
commit
f91b5ceaf2
5 changed files with 120 additions and 22 deletions
|
@ -42,6 +42,10 @@ ast_passes_const_and_async = functions cannot be both `const` and `async`
|
||||||
.async = `async` because of this
|
.async = `async` because of this
|
||||||
.label = {""}
|
.label = {""}
|
||||||
|
|
||||||
|
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
|
||||||
|
.const = `const` because of this
|
||||||
|
.variadic = C-variadic because of this
|
||||||
|
|
||||||
ast_passes_const_without_body =
|
ast_passes_const_without_body =
|
||||||
free constant item without body
|
free constant item without body
|
||||||
.suggestion = provide a definition for the constant
|
.suggestion = provide a definition for the constant
|
||||||
|
|
|
@ -482,8 +482,11 @@ impl<'a> AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reject C-variadic type unless the function is foreign,
|
/// Reject invalid C-variadic types.
|
||||||
/// or free and `unsafe extern "C"` semantically.
|
///
|
||||||
|
/// C-variadics must be:
|
||||||
|
/// - Non-const
|
||||||
|
/// - Either foreign, or free and `unsafe extern "C"` semantically
|
||||||
fn check_c_variadic_type(&self, fk: FnKind<'a>) {
|
fn check_c_variadic_type(&self, fk: FnKind<'a>) {
|
||||||
let variadic_spans: Vec<_> = fk
|
let variadic_spans: Vec<_> = fk
|
||||||
.decl()
|
.decl()
|
||||||
|
@ -497,6 +500,18 @@ impl<'a> AstValidator<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(header) = fk.header() {
|
||||||
|
if let Const::Yes(const_span) = header.constness {
|
||||||
|
let mut spans = variadic_spans.clone();
|
||||||
|
spans.push(const_span);
|
||||||
|
self.err_handler().emit_err(errors::ConstAndCVariadic {
|
||||||
|
spans,
|
||||||
|
const_span,
|
||||||
|
variadic_spans: variadic_spans.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match (fk.ctxt(), fk.header()) {
|
match (fk.ctxt(), fk.header()) {
|
||||||
(Some(FnCtxt::Foreign), _) => return,
|
(Some(FnCtxt::Foreign), _) => return,
|
||||||
(Some(FnCtxt::Free), Some(header)) => match header.ext {
|
(Some(FnCtxt::Free), Some(header)) => match header.ext {
|
||||||
|
|
|
@ -583,6 +583,17 @@ pub struct ConstAndAsync {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(ast_passes_const_and_c_variadic)]
|
||||||
|
pub struct ConstAndCVariadic {
|
||||||
|
#[primary_span]
|
||||||
|
pub spans: Vec<Span>,
|
||||||
|
#[label(ast_passes_const)]
|
||||||
|
pub const_span: Span,
|
||||||
|
#[label(ast_passes_variadic)]
|
||||||
|
pub variadic_spans: Vec<Span>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_pattern_in_foreign, code = "E0130")]
|
#[diag(ast_passes_pattern_in_foreign, code = "E0130")]
|
||||||
pub struct PatternInForeign {
|
pub struct PatternInForeign {
|
||||||
|
|
|
@ -32,6 +32,18 @@ extern "C" fn f3_3(..., x: isize) {}
|
||||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
//~| ERROR `...` must be the last argument of a C-variadic function
|
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||||
|
|
||||||
|
const unsafe extern "C" fn f4_1(x: isize, ...) {}
|
||||||
|
//~^ ERROR functions cannot be both `const` and C-variadic
|
||||||
|
|
||||||
|
const extern "C" fn f4_2(x: isize, ...) {}
|
||||||
|
//~^ ERROR functions cannot be both `const` and C-variadic
|
||||||
|
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
|
||||||
|
const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||||
|
//~^ ERROR functions cannot be both `const` and C-variadic
|
||||||
|
//~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn e_f1(...);
|
fn e_f1(...);
|
||||||
//~^ ERROR C-variadic function must be declared with at least one named argument
|
//~^ ERROR C-variadic function must be declared with at least one named argument
|
||||||
|
@ -53,6 +65,9 @@ impl X {
|
||||||
fn i_f4(..., x: isize, ...) {}
|
fn i_f4(..., x: isize, ...) {}
|
||||||
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
//~| ERROR `...` must be the last argument of a C-variadic function
|
//~| ERROR `...` must be the last argument of a C-variadic function
|
||||||
|
const fn i_f5(x: isize, ...) {}
|
||||||
|
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
//~| ERROR functions cannot be both `const` and C-variadic
|
||||||
}
|
}
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
|
|
|
@ -76,119 +76,172 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
LL | extern "C" fn f3_3(..., x: isize) {}
|
LL | extern "C" fn f3_3(..., x: isize) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
|
error: functions cannot be both `const` and C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:35:1
|
||||||
|
|
|
||||||
|
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
|
||||||
|
| ^^^^^ `const` because of this ^^^ C-variadic because of this
|
||||||
|
|
||||||
|
error: functions cannot be both `const` and C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:38:1
|
||||||
|
|
|
||||||
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||||
|
| ^^^^^ `const` because of this ^^^ C-variadic because of this
|
||||||
|
|
||||||
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:38:36
|
||||||
|
|
|
||||||
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: `...` must be the last argument of a C-variadic function
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
|
||||||
|
|
|
||||||
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: functions cannot be both `const` and C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:1
|
||||||
|
|
|
||||||
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||||
|
| ^^^^^ ^^^ ^^^ C-variadic because of this
|
||||||
|
| | |
|
||||||
|
| | C-variadic because of this
|
||||||
|
| `const` because of this
|
||||||
|
|
||||||
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
|
||||||
|
|
|
||||||
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
|
||||||
|
| ^^^ ^^^
|
||||||
|
|
||||||
error: C-variadic function must be declared with at least one named argument
|
error: C-variadic function must be declared with at least one named argument
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:36:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:48:13
|
||||||
|
|
|
|
||||||
LL | fn e_f1(...);
|
LL | fn e_f1(...);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `...` must be the last argument of a C-variadic function
|
error: `...` must be the last argument of a C-variadic function
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:38:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
|
||||||
|
|
|
|
||||||
LL | fn e_f2(..., x: isize);
|
LL | fn e_f2(..., x: isize);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:45:23
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:57:23
|
||||||
|
|
|
|
||||||
LL | fn i_f1(x: isize, ...) {}
|
LL | fn i_f1(x: isize, ...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: C-variadic function must be declared with at least one named argument
|
error: C-variadic function must be declared with at least one named argument
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
|
||||||
|
|
|
|
||||||
LL | fn i_f2(...) {}
|
LL | fn i_f2(...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
|
||||||
|
|
|
|
||||||
LL | fn i_f2(...) {}
|
LL | fn i_f2(...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `...` must be the last argument of a C-variadic function
|
error: `...` must be the last argument of a C-variadic function
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
|
||||||
|
|
|
|
||||||
LL | fn i_f3(..., x: isize, ...) {}
|
LL | fn i_f3(..., x: isize, ...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
|
||||||
|
|
|
|
||||||
LL | fn i_f3(..., x: isize, ...) {}
|
LL | fn i_f3(..., x: isize, ...) {}
|
||||||
| ^^^ ^^^
|
| ^^^ ^^^
|
||||||
|
|
||||||
error: `...` must be the last argument of a C-variadic function
|
error: `...` must be the last argument of a C-variadic function
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
|
||||||
|
|
|
|
||||||
LL | fn i_f4(..., x: isize, ...) {}
|
LL | fn i_f4(..., x: isize, ...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:53:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
|
||||||
|
|
|
|
||||||
LL | fn i_f4(..., x: isize, ...) {}
|
LL | fn i_f4(..., x: isize, ...) {}
|
||||||
| ^^^ ^^^
|
| ^^^ ^^^
|
||||||
|
|
||||||
|
error: functions cannot be both `const` and C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:68:5
|
||||||
|
|
|
||||||
|
LL | const fn i_f5(x: isize, ...) {}
|
||||||
|
| ^^^^^ ^^^ C-variadic because of this
|
||||||
|
| |
|
||||||
|
| `const` because of this
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:59:23
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:68:29
|
||||||
|
|
|
||||||
|
LL | const fn i_f5(x: isize, ...) {}
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:74:23
|
||||||
|
|
|
|
||||||
LL | fn t_f1(x: isize, ...) {}
|
LL | fn t_f1(x: isize, ...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:61:23
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:76:23
|
||||||
|
|
|
|
||||||
LL | fn t_f2(x: isize, ...);
|
LL | fn t_f2(x: isize, ...);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: C-variadic function must be declared with at least one named argument
|
error: C-variadic function must be declared with at least one named argument
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:63:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
|
||||||
|
|
|
|
||||||
LL | fn t_f3(...) {}
|
LL | fn t_f3(...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:63:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
|
||||||
|
|
|
|
||||||
LL | fn t_f3(...) {}
|
LL | fn t_f3(...) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: C-variadic function must be declared with at least one named argument
|
error: C-variadic function must be declared with at least one named argument
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:66:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
|
||||||
|
|
|
|
||||||
LL | fn t_f4(...);
|
LL | fn t_f4(...);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:66:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
|
||||||
|
|
|
|
||||||
LL | fn t_f4(...);
|
LL | fn t_f4(...);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `...` must be the last argument of a C-variadic function
|
error: `...` must be the last argument of a C-variadic function
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:69:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
|
||||||
|
|
|
|
||||||
LL | fn t_f5(..., x: isize) {}
|
LL | fn t_f5(..., x: isize) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:69:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
|
||||||
|
|
|
|
||||||
LL | fn t_f5(..., x: isize) {}
|
LL | fn t_f5(..., x: isize) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `...` must be the last argument of a C-variadic function
|
error: `...` must be the last argument of a C-variadic function
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:72:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
|
||||||
|
|
|
|
||||||
LL | fn t_f6(..., x: isize);
|
LL | fn t_f6(..., x: isize);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
error: only foreign or `unsafe extern "C"` functions may be C-variadic
|
||||||
--> $DIR/variadic-ffi-semantic-restrictions.rs:72:13
|
--> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
|
||||||
|
|
|
|
||||||
LL | fn t_f6(..., x: isize);
|
LL | fn t_f6(..., x: isize);
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 32 previous errors
|
error: aborting due to 40 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue