diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index ba2da7694978d..4a8444dec32d9 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -652,7 +652,7 @@ impl<'a> AstValidator<'a> { self.err_handler() .struct_span_err( *span, - "only foreign or `unsafe extern \"C\" functions may be C-variadic", + "only foreign or `unsafe extern \"C\"` functions may be C-variadic", ) .emit(); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 17a56046a5cc8..8dcdd4b149ea6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -56,33 +56,42 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap(); let poly_fn_sig = self.tcx().fn_sig(id); let fn_sig = self.tcx().liberate_late_bound_regions(id, poly_fn_sig); - body.params.iter().enumerate().find_map(|(index, param)| { - // May return None; sometimes the tables are not yet populated. - let ty = fn_sig.inputs()[index]; - let mut found_anon_region = false; - let new_param_ty = self.tcx().fold_regions(ty, &mut false, |r, _| { - if *r == *anon_region { - found_anon_region = true; - replace_region + body.params + .iter() + .take(if fn_sig.c_variadic { + fn_sig.inputs().len() + } else { + assert_eq!(fn_sig.inputs().len(), body.params.len()); + body.params.len() + }) + .enumerate() + .find_map(|(index, param)| { + // May return None; sometimes the tables are not yet populated. + let ty = fn_sig.inputs()[index]; + let mut found_anon_region = false; + let new_param_ty = self.tcx().fold_regions(ty, &mut false, |r, _| { + if *r == *anon_region { + found_anon_region = true; + replace_region + } else { + r + } + }); + if found_anon_region { + let ty_hir_id = fn_decl.inputs[index].hir_id; + let param_ty_span = hir.span(ty_hir_id); + let is_first = index == 0; + Some(AnonymousParamInfo { + param, + param_ty: new_param_ty, + param_ty_span, + bound_region, + is_first, + }) } else { - r + None } - }); - if found_anon_region { - let ty_hir_id = fn_decl.inputs[index].hir_id; - let param_ty_span = hir.span(ty_hir_id); - let is_first = index == 0; - Some(AnonymousParamInfo { - param, - param_ty: new_param_ty, - param_ty_span, - bound_region, - is_first, - }) - } else { - None - } - }) + }) } pub(super) fn future_return_type( diff --git a/src/test/ui/c-variadic/issue-86053-1.rs b/src/test/ui/c-variadic/issue-86053-1.rs new file mode 100644 index 0000000000000..b30548e19f9ff --- /dev/null +++ b/src/test/ui/c-variadic/issue-86053-1.rs @@ -0,0 +1,12 @@ +// Regression test for the ICE described in issue #86053. +// error-pattern:unexpected `self` parameter in function +// error-pattern:`...` must be the last argument of a C-variadic function +// error-pattern:cannot find type `F` in this scope +// error-pattern:in type `&'a &'b usize`, reference has a longer lifetime than the data it references + +#![feature(c_variadic)] +#![crate_type="lib"] + +fn ordering4 < 'a , 'b > ( a : , self , self , self , + self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { +} diff --git a/src/test/ui/c-variadic/issue-86053-1.stderr b/src/test/ui/c-variadic/issue-86053-1.stderr new file mode 100644 index 0000000000000..ec7ee74aef29a --- /dev/null +++ b/src/test/ui/c-variadic/issue-86053-1.stderr @@ -0,0 +1,101 @@ +error: expected type, found `,` + --> $DIR/issue-86053-1.rs:10:47 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^ expected type + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:10:51 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:10:58 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:10:67 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:11:5 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:11:20 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ must be the first parameter of an associated function + +error: unexpected `self` parameter in function + --> $DIR/issue-86053-1.rs:11:29 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ must be the first parameter of an associated function + +error: `...` must be the last argument of a C-variadic function + --> $DIR/issue-86053-1.rs:11:12 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/issue-86053-1.rs:11:12 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ + +error: only foreign or `unsafe extern "C"` functions may be C-variadic + --> $DIR/issue-86053-1.rs:11:36 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^ + +error[E0412]: cannot find type `F` in this scope + --> $DIR/issue-86053-1.rs:11:48 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^ + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | pub trait Fn: FnMut { + | ------------------------------- similarly named trait `Fn` defined here + | +help: a trait with a similar name exists + | +LL | self , ... , self , self , ... ) where Fn : FnOnce ( & 'a & 'b usize ) { + | ^^ +help: you might be missing a type parameter + | +LL | fn ordering4 < 'a , 'b, F > ( a : , self , self , self , + | ^^^ + +error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references + --> $DIR/issue-86053-1.rs:11:52 + | +LL | self , ... , self , self , ... ) where F : FnOnce ( & 'a & 'b usize ) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the pointer is valid for the lifetime `'a` as defined on the function body at 10:16 + --> $DIR/issue-86053-1.rs:10:16 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^^ +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 10:21 + --> $DIR/issue-86053-1.rs:10:21 + | +LL | fn ordering4 < 'a , 'b > ( a : , self , self , self , + | ^^ + +error: aborting due to 12 previous errors + +Some errors have detailed explanations: E0412, E0491. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/c-variadic/issue-86053-2.rs b/src/test/ui/c-variadic/issue-86053-2.rs new file mode 100644 index 0000000000000..c545831f7171a --- /dev/null +++ b/src/test/ui/c-variadic/issue-86053-2.rs @@ -0,0 +1,11 @@ +// Regression test for the ICE caused by the example in +// https://github.com/rust-lang/rust/issues/86053#issuecomment-855672258 + +#![feature(c_variadic)] + +trait H {} + +unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} +//~^ ERROR: in type `&'static &'a ()`, reference has a longer lifetime than the data it references [E0491] + +fn main() {} diff --git a/src/test/ui/c-variadic/issue-86053-2.stderr b/src/test/ui/c-variadic/issue-86053-2.stderr new file mode 100644 index 0000000000000..4fc5e6315e45b --- /dev/null +++ b/src/test/ui/c-variadic/issue-86053-2.stderr @@ -0,0 +1,16 @@ +error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references + --> $DIR/issue-86053-2.rs:8:39 + | +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} + | ^^^^^^^^^^^^^^^^^^ + | + = note: the pointer is valid for the static lifetime +note: but the referenced data is only valid for the lifetime `'a` as defined on the function body at 8:32 + --> $DIR/issue-86053-2.rs:8:32 + | +LL | unsafe extern "C" fn ordering4<'a, F: H<&'static &'a ()>>(_: (), ...) {} + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0491`. diff --git a/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs b/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs index 4d404d015ec0b..0086d2ec18cfa 100644 --- a/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs +++ b/src/test/ui/mir/issue-83499-input-output-iteration-ice.rs @@ -5,6 +5,6 @@ fn main() {} fn foo(_: Bar, ...) -> impl {} -//~^ 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 cannot find type `Bar` in this scope //~| ERROR at least one trait must be specified diff --git a/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr b/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr index eb172684899cf..4eb3adc8b4f1c 100644 --- a/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr +++ b/src/test/ui/mir/issue-83499-input-output-iteration-ice.stderr @@ -1,4 +1,4 @@ -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/issue-83499-input-output-iteration-ice.rs:7:16 | LL | fn foo(_: Bar, ...) -> impl {} diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs index fe993a6ee1302..0b61e267da80b 100644 --- a/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -4,32 +4,32 @@ fn main() {} fn f1_1(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 fn f1_2(...) {} -//~^ 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 C-variadic function must be declared with at least one named argument extern "C" fn f2_1(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 extern "C" fn f2_2(...) {} -//~^ 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 C-variadic function must be declared with at least one named argument extern "C" fn f2_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 extern "C" fn f3_1(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 extern "C" fn f3_2(...) {} -//~^ 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 C-variadic function must be declared with at least one named argument 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 extern "C" { @@ -43,35 +43,35 @@ struct X; impl X { fn i_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 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 //~| ERROR C-variadic function must be declared with at least one named argument 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 + //~^ 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 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 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 } trait T { 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 fn t_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 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 //~| ERROR C-variadic function must be declared with at least one named argument 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 //~| ERROR C-variadic function must be declared with at least one named argument 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 //~| ERROR `...` must be the last argument of a C-variadic function 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 //~| ERROR `...` must be the last argument of a C-variadic function } diff --git a/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr index 10fd05c0bef3f..f1cbbb279c849 100644 --- a/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/src/test/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -1,4 +1,4 @@ -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:6:19 | LL | fn f1_1(x: isize, ...) {} @@ -10,13 +10,13 @@ error: C-variadic function must be declared with at least one named argument LL | fn f1_2(...) {} | ^^^ -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:9:9 | LL | fn f1_2(...) {} | ^^^ -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:13:30 | LL | extern "C" fn f2_1(x: isize, ...) {} @@ -28,7 +28,7 @@ error: C-variadic function must be declared with at least one named argument LL | extern "C" fn f2_2(...) {} | ^^^ -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:16:20 | LL | extern "C" fn f2_2(...) {} @@ -40,13 +40,13 @@ error: `...` must be the last argument of a C-variadic function LL | extern "C" fn f2_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 --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20 | LL | extern "C" fn f2_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 --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30 | LL | extern "C" fn f3_1(x: isize, ...) {} @@ -58,7 +58,7 @@ error: C-variadic function must be declared with at least one named argument LL | extern "C" fn f3_2(...) {} | ^^^ -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:27:20 | LL | extern "C" fn f3_2(...) {} @@ -70,7 +70,7 @@ error: `...` must be the last argument of a C-variadic function LL | 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 --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20 | LL | extern "C" fn f3_3(..., x: isize) {} @@ -88,7 +88,7 @@ error: `...` must be the last argument of a C-variadic function 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 | LL | fn i_f1(x: isize, ...) {} @@ -100,7 +100,7 @@ error: C-variadic function must be declared with at least one named argument 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 | LL | fn i_f2(...) {} @@ -112,13 +112,13 @@ error: `...` must be the last argument of a C-variadic function 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 | 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:28 | LL | fn i_f3(..., x: isize, ...) {} @@ -130,25 +130,25 @@ error: `...` must be the last argument of a C-variadic function 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:54:13 | 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:54:28 | 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:61:23 | 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:63:23 | LL | fn t_f2(x: isize, ...); @@ -160,7 +160,7 @@ error: C-variadic function must be declared with at least one named argument 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:65:13 | LL | fn t_f3(...) {} @@ -172,7 +172,7 @@ error: C-variadic function must be declared with at least one named argument 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:68:13 | LL | fn t_f4(...); @@ -184,7 +184,7 @@ error: `...` must be the last argument of a C-variadic function 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:71:13 | LL | fn t_f5(..., x: isize) {} @@ -196,7 +196,7 @@ error: `...` must be the last argument of a C-variadic function 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:74:13 | LL | fn t_f6(..., x: isize);