Auto merge of #139940 - matthiaskrgr:rollup-rd4d3fn, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #135340 (Add `explicit_extern_abis` Feature and Enforce Explicit ABIs)
 - #139440 (rustc_target: RISC-V: feature addition batch 2)
 - #139667 (cfi: Remove #[no_sanitize(cfi)] for extern weak functions)
 - #139828 (Don't require rigid alias's trait to hold)
 - #139854 (Improve parse errors for stray lifetimes in type position)
 - #139889 (Clean UI tests 3 of n)
 - #139894 (Fix `opt-dist` CLI flag and make it work without LLD)
 - #139900 (stepping into impls for normalization is unproductive)
 - #139915 (replace some #[rustc_intrinsic] usage with use of the libcore declarations)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-04-17 04:52:34 +00:00
commit 15c4ccef03
79 changed files with 939 additions and 231 deletions

View file

@ -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

View file

@ -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.

View file

@ -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 \"<abi>\"", applicability = "has-placeholders")]
pub span: Span,
}

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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)
})
})

View file

@ -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

View file

@ -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]
@ -2800,6 +2799,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)]

View file

@ -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(())
}

View file

@ -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<TyKind, Diag<'cx>> {
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(

View file

@ -916,6 +916,7 @@ symbols! {
expf16,
expf32,
expf64,
explicit_extern_abis,
explicit_generic_args_with_impl_trait,
explicit_tail_calls,
export_name,

View file

@ -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),

View file

@ -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"]),

View file

@ -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)]

View file

