diff --git a/RELEASES.md b/RELEASES.md index 2b65d070d5fd1..aa5f37fffebff 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,5 @@ -Version 1.90 (2025-09-18) -========================== +Version 1.90.0 (2025-09-18) +=========================== diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index e5405a7ad910c..5e10c5a77d97d 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -64,8 +64,6 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect -ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list - ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions .label = `extern "{$abi}"` because of this .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dc221c2fb1abc..f773b02058ef1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -696,7 +696,7 @@ impl<'a> AstValidator<'a> { match fn_ctxt { FnCtxt::Foreign => return, - FnCtxt::Free => match sig.header.ext { + FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext { Extern::Implicit(_) => { if !matches!(sig.header.safety, Safety::Unsafe(_)) { self.dcx().emit_err(errors::CVariadicMustBeUnsafe { @@ -726,11 +726,6 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(err); } }, - FnCtxt::Assoc(_) => { - // For now, C variable argument lists are unsupported in associated functions. - let err = errors::CVariadicAssociatedFunction { span: variadic_param.span }; - self.dcx().emit_err(err); - } } } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index e09ca5b81c80c..fd75e999d1381 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -318,13 +318,6 @@ pub(crate) struct ExternItemAscii { pub block: Span, } -#[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_associated_function)] -pub(crate) struct CVariadicAssociatedFunction { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(ast_passes_c_variadic_no_extern)] #[help] diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index 94379cdebf730..6be90994015f3 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -166,13 +166,9 @@ impl RegionTracker { } } - /// Determine if the tracked universes of the two SCCs are compatible. - pub(crate) fn universe_compatible_with(&self, other: Self) -> bool { - // HACK: We first check whether we can name the highest existential universe - // of `other`. This only exists to avoid errors in case that scc already - // depends on a placeholder it cannot name itself. - self.max_nameable_universe().can_name(other.max_nameable_universe()) - || other.reachable_placeholders.can_be_named_by(self.max_nameable_universe()) + /// Determine if we can name all the placeholders in `other`. + pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool { + other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0) } /// If this SCC reaches a placeholder it can't name, return it. diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index f57456949bb5e..5f4bfd9df48e5 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -571,11 +571,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Returns `true` if all the elements in the value of `scc_b` are nameable + /// Returns `true` if all the placeholders in the value of `scc_b` are nameable /// in `scc_a`. Used during constraint propagation, and only once /// the value of `scc_b` has been computed. - fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool { - self.scc_annotations[scc_a].universe_compatible_with(self.scc_annotations[scc_b]) + fn can_name_all_placeholders( + &self, + scc_a: ConstraintSccIndex, + scc_b: ConstraintSccIndex, + ) -> bool { + self.scc_annotations[scc_a].can_name_all_placeholders(self.scc_annotations[scc_b]) } /// Once regions have been propagated, this method is used to see @@ -964,16 +968,22 @@ impl<'tcx> RegionInferenceContext<'tcx> { return true; } + let fr_static = self.universal_regions().fr_static; + // If we are checking that `'sup: 'sub`, and `'sub` contains // some placeholder that `'sup` cannot name, then this is only // true if `'sup` outlives static. - if !self.universe_compatible(sub_region_scc, sup_region_scc) { + // + // Avoid infinite recursion if `sub_region` is already `'static` + if sub_region != fr_static + && !self.can_name_all_placeholders(sup_region_scc, sub_region_scc) + { debug!( "sub universe `{sub_region_scc:?}` is not nameable \ by super `{sup_region_scc:?}`, promoting to static", ); - return self.eval_outlives(sup_region, self.universal_regions().fr_static); + return self.eval_outlives(sup_region, fr_static); } // Both the `sub_region` and `sup_region` consist of the union diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 2627ed899a933..aece0bda34692 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -230,8 +230,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { location: impl NormalizeLocation, ) -> Ty<'tcx> { let tcx = self.tcx(); + let body = self.body; + + let cause = ObligationCause::misc( + location.to_locations().span(body), + body.source.def_id().expect_local(), + ); + if self.infcx.next_trait_solver() { - let body = self.body; let param_env = self.infcx.param_env; // FIXME: Make this into a real type op? self.fully_perform_op( @@ -241,10 +247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { |ocx| { let structurally_normalize = |ty| { ocx.structurally_normalize_ty( - &ObligationCause::misc( - location.to_locations().span(body), - body.source.def_id().expect_local(), - ), + &cause, param_env, ty, ) @@ -253,6 +256,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tail = tcx.struct_tail_raw( ty, + &cause, structurally_normalize, || {}, ); @@ -265,7 +269,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } else { let mut normalize = |ty| self.normalize(ty, location); - let tail = tcx.struct_tail_raw(ty, &mut normalize, || {}); + let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {}); normalize(tail) } } diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 37c6c4a61d8d6..7c41258ebfe5f 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,6 +1,7 @@ use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::layout::{LayoutCx, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; @@ -196,6 +197,7 @@ fn reconstruct_place_meta<'tcx>( // Traverse the type, and update `last_valtree` as we go. let tail = tcx.struct_tail_raw( layout.ty, + &ObligationCause::dummy(), |ty| ty, || { let branches = last_valtree.unwrap_branch(); diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index 6d95b6917e296..2fbea5b61cfc6 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -1,3 +1,4 @@ +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -74,8 +75,14 @@ impl<'a, 'tcx> Expectation<'tcx> { /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169 /// for examples of where this comes up,. pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> { + let span = match ty.kind() { + ty::Adt(adt_def, _) => fcx.tcx.def_span(adt_def.did()), + _ => fcx.tcx.def_span(fcx.body_id), + }; + let cause = ObligationCause::misc(span, fcx.body_id); + // FIXME: This is not right, even in the old solver... - match fcx.tcx.struct_tail_raw(ty, |ty| ty, || {}).kind() { + match fcx.tcx.struct_tail_raw(ty, &cause, |ty| ty, || {}).kind() { ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty), _ => ExpectHasType(ty), } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 7370124e800da..4563159314d15 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -424,6 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !ty.references_error() { let tail = self.tcx.struct_tail_raw( ty, + &self.misc(span), |ty| { if self.next_trait_solver() { self.try_structurally_resolve_type(span, ty) diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index dad402ec69616..e3e1393b5f9ae 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -71,6 +71,8 @@ pub enum TypeMismatchReason { #[diag(middle_recursion_limit_reached)] #[help] pub(crate) struct RecursionLimitReached<'tcx> { + #[primary_span] + pub span: Span, pub ty: Ty<'tcx>, pub suggested_limit: rustc_hir::limit::Limit, } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index ab8a314295392..0c7bddf60d974 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -823,6 +823,9 @@ impl DynCompatibilityViolation { DynCompatibilityViolation::Method(name, MethodViolationCode::AsyncFn, _) => { format!("method `{name}` is `async`").into() } + DynCompatibilityViolation::Method(name, MethodViolationCode::CVariadic, _) => { + format!("method `{name}` is C-variadic").into() + } DynCompatibilityViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -977,6 +980,9 @@ pub enum MethodViolationCode { /// e.g., `fn foo()` Generic, + /// e.g., `fn (mut ap: ...)` + CVariadic, + /// the method's receiver (`self` argument) can't be dispatched on UndispatchableReceiver(Option), } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 9524057eebc6c..c477e65f5d6b3 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -22,6 +22,7 @@ use {rustc_abi as abi, rustc_hir as hir}; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::TyCtxtAt; +use crate::traits::ObligationCause; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, CoroutineArgsExt, Ty, TyCtxt, TypeVisitableExt}; @@ -384,6 +385,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_raw( pointee, + &ObligationCause::dummy(), |ty| match tcx.try_normalize_erasing_regions(typing_env, ty) { Ok(ty) => ty, Err(e) => Ty::new_error_with_message( diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2bea797799958..de35e5e847c81 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -23,6 +23,7 @@ use ty::util::IntTypeExt; use super::GenericParamDefKind; use crate::infer::canonical::Canonical; +use crate::traits::ObligationCause; use crate::ty::InferTy::*; use crate::ty::{ self, AdtDef, BoundRegionKind, Discr, GenericArg, GenericArgs, GenericArgsRef, List, ParamEnv, @@ -1638,7 +1639,7 @@ impl<'tcx> Ty<'tcx> { tcx: TyCtxt<'tcx>, normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, ) -> Result, Ty<'tcx>> { - let tail = tcx.struct_tail_raw(self, normalize, || {}); + let tail = tcx.struct_tail_raw(self, &ObligationCause::dummy(), normalize, || {}); match tail.kind() { // Sized types ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b79b67c5927b0..4f039381e500d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -24,6 +24,7 @@ use super::TypingEnv; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; use crate::query::Providers; +use crate::traits::ObligationCause; use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, Asyncness, FallibleTypeFolder, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeFoldable, @@ -216,7 +217,12 @@ impl<'tcx> TyCtxt<'tcx> { typing_env: ty::TypingEnv<'tcx>, ) -> Ty<'tcx> { let tcx = self; - tcx.struct_tail_raw(ty, |ty| tcx.normalize_erasing_regions(typing_env, ty), || {}) + tcx.struct_tail_raw( + ty, + &ObligationCause::dummy(), + |ty| tcx.normalize_erasing_regions(typing_env, ty), + || {}, + ) } /// Returns true if a type has metadata. @@ -248,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn struct_tail_raw( self, mut ty: Ty<'tcx>, + cause: &ObligationCause<'tcx>, mut normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>, // This is currently used to allow us to walk a ValTree // in lockstep with the type in order to get the ValTree branch that @@ -261,9 +268,11 @@ impl<'tcx> TyCtxt<'tcx> { Limit(0) => Limit(2), limit => limit * 2, }; - let reported = self - .dcx() - .emit_err(crate::error::RecursionLimitReached { ty, suggested_limit }); + let reported = self.dcx().emit_err(crate::error::RecursionLimitReached { + span: cause.span, + ty, + suggested_limit, + }); return Ty::new_error(self, reported); } match *ty.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index bcd11d6918d9a..3260dd712b9e4 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -426,6 +426,9 @@ fn virtual_call_violations_for_method<'tcx>( if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) { errors.push(code); } + if sig.skip_binder().c_variadic { + errors.push(MethodViolationCode::CVariadic); + } // We can't monomorphize things like `fn foo(...)`. let own_counts = tcx.generics_of(method.def_id).own_counts(); diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 884d53732fe2a..042d6def84c33 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1057,6 +1057,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( Some(LangItem::PointeeTrait) => { let tail = selcx.tcx().struct_tail_raw( self_ty, + &obligation.cause, |ty| { // We throw away any obligations we get from this, since we normalize // and confirm these obligations once again during confirmation diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 643e3db8f83fe..c4cb43011adb0 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -10,6 +10,7 @@ use rustc_hashes::Hash64; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::query::Providers; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::layout::{ FloatExt, HasTyCtxt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, }; @@ -390,30 +391,31 @@ fn layout_of_uncached<'tcx>( let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() { let pointee_metadata = Ty::new_projection(tcx, metadata_def_id, [pointee]); - let metadata_ty = - match tcx.try_normalize_erasing_regions(cx.typing_env, pointee_metadata) { - Ok(metadata_ty) => metadata_ty, - Err(mut err) => { - // Usually `::Metadata` can't be normalized because - // its struct tail cannot be normalized either, so try to get a - // more descriptive layout error here, which will lead to less confusing - // diagnostics. - // - // We use the raw struct tail function here to get the first tail - // that is an alias, which is likely the cause of the normalization - // error. - match tcx.try_normalize_erasing_regions( - cx.typing_env, - tcx.struct_tail_raw(pointee, |ty| ty, || {}), - ) { - Ok(_) => {} - Err(better_err) => { - err = better_err; - } + let metadata_ty = match tcx + .try_normalize_erasing_regions(cx.typing_env, pointee_metadata) + { + Ok(metadata_ty) => metadata_ty, + Err(mut err) => { + // Usually `::Metadata` can't be normalized because + // its struct tail cannot be normalized either, so try to get a + // more descriptive layout error here, which will lead to less confusing + // diagnostics. + // + // We use the raw struct tail function here to get the first tail + // that is an alias, which is likely the cause of the normalization + // error. + match tcx.try_normalize_erasing_regions( + cx.typing_env, + tcx.struct_tail_raw(pointee, &ObligationCause::dummy(), |ty| ty, || {}), + ) { + Ok(_) => {} + Err(better_err) => { + err = better_err; } - return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); } - }; + return Err(error(cx, LayoutError::NormalizationFailure(pointee, err))); + } + }; let metadata_layout = cx.layout_of(metadata_ty)?; // If the metadata is a 1-zst, then the pointer is thin. diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 18a9a7c22d9dd..e91e5055e9053 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -353,6 +353,7 @@ fn impl_self_is_guaranteed_unsized<'tcx>(tcx: TyCtxt<'tcx>, impl_def_id: DefId) let tail = tcx.struct_tail_raw( tcx.type_of(impl_def_id).instantiate_identity(), + &cause, |ty| { ocx.structurally_normalize_ty(&cause, param_env, ty).unwrap_or_else(|_| { Ty::new_error_with_message( diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index 54e54f734f647..913f766ec1683 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -111,6 +111,13 @@ fn from_str_issue7588() { assert_eq!(s, None); } +#[test] +#[should_panic = "radix must lie in the range `[2, 36]`"] +fn from_ascii_radix_panic() { + let radix = 1; + let _parsed = u64::from_str_radix("12345ABCD", radix); +} + #[test] fn test_int_from_str_overflow() { test_parse::("127", Ok(127)); diff --git a/tests/ui/c-variadic/inherent-method.rs b/tests/ui/c-variadic/inherent-method.rs new file mode 100644 index 0000000000000..537bae7b3f0f4 --- /dev/null +++ b/tests/ui/c-variadic/inherent-method.rs @@ -0,0 +1,45 @@ +//@ run-pass +#![feature(c_variadic)] + +#[repr(transparent)] +struct S(i32); + +impl S { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method_owned(self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn method_ref(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn method_mut(&mut self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn fat_pointer(self: Box, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } +} + +fn main() { + unsafe { + assert_eq!(S::associated_function(32), 32); + assert_eq!(S(100).method_owned(32), 132); + assert_eq!(S(100).method_ref(32), 132); + assert_eq!(S(100).method_mut(32), 132); + assert_eq!(S::fat_pointer(Box::new(S(100)), 32), 132); + + type Method = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((S::associated_function as unsafe extern "C" fn(...) -> i32)(32), 32); + assert_eq!((S::method_owned as Method<_>)(S(100), 32), 132); + assert_eq!((S::method_ref as Method<_>)(&S(100), 32), 132); + assert_eq!((S::method_mut as Method<_>)(&mut S(100), 32), 132); + assert_eq!((S::fat_pointer as Method<_>)(Box::new(S(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs index 45a7e1f8972bf..bdb51a9a43232 100644 --- a/tests/ui/c-variadic/not-async.rs +++ b/tests/ui/c-variadic/not-async.rs @@ -2,6 +2,14 @@ #![feature(c_variadic)] #![crate_type = "lib"] -async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} +async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds + +struct S; + +impl S { + async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + //~^ ERROR functions cannot be both `async` and C-variadic + //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds +} diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index b8caf0d8bd852..eab4c4f0822c4 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -1,19 +1,35 @@ error: functions cannot be both `async` and C-variadic --> $DIR/not-async.rs:5:1 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this + +error: functions cannot be both `async` and C-variadic + --> $DIR/not-async.rs:12:5 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds - --> $DIR/not-async.rs:5:59 + --> $DIR/not-async.rs:5:62 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | --------------------------------------------------------- ^^ +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ------------------------------------------------------------ ^^ | | | opaque type defined here | - = note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_` + = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` + +error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds + --> $DIR/not-async.rs:12:70 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ---------------------------------------------------------------- ^^ + | | + | opaque type defined here + | + = note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/c-variadic/not-dyn-compatible.rs b/tests/ui/c-variadic/not-dyn-compatible.rs new file mode 100644 index 0000000000000..b40a13e584762 --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.rs @@ -0,0 +1,35 @@ +// Traits where a method is c-variadic are not dyn compatible. +// +// Creating a function pointer from a method on an `&dyn T` value creates a ReifyShim. +// This shim cannot reliably forward C-variadic arguments. Thus the trait as a whole +// is dyn-incompatible to prevent invalid shims from being created. +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(u64); + +trait Trait { + fn get(&self) -> u64; + + unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + self.get() + unsafe { ap.arg::() } + } +} + +impl Trait for Struct { + fn get(&self) -> u64 { + self.0 + } +} + +fn main() { + unsafe { + let dyn_object: &dyn Trait = &Struct(64); + //~^ ERROR the trait `Trait` is not dyn compatible + assert_eq!(dyn_object.dyn_method_ref(100), 164); + assert_eq!( + (Trait::dyn_method_ref as unsafe extern "C" fn(_, ...) -> u64)(dyn_object, 100), + 164 + ); + } +} diff --git a/tests/ui/c-variadic/not-dyn-compatible.stderr b/tests/ui/c-variadic/not-dyn-compatible.stderr new file mode 100644 index 0000000000000..76630600c511f --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/not-dyn-compatible.rs:27:30 + | +LL | let dyn_object: &dyn Trait = &Struct(64); + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/not-dyn-compatible.rs:14:26 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +... +LL | unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + | ^^^^^^^^^^^^^^ ...because method `dyn_method_ref` is C-variadic + = help: consider moving `dyn_method_ref` to another trait + = help: only type `Struct` implements `Trait`; consider using it directly instead. + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/c-variadic/trait-method.rs b/tests/ui/c-variadic/trait-method.rs new file mode 100644 index 0000000000000..97da0706a3a18 --- /dev/null +++ b/tests/ui/c-variadic/trait-method.rs @@ -0,0 +1,73 @@ +//@ run-pass +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(i32); + +impl Struct { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } +} + +trait Trait: Sized { + fn get(&self) -> i32; + + unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn trait_method_owned(self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_method_ref(&self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_method_mut(&mut self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_fat_pointer(self: Box, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } +} + +impl Trait for Struct { + fn get(&self) -> i32 { + self.0 + } +} + +fn main() { + unsafe { + assert_eq!(Struct::associated_function(32), 32); + assert_eq!(Struct(100).method(32), 132); + + assert_eq!(Struct::trait_associated_function(32), 32); + assert_eq!(Struct(100).trait_method_owned(32), 132); + assert_eq!(Struct(100).trait_method_ref(32), 132); + assert_eq!(Struct(100).trait_method_mut(32), 132); + assert_eq!(Struct::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + assert_eq!(::trait_associated_function(32), 32); + assert_eq!(Trait::trait_method_owned(Struct(100), 32), 132); + assert_eq!(Trait::trait_method_ref(&Struct(100), 32), 132); + assert_eq!(Trait::trait_method_mut(&mut Struct(100), 32), 132); + assert_eq!(Trait::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + type Associated = unsafe extern "C" fn(...) -> i32; + type Method = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((Struct::trait_associated_function as Associated)(32), 32); + assert_eq!((Struct::trait_method_owned as Method<_>)(Struct(100), 32), 132); + assert_eq!((Struct::trait_method_ref as Method<_>)(&Struct(100), 32), 132); + assert_eq!((Struct::trait_method_mut as Method<_>)(&mut Struct(100), 32), 132); + assert_eq!((Struct::trait_fat_pointer as Method<_>)(Box::new(Struct(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/unsupported-abi.rs b/tests/ui/c-variadic/unsupported-abi.rs new file mode 100644 index 0000000000000..40179b164ce42 --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.rs @@ -0,0 +1,123 @@ +//@ add-core-stubs +//@ needs-llvm-components: x86 +//@ compile-flags: --target=i686-pc-windows-gnu --crate-type=rlib +#![no_core] +#![feature(no_core, lang_items, c_variadic)] + +// Test that ABIs for which C-variadics are not supported report an error. + +extern crate minicore; +use minicore::*; + +#[rustfmt::skip] +mod foreign { + extern "Rust" { fn rust_foreign_explicit(_: ...); } + //~^ ERROR C-variadic functions with the "Rust" calling convention are not supported + extern "C" { fn c_foreign(_: ...); } + extern "C-unwind" { fn c_unwind_foreign(_: ...); } + extern "cdecl" { fn cdecl_foreign(_: ...); } + extern "cdecl-unwind" { fn cdecl_unwind_foreign(_: ...); } + extern "stdcall" { fn stdcall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall" calling convention are not supported + extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall-unwind" calling convention are not supported + extern "thiscall" { fn thiscall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall" calling convention are not supported + extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall-unwind" calling convention are not supported +} + +#[lang = "va_list"] +struct VaList(*mut u8); + +unsafe fn rust_free(_: ...) {} +//~^ ERROR `...` is not supported for non-extern functions +unsafe extern "Rust" fn rust_free_explicit(_: ...) {} +//~^ ERROR `...` is not supported for `extern "Rust"` functions + +unsafe extern "C" fn c_free(_: ...) {} +unsafe extern "C-unwind" fn c_unwind_free(_: ...) {} + +unsafe extern "cdecl" fn cdecl_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl"` functions +unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions +unsafe extern "stdcall" fn stdcall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall"` functions +unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions +unsafe extern "thiscall" fn thiscall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall"` functions +unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions + +struct S; + +impl S { + unsafe fn rust_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +trait T { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +impl T for S { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} diff --git a/tests/ui/c-variadic/unsupported-abi.stderr b/tests/ui/c-variadic/unsupported-abi.stderr new file mode 100644 index 0000000000000..daed91714065a --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.stderr @@ -0,0 +1,345 @@ +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:33:21 + | +LL | unsafe fn rust_free(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:35:44 + | +LL | unsafe extern "Rust" fn rust_free_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:41:37 + | +LL | unsafe extern "cdecl" fn cdecl_free(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:43:51 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:45:41 + | +LL | unsafe extern "stdcall" fn stdcall_free(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:47:55 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:49:43 + | +LL | unsafe extern "thiscall" fn thiscall_free(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:51:57 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:57:27 + | +LL | unsafe fn rust_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:59:50 + | +LL | unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:65:43 + | +LL | unsafe extern "cdecl" fn cdecl_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:67:57 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:69:47 + | +LL | unsafe extern "stdcall" fn stdcall_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:71:61 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:73:49 + | +LL | unsafe extern "thiscall" fn thiscall_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:75:63 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:80:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:82:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:88:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:90:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:92:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:94:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:96:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:98:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:103:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:105:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:111:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:113:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:115:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:117:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:119:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:121:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error[E0045]: C-variadic functions with the "Rust" calling convention are not supported + --> $DIR/unsupported-abi.rs:14:22 + | +LL | extern "Rust" { fn rust_foreign_explicit(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall" calling convention are not supported + --> $DIR/unsupported-abi.rs:20:25 + | +LL | extern "stdcall" { fn stdcall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:22:32 + | +LL | extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall" calling convention are not supported + --> $DIR/unsupported-abi.rs:24:26 + | +LL | extern "thiscall" { fn thiscall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:26:33 + | +LL | extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error: aborting due to 37 previous errors + +For more information about this error, try `rustc --explain E0045`. diff --git a/tests/ui/did_you_mean/recursion_limit_deref.rs b/tests/ui/did_you_mean/recursion_limit_deref.rs index e53007388af25..3ae956b751d84 100644 --- a/tests/ui/did_you_mean/recursion_limit_deref.rs +++ b/tests/ui/did_you_mean/recursion_limit_deref.rs @@ -1,3 +1,6 @@ +//~ ERROR reached the recursion limit finding the struct tail for `K` +//~| ERROR reached the recursion limit finding the struct tail for `Bottom` + // Test that the recursion limit can be changed and that the compiler // suggests a fix. In this case, we have a long chain of Deref impls // which will cause an overflow during the autoderef loop. @@ -9,6 +12,7 @@ macro_rules! link { ($outer:ident, $inner:ident) => { struct $outer($inner); + //~^ ERROR reached the recursion limit finding the struct tail for `Bottom` impl $outer { fn new() -> $outer { @@ -51,6 +55,3 @@ fn main() { let x: &Bottom = &t; //~ ERROR mismatched types //~^ error recursion limit } - -//~? ERROR reached the recursion limit finding the struct tail for `K` -//~? ERROR reached the recursion limit finding the struct tail for `Bottom` diff --git a/tests/ui/did_you_mean/recursion_limit_deref.stderr b/tests/ui/did_you_mean/recursion_limit_deref.stderr index 23341ec6bdc27..faa85dc5ae98c 100644 --- a/tests/ui/did_you_mean/recursion_limit_deref.stderr +++ b/tests/ui/did_you_mean/recursion_limit_deref.stderr @@ -6,8 +6,20 @@ error: reached the recursion limit finding the struct tail for `Bottom` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` +error: reached the recursion limit finding the struct tail for `Bottom` + --> $DIR/recursion_limit_deref.rs:14:9 + | +LL | struct $outer($inner); + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | link!(A, B); + | ----------- in this macro invocation + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` + = note: this error originates in the macro `link` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0055]: reached the recursion limit while auto-dereferencing `J` - --> $DIR/recursion_limit_deref.rs:51:22 + --> $DIR/recursion_limit_deref.rs:55:22 | LL | let x: &Bottom = &t; | ^^ deref recursion limit reached @@ -15,7 +27,7 @@ LL | let x: &Bottom = &t; = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`recursion_limit_deref`) error[E0308]: mismatched types - --> $DIR/recursion_limit_deref.rs:51:22 + --> $DIR/recursion_limit_deref.rs:55:22 | LL | let x: &Bottom = &t; | ------- ^^ expected `&Bottom`, found `&Top` @@ -25,7 +37,7 @@ LL | let x: &Bottom = &t; = note: expected reference `&Bottom` found reference `&Top` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0055, E0308. For more information about an error, try `rustc --explain E0055`. diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.rs b/tests/ui/feature-gates/feature-gate-c_variadic.rs index 88d91dbd081fb..649816b48d784 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.rs +++ b/tests/ui/feature-gates/feature-gate-c_variadic.rs @@ -6,5 +6,4 @@ pub unsafe extern "C" fn test(_: i32, ap: ...) {} trait Trait { unsafe extern "C" fn trait_test(_: i32, ap: ...) {} //~^ ERROR C-variadic functions are unstable - //~| ERROR associated functions cannot have a C variable argument list } diff --git a/tests/ui/feature-gates/feature-gate-c_variadic.stderr b/tests/ui/feature-gates/feature-gate-c_variadic.stderr index 808aa20948d03..ae880093b980c 100644 --- a/tests/ui/feature-gates/feature-gate-c_variadic.stderr +++ b/tests/ui/feature-gates/feature-gate-c_variadic.stderr @@ -1,9 +1,3 @@ -error: associated functions cannot have a C variable argument list - --> $DIR/feature-gate-c_variadic.rs:7:45 - | -LL | unsafe extern "C" fn trait_test(_: i32, ap: ...) {} - | ^^^^^^^ - error[E0658]: C-variadic functions are unstable --> $DIR/feature-gate-c_variadic.rs:3:1 | @@ -24,6 +18,6 @@ LL | unsafe extern "C" fn trait_test(_: i32, ap: ...) {} = help: add `#![feature(c_variadic)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index f7117368ece7b..b8ea353df9385 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -1,4 +1,17 @@ -//~ ERROR reached the recursion limit while instantiating `` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit while instantiating ` as MyTrait>::virtualize` + //@ build-fail //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes @@ -72,16 +85,3 @@ fn main() { let test = SomeData([0; 256]); test.virtualize(); } - -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index faf9cbe2318c4..deccc88e64fa5 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | unsafe { virtualize_my_trait(L, self) } error: reached the recursion limit while instantiating ` as MyTrait>::virtualize` | note: ` as MyTrait>::virtualize` defined here - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:24:5 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:37:5 | LL | fn virtualize(&self) -> &dyn MyTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite/infinite-struct.rs b/tests/ui/infinite/infinite-struct.rs index fd47a4ec9cc6a..d784455824604 100644 --- a/tests/ui/infinite/infinite-struct.rs +++ b/tests/ui/infinite/infinite-struct.rs @@ -1,6 +1,7 @@ struct Take(Take); //~^ ERROR has infinite size //~| ERROR cycle +//~| ERROR reached the recursion limit finding the struct tail for `Take` // check that we don't hang trying to find the tail of a recursive struct (#79437) fn foo() -> Take { @@ -15,5 +16,3 @@ struct Foo { //~ ERROR has infinite size struct Bar([T; 1]); fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `Take` diff --git a/tests/ui/infinite/infinite-struct.stderr b/tests/ui/infinite/infinite-struct.stderr index 5896aec399dc4..0d1ec4989aa53 100644 --- a/tests/ui/infinite/infinite-struct.stderr +++ b/tests/ui/infinite/infinite-struct.stderr @@ -10,7 +10,7 @@ LL | struct Take(Box); | ++++ + error[E0072]: recursive type `Foo` has infinite size - --> $DIR/infinite-struct.rs:11:1 + --> $DIR/infinite-struct.rs:12:1 | LL | struct Foo { | ^^^^^^^^^^ @@ -23,6 +23,10 @@ LL | x: Bar>, | ++++ + error: reached the recursion limit finding the struct tail for `Take` + --> $DIR/infinite-struct.rs:1:1 + | +LL | struct Take(Take); + | ^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` diff --git a/tests/ui/invalid/issue-114435-layout-type-err.rs b/tests/ui/invalid/issue-114435-layout-type-err.rs index 07f310478d3c9..ae04759af5df2 100644 --- a/tests/ui/invalid/issue-114435-layout-type-err.rs +++ b/tests/ui/invalid/issue-114435-layout-type-err.rs @@ -1,3 +1,4 @@ +//~ ERROR reached the recursion limit finding the struct tail for `Bottom` //@ check-fail //@ compile-flags: --crate-type lib -Cdebuginfo=2 @@ -40,5 +41,3 @@ link!(J, K); link!(K, Bottom); fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `Bottom` diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs new file mode 100644 index 0000000000000..16039f177b4de --- /dev/null +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs @@ -0,0 +1,13 @@ +// Regression test for #91831 + +struct Foo<'a>(&'a i32); + +impl<'a> Foo<'a> { + fn modify(&'a mut self) {} +} + +fn bar(foo: &mut Foo) { + foo.modify(); //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr new file mode 100644 index 0000000000000..f02b65230b6eb --- /dev/null +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct-5.rs:10:5 + | +LL | fn bar(foo: &mut Foo) { + | --- - let's call the lifetime of this reference `'1` + | | + | has type `&mut Foo<'2>` +LL | foo.modify(); + | ^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of a mutable reference to `Foo<'_>` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance +help: consider introducing a named lifetime parameter + | +LL | fn bar<'a>(foo: &'a mut Foo<'a>) { + | ++++ ++ ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 4db056f15a51f..415472176d9c4 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -53,30 +53,30 @@ struct X; impl X { fn i_f1(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f2(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f3(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function fn i_f4(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR functions cannot be both `const` and C-variadic //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time } trait T { fn t_f1(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f2(x: isize, ...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f3(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f4(...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f5(..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function fn t_f6(..., x: isize); diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 0cd78318de6a8..da9c9b0f76099 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -132,17 +132,21 @@ error: `...` must be the last argument of a C-variadic function LL | fn e_f2(..., x: isize); | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13 | LL | fn i_f2(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 @@ -150,11 +154,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f3(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13 @@ -162,11 +168,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f4(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 @@ -176,35 +184,45 @@ LL | const fn i_f5(x: isize, ...) {} | | | `const` because of this -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23 | LL | fn t_f2(x: isize, ...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13 | LL | fn t_f3(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13 | LL | fn t_f4(...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13 diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs index 723179302e30a..c5c2c27b28267 100644 --- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs @@ -1,3 +1,4 @@ +//~ ERROR reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` // Regression test for #129541 //@ revisions: unique_curr unique_next multiple_curr multiple_next @@ -24,5 +25,3 @@ struct Hello { } fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`