diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 25944392a52a9..80754a8f65a69 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -79,6 +79,10 @@ ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$de .suggestion = remove the {$remove_descr} .label = `extern` block begins here +ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed + .suggestion = specify an ABI + .help = prior to Rust 2024, a default ABI was inferred + ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel .suggestion = remove the attribute .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index dc77e7b283442..9a7b7daabbf1d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -684,7 +684,7 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::PatternFnPointer { span }); }); if let Extern::Implicit(extern_span) = bfty.ext { - self.maybe_lint_missing_abi(extern_span, ty.id); + self.handle_missing_abi(extern_span, ty.id); } } TyKind::TraitObject(bounds, ..) => { @@ -717,10 +717,12 @@ impl<'a> AstValidator<'a> { } } - fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) { + fn handle_missing_abi(&mut self, span: Span, id: NodeId) { // FIXME(davidtwco): This is a hack to detect macros which produce spans of the // call site which do not have a macro backtrace. See #61963. - if self + if span.edition().at_least_edition_future() && self.features.explicit_extern_abis() { + self.dcx().emit_err(errors::MissingAbi { span }); + } else if self .sess .source_map() .span_to_snippet(span) @@ -996,7 +998,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } if abi.is_none() { - self.maybe_lint_missing_abi(*extern_span, item.id); + self.handle_missing_abi(*extern_span, item.id); } self.with_in_extern_mod(*safety, |this| { visit::walk_item(this, item); @@ -1370,7 +1372,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }, ) = fk { - self.maybe_lint_missing_abi(*extern_span, id); + self.handle_missing_abi(*extern_span, id); } // Functions without bodies cannot have patterns. diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 8e53e600f7ac6..2373a7d223e80 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -823,3 +823,12 @@ pub(crate) struct DuplicatePreciseCapturing { #[label] pub bound2: Span, } + +#[derive(Diagnostic)] +#[diag(ast_passes_extern_without_abi)] +#[help] +pub(crate) struct MissingAbi { + #[primary_span] + #[suggestion(code = "extern \"\"", applicability = "has-placeholders")] + pub span: Span, +} diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 36e375c778d3f..d0ac822ba26e4 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -477,6 +477,8 @@ declare_features! ( (incomplete, ergonomic_clones, "1.87.0", Some(132290)), /// Allows exhaustive pattern matching on types that contain uninhabited types. (unstable, exhaustive_patterns, "1.13.0", Some(51085)), + /// Disallows `extern` without an explicit ABI. + (unstable, explicit_extern_abis, "CURRENT_RUSTC_VERSION", Some(134986)), /// Allows explicit tail calls via `become` expression. (incomplete, explicit_tail_calls, "1.72.0", Some(112788)), /// Allows using `aapcs`, `efiapi`, `sysv64` and `win64` as calling conventions diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 782d328a95102..60c183bd56b1f 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -271,7 +271,7 @@ lint_expectation = this lint expectation is unfulfilled lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition .suggestion = convert it to a `use` -lint_extern_without_abi = extern declarations without an explicit ABI are deprecated +lint_extern_without_abi = `extern` declarations without an explicit ABI are deprecated .label = ABI should be specified here .suggestion = explicitly specify the {$default_abi} ABI diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 148ba02252d94..9994c85d0d0d4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -286,18 +286,23 @@ where // fixing it may cause inference breakage or introduce ambiguity. GoalSource::Misc => PathKind::Unknown, GoalSource::NormalizeGoal(path_kind) => path_kind, - GoalSource::ImplWhereBound => { + GoalSource::ImplWhereBound => match self.current_goal_kind { // We currently only consider a cycle coinductive if it steps // into a where-clause of a coinductive trait. + CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive, + // While normalizing via an impl does step into a where-clause of + // an impl, accessing the associated item immediately steps out of + // it again. This means cycles/recursive calls are not guarded + // by impls used for normalization. // + // See tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs + // for how this can go wrong. + CurrentGoalKind::NormalizesTo => PathKind::Inductive, // We probably want to make all traits coinductive in the future, - // so we treat cycles involving their where-clauses as ambiguous. - if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind { - PathKind::Coinductive - } else { - PathKind::Unknown - } - } + // so we treat cycles involving where-clauses of not-yet coinductive + // traits as ambiguous for now. + CurrentGoalKind::Misc => PathKind::Unknown, + }, // Relating types is always unproductive. If we were to map proof trees to // corecursive functions as explained in #136824, relating types never // introduces a constructor which could cause the recursion to be guarded. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 2d027f16e5d96..fdeb276a58e69 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -45,7 +45,6 @@ where goal, goal.predicate.alias, ); - this.add_goal(GoalSource::AliasWellFormed, goal.with(cx, trait_ref)); this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) }) diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 93fa89b68b97a..80cd87a69f78e 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -543,7 +543,7 @@ parse_maybe_recover_from_bad_qpath_stage_2 = .suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths parse_maybe_recover_from_bad_type_plus = - expected a path on the left-hand side of `+`, not `{$ty}` + expected a path on the left-hand side of `+` parse_maybe_report_ambiguous_plus = ambiguous `+` in a type @@ -642,7 +642,9 @@ parse_mut_on_nested_ident_pattern = `mut` must be attached to each individual bi .suggestion = add `mut` to each binding parse_mut_on_non_ident_pattern = `mut` must be followed by a named binding .suggestion = remove the `mut` prefix -parse_need_plus_after_trait_object_lifetime = lifetime in trait object type must be followed by `+` + +parse_need_plus_after_trait_object_lifetime = lifetimes must be followed by `+` to form a trait object type + .suggestion = consider adding a trait bound after the potential lifetime bound parse_nested_adt = `{$kw_str}` definition cannot be nested inside `{$keyword}` .suggestion = consider creating a new `{$kw_str}` definition instead of nesting diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index dfdef018bc374..aad8a8bc20527 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -30,7 +30,6 @@ pub(crate) struct AmbiguousPlus { #[derive(Diagnostic)] #[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)] pub(crate) struct BadTypePlus { - pub ty: String, #[primary_span] pub span: Span, #[subdiagnostic] @@ -2806,6 +2805,8 @@ pub(crate) struct ReturnTypesUseThinArrow { pub(crate) struct NeedPlusAfterTraitObjectLifetime { #[primary_span] pub span: Span, + #[suggestion(code = " + /* Trait */", applicability = "has-placeholders")] + pub suggestion: Span, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a4978b5a0fe1d..fa38c5b9a7167 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1657,19 +1657,19 @@ impl<'a> Parser<'a> { self.bump(); // `+` let _bounds = self.parse_generic_bounds()?; - let sum_span = ty.span.to(self.prev_token.span); - let sub = match &ty.kind { TyKind::Ref(_lifetime, mut_ty) => { let lo = mut_ty.ty.span.shrink_to_lo(); let hi = self.prev_token.span.shrink_to_hi(); BadTypePlusSub::AddParen { suggestion: AddParen { lo, hi } } } - TyKind::Ptr(..) | TyKind::BareFn(..) => BadTypePlusSub::ForgotParen { span: sum_span }, - _ => BadTypePlusSub::ExpectPath { span: sum_span }, + TyKind::Ptr(..) | TyKind::BareFn(..) => { + BadTypePlusSub::ForgotParen { span: ty.span.to(self.prev_token.span) } + } + _ => BadTypePlusSub::ExpectPath { span: ty.span }, }; - self.dcx().emit_err(BadTypePlus { ty: pprust::ty_to_string(ty), span: sum_span, sub }); + self.dcx().emit_err(BadTypePlus { span: ty.span, sub }); Ok(()) } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d0cff42a20913..42ebf26784df6 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -7,7 +7,7 @@ use rustc_ast::{ Pinnedness, PolyTraitRef, PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, UnsafeBinderTy, }; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym}; use thin_vec::{ThinVec, thin_vec}; @@ -411,6 +411,9 @@ impl<'a> Parser<'a> { TyKind::Path(None, path) if maybe_bounds => { self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true) } + // For `('a) + …`, we know that `'a` in type position already lead to an error being + // emitted. To reduce output, let's indirectly suppress E0178 (bad `+` in type) and + // other irrelevant consequential errors. TyKind::TraitObject(bounds, TraitObjectSyntax::None) if maybe_bounds && bounds.len() == 1 && !trailing_plus => { @@ -425,12 +428,60 @@ impl<'a> Parser<'a> { } fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { - let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()); - let bounds = self.parse_generic_bounds_common(allow_plus)?; - if lt_no_plus { - self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime { span: lo }); + // A lifetime only begins a bare trait object type if it is followed by `+`! + if self.token.is_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()) { + // In Rust 2021 and beyond, we assume that the user didn't intend to write a bare trait + // object type with a leading lifetime bound since that seems very unlikely given the + // fact that `dyn`-less trait objects are *semantically* invalid. + if self.psess.edition.at_least_rust_2021() { + let lt = self.expect_lifetime(); + let mut err = self.dcx().struct_span_err(lo, "expected type, found lifetime"); + err.span_label(lo, "expected type"); + return Ok(match self.maybe_recover_ref_ty_no_leading_ampersand(lt, lo, err) { + Ok(ref_ty) => ref_ty, + Err(err) => TyKind::Err(err.emit()), + }); + } + + self.dcx().emit_err(NeedPlusAfterTraitObjectLifetime { + span: lo, + suggestion: lo.shrink_to_hi(), + }); + } + Ok(TyKind::TraitObject( + self.parse_generic_bounds_common(allow_plus)?, + TraitObjectSyntax::None, + )) + } + + fn maybe_recover_ref_ty_no_leading_ampersand<'cx>( + &mut self, + lt: Lifetime, + lo: Span, + mut err: Diag<'cx>, + ) -> Result> { + if !self.may_recover() { + return Err(err); + } + let snapshot = self.create_snapshot_for_diagnostic(); + let mutbl = self.parse_mutability(); + match self.parse_ty_no_plus() { + Ok(ty) => { + err.span_suggestion_verbose( + lo.shrink_to_lo(), + "you might have meant to write a reference type here", + "&", + Applicability::MaybeIncorrect, + ); + err.emit(); + Ok(TyKind::Ref(Some(lt), MutTy { ty, mutbl })) + } + Err(diag) => { + diag.cancel(); + self.restore_snapshot(snapshot); + Err(err) + } } - Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } fn parse_remaining_bounds_path( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 2af567f2ec502..cc817d99cfaba 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -916,6 +916,7 @@ symbols! { expf16, expf32, expf64, + explicit_extern_abis, explicit_generic_args_with_impl_trait, explicit_tail_calls, export_name, diff --git a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs index 9f02ed4bcbe9f..b9176c939f805 100644 --- a/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/riscv64_linux_android.rs @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { options: TargetOptions { code_model: Some(CodeModel::Medium), cpu: "generic-rv64".into(), - features: "+m,+a,+f,+d,+c,+zicsr,+zifencei,+zba,+zbb,+zbs,+v".into(), + features: "+m,+a,+f,+d,+c,+b,+v,+zicsr,+zifencei".into(), llvm_abiname: "lp64d".into(), supported_sanitizers: SanitizerSet::ADDRESS, max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index b4ec1879fed5c..aeace6a40c72e 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -491,7 +491,8 @@ const MIPS_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ // tidy-alphabetical-start ("a", Stable, &["zaamo", "zalrsc"]), - ("c", Stable, &[]), + ("b", Unstable(sym::riscv_target_feature), &["zba", "zbb", "zbs"]), + ("c", Stable, &["zca"]), ("d", Unstable(sym::riscv_target_feature), &["f"]), ("e", Unstable(sym::riscv_target_feature), &[]), ("f", Unstable(sym::riscv_target_feature), &["zicsr"]), @@ -520,17 +521,25 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zbkc", Stable, &[]), ("zbkx", Stable, &[]), ("zbs", Stable, &[]), + ("zca", Unstable(sym::riscv_target_feature), &[]), + ("zcb", Unstable(sym::riscv_target_feature), &["zca"]), + ("zcmop", Unstable(sym::riscv_target_feature), &["zca"]), ("zdinx", Unstable(sym::riscv_target_feature), &["zfinx"]), + ("zfa", Unstable(sym::riscv_target_feature), &["f"]), ("zfh", Unstable(sym::riscv_target_feature), &["zfhmin"]), ("zfhmin", Unstable(sym::riscv_target_feature), &["f"]), ("zfinx", Unstable(sym::riscv_target_feature), &["zicsr"]), ("zhinx", Unstable(sym::riscv_target_feature), &["zhinxmin"]), ("zhinxmin", Unstable(sym::riscv_target_feature), &["zfinx"]), + ("zicboz", Unstable(sym::riscv_target_feature), &[]), ("zicntr", Unstable(sym::riscv_target_feature), &["zicsr"]), + ("zicond", Unstable(sym::riscv_target_feature), &[]), ("zicsr", Unstable(sym::riscv_target_feature), &[]), ("zifencei", Unstable(sym::riscv_target_feature), &[]), + ("zihintntl", Unstable(sym::riscv_target_feature), &[]), ("zihintpause", Unstable(sym::riscv_target_feature), &[]), ("zihpm", Unstable(sym::riscv_target_feature), &["zicsr"]), + ("zimop", Unstable(sym::riscv_target_feature), &[]), ("zk", Stable, &["zkn", "zkr", "zkt"]), ("zkn", Stable, &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]), ("zknd", Stable, &[]), @@ -541,6 +550,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zksed", Stable, &[]), ("zksh", Stable, &[]), ("zkt", Stable, &[]), + ("ztso", Unstable(sym::riscv_target_feature), &[]), ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]), ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]), diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5c381181218df..3a52b7790376c 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -312,7 +312,6 @@ #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] -#![feature(no_sanitize)] #![feature(optimize_attribute)] #![feature(prelude_import)] #![feature(rustc_attrs)] diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index 13fefb4031d08..cdca73cdca11e 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -259,9 +259,6 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { weak!( fn preadv64( diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 87865be0387d5..687fc322e598d 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1463,20 +1463,6 @@ impl File { Ok(()) } - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[cfg_attr( - any( - target_os = "android", - all( - target_os = "linux", - target_env = "gnu", - target_pointer_width = "32", - not(target_arch = "riscv32") - ) - ), - no_sanitize(cfi) - )] pub fn set_times(&self, times: FileTimes) -> io::Result<()> { #[cfg(not(any( target_os = "redox", diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 4f1517b7ef420..4cdc2eaf0e535 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -194,9 +194,6 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak!( fn pthread_setname_np( diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index b8469b1681f03..0074d7674741b 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,17 +96,6 @@ impl Timespec { } } - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[cfg_attr( - all( - target_os = "linux", - target_env = "gnu", - target_pointer_width = "32", - not(target_arch = "riscv32") - ), - no_sanitize(cfi) - )] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index e4c814fba8cef..a034995e6525d 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -155,9 +155,6 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => ( - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[no_sanitize(cfi)] unsafe fn $name($($param: $t),*) -> $ret { weak!(fn $name($($param: $t),*) -> $ret;); diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 191a09c8da913..3b04ec50db30e 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -434,9 +434,6 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] - // FIXME(#115199): Rust currently omits weak function definitions - // and its metadata from LLVM IR. - #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, stdio: &ChildPipes, diff --git a/library/std/src/sys/thread_local/destructors/linux_like.rs b/library/std/src/sys/thread_local/destructors/linux_like.rs index 817941229eefe..d7cbaeb89f42e 100644 --- a/library/std/src/sys/thread_local/destructors/linux_like.rs +++ b/library/std/src/sys/thread_local/destructors/linux_like.rs @@ -12,9 +12,6 @@ use crate::mem::transmute; -// FIXME: The Rust compiler currently omits weakly function definitions (i.e., -// __cxa_thread_atexit_impl) and its metadata from LLVM IR. -#[no_sanitize(cfi, kcfi)] pub unsafe fn register(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { /// This is necessary because the __cxa_thread_atexit_impl implementation /// std links to by default may be a C or C++ implementation that was not diff --git a/src/doc/unstable-book/src/language-features/explicit-extern-abis.md b/src/doc/unstable-book/src/language-features/explicit-extern-abis.md new file mode 100644 index 0000000000000..ba622466ba74a --- /dev/null +++ b/src/doc/unstable-book/src/language-features/explicit-extern-abis.md @@ -0,0 +1,23 @@ +# `explicit_extern_abis` + +The tracking issue for this feature is: #134986 + +------ + +Disallow `extern` without an explicit ABI. We should write `extern "C"` +(or another ABI) instead of just `extern`. + +By making the ABI explicit, it becomes much clearer that "C" is just one of the +possible choices, rather than the "standard" way for external functions. +Removing the default makes it easier to add a new ABI on equal footing as "C". + +```rust,editionfuture,compile_fail +#![feature(explicit_extern_abis)] + +extern fn function1() {} // ERROR `extern` declarations without an explicit ABI + // are disallowed + +extern "C" fn function2() {} // compiles + +extern "aapcs" fn function3() {} // compiles +``` diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index ac5d294f07ed1..ff4ddbaea49b7 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -76,7 +76,7 @@ enum EnvironmentCmd { rustc_perf_checkout_dir: Option, /// Is LLVM for `rustc` built in shared library mode? - #[arg(long, default_value_t = true)] + #[arg(long, default_value_t = true, action(clap::ArgAction::Set))] llvm_shared: bool, /// Should BOLT optimization be used? If yes, host LLVM must have BOLT binaries diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs index 32d88a59af92d..fb4f14ea41aea 100644 --- a/src/tools/opt-dist/src/utils/mod.rs +++ b/src/tools/opt-dist/src/utils/mod.rs @@ -36,7 +36,9 @@ pub fn clear_llvm_files(env: &Environment) -> anyhow::Result<()> { // directories ourselves. log::info!("Clearing LLVM build files"); delete_directory(&env.build_artifacts().join("llvm"))?; - delete_directory(&env.build_artifacts().join("lld"))?; + if env.build_artifacts().join("lld").is_dir() { + delete_directory(&env.build_artifacts().join("lld"))?; + } Ok(()) } diff --git a/tests/codegen/intrinsic-no-unnamed-attr.rs b/tests/codegen/intrinsic-no-unnamed-attr.rs index 35eb025ab6bb6..4bec579831dc4 100644 --- a/tests/codegen/intrinsic-no-unnamed-attr.rs +++ b/tests/codegen/intrinsic-no-unnamed-attr.rs @@ -1,9 +1,8 @@ //@ compile-flags: -C no-prepopulate-passes -#![feature(intrinsics)] +#![feature(core_intrinsics)] -#[rustc_intrinsic] -unsafe fn sqrtf32(x: f32) -> f32; +use std::intrinsics::sqrtf32; // CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}} diff --git a/tests/ui/check-cfg/target_feature.stderr b/tests/ui/check-cfg/target_feature.stderr index aa5fd09c0c7bb..4f7b8345e86ad 100644 --- a/tests/ui/check-cfg/target_feature.stderr +++ b/tests/ui/check-cfg/target_feature.stderr @@ -49,6 +49,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `avxvnni` `avxvnniint16` `avxvnniint8` +`b` `backchain` `bf16` `bmi1` @@ -318,17 +319,25 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `zbkc` `zbkx` `zbs` +`zca` +`zcb` +`zcmop` `zdinx` +`zfa` `zfh` `zfhmin` `zfinx` `zhinx` `zhinxmin` +`zicboz` `zicntr` +`zicond` `zicsr` `zifencei` +`zihintntl` `zihintpause` `zihpm` +`zimop` `zk` `zkn` `zknd` @@ -339,6 +348,7 @@ LL | cfg!(target_feature = "_UNEXPECTED_VALUE"); `zksed` `zksh` `zkt` +`ztso` `zvbb` `zvbc` `zve32f` diff --git a/tests/ui/coroutine/higher-ranked-rigid.rs b/tests/ui/coroutine/higher-ranked-rigid.rs new file mode 100644 index 0000000000000..23a7d51300c9f --- /dev/null +++ b/tests/ui/coroutine/higher-ranked-rigid.rs @@ -0,0 +1,41 @@ +//@ edition: 2024 +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// Regression test for . +// Coroutines erase all free lifetimes from their interior types, replacing them with higher- +// ranked regions which act as universals, to properly represent the fact that we don't know what +// the value of the region is within the coroutine. +// +// In the future in `from_request`, that means that the `'r` lifetime is being replaced in +// `>::Assoc`, which is in present in the existential bounds of the +// `dyn Future` that it's awaiting. Normalizing this associated type, with its free lifetimes +// replaced, means proving `T: FromRequest<'!0>`, which doesn't hold without constraining the +// `'!0` lifetime, which we don't do today. + +// Proving `T: Trait` holds when `::Assoc` is rigid is not necessary for soundness, +// at least not *yet*, and it's not even necessary for diagnostics since we have other special +// casing for, e.g., AliasRelate goals failing in the BestObligation folder. + +// The old solver unintentioanlly avoids this by never checking that `T: Trait` holds when +// `::Assoc` is rigid. Introducing this additional requirement when projecting rigidly +// in the old solver causes this (and tons of production crates) to fail. See the fallout from the +// crater run at . + +use std::future::Future; +use std::pin::Pin; + +pub trait FromRequest<'r> { + type Assoc; + fn from_request() -> Pin + Send>>; +} + +fn test<'r, T: FromRequest<'r>>() -> Pin + Send>> { + Box::pin(async move { + T::from_request().await; + }) +} + +fn main() {} diff --git a/tests/ui/did_you_mean/E0178.stderr b/tests/ui/did_you_mean/E0178.stderr index 5f289da8a6c30..36e4dbdf7c45d 100644 --- a/tests/ui/did_you_mean/E0178.stderr +++ b/tests/ui/did_you_mean/E0178.stderr @@ -1,41 +1,43 @@ -error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/E0178.rs:6:8 | LL | w: &'a Foo + Copy, - | ^^^^^^^^^^^^^^ + | ^^^^^^^ | help: try adding parentheses | LL | w: &'a (Foo + Copy), | + + -error[E0178]: expected a path on the left-hand side of `+`, not `&'a Foo` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/E0178.rs:7:8 | LL | x: &'a Foo + 'a, - | ^^^^^^^^^^^^ + | ^^^^^^^ | help: try adding parentheses | LL | x: &'a (Foo + 'a), | + + -error[E0178]: expected a path on the left-hand side of `+`, not `&'a mut Foo` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/E0178.rs:8:8 | LL | y: &'a mut Foo + 'a, - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | help: try adding parentheses | LL | y: &'a mut (Foo + 'a), | + + -error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> Foo` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/E0178.rs:9:8 | LL | z: fn() -> Foo + 'a, - | ^^^^^^^^^^^^^^^^ perhaps you forgot parentheses? + | ^^^^^^^^^^^----- + | | + | perhaps you forgot parentheses? error: aborting due to 4 previous errors diff --git a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index 4fee6cc9a2227..762b37b9e9d69 100644 --- a/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/tests/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -1,19 +1,19 @@ -error[E0178]: expected a path on the left-hand side of `+`, not `&Copy` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/trait-object-reference-without-parens-suggestion.rs:4:12 | LL | let _: &Copy + 'static; - | ^^^^^^^^^^^^^^^ + | ^^^^^ | help: try adding parentheses | LL | let _: &(Copy + 'static); | + + -error[E0178]: expected a path on the left-hand side of `+`, not `&'static Copy` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/trait-object-reference-without-parens-suggestion.rs:6:12 | LL | let _: &'static Copy + 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ | help: try adding parentheses | diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed new file mode 100644 index 0000000000000..525f78d162fc0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.fixed @@ -0,0 +1,45 @@ +// The purpose of this feature gate is to make something into a hard error in a +// future edition. Consequently, this test differs from most other feature gate +// tests. Instead of verifying that an error occurs when the feature gate is +// missing, it ensures that the hard error is only produced with the feature +// gate is present in the `future` edition -- and otherwise that only a warning +// is emitted. + +//@ revisions: current current_feature future future_feature + +//@ [current] run-rustfix +//@ [current] check-pass + +//@ [current_feature] run-rustfix +//@ [current_feature] check-pass + +//@ [future] edition: future +//@ [future] compile-flags: -Z unstable-options +//@ [future] run-rustfix +//@ [future] check-pass + +//@ [future_feature] edition: future +//@ [future_feature] compile-flags: -Z unstable-options + +#![cfg_attr(future_feature, feature(explicit_extern_abis))] +#![cfg_attr(current_feature, feature(explicit_extern_abis))] + +extern "C" fn _foo() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" fn _bar() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr new file mode 100644 index 0000000000000..cf927807c7c3c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current.stderr @@ -0,0 +1,22 @@ +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + | +LL | extern fn _foo() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + | + = note: `#[warn(missing_abi)]` on by default + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + | +LL | unsafe extern fn _bar() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + | +LL | unsafe extern {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: 3 warnings emitted + diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed new file mode 100644 index 0000000000000..525f78d162fc0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.fixed @@ -0,0 +1,45 @@ +// The purpose of this feature gate is to make something into a hard error in a +// future edition. Consequently, this test differs from most other feature gate +// tests. Instead of verifying that an error occurs when the feature gate is +// missing, it ensures that the hard error is only produced with the feature +// gate is present in the `future` edition -- and otherwise that only a warning +// is emitted. + +//@ revisions: current current_feature future future_feature + +//@ [current] run-rustfix +//@ [current] check-pass + +//@ [current_feature] run-rustfix +//@ [current_feature] check-pass + +//@ [future] edition: future +//@ [future] compile-flags: -Z unstable-options +//@ [future] run-rustfix +//@ [future] check-pass + +//@ [future_feature] edition: future +//@ [future_feature] compile-flags: -Z unstable-options + +#![cfg_attr(future_feature, feature(explicit_extern_abis))] +#![cfg_attr(current_feature, feature(explicit_extern_abis))] + +extern "C" fn _foo() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" fn _bar() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr new file mode 100644 index 0000000000000..cf927807c7c3c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.current_feature.stderr @@ -0,0 +1,22 @@ +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + | +LL | extern fn _foo() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + | + = note: `#[warn(missing_abi)]` on by default + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + | +LL | unsafe extern fn _bar() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + | +LL | unsafe extern {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: 3 warnings emitted + diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed new file mode 100644 index 0000000000000..525f78d162fc0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.fixed @@ -0,0 +1,45 @@ +// The purpose of this feature gate is to make something into a hard error in a +// future edition. Consequently, this test differs from most other feature gate +// tests. Instead of verifying that an error occurs when the feature gate is +// missing, it ensures that the hard error is only produced with the feature +// gate is present in the `future` edition -- and otherwise that only a warning +// is emitted. + +//@ revisions: current current_feature future future_feature + +//@ [current] run-rustfix +//@ [current] check-pass + +//@ [current_feature] run-rustfix +//@ [current_feature] check-pass + +//@ [future] edition: future +//@ [future] compile-flags: -Z unstable-options +//@ [future] run-rustfix +//@ [future] check-pass + +//@ [future_feature] edition: future +//@ [future_feature] compile-flags: -Z unstable-options + +#![cfg_attr(future_feature, feature(explicit_extern_abis))] +#![cfg_attr(current_feature, feature(explicit_extern_abis))] + +extern "C" fn _foo() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" fn _bar() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern "C" {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr new file mode 100644 index 0000000000000..cf927807c7c3c --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future.stderr @@ -0,0 +1,22 @@ +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + | +LL | extern fn _foo() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + | + = note: `#[warn(missing_abi)]` on by default + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + | +LL | unsafe extern fn _bar() {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: `extern` declarations without an explicit ABI are deprecated + --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + | +LL | unsafe extern {} + | ^^^^^^ help: explicitly specify the "C" ABI: `extern "C"` + +warning: 3 warnings emitted + diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr new file mode 100644 index 0000000000000..096a6f4341699 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.future_feature.stderr @@ -0,0 +1,26 @@ +error: `extern` declarations without an explicit ABI are disallowed + --> $DIR/feature-gate-explicit-extern-abis.rs:27:1 + | +LL | extern fn _foo() {} + | ^^^^^^ help: specify an ABI: `extern ""` + | + = help: prior to Rust 2024, a default ABI was inferred + +error: `extern` declarations without an explicit ABI are disallowed + --> $DIR/feature-gate-explicit-extern-abis.rs:33:8 + | +LL | unsafe extern fn _bar() {} + | ^^^^^^ help: specify an ABI: `extern ""` + | + = help: prior to Rust 2024, a default ABI was inferred + +error: `extern` declarations without an explicit ABI are disallowed + --> $DIR/feature-gate-explicit-extern-abis.rs:39:8 + | +LL | unsafe extern {} + | ^^^^^^ help: specify an ABI: `extern ""` + | + = help: prior to Rust 2024, a default ABI was inferred + +error: aborting due to 3 previous errors + diff --git a/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs new file mode 100644 index 0000000000000..379c45f589907 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-explicit-extern-abis.rs @@ -0,0 +1,45 @@ +// The purpose of this feature gate is to make something into a hard error in a +// future edition. Consequently, this test differs from most other feature gate +// tests. Instead of verifying that an error occurs when the feature gate is +// missing, it ensures that the hard error is only produced with the feature +// gate is present in the `future` edition -- and otherwise that only a warning +// is emitted. + +//@ revisions: current current_feature future future_feature + +//@ [current] run-rustfix +//@ [current] check-pass + +//@ [current_feature] run-rustfix +//@ [current_feature] check-pass + +//@ [future] edition: future +//@ [future] compile-flags: -Z unstable-options +//@ [future] run-rustfix +//@ [future] check-pass + +//@ [future_feature] edition: future +//@ [future_feature] compile-flags: -Z unstable-options + +#![cfg_attr(future_feature, feature(explicit_extern_abis))] +#![cfg_attr(current_feature, feature(explicit_extern_abis))] + +extern fn _foo() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern fn _bar() {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +unsafe extern {} +//[current]~^ WARN `extern` declarations without an explicit ABI are deprecated +//[current_feature]~^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future]~^^^ WARN `extern` declarations without an explicit ABI are deprecated +//[future_feature]~^^^^ ERROR `extern` declarations without an explicit ABI are disallowed + +fn main() {} diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index 85661c1b84480..294fb6743fbcd 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -3,7 +3,7 @@ trait X { } fn foo<'a>(arg: Box>) {} - //~^ ERROR: lifetime in trait object type must be followed by `+` + //~^ ERROR: lifetimes must be followed by `+` to form a trait object type //~| ERROR: parenthesized generic arguments cannot be used //~| ERROR associated type takes 0 generic arguments but 1 generic argument //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index 99300ea1cb7f1..e18d8198c9455 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -1,8 +1,13 @@ -error: lifetime in trait object type must be followed by `+` +error: lifetimes must be followed by `+` to form a trait object type --> $DIR/gat-trait-path-parenthesised-args.rs:5:29 | LL | fn foo<'a>(arg: Box>) {} | ^^ + | +help: consider adding a trait bound after the potential lifetime bound + | +LL | fn foo<'a>(arg: Box>) {} + | +++++++++++++ error: parenthesized generic arguments cannot be used in associated type constraints --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 diff --git a/tests/ui/impl-trait/impl-trait-plus-priority.rs b/tests/ui/impl-trait/impl-trait-plus-priority.rs index 5575493a17d36..8f76d41266222 100644 --- a/tests/ui/impl-trait/impl-trait-plus-priority.rs +++ b/tests/ui/impl-trait/impl-trait-plus-priority.rs @@ -27,7 +27,7 @@ type A = fn() -> impl A + B; type A = fn() -> dyn A + B; //~^ ERROR ambiguous `+` in a type type A = fn() -> A + B; -//~^ ERROR expected a path on the left-hand side of `+`, not `fn() -> A` +//~^ ERROR expected a path on the left-hand side of `+` type A = Fn() -> impl A +; //~^ ERROR ambiguous `+` in a type @@ -44,6 +44,6 @@ type A = &impl A + B; type A = &dyn A + B; //~^ ERROR ambiguous `+` in a type type A = &A + B; -//~^ ERROR expected a path on the left-hand side of `+`, not `&A` +//~^ ERROR expected a path on the left-hand side of `+` fn main() {} diff --git a/tests/ui/impl-trait/impl-trait-plus-priority.stderr b/tests/ui/impl-trait/impl-trait-plus-priority.stderr index 03e7910095a90..1612065796031 100644 --- a/tests/ui/impl-trait/impl-trait-plus-priority.stderr +++ b/tests/ui/impl-trait/impl-trait-plus-priority.stderr @@ -31,11 +31,13 @@ help: try adding parentheses LL | type A = fn() -> (dyn A + B); | + + -error[E0178]: expected a path on the left-hand side of `+`, not `fn() -> A` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/impl-trait-plus-priority.rs:29:10 | LL | type A = fn() -> A + B; - | ^^^^^^^^^^^^^ perhaps you forgot parentheses? + | ^^^^^^^^^---- + | | + | perhaps you forgot parentheses? error: ambiguous `+` in a type --> $DIR/impl-trait-plus-priority.rs:32:18 @@ -103,11 +105,11 @@ help: try adding parentheses LL | type A = &(dyn A + B); | + + -error[E0178]: expected a path on the left-hand side of `+`, not `&A` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/impl-trait-plus-priority.rs:46:10 | LL | type A = &A + B; - | ^^^^^^ + | ^^ | help: try adding parentheses | diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs index 6bc3f8d884db1..9127cc649e66d 100644 --- a/tests/ui/intrinsics/intrinsic-atomics.rs +++ b/tests/ui/intrinsics/intrinsic-atomics.rs @@ -1,53 +1,6 @@ //@ run-pass -#![feature(intrinsics)] - -mod rusti { - - #[rustc_intrinsic] - pub unsafe fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - #[rustc_intrinsic] - pub unsafe fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - #[rustc_intrinsic] - pub unsafe fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - - #[rustc_intrinsic] - pub unsafe fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - #[rustc_intrinsic] - pub unsafe fn atomic_cxchgweak_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - #[rustc_intrinsic] - pub unsafe fn atomic_cxchgweak_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - - #[rustc_intrinsic] - pub unsafe fn atomic_load_seqcst(src: *const T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_load_acquire(src: *const T) -> T; - - #[rustc_intrinsic] - pub unsafe fn atomic_store_seqcst(dst: *mut T, val: T); - #[rustc_intrinsic] - pub unsafe fn atomic_store_release(dst: *mut T, val: T); - - #[rustc_intrinsic] - pub unsafe fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xchg_release(dst: *mut T, src: T) -> T; - - #[rustc_intrinsic] - pub unsafe fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xadd_release(dst: *mut T, src: T) -> T; - - #[rustc_intrinsic] - pub unsafe fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; - #[rustc_intrinsic] - pub unsafe fn atomic_xsub_release(dst: *mut T, src: T) -> T; -} +#![feature(core_intrinsics)] +use std::intrinsics as rusti; pub fn main() { unsafe { diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.rs b/tests/ui/link-native-libs/suggest-libname-only-1.rs index c69949d1fdb36..8699e4819e623 100644 --- a/tests/ui/link-native-libs/suggest-libname-only-1.rs +++ b/tests/ui/link-native-libs/suggest-libname-only-1.rs @@ -2,7 +2,7 @@ //@ compile-flags: --crate-type rlib #[link(name = "libfoo.a", kind = "static")] -extern { } //~ WARN extern declarations without an explicit ABI are deprecated +extern { } //~ WARN `extern` declarations without an explicit ABI are deprecated //~| HELP explicitly specify the "C" ABI pub fn main() { } diff --git a/tests/ui/link-native-libs/suggest-libname-only-1.stderr b/tests/ui/link-native-libs/suggest-libname-only-1.stderr index 0320294a8004b..59bd99f619a0f 100644 --- a/tests/ui/link-native-libs/suggest-libname-only-1.stderr +++ b/tests/ui/link-native-libs/suggest-libname-only-1.stderr @@ -1,4 +1,4 @@ -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/suggest-libname-only-1.rs:5:1 | LL | extern { } diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.rs b/tests/ui/link-native-libs/suggest-libname-only-2.rs index d5150c327cd5e..87373f563d090 100644 --- a/tests/ui/link-native-libs/suggest-libname-only-2.rs +++ b/tests/ui/link-native-libs/suggest-libname-only-2.rs @@ -2,7 +2,7 @@ //@ compile-flags: --crate-type rlib #[link(name = "bar.lib", kind = "static")] -extern { } //~ WARN extern declarations without an explicit ABI are deprecated +extern { } //~ WARN `extern` declarations without an explicit ABI are deprecated //~| HELP explicitly specify the "C" ABI pub fn main() { } diff --git a/tests/ui/link-native-libs/suggest-libname-only-2.stderr b/tests/ui/link-native-libs/suggest-libname-only-2.stderr index e492aea27b455..298a9ced17076 100644 --- a/tests/ui/link-native-libs/suggest-libname-only-2.stderr +++ b/tests/ui/link-native-libs/suggest-libname-only-2.stderr @@ -1,4 +1,4 @@ -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/suggest-libname-only-2.rs:5:1 | LL | extern { } diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr index fb8779ad4f15d..fe3437ae3d752 100644 --- a/tests/ui/lint/cli-lint-override.forbid_warn.stderr +++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr @@ -1,4 +1,4 @@ -error: extern declarations without an explicit ABI are deprecated +error: `extern` declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr index 10fc13e3f52f8..f48fca4bd9f37 100644 --- a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr @@ -1,4 +1,4 @@ -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} diff --git a/tests/ui/lint/cli-lint-override.rs b/tests/ui/lint/cli-lint-override.rs index 4b3fd0d9c01c9..b733872166aa2 100644 --- a/tests/ui/lint/cli-lint-override.rs +++ b/tests/ui/lint/cli-lint-override.rs @@ -10,8 +10,8 @@ extern fn foo() {} -//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated -//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated -//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated +//[warn_deny]~^ ERROR `extern` declarations without an explicit ABI are deprecated +//[forbid_warn]~^^ ERROR `extern` declarations without an explicit ABI are deprecated +//[force_warn_deny]~^^^ WARN `extern` declarations without an explicit ABI are deprecated fn main() {} diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr index 979ca22324f1e..91baad1f9f870 100644 --- a/tests/ui/lint/cli-lint-override.warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr @@ -1,4 +1,4 @@ -error: extern declarations without an explicit ABI are deprecated +error: `extern` declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} diff --git a/tests/ui/numbers-arithmetic/int.rs b/tests/ui/numbers-arithmetic/int.rs deleted file mode 100644 index 42f8e50d6efaf..0000000000000 --- a/tests/ui/numbers-arithmetic/int.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-pass - - - - -pub fn main() { let _x: isize = 10; } diff --git a/tests/ui/numbers-arithmetic/isize-base.rs b/tests/ui/numbers-arithmetic/isize-base.rs new file mode 100644 index 0000000000000..412e7ac7a2e92 --- /dev/null +++ b/tests/ui/numbers-arithmetic/isize-base.rs @@ -0,0 +1,25 @@ +//! Tests basic `isize` functionality + +//@ run-pass + +pub fn main() { + // Literal matches assignment type + let a: isize = 42isize; + // Literal cast + let b: isize = 42 as isize; + // Literal type inference from assignment type + let c: isize = 42; + // Assignment type inference from literal (and later comparison) + let d = 42isize; + // Function return value type inference + let e = return_val(); + + assert_eq!(a, b); + assert_eq!(a, c); + assert_eq!(a, d); + assert_eq!(a, e); +} + +fn return_val() -> isize { + 42 +} diff --git a/tests/ui/numbers-arithmetic/uint.rs b/tests/ui/numbers-arithmetic/uint.rs deleted file mode 100644 index c2087b5a06c63..0000000000000 --- a/tests/ui/numbers-arithmetic/uint.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-pass - - - - -pub fn main() { let _x: usize = 10 as usize; } diff --git a/tests/ui/numbers-arithmetic/usize-base.rs b/tests/ui/numbers-arithmetic/usize-base.rs new file mode 100644 index 0000000000000..833fc0497989d --- /dev/null +++ b/tests/ui/numbers-arithmetic/usize-base.rs @@ -0,0 +1,25 @@ +//! Tests basic `usize` functionality + +//@ run-pass + +pub fn main() { + // Literal matches assignment type + let a: usize = 42usize; + // Literal cast + let b: usize = 42 as usize; + // Literal type inference from assignment type + let c: usize = 42; + // Assignment type inference from literal (and later comparison) + let d = 42usize; + // Function return value type inference + let e = return_val(); + + assert_eq!(a, b); + assert_eq!(a, c); + assert_eq!(a, d); + assert_eq!(a, e); +} + +fn return_val() -> usize { + 42 +} diff --git a/tests/ui/parser/bad-lit-suffixes.stderr b/tests/ui/parser/bad-lit-suffixes.stderr index d6b50b0e0d1fe..86ef35bf7833f 100644 --- a/tests/ui/parser/bad-lit-suffixes.stderr +++ b/tests/ui/parser/bad-lit-suffixes.stderr @@ -51,7 +51,7 @@ LL | #[rustc_layout_scalar_valid_range_start(0suffix)] | = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/bad-lit-suffixes.rs:3:1 | LL | extern @@ -59,7 +59,7 @@ LL | extern | = note: `#[warn(missing_abi)]` on by default -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/bad-lit-suffixes.rs:7:1 | LL | extern diff --git a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs index cf754a6854ecf..782a46ab060e0 100644 --- a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs +++ b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.rs @@ -12,7 +12,7 @@ mac!('a); // avoid false positives fn y<'a>(y: &mut 'a + Send) { - //~^ ERROR expected a path on the left-hand side of `+`, not `&mut 'a` + //~^ ERROR expected a path on the left-hand side of `+` //~| ERROR at least one trait is required for an object type let z = y as &mut 'a + Send; //~^ ERROR expected value, found trait `Send` diff --git a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr index 6b8f8e4fe4ee3..ae1ed72853de3 100644 --- a/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr +++ b/tests/ui/parser/issues/issue-73568-lifetime-after-mut.stderr @@ -10,11 +10,11 @@ LL - fn x<'a>(x: &mut 'a i32){} LL + fn x<'a>(x: &'a mut i32){} | -error[E0178]: expected a path on the left-hand side of `+`, not `&mut 'a` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/issue-73568-lifetime-after-mut.rs:14:13 | LL | fn y<'a>(y: &mut 'a + Send) { - | ^^^^^^^^^^^^^^ + | ^^^^^^^ | help: try adding parentheses | diff --git a/tests/ui/parser/lit-err-in-macro.stderr b/tests/ui/parser/lit-err-in-macro.stderr index 9422f22f9c8fe..08fe58643d40a 100644 --- a/tests/ui/parser/lit-err-in-macro.stderr +++ b/tests/ui/parser/lit-err-in-macro.stderr @@ -4,7 +4,7 @@ error: suffixes on string literals are invalid LL | f!("Foo"__); | ^^^^^^^ invalid suffix `__` -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/lit-err-in-macro.rs:3:9 | LL | extern $abi fn f() {} diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.e2015.stderr b/tests/ui/parser/macro/trait-object-macro-matcher.e2015.stderr new file mode 100644 index 0000000000000..f2db351de4a7f --- /dev/null +++ b/tests/ui/parser/macro/trait-object-macro-matcher.e2015.stderr @@ -0,0 +1,32 @@ +error: lifetimes must be followed by `+` to form a trait object type + --> $DIR/trait-object-macro-matcher.rs:17:8 + | +LL | m!('static); + | ^^^^^^^ + | +help: consider adding a trait bound after the potential lifetime bound + | +LL | m!('static + /* Trait */); + | +++++++++++++ + +error: lifetimes must be followed by `+` to form a trait object type + --> $DIR/trait-object-macro-matcher.rs:17:8 + | +LL | m!('static); + | ^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider adding a trait bound after the potential lifetime bound + | +LL | m!('static + /* Trait */); + | +++++++++++++ + +error[E0224]: at least one trait is required for an object type + --> $DIR/trait-object-macro-matcher.rs:17:8 + | +LL | m!('static); + | ^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.e2021.stderr b/tests/ui/parser/macro/trait-object-macro-matcher.e2021.stderr new file mode 100644 index 0000000000000..7d9e8d795d18a --- /dev/null +++ b/tests/ui/parser/macro/trait-object-macro-matcher.e2021.stderr @@ -0,0 +1,16 @@ +error: expected type, found lifetime + --> $DIR/trait-object-macro-matcher.rs:17:8 + | +LL | m!('static); + | ^^^^^^^ expected type + +error: expected type, found lifetime + --> $DIR/trait-object-macro-matcher.rs:17:8 + | +LL | m!('static); + | ^^^^^^^ expected type + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.rs b/tests/ui/parser/macro/trait-object-macro-matcher.rs index d4ec199070e7c..ba61752fe4024 100644 --- a/tests/ui/parser/macro/trait-object-macro-matcher.rs +++ b/tests/ui/parser/macro/trait-object-macro-matcher.rs @@ -1,6 +1,10 @@ // A single lifetime is not parsed as a type. // `ty` matcher in particular doesn't accept a single lifetime +//@ revisions: e2015 e2021 +//@[e2015] edition: 2015 +//@[e2021] edition: 2021 + macro_rules! m { ($t: ty) => { let _: $t; @@ -8,8 +12,10 @@ macro_rules! m { } fn main() { + //[e2021]~vv ERROR expected type, found lifetime + //[e2021]~v ERROR expected type, found lifetime m!('static); - //~^ ERROR lifetime in trait object type must be followed by `+` - //~| ERROR lifetime in trait object type must be followed by `+` - //~| ERROR at least one trait is required for an object type + //[e2015]~^ ERROR lifetimes must be followed by `+` to form a trait object type + //[e2015]~| ERROR lifetimes must be followed by `+` to form a trait object type + //[e2015]~| ERROR at least one trait is required for an object type } diff --git a/tests/ui/parser/macro/trait-object-macro-matcher.stderr b/tests/ui/parser/macro/trait-object-macro-matcher.stderr deleted file mode 100644 index 81dca6f71c436..0000000000000 --- a/tests/ui/parser/macro/trait-object-macro-matcher.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error: lifetime in trait object type must be followed by `+` - --> $DIR/trait-object-macro-matcher.rs:11:8 - | -LL | m!('static); - | ^^^^^^^ - -error: lifetime in trait object type must be followed by `+` - --> $DIR/trait-object-macro-matcher.rs:11:8 - | -LL | m!('static); - | ^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0224]: at least one trait is required for an object type - --> $DIR/trait-object-macro-matcher.rs:11:8 - | -LL | m!('static); - | ^^^^^^^ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/parser/recover/recover-ampersand-less-ref-ty.rs b/tests/ui/parser/recover/recover-ampersand-less-ref-ty.rs new file mode 100644 index 0000000000000..8f1a42473b5a6 --- /dev/null +++ b/tests/ui/parser/recover/recover-ampersand-less-ref-ty.rs @@ -0,0 +1,13 @@ +//@ edition: 2021 + +struct Entity<'a> { + name: 'a str, //~ ERROR expected type, found lifetime + //~^ HELP you might have meant to write a reference type here +} + +struct Buffer<'buf> { + bytes: 'buf mut [u8], //~ ERROR expected type, found lifetime + //~^ HELP you might have meant to write a reference type here +} + +fn main() {} diff --git a/tests/ui/parser/recover/recover-ampersand-less-ref-ty.stderr b/tests/ui/parser/recover/recover-ampersand-less-ref-ty.stderr new file mode 100644 index 0000000000000..033348b2c4058 --- /dev/null +++ b/tests/ui/parser/recover/recover-ampersand-less-ref-ty.stderr @@ -0,0 +1,24 @@ +error: expected type, found lifetime + --> $DIR/recover-ampersand-less-ref-ty.rs:4:11 + | +LL | name: 'a str, + | ^^ expected type + | +help: you might have meant to write a reference type here + | +LL | name: &'a str, + | + + +error: expected type, found lifetime + --> $DIR/recover-ampersand-less-ref-ty.rs:9:12 + | +LL | bytes: 'buf mut [u8], + | ^^^^ expected type + | +help: you might have meant to write a reference type here + | +LL | bytes: &'buf mut [u8], + | + + +error: aborting due to 2 previous errors + diff --git a/tests/ui/parser/trait-object-bad-parens.rs b/tests/ui/parser/trait-object-bad-parens.rs index 8e267c7448feb..bb047a4b43142 100644 --- a/tests/ui/parser/trait-object-bad-parens.rs +++ b/tests/ui/parser/trait-object-bad-parens.rs @@ -5,12 +5,8 @@ auto trait Auto {} fn main() { - let _: Box<((Auto)) + Auto>; - //~^ ERROR expected a path on the left-hand side of `+`, not `((Auto))` - let _: Box<(Auto + Auto) + Auto>; - //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto + Auto)` - let _: Box<(Auto +) + Auto>; - //~^ ERROR expected a path on the left-hand side of `+`, not `(Auto)` - let _: Box<(dyn Auto) + Auto>; - //~^ ERROR expected a path on the left-hand side of `+`, not `(dyn Auto)` + let _: Box<((Auto)) + Auto>; //~ ERROR expected a path on the left-hand side of `+` + let _: Box<(Auto + Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+` + let _: Box<(Auto +) + Auto>; //~ ERROR expected a path on the left-hand side of `+` + let _: Box<(dyn Auto) + Auto>; //~ ERROR expected a path on the left-hand side of `+` } diff --git a/tests/ui/parser/trait-object-bad-parens.stderr b/tests/ui/parser/trait-object-bad-parens.stderr index 74e484eebee1f..7c2559ce89fd1 100644 --- a/tests/ui/parser/trait-object-bad-parens.stderr +++ b/tests/ui/parser/trait-object-bad-parens.stderr @@ -1,26 +1,26 @@ -error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/trait-object-bad-parens.rs:8:16 | LL | let _: Box<((Auto)) + Auto>; - | ^^^^^^^^^^^^^^^ expected a path + | ^^^^^^^^ expected a path -error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)` - --> $DIR/trait-object-bad-parens.rs:10:16 +error[E0178]: expected a path on the left-hand side of `+` + --> $DIR/trait-object-bad-parens.rs:9:16 | LL | let _: Box<(Auto + Auto) + Auto>; - | ^^^^^^^^^^^^^^^^^^^^ expected a path + | ^^^^^^^^^^^^^ expected a path -error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)` - --> $DIR/trait-object-bad-parens.rs:12:16 +error[E0178]: expected a path on the left-hand side of `+` + --> $DIR/trait-object-bad-parens.rs:10:16 | LL | let _: Box<(Auto +) + Auto>; - | ^^^^^^^^^^^^^^^ expected a path + | ^^^^^^^^ expected a path -error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)` - --> $DIR/trait-object-bad-parens.rs:14:16 +error[E0178]: expected a path on the left-hand side of `+` + --> $DIR/trait-object-bad-parens.rs:11:16 | LL | let _: Box<(dyn Auto) + Auto>; - | ^^^^^^^^^^^^^^^^^ expected a path + | ^^^^^^^^^^ expected a path error: aborting due to 4 previous errors diff --git a/tests/ui/parser/trait-object-lifetime-parens.stderr b/tests/ui/parser/trait-object-lifetime-parens.e2015.stderr similarity index 60% rename from tests/ui/parser/trait-object-lifetime-parens.stderr rename to tests/ui/parser/trait-object-lifetime-parens.e2015.stderr index 280c0e40c6408..cf0b3d77f5b5a 100644 --- a/tests/ui/parser/trait-object-lifetime-parens.stderr +++ b/tests/ui/parser/trait-object-lifetime-parens.e2015.stderr @@ -1,5 +1,5 @@ error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:5:21 + --> $DIR/trait-object-lifetime-parens.rs:9:21 | LL | fn f<'a, T: Trait + ('a)>() {} | ^^^^ @@ -11,7 +11,7 @@ LL + fn f<'a, T: Trait + 'a>() {} | error: parenthesized lifetime bounds are not supported - --> $DIR/trait-object-lifetime-parens.rs:8:24 + --> $DIR/trait-object-lifetime-parens.rs:12:24 | LL | let _: Box; | ^^^^ @@ -22,11 +22,16 @@ LL - let _: Box; LL + let _: Box; | -error: lifetime in trait object type must be followed by `+` - --> $DIR/trait-object-lifetime-parens.rs:10:17 +error: lifetimes must be followed by `+` to form a trait object type + --> $DIR/trait-object-lifetime-parens.rs:16:17 | LL | let _: Box<('a) + Trait>; | ^^ + | +help: consider adding a trait bound after the potential lifetime bound + | +LL | let _: Box<('a + /* Trait */) + Trait>; + | +++++++++++++ error: aborting due to 3 previous errors diff --git a/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr b/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr new file mode 100644 index 0000000000000..b65c079788a9c --- /dev/null +++ b/tests/ui/parser/trait-object-lifetime-parens.e2021.stderr @@ -0,0 +1,51 @@ +error: parenthesized lifetime bounds are not supported + --> $DIR/trait-object-lifetime-parens.rs:9:21 + | +LL | fn f<'a, T: Trait + ('a)>() {} + | ^^^^ + | +help: remove the parentheses + | +LL - fn f<'a, T: Trait + ('a)>() {} +LL + fn f<'a, T: Trait + 'a>() {} + | + +error: parenthesized lifetime bounds are not supported + --> $DIR/trait-object-lifetime-parens.rs:12:24 + | +LL | let _: Box; + | ^^^^ + | +help: remove the parentheses + | +LL - let _: Box; +LL + let _: Box; + | + +error: expected type, found lifetime + --> $DIR/trait-object-lifetime-parens.rs:16:17 + | +LL | let _: Box<('a) + Trait>; + | ^^ expected type + +error[E0178]: expected a path on the left-hand side of `+` + --> $DIR/trait-object-lifetime-parens.rs:16:16 + | +LL | let _: Box<('a) + Trait>; + | ^^^^ expected a path + +error[E0782]: expected a type, found a trait + --> $DIR/trait-object-lifetime-parens.rs:12:16 + | +LL | let _: Box; + | ^^^^^^^^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | let _: Box; + | +++ + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0178, E0782. +For more information about an error, try `rustc --explain E0178`. diff --git a/tests/ui/parser/trait-object-lifetime-parens.rs b/tests/ui/parser/trait-object-lifetime-parens.rs index f44ebe5ba5bf2..0ff4660bb0d58 100644 --- a/tests/ui/parser/trait-object-lifetime-parens.rs +++ b/tests/ui/parser/trait-object-lifetime-parens.rs @@ -1,4 +1,8 @@ -#![allow(bare_trait_objects)] +//@ revisions: e2015 e2021 +//@[e2015] edition: 2015 +//@[e2021] edition: 2021 + +#![cfg_attr(e2015, allow(bare_trait_objects))] trait Trait {} @@ -6,8 +10,12 @@ fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not s fn check<'a>() { let _: Box; //~ ERROR parenthesized lifetime bounds are not supported - // FIXME: It'd be great if we could add suggestion to the following case. - let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+` + //[e2021]~^ ERROR expected a type, found a trait + // FIXME: It'd be great if we could suggest removing the parentheses here too. + //[e2015]~v ERROR lifetimes must be followed by `+` to form a trait object type + let _: Box<('a) + Trait>; + //[e2021]~^ ERROR expected type, found lifetime + //[e2021]~| ERROR expected a path on the left-hand side of `+` } fn main() {} diff --git a/tests/ui/parser/trait-object-polytrait-priority.rs b/tests/ui/parser/trait-object-polytrait-priority.rs index e7f085104ae9b..85568f0fe1b18 100644 --- a/tests/ui/parser/trait-object-polytrait-priority.rs +++ b/tests/ui/parser/trait-object-polytrait-priority.rs @@ -4,6 +4,6 @@ trait Trait<'a> {} fn main() { let _: &for<'a> Trait<'a> + 'static; - //~^ ERROR expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>` + //~^ ERROR expected a path on the left-hand side of `+` //~| HELP try adding parentheses } diff --git a/tests/ui/parser/trait-object-polytrait-priority.stderr b/tests/ui/parser/trait-object-polytrait-priority.stderr index 8cb564e79300e..a291a8e229c4b 100644 --- a/tests/ui/parser/trait-object-polytrait-priority.stderr +++ b/tests/ui/parser/trait-object-polytrait-priority.stderr @@ -1,8 +1,8 @@ -error[E0178]: expected a path on the left-hand side of `+`, not `&for<'a> Trait<'a>` +error[E0178]: expected a path on the left-hand side of `+` --> $DIR/trait-object-polytrait-priority.rs:6:12 | LL | let _: &for<'a> Trait<'a> + 'static; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | help: try adding parentheses | diff --git a/tests/ui/proc-macro/inner-attrs.rs b/tests/ui/proc-macro/inner-attrs.rs index c541e93f9041d..ca4b2029a3384 100644 --- a/tests/ui/proc-macro/inner-attrs.rs +++ b/tests/ui/proc-macro/inner-attrs.rs @@ -82,7 +82,7 @@ fn bar() { } -extern { //~ WARN extern declarations without an explicit ABI are deprecated +extern { //~ WARN `extern` declarations without an explicit ABI are deprecated fn weird_extern() { #![print_target_and_args_consume(tenth)] } diff --git a/tests/ui/proc-macro/inner-attrs.stderr b/tests/ui/proc-macro/inner-attrs.stderr index 4e7825c0d007c..54cccae8da082 100644 --- a/tests/ui/proc-macro/inner-attrs.stderr +++ b/tests/ui/proc-macro/inner-attrs.stderr @@ -22,7 +22,7 @@ error: expected non-macro inner attribute, found attribute macro `print_attr` LL | #![print_attr] | ^^^^^^^^^^ not a non-macro inner attribute -warning: extern declarations without an explicit ABI are deprecated +warning: `extern` declarations without an explicit ABI are deprecated --> $DIR/inner-attrs.rs:85:1 | LL | extern { diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive-2.rs b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive-2.rs new file mode 100644 index 0000000000000..bb3540f9a214f --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive-2.rs @@ -0,0 +1,24 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#176. +// +// Normalizing ` as IntoIterator>::IntoIter` has two candidates +// inside of the function: +// - `impl IntoIterator for Vec` which trivially applies +// - `impl IntoIterator for I` +// - requires `Vec: Iterator` +// - where-clause requires ` as IntoIterator>::IntoIter eq Vec` +// - normalize ` as IntoIterator>::IntoIter` again, cycle +// +// We need to treat this cycle as an error to be able to use the actual impl. + +fn test() +where + as IntoIterator>::IntoIter: Iterator, +{ +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.current.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.current.stderr new file mode 100644 index 0000000000000..0a5b90f3d12bf --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.current.stderr @@ -0,0 +1,48 @@ +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:41:1 + | +LL | / fn generic() +LL | | where +LL | | >::Assoc: Bound, + | |____________________________________^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required for `Foo` to implement `Trait` + --> $DIR/normalizes-to-is-not-productive.rs:24:19 + | +LL | impl Trait for T { + | ----- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:41:4 + | +LL | fn generic() + | ^^^^^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required for `Foo` to implement `Trait` + --> $DIR/normalizes-to-is-not-productive.rs:24:19 + | +LL | impl Trait for T { + | ----- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:48:19 + | +LL | impls_bound::(); + | ^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required by a bound in `impls_bound` + --> $DIR/normalizes-to-is-not-productive.rs:28:19 + | +LL | fn impls_bound() { + | ^^^^^ required by this bound in `impls_bound` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.next.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.next.stderr new file mode 100644 index 0000000000000..d888fbf9db183 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.next.stderr @@ -0,0 +1,31 @@ +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:43:31 + | +LL | >::Assoc: Bound, + | ^^^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required for `Foo` to implement `Trait` + --> $DIR/normalizes-to-is-not-productive.rs:24:19 + | +LL | impl Trait for T { + | ----- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:48:19 + | +LL | impls_bound::(); + | ^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required by a bound in `impls_bound` + --> $DIR/normalizes-to-is-not-productive.rs:28:19 + | +LL | fn impls_bound() { + | ^^^^^ required by this bound in `impls_bound` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs new file mode 100644 index 0000000000000..ffbbecaf89570 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs @@ -0,0 +1,54 @@ +//@ ignore-compare-mode-next-solver (explicit) +//@ compile-flags: -Znext-solver + +// Make sure that stepping into impl where-clauses of `NormalizesTo` +// goals is unproductive. This must not compile, see the inline +// comments. + +trait Bound { + fn method(); +} +impl Bound for u32 { + fn method() {} +} +trait Trait { + type Assoc: Bound; +} + +struct Foo; + +impl Trait for Foo { + type Assoc = u32; +} +impl Trait for T { + type Assoc = T; +} + +fn impls_bound() { + T::method(); +} + +// The where-clause requires `Foo: Trait` to hold to be wf. +// If stepping into where-clauses during normalization is considered +// to be productive, this would be the case: +// +// - `Foo: Trait` +// - via blanket impls, requires `Foo: Bound` +// - via where-bound, requires `Foo eq >::Assoc` +// - normalize `>::Assoc` +// - via blanket impl, requires where-clause `Foo: Bound` -> cycle +fn generic() +where + >::Assoc: Bound, + //~^ ERROR the trait bound `Foo: Bound` is not satisfied +{ + // Requires proving `Foo: Bound` by normalizing + // `>::Assoc` to `Foo`. + impls_bound::(); + //~^ ERROR the trait bound `Foo: Bound` is not satisfied +} +fn main() { + // Requires proving `>::Assoc: Bound`. + // This is trivially true. + generic::(); +} diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr new file mode 100644 index 0000000000000..8901805a20f5f --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -0,0 +1,31 @@ +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:42:31 + | +LL | >::Assoc: Bound, + | ^^^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required for `Foo` to implement `Trait` + --> $DIR/normalizes-to-is-not-productive.rs:23:19 + | +LL | impl Trait for T { + | ----- ^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the trait bound `Foo: Bound` is not satisfied + --> $DIR/normalizes-to-is-not-productive.rs:47:19 + | +LL | impls_bound::(); + | ^^^ the trait `Bound` is not implemented for `Foo` + | + = help: the trait `Bound` is implemented for `u32` +note: required by a bound in `impls_bound` + --> $DIR/normalizes-to-is-not-productive.rs:27:19 + | +LL | fn impls_bound() { + | ^^^^^ required by this bound in `impls_bound` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.