@ -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<usize> {
weak!(
fn preadv64(

View file

@ -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",

View file

@ -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(

View file

@ -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;

View file

@ -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;);

View file

@ -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,

View file

@ -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

View file

@ -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
```

View file

@ -76,7 +76,7 @@ enum EnvironmentCmd {
rustc_perf_checkout_dir: Option<Utf8PathBuf>,
/// 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

View file

@ -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(())
}

View file

@ -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]*}}

View file

@ -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`

View file

@ -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 <https://github.com/rust-lang/trait-system-refactor-initiative/issues/177>.
// 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
// `<T as FromRequest<'r>>::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 `<T as Trait>::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
// `<T as Trait>::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 <https://github.com/rust-lang/rust/pull/139763>.
use std::future::Future;
use std::pin::Pin;
pub trait FromRequest<'r> {
type Assoc;
fn from_request() -> Pin<Box<dyn Future<Output = Self::Assoc> + Send>>;
}
fn test<'r, T: FromRequest<'r>>() -> Pin<Box<dyn Future<Output = ()> + Send>> {
Box::pin(async move {
T::from_request().await;
})
}
fn main() {}

View file

@ -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

View file

@ -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
|

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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 "<abi>"`
|
= 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 "<abi>"`
|
= 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 "<abi>"`
|
= help: prior to Rust 2024, a default ABI was inferred
error: aborting due to 3 previous errors

View file

@ -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() {}

View file

@ -3,7 +3,7 @@ trait X {
}
fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {}
//~^ 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

View file

@ -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<dyn X<Y('a) = &'a ()>>) {}
| ^^
|
help: consider adding a trait bound after the potential lifetime bound
|
LL | fn foo<'a>(arg: Box<dyn X<Y('a + /* Trait */) = &'a ()>>) {}
| +++++++++++++
error: parenthesized generic arguments cannot be used in associated type constraints
--> $DIR/gat-trait-path-parenthesised-args.rs:5:27

View file

@ -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() {}

View file

@ -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
|

View file

@ -1,53 +1,6 @@
//@ run-pass
#![feature(intrinsics)]
mod rusti {
#[rustc_intrinsic]
pub unsafe fn atomic_cxchg_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_cxchg_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_cxchg_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_cxchgweak_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_cxchgweak_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_cxchgweak_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
#[rustc_intrinsic]
pub unsafe fn atomic_load_seqcst<T>(src: *const T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_load_acquire<T>(src: *const T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_store_seqcst<T>(dst: *mut T, val: T);
#[rustc_intrinsic]
pub unsafe fn atomic_store_release<T>(dst: *mut T, val: T);
#[rustc_intrinsic]
pub unsafe fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xchg_acquire<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xchg_release<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xadd_acquire<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xadd_release<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xsub_seqcst<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xsub_acquire<T>(dst: *mut T, src: T) -> T;
#[rustc_intrinsic]
pub unsafe fn atomic_xsub_release<T>(dst: *mut T, src: T) -> T;
}
#![feature(core_intrinsics)]
use std::intrinsics as rusti;
pub fn main() {
unsafe {

View file

@ -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() { }

View file

@ -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 { }

View file

@ -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() { }

View file

@ -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 { }

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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() {}

View file

@ -1,6 +0,0 @@
//@ run-pass
pub fn main() { let _x: isize = 10; }

View file

@ -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
}

View file

@ -1,6 +0,0 @@
//@ run-pass
pub fn main() { let _x: usize = 10 as usize; }

View file

@ -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
}

View file

@ -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

View file

@ -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`

View file

@ -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
|

View file

@ -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() {}

View file

@ -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`.

View file

@ -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

View file

@ -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
}

View file

@ -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`.

View file

@ -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() {}

View file

@ -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

View file

@ -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 `+`
}

View file

@ -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

View file

@ -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<Trait + ('a)>;
| ^^^^
@ -22,11 +22,16 @@ LL - let _: Box<Trait + ('a)>;
LL + let _: Box<Trait + 'a>;
|
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

View file

@ -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<Trait + ('a)>;
| ^^^^
|
help: remove the parentheses
|
LL - let _: Box<Trait + ('a)>;
LL + let _: Box<Trait + 'a>;
|
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<Trait + ('a)>;
| ^^^^^^^^^^^^
|
help: you can add the `dyn` keyword if you want a trait object
|
LL | let _: Box<dyn Trait + ('a)>;
| +++
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0178, E0782.
For more information about an error, try `rustc --explain E0178`.

View file

@ -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<Trait + ('a)>; //~ 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() {}

View file

@ -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
}

View file

@ -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
|

View file

@ -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)]
}

View file

@ -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 {

View file

@ -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 `<Vec<T> as IntoIterator>::IntoIter` has two candidates
// inside of the function:
// - `impl<T> IntoIterator for Vec<T>` which trivially applies
// - `impl<I: Iterator> IntoIterator for I`
// - requires `Vec<T>: Iterator`
// - where-clause requires `<Vec<T> as IntoIterator>::IntoIter eq Vec<T>`
// - normalize `<Vec<T> as IntoIterator>::IntoIter` again, cycle
//
// We need to treat this cycle as an error to be able to use the actual impl.
fn test<T>()
where
<Vec<T> as IntoIterator>::IntoIter: Iterator,
{
}
fn main() {}

View file

@ -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<T>()
LL | | where
LL | | <Foo as Trait<T>>::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<T>`
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
LL | impl<T: Bound, U> Trait<U> 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<T>()
| ^^^^^^^ the trait `Bound` is not implemented for `Foo`
|
= help: the trait `Bound` is implemented for `u32`
note: required for `Foo` to implement `Trait<T>`
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
LL | impl<T: Bound, U> Trait<U> 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::<Foo>();
| ^^^ 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<T: 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`.

View file

@ -0,0 +1,31 @@
error[E0277]: the trait bound `Foo: Bound` is not satisfied
--> $DIR/normalizes-to-is-not-productive.rs:43:31
|
LL | <Foo as Trait<T>>::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<T>`
--> $DIR/normalizes-to-is-not-productive.rs:24:19
|
LL | impl<T: Bound, U> Trait<U> 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::<Foo>();
| ^^^ 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<T: 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`.

View file

@ -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<T> {
type Assoc: Bound;
}
struct Foo;
impl Trait<u32> for Foo {
type Assoc = u32;
}
impl<T: Bound, U> Trait<U> for T {
type Assoc = T;
}
fn impls_bound<T: Bound>() {
T::method();
}
// The where-clause requires `Foo: Trait<T>` to hold to be wf.
// If stepping into where-clauses during normalization is considered
// to be productive, this would be the case:
//
// - `Foo: Trait<T>`
// - via blanket impls, requires `Foo: Bound`
// - via where-bound, requires `Foo eq <Foo as Trait<T>>::Assoc`
// - normalize `<Foo as Trait<T>>::Assoc`
// - via blanket impl, requires where-clause `Foo: Bound` -> cycle
fn generic<T>()
where
<Foo as Trait<T>>::Assoc: Bound,
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
{
// Requires proving `Foo: Bound` by normalizing
// `<Foo as Trait<T>>::Assoc` to `Foo`.
impls_bound::<Foo>();
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
}
fn main() {
// Requires proving `<Foo as Trait<u32>>::Assoc: Bound`.
// This is trivially true.
generic::<u32>();
}

View file

@ -0,0 +1,31 @@
error[E0277]: the trait bound `Foo: Bound` is not satisfied
--> $DIR/normalizes-to-is-not-productive.rs:42:31
|
LL | <Foo as Trait<T>>::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<T>`
--> $DIR/normalizes-to-is-not-productive.rs:23:19
|
LL | impl<T: Bound, U> Trait<U> 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::<Foo>();
| ^^^ 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<T: 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`.