Auto merge of #133658 - jieyouxu:rollup-rq7e0gk, r=jieyouxu

Rollup of 10 pull requests

Successful merges:

 - #116161 (Stabilize `extended_varargs_abi_support`)
 - #132750 ([AIX] handle libunwind native_libs)
 - #133488 (tests: Add regression test for self referential structs with cow as last field)
 - #133569 (Bump `ruzstd` to 0.7.3)
 - #133585 (Do not call `extern_crate` on current trait on crate mismatch errors)
 - #133587 (Fix target_feature handling in freg of LoongArch inline assembly)
 - #133599 (Add `+forced-atomics` feature to esp32s2 no_std  target)
 - #133620 (Simplify hir_typeck_pass_to_variadic_function)
 - #133623 (Improve span handling in `parse_expr_bottom`.)
 - #133625 (custom MIR: add doc comment for debuginfo)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-11-30 14:34:27 +00:00
commit e93e096cc8
44 changed files with 580 additions and 255 deletions

View File

@ -4713,9 +4713,9 @@ checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]]
name = "ruzstd"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c3938e133aac070997ddc684d4b393777d293ba170f2988c8fd5ea2ad4ce21"
checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f"
dependencies = [
"twox-hash",
]

View File

@ -193,6 +193,9 @@ declare_features! (
(accepted, expr_fragment_specifier_2024, "1.83.0", Some(123742)),
/// Allows arbitrary expressions in key-value attributes at parse time.
(accepted, extended_key_value_attributes, "1.54.0", Some(78835)),
/// Allows using `efiapi`, `aapcs`, `sysv64` and `win64` as calling
/// convention for functions with varargs.
(accepted, extended_varargs_abi_support, "CURRENT_RUSTC_VERSION", Some(100189)),
/// Allows resolving absolute paths as paths from other crates.
(accepted, extern_absolute_paths, "1.30.0", Some(44660)),
/// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.

View File

@ -475,9 +475,6 @@ declare_features! (
(unstable, exhaustive_patterns, "1.13.0", Some(51085)),
/// Allows explicit tail calls via `become` expression.
(incomplete, explicit_tail_calls, "1.72.0", Some(112788)),
/// Allows using `efiapi`, `sysv64` and `win64` as calling convention
/// for functions with varargs.
(unstable, extended_varargs_abi_support, "1.65.0", Some(100189)),
/// Allows defining `extern type`s.
(unstable, extern_types, "1.23.0", Some(43467)),
/// Allow using 128-bit (quad precision) floating point numbers.

View File

@ -590,7 +590,7 @@ hir_analysis_value_of_associated_struct_already_specified =
.label = re-bound here
.previous_bound_label = `{$item_name}` bound here first
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions}
hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
.label = C-variadic function must have a compatible calling convention
hir_analysis_variances_of = {$variances}

View File

@ -672,11 +672,10 @@ pub(crate) struct MainFunctionGenericParameters {
#[derive(Diagnostic)]
#[diag(hir_analysis_variadic_function_compatible_convention, code = E0045)]
pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
pub(crate) struct VariadicFunctionCompatibleConvention {
#[primary_span]
#[label]
pub span: Span,
pub conventions: &'a str,
}
#[derive(Diagnostic)]

View File

@ -98,9 +98,7 @@ use rustc_middle::middle;
use rustc_middle::mir::interpret::GlobalId;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
use rustc_session::parse::feature_err;
use rustc_span::Span;
use rustc_span::symbol::sym;
use rustc_trait_selection::traits;
use self::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
@ -113,34 +111,9 @@ fn require_c_abi_if_c_variadic(
abi: ExternAbi,
span: Span,
) {
const CONVENTIONS_UNSTABLE: &str =
"`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
const UNSTABLE_EXPLAIN: &str =
"using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
return;
if decl.c_variadic && !abi.supports_varargs() {
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span });
}
let extended_abi_support = tcx.features().extended_varargs_abi_support();
let conventions = match (extended_abi_support, abi.supports_varargs()) {
// User enabled additional ABI support for varargs and function ABI matches those ones.
(true, true) => return,
// Using this ABI would be ok, if the feature for additional ABI support was enabled.
// Return CONVENTIONS_STABLE, because we want the other error to look the same.
(false, true) => {
feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
.emit();
CONVENTIONS_STABLE
}
(false, false) => CONVENTIONS_STABLE,
(true, false) => CONVENTIONS_UNSTABLE,
};
tcx.dcx().emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions });
}
pub fn provide(providers: &mut Providers) {

View File

@ -146,7 +146,6 @@ hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value in
hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
.suggestion = cast the value to `{$cast_ty}`
.help = cast the value to `{$cast_ty}`
.teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard
hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len ->

View File

@ -789,11 +789,8 @@ pub(crate) struct PassToVariadicFunction<'a, 'tcx> {
pub span: Span,
pub ty: Ty<'tcx>,
pub cast_ty: &'a str,
#[suggestion(code = "{replace}", applicability = "machine-applicable")]
pub sugg_span: Option<Span>,
pub replace: String,
#[help]
pub help: bool,
#[suggestion(code = " as {cast_ty}", applicability = "machine-applicable", style = "verbose")]
pub sugg_span: Span,
#[note(hir_typeck_teach_help)]
pub(crate) teach: bool,
}

View File

@ -440,20 +440,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty: Ty<'tcx>,
cast_ty: &str,
) {
let (sugg_span, replace, help) =
if let Ok(snippet) = sess.source_map().span_to_snippet(span) {
(Some(span), format!("{snippet} as {cast_ty}"), false)
} else {
(None, "".to_string(), true)
};
sess.dcx().emit_err(errors::PassToVariadicFunction {
span,
ty,
cast_ty,
help,
replace,
sugg_span,
sugg_span: span.shrink_to_hi(),
teach: sess.teach(E0617),
});
}

View File

@ -54,9 +54,13 @@ pub fn walk_native_lib_search_dirs<R>(
// The targets here should be in sync with `copy_third_party_objects` in bootstrap.
// FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind
// and sanitizers to self-contained directory, and stop adding this search path.
// FIXME: On AIX this also has the side-effect of making the list of library search paths
// non-empty, which is needed or the linker may decide to record the LIBPATH env, if
// defined, as the search path instead of appending the default search paths.
if sess.target.vendor == "fortanix"
|| sess.target.os == "linux"
|| sess.target.os == "fuchsia"
|| sess.target.is_like_aix
|| sess.target.is_like_osx && !sess.opts.unstable_opts.sanitizer.is_empty()
{
f(&sess.target_tlib_path.dir, false)?;

View File

@ -1990,7 +1990,6 @@ impl<'a> Parser<'a> {
/// `await? <expr>`, `await(<expr>)`, and `await { <expr> }`.
pub(super) fn recover_incorrect_await_syntax(
&mut self,
lo: Span,
await_sp: Span,
) -> PResult<'a, P<Expr>> {
let (hi, expr, is_question) = if self.token == token::Not {
@ -1999,8 +1998,8 @@ impl<'a> Parser<'a> {
} else {
self.recover_await_prefix(await_sp)?
};
let (sp, guar) = self.error_on_incorrect_await(lo, hi, &expr, is_question);
let expr = self.mk_expr_err(lo.to(sp), guar);
let (sp, guar) = self.error_on_incorrect_await(await_sp, hi, &expr, is_question);
let expr = self.mk_expr_err(await_sp.to(sp), guar);
self.maybe_recover_from_bad_qpath(expr)
}

View File

@ -1446,34 +1446,31 @@ impl<'a> Parser<'a> {
this.parse_expr_closure()
} else {
assert!(this.eat_keyword(kw::For));
this.parse_expr_for(None, this.prev_token.span)
this.parse_expr_for(None, lo)
}
} else if this.eat_keyword(kw::While) {
this.parse_expr_while(None, this.prev_token.span)
this.parse_expr_while(None, lo)
} else if let Some(label) = this.eat_label() {
this.parse_expr_labeled(label, true)
} else if this.eat_keyword(kw::Loop) {
let sp = this.prev_token.span;
this.parse_expr_loop(None, this.prev_token.span).map_err(|mut err| {
err.span_label(sp, "while parsing this `loop` expression");
this.parse_expr_loop(None, lo).map_err(|mut err| {
err.span_label(lo, "while parsing this `loop` expression");
err
})
} else if this.eat_keyword(kw::Match) {
let match_sp = this.prev_token.span;
this.parse_expr_match().map_err(|mut err| {
err.span_label(match_sp, "while parsing this `match` expression");
err.span_label(lo, "while parsing this `match` expression");
err
})
} else if this.eat_keyword(kw::Unsafe) {
let sp = this.prev_token.span;
this.parse_expr_block(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err(
|mut err| {
err.span_label(sp, "while parsing this `unsafe` expression");
err.span_label(lo, "while parsing this `unsafe` expression");
err
},
)
} else if this.check_inline_const(0) {
this.parse_const_block(lo.to(this.token.span), false)
this.parse_const_block(lo, false)
} else if this.may_recover() && this.is_do_catch_block() {
this.recover_do_catch()
} else if this.is_try_block() {
@ -1514,7 +1511,7 @@ impl<'a> Parser<'a> {
this.parse_expr_closure()
}
} else if this.eat_keyword_noexpect(kw::Await) {
this.recover_incorrect_await_syntax(lo, this.prev_token.span)
this.recover_incorrect_await_syntax(lo)
} else {
this.parse_expr_lit()
}

View File

@ -274,7 +274,6 @@ impl<'a> Parser<'a> {
// Function pointer type
self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)?
} else if self.check_keyword(kw::For) {
let for_span = self.token.span;
// Function pointer type or bound list (trait object type) starting with a poly-trait.
// `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
// `for<'lt> Trait1<'lt> + Trait2 + 'a`
@ -302,7 +301,7 @@ impl<'a> Parser<'a> {
kw: kw.name.as_str(),
sugg: errors::TransposeDynOrImplSugg {
removal_span,
insertion_span: for_span.shrink_to_lo(),
insertion_span: lo.shrink_to_lo(),
kw: kw.name.as_str(),
},
});
@ -345,16 +344,14 @@ impl<'a> Parser<'a> {
// FIXME(c_variadic): Should we just allow `...` syntactically
// anywhere in a type and use semantic restrictions instead?
// NOTE: This may regress certain MBE calls if done incorrectly.
let guar = self
.dcx()
.emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) });
let guar = self.dcx().emit_err(NestedCVariadicType { span: lo });
TyKind::Err(guar)
}
}
} else {
let msg = format!("expected type, found {}", super::token_descr(&self.token));
let mut err = self.dcx().struct_span_err(self.token.span, msg);
err.span_label(self.token.span, "expected type");
let mut err = self.dcx().struct_span_err(lo, msg);
err.span_label(lo, "expected type");
return Err(err);
};

View File

@ -38,7 +38,7 @@ impl LoongArchInlineAsmRegClass {
) -> &'static [(InlineAsmType, Option<Symbol>)] {
match self {
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
Self::freg => types! { _: F32, F64; },
Self::freg => types! { f: F32; d: F64; },
}
}
}

View File

@ -19,6 +19,7 @@ pub(crate) fn target() -> Target {
cpu: "esp32-s2".into(),
linker: Some("xtensa-esp32s2-elf-gcc".into()),
max_atomic_width: Some(32),
features: "+forced-atomics".into(),
..xtensa::opts()
},
}

View File

@ -1731,6 +1731,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
for (sp, label) in [trait_def_id, other_trait_def_id]
.iter()
// The current crate-version might depend on another version of the same crate
// (Think "semver-trick"). Do not call `extern_crate` in that case for the local
// crate as that doesn't make sense and ICEs (#133563).
.filter(|def_id| !def_id.is_local())
.filter_map(|def_id| self.tcx.extern_crate(def_id.krate))
.map(|data| {
let dependency = if data.dependency_of == LOCAL_CRATE {

View File

@ -249,6 +249,39 @@
//! `Call(ret_val = function(arg1, arg2, ...), ReturnTo(next_block), UnwindContinue())`.
//! - [`TailCall`] does not have a return destination or next block, so its syntax is just
//! `TailCall(function(arg1, arg2, ...))`.
//!
//! #### Debuginfo
//!
//! Debuginfo associates source code variable names (of variables that may not exist any more) with
//! MIR expressions that indicate where the value of that variable is stored. The syntax to do so
//! is:
//! ```text
//! debug source_var_name => expression;
//! ```
//! Both places and constants are supported in the `expression`.
//!
//! ```rust
//! #![allow(internal_features)]
//! #![feature(core_intrinsics, custom_mir)]
//!
//! use core::intrinsics::mir::*;
//!
//! #[custom_mir(dialect = "built")]
//! fn debuginfo(arg: Option<&i32>) {
//! mir!(
//! // Debuginfo for a source variable `plain_local` that just duplicates `arg`.
//! debug plain_local => arg;
//! // Debuginfo for a source variable `projection` that can be computed by dereferencing
//! // a field of `arg`.
//! debug projection => *Field::<&i32>(Variant(arg, 1), 0);
//! // Debuginfo for a source variable `constant` that always holds the value `5`.
//! debug constant => 5_usize;
//! {
//! Return()
//! }
//! )
//! }
//! ```
#![unstable(
feature = "custom_mir",

View File

@ -290,7 +290,6 @@
#![feature(doc_masked)]
#![feature(doc_notable_trait)]
#![feature(dropck_eyepatch)]
#![feature(extended_varargs_abi_support)]
#![feature(f128)]
#![feature(f16)]
#![feature(if_let_guard)]

View File

@ -330,7 +330,7 @@ fn copy_third_party_objects(
if target == "x86_64-fortanix-unknown-sgx"
|| builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree
&& (target.contains("linux") || target.contains("fuchsia"))
&& (target.contains("linux") || target.contains("fuchsia") || target.contains("aix"))
{
let libunwind_path =
copy_llvm_libunwind(builder, target, &builder.sysroot_target_libdir(*compiler, target));

View File

@ -1,10 +0,0 @@
# `extended_varargs_abi_support`
The tracking issue for this feature is: [#100189]
[#100189]: https://github.com/rust-lang/rust/issues/100189
------------------------
This feature adds the possibility of using `sysv64`, `win64` or `efiapi` calling
conventions on functions with varargs.

View File

@ -227,6 +227,12 @@ impl Rustc {
self
}
/// Normalize the line number in the stderr output
pub fn ui_testing(&mut self) -> &mut Self {
self.cmd.arg(format!("-Zui-testing"));
self
}
/// Specify the target triple, or a path to a custom target json spec file.
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
let target = target.as_ref();

View File

@ -0,0 +1,10 @@
// MIR for `constant` after built
fn constant() -> () {
debug scalar => const 5_usize;
let mut _0: ();
bb0: {
return;
}
}

View File

@ -2,7 +2,7 @@
fn numbered(_1: (u32, i32)) -> () {
debug first => (_1.0: u32);
debug second => (_1.0: u32);
debug second => (_1.1: i32);
let mut _0: ();
bb0: {

View File

@ -1,4 +1,3 @@
// skip-filecheck
#![feature(custom_mir, core_intrinsics)]
extern crate core;
@ -7,6 +6,8 @@ use core::intrinsics::mir::*;
// EMIT_MIR debuginfo.pointee.built.after.mir
#[custom_mir(dialect = "built")]
fn pointee(opt: &mut Option<i32>) {
// CHECK-LABEL: fn pointee(
// CHECK: debug foo => (((*_1) as variant#1).0: i32);
mir! {
debug foo => Field::<i32>(Variant(*opt, 1), 0);
{
@ -18,9 +19,12 @@ fn pointee(opt: &mut Option<i32>) {
// EMIT_MIR debuginfo.numbered.built.after.mir
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
fn numbered(i: (u32, i32)) {
// CHECK-LABEL: fn numbered(
// CHECK: debug first => (_1.0: u32);
// CHECK: debug second => (_1.1: i32);
mir! {
debug first => i.0;
debug second => i.0;
debug second => i.1;
{
Return()
}
@ -34,6 +38,8 @@ struct S {
// EMIT_MIR debuginfo.structured.built.after.mir
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
fn structured(i: S) {
// CHECK-LABEL: fn structured(
// CHECK: debug x => (_1.0: f32);
mir! {
debug x => i.x;
{
@ -45,6 +51,8 @@ fn structured(i: S) {
// EMIT_MIR debuginfo.variant.built.after.mir
#[custom_mir(dialect = "built")]
fn variant(opt: Option<i32>) {
// CHECK-LABEL: fn variant(
// CHECK: debug inner => ((_1 as variant#1).0: i32);
mir! {
debug inner => Field::<i32>(Variant(opt, 1), 0);
{
@ -56,6 +64,9 @@ fn variant(opt: Option<i32>) {
// EMIT_MIR debuginfo.variant_deref.built.after.mir
#[custom_mir(dialect = "built")]
fn variant_deref(opt: Option<&i32>) {
// CHECK-LABEL: fn variant_deref(
// CHECK: debug pointer => ((_1 as variant#1).0: &i32);
// CHECK: debug deref => (*((_1 as variant#1).0: &i32));
mir! {
debug pointer => Field::<&i32>(Variant(opt, 1), 0);
debug deref => *Field::<&i32>(Variant(opt, 1), 0);
@ -65,10 +76,24 @@ fn variant_deref(opt: Option<&i32>) {
}
}
// EMIT_MIR debuginfo.constant.built.after.mir
#[custom_mir(dialect = "built")]
fn constant() {
// CHECK-LABEL: fn constant(
// CHECK: debug scalar => const 5_usize;
mir!(
debug scalar => 5_usize;
{
Return()
}
)
}
fn main() {
numbered((5, 6));
structured(S { x: 5. });
variant(Some(5));
variant_deref(Some(&5));
pointee(&mut Some(5));
constant();
}

View File

@ -0,0 +1,14 @@
#![crate_type = "lib"]
#![crate_name = "foo"]
extern crate foo;
pub struct Struct;
pub trait Trait {}
impl Trait for Struct {}
fn check_trait<T: Trait>() {}
fn ice() {
check_trait::<foo::Struct>();
}

View File

@ -0,0 +1,6 @@
#![crate_type = "lib"]
#![crate_name = "foo"]
pub struct Struct;
pub trait Trait {}
impl Trait for Struct {}

View File

@ -0,0 +1,34 @@
error[E0277]: the trait bound `foo::Struct: Trait` is not satisfied
--> foo-current.rs:13:19
|
13 | check_trait::<foo::Struct>();
| ^^^^^^^^^^^ the trait `Trait` is not implemented for `foo::Struct`
|
note: there are multiple different versions of crate `foo` in the dependency graph
--> foo-current.rs:7:1
|
4 | extern crate foo;
| ----------------- one version of crate `foo` is used here, as a direct dependency of the current crate
5 |
6 | pub struct Struct;
| ----------------- this type implements the required trait
7 | pub trait Trait {}
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: foo-prev.rs:X:Y
|
4 | pub struct Struct;
| ----------------- this type doesn't implement the required trait
5 | pub trait Trait {}
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
note: required by a bound in `check_trait`
--> foo-current.rs:10:19
|
10 | fn check_trait<T: Trait>() {}
| ^^^^^ required by this bound in `check_trait`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -0,0 +1,31 @@
//@ only-linux
//@ ignore-wasm32
//@ ignore-wasm64
// ignore-tidy-linelength
// Verify that if the current crate depends on a different version of the same crate, *and* types
// and traits of the different versions are mixed, we produce diagnostic output and not an ICE.
// #133563
use run_make_support::{diff, rust_lib_name, rustc};
fn main() {
rustc().input("foo-prev.rs").run();
let out = rustc()
.extra_filename("current")
.metadata("current")
.input("foo-current.rs")
.extern_("foo", rust_lib_name("foo"))
.run_fail()
.stderr_utf8();
// We don't remap the path of the `foo-prev` crate, so we remap it here.
let mut lines: Vec<_> = out.lines().collect();
for line in &mut lines {
if line.starts_with(" ::: ") {
*line = " ::: foo-prev.rs:X:Y";
}
}
diff().expected_file("foo.stderr").actual_text("(rustc)", &lines.join("\n")).run();
}

View File

@ -0,0 +1,127 @@
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
--> replaced
|
LL | do_something(Type);
| ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
| |
| required by a bound introduced by this call
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> replaced
|
LL | pub struct Type(pub i32);
| --------------- this type implements the required trait
LL | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
|
::: replaced
|
LL | pub struct Type;
| --------------- this type doesn't implement the required trait
LL | pub trait Trait {
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree
note: required by a bound in `do_something`
--> replaced
|
LL | pub fn do_something<X: Trait>(_: X) {}
| ^^^^^ required by this bound in `do_something`
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
--> replaced
|
LL | Type.foo();
| ^^^ method not found in `Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> replaced
|
LL | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the trait that is needed
LL | fn foo(&self);
| -------------- the method is available for `dep_2_reexport::Type` here
|
::: replaced
|
LL | use dependency::{Trait, do_something};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
|
::: replaced
|
LL | pub trait Trait {
| --------------- this is the trait that was imported
error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
--> replaced
|
LL | Type::bar();
| ^^^ function or associated item not found in `Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> replaced
|
LL | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the trait that is needed
LL | fn foo(&self);
LL | fn bar();
| --------- the associated function is available for `dep_2_reexport::Type` here
|
::: replaced
|
LL | use dependency::{Trait, do_something};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
|
::: replaced
|
LL | pub trait Trait {
| --------------- this is the trait that was imported
error[E0277]: the trait bound `OtherType: Trait` is not satisfied
--> replaced
|
LL | do_something(OtherType);
| ------------ ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType`
| |
| required by a bound introduced by this call
|
note: there are multiple different versions of crate `dependency` in the dependency graph
--> replaced
|
LL | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
|
::: replaced
|
LL | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
LL | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
|
::: replaced
|
LL | pub struct OtherType;
| -------------------- this type doesn't implement the required trait
|
::: replaced
|
LL | pub trait Trait {
| --------------- this is the found trait
= help: you can use `cargo tree` to explore your dependency tree
note: required by a bound in `do_something`
--> replaced
|
LL | pub fn do_something<X: Trait>(_: X) {}
| ^^^^^ required by this bound in `do_something`
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.

View File

@ -3,7 +3,7 @@
//@ ignore-wasm64
// ignore-tidy-linelength
use run_make_support::{rust_lib_name, rustc};
use run_make_support::{diff, rust_lib_name, rustc};
fn main() {
rustc().input("multiple-dep-versions-1.rs").run();
@ -13,83 +13,26 @@ fn main() {
.extern_("dependency", rust_lib_name("dependency2"))
.run();
rustc()
let out = rustc()
.input("multiple-dep-versions.rs")
.extern_("dependency", rust_lib_name("dependency"))
.extern_("dep_2_reexport", rust_lib_name("foo"))
.ui_testing()
.run_fail()
.assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied
--> multiple-dep-versions.rs:7:18
|
7 | do_something(Type);
| ------------ ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
| |
| required by a bound introduced by this call
|
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
.assert_stderr_contains(r#"
3 | pub struct Type(pub i32);
| --------------- this type implements the required trait
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the required trait
"#)
.assert_stderr_contains(r#"
1 | extern crate dep_2_reexport;
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
2 | extern crate dependency;
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#)
.assert_stderr_contains(r#"
3 | pub struct Type;
| --------------- this type doesn't implement the required trait
4 | pub trait Trait {
| --------------- this is the found trait
= note: two types coming from two different versions of the same crate are different types even if they look the same
= help: you can use `cargo tree` to explore your dependency tree"#)
.assert_stderr_contains(r#"note: required by a bound in `do_something`"#)
.assert_stderr_contains(r#"
12 | pub fn do_something<X: Trait>(_: X) {}
| ^^^^^ required by this bound in `do_something`"#)
.assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
--> multiple-dep-versions.rs:8:10
|
8 | Type.foo();
| ^^^ method not found in `Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
.assert_stderr_contains(r#"
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the trait that is needed
5 | fn foo(&self);
| -------------- the method is available for `dep_2_reexport::Type` here
|
::: multiple-dep-versions.rs:4:18
|
4 | use dependency::{Trait, do_something};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
.assert_stderr_contains(r#"
4 | pub trait Trait {
| --------------- this is the trait that was imported"#)
.assert_stderr_contains(r#"
error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
--> multiple-dep-versions.rs:9:11
|
9 | Type::bar();
| ^^^ function or associated item not found in `Type`
|
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
.assert_stderr_contains(r#"
4 | pub trait Trait {
| ^^^^^^^^^^^^^^^ this is the trait that is needed
5 | fn foo(&self);
6 | fn bar();
| --------- the associated function is available for `dep_2_reexport::Type` here
|
::: multiple-dep-versions.rs:4:18
|
4 | use dependency::{Trait, do_something};
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
.assert_stderr_contains(
r#"
6 | pub struct OtherType;
| -------------------- this type doesn't implement the required trait"#);
.stderr_utf8();
// We don't remap all the paths, so we remap it here.
let mut lines: Vec<_> = out.lines().collect();
for line in &mut lines {
if line.starts_with(" --> ") {
*line = " --> replaced";
}
if line.starts_with(" ::: ") {
*line = " ::: replaced";
}
}
diff()
.expected_file("multiple-dep-versions.stderr")
.actual_text("(rustc)", &lines.join("\n"))
.run();
}

View File

@ -0,0 +1,38 @@
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:22:18
|
LL | asm!("", out("$r0") _);
| ^^^^^^^^^^^^
error: invalid register `$tp`: reserved for TLS
--> $DIR/bad-reg.rs:24:18
|
LL | asm!("", out("$tp") _);
| ^^^^^^^^^^^^
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:26:18
|
LL | asm!("", out("$sp") _);
| ^^^^^^^^^^^^
error: invalid register `$r21`: reserved by the ABI
--> $DIR/bad-reg.rs:28:18
|
LL | asm!("", out("$r21") _);
| ^^^^^^^^^^^^^
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:30:18
|
LL | asm!("", out("$fp") _);
| ^^^^^^^^^^^^
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
|
LL | asm!("", out("$r31") _);
| ^^^^^^^^^^^^^
error: aborting due to 6 previous errors

View File

@ -0,0 +1,62 @@
error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:22:18
|
LL | asm!("", out("$r0") _);
| ^^^^^^^^^^^^
error: invalid register `$tp`: reserved for TLS
--> $DIR/bad-reg.rs:24:18
|
LL | asm!("", out("$tp") _);
| ^^^^^^^^^^^^
error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:26:18
|
LL | asm!("", out("$sp") _);
| ^^^^^^^^^^^^
error: invalid register `$r21`: reserved by the ABI
--> $DIR/bad-reg.rs:28:18
|
LL | asm!("", out("$r21") _);
| ^^^^^^^^^^^^^
error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:30:18
|
LL | asm!("", out("$fp") _);
| ^^^^^^^^^^^^
error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
--> $DIR/bad-reg.rs:32:18
|
LL | asm!("", out("$r31") _);
| ^^^^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:36:26
|
LL | asm!("/* {} */", in(freg) f);
| ^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:38:26
|
LL | asm!("/* {} */", out(freg) _);
| ^^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:40:26
|
LL | asm!("/* {} */", in(freg) d);
| ^^^^^^^^^^
error: register class `freg` requires at least one of the following target features: d, f
--> $DIR/bad-reg.rs:42:26
|
LL | asm!("/* {} */", out(freg) d);
| ^^^^^^^^^^^
error: aborting due to 10 previous errors

View File

@ -0,0 +1,45 @@
//@ add-core-stubs
//@ needs-asm-support
//@ revisions: loongarch64_lp64d loongarch64_lp64s
//@[loongarch64_lp64d] compile-flags: --target loongarch64-unknown-linux-gnu
//@[loongarch64_lp64d] needs-llvm-components: loongarch
//@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat
//@[loongarch64_lp64s] needs-llvm-components: loongarch
#![crate_type = "lib"]
#![feature(no_core, rustc_attrs)]
#![no_core]
extern crate minicore;
use minicore::*;
fn f() {
let mut x = 0;
let mut f = 0.0_f32;
let mut d = 0.0_f64;
unsafe {
// Unsupported registers
asm!("", out("$r0") _);
//~^ ERROR constant zero cannot be used as an operand for inline asm
asm!("", out("$tp") _);
//~^ ERROR invalid register `$tp`: reserved for TLS
asm!("", out("$sp") _);
//~^ ERROR invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm
asm!("", out("$r21") _);
//~^ ERROR invalid register `$r21`: reserved by the ABI
asm!("", out("$fp") _);
//~^ ERROR invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm
asm!("", out("$r31") _);
//~^ ERROR invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm
asm!("", out("$f0") _); // ok
asm!("/* {} */", in(freg) f);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", out(freg) _);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", in(freg) d);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
asm!("/* {} */", out(freg) d);
//[loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f
}
}

View File

@ -1,19 +0,0 @@
//@ only-x86_64
fn efiapi(f: extern "efiapi" fn(usize, ...)) {
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
f(22, 44);
}
fn sysv(f: extern "sysv64" fn(usize, ...)) {
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
f(22, 44);
}
fn win(f: extern "win64" fn(usize, ...)) {
//~^ ERROR: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
//~^^ ERROR: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
f(22, 44);
}
fn main() {}

View File

@ -1,52 +0,0 @@
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
--> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
|
LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
= help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> $DIR/feature-gate-extended_varargs_abi_support.rs:3:14
|
LL | fn efiapi(f: extern "efiapi" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
--> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
|
LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
= help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> $DIR/feature-gate-extended_varargs_abi_support.rs:8:12
|
LL | fn sysv(f: extern "sysv64" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error[E0658]: using calling conventions other than `C` or `cdecl` for varargs functions is unstable
--> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
|
LL | fn win(f: extern "win64" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #100189 <https://github.com/rust-lang/rust/issues/100189> for more information
= help: add `#![feature(extended_varargs_abi_support)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
--> $DIR/feature-gate-extended_varargs_abi_support.rs:13:11
|
LL | fn win(f: extern "win64" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0045, E0658.
For more information about an error, try `rustc --explain E0045`.

View File

@ -1,4 +1,4 @@
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
--> $DIR/variadic-ffi-1.rs:9:5
|
LL | fn printf(_: *const u8, ...);
@ -62,37 +62,67 @@ error[E0617]: can't pass `f32` to variadic function
--> $DIR/variadic-ffi-1.rs:28:19
|
LL | foo(1, 2, 3f32);
| ^^^^ help: cast the value to `c_double`: `3f32 as c_double`
| ^^^^
|
help: cast the value to `c_double`
|
LL | foo(1, 2, 3f32 as c_double);
| +++++++++++
error[E0617]: can't pass `bool` to variadic function
--> $DIR/variadic-ffi-1.rs:29:19
|
LL | foo(1, 2, true);
| ^^^^ help: cast the value to `c_int`: `true as c_int`
| ^^^^
|
help: cast the value to `c_int`
|
LL | foo(1, 2, true as c_int);
| ++++++++
error[E0617]: can't pass `i8` to variadic function
--> $DIR/variadic-ffi-1.rs:30:19
|
LL | foo(1, 2, 1i8);
| ^^^ help: cast the value to `c_int`: `1i8 as c_int`
| ^^^
|
help: cast the value to `c_int`
|
LL | foo(1, 2, 1i8 as c_int);
| ++++++++
error[E0617]: can't pass `u8` to variadic function
--> $DIR/variadic-ffi-1.rs:31:19
|
LL | foo(1, 2, 1u8);
| ^^^ help: cast the value to `c_uint`: `1u8 as c_uint`
| ^^^
|
help: cast the value to `c_uint`
|
LL | foo(1, 2, 1u8 as c_uint);
| +++++++++
error[E0617]: can't pass `i16` to variadic function
--> $DIR/variadic-ffi-1.rs:32:19
|
LL | foo(1, 2, 1i16);
| ^^^^ help: cast the value to `c_int`: `1i16 as c_int`
| ^^^^
|
help: cast the value to `c_int`
|
LL | foo(1, 2, 1i16 as c_int);
| ++++++++
error[E0617]: can't pass `u16` to variadic function
--> $DIR/variadic-ffi-1.rs:33:19
|
LL | foo(1, 2, 1u16);
| ^^^^ help: cast the value to `c_uint`: `1u16 as c_uint`
| ^^^^
|
help: cast the value to `c_uint`
|
LL | foo(1, 2, 1u16 as c_uint);
| +++++++++
error: aborting due to 11 previous errors

View File

@ -1,6 +1,5 @@
//@ only-arm
//@ build-pass
#![feature(extended_varargs_abi_support)]
fn aapcs(f: extern "aapcs" fn(usize, ...)) {
f(22, 44);

View File

@ -1,5 +1,4 @@
//@ ignore-arm stdcall isn't supported
#![feature(extended_varargs_abi_support)]
#[allow(unsupported_fn_ptr_calling_conventions)]
fn baz(f: extern "stdcall" fn(usize, ...)) {

View File

@ -1,5 +1,5 @@
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
--> $DIR/variadic-ffi-2.rs:5:11
--> $DIR/variadic-ffi-2.rs:4:11
|
LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention

View File

@ -39,4 +39,4 @@ type WithTransparentTraitObject =
//~^ ERROR return value of `"C-cmse-nonsecure-call"` function too large to pass via registers [E0798]
type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);
//~^ ERROR C-variadic function must have a compatible calling convention, like `C` or `cdecl` [E0045]
//~^ ERROR C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi` [E0045]

View File

@ -68,7 +68,7 @@ LL | extern "C-cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspa
= note: functions with the `"C-cmse-nonsecure-call"` ABI must pass their result via the available return registers
= note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
--> $DIR/generics.rs:41:20
|
LL | type WithVarArgs = extern "C-cmse-nonsecure-call" fn(u32, ...);

View File

@ -1,4 +1,4 @@
error[E0045]: C-variadic function must have a compatible calling convention, like `C` or `cdecl`
error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
--> $DIR/E0045.rs:1:17
|
LL | extern "Rust" { fn foo(x: u8, ...); }

View File

@ -2,31 +2,56 @@ error[E0617]: can't pass `f32` to variadic function
--> $DIR/E0617.rs:7:36
|
LL | printf(::std::ptr::null(), 0f32);
| ^^^^ help: cast the value to `c_double`: `0f32 as c_double`
| ^^^^
|
help: cast the value to `c_double`
|
LL | printf(::std::ptr::null(), 0f32 as c_double);
| +++++++++++
error[E0617]: can't pass `i8` to variadic function
--> $DIR/E0617.rs:10:36
|
LL | printf(::std::ptr::null(), 0i8);
| ^^^ help: cast the value to `c_int`: `0i8 as c_int`
| ^^^
|
help: cast the value to `c_int`
|
LL | printf(::std::ptr::null(), 0i8 as c_int);
| ++++++++
error[E0617]: can't pass `i16` to variadic function
--> $DIR/E0617.rs:13:36
|
LL | printf(::std::ptr::null(), 0i16);
| ^^^^ help: cast the value to `c_int`: `0i16 as c_int`
| ^^^^
|
help: cast the value to `c_int`
|
LL | printf(::std::ptr::null(), 0i16 as c_int);
| ++++++++
error[E0617]: can't pass `u8` to variadic function
--> $DIR/E0617.rs:16:36
|
LL | printf(::std::ptr::null(), 0u8);
| ^^^ help: cast the value to `c_uint`: `0u8 as c_uint`
| ^^^
|
help: cast the value to `c_uint`
|
LL | printf(::std::ptr::null(), 0u8 as c_uint);
| +++++++++
error[E0617]: can't pass `u16` to variadic function
--> $DIR/E0617.rs:19:36
|
LL | printf(::std::ptr::null(), 0u16);
| ^^^^ help: cast the value to `c_uint`: `0u16 as c_uint`
| ^^^^
|
help: cast the value to `c_uint`
|
LL | printf(::std::ptr::null(), 0u16 as c_uint);
| +++++++++
error[E0617]: can't pass a function item to a variadic function
--> $DIR/E0617.rs:22:36

View File

@ -0,0 +1,19 @@
// Regression test for #107481
//@ check-pass
use std::{borrow::Cow, collections::HashMap};
#[derive(Clone)]
struct Foo<'a>(Cow<'a, [Self]>);
#[derive(Clone)]
struct Bar<'a>(Cow<'a, HashMap<String, Self>>);
#[derive(Clone)]
struct Baz<'a>(Cow<'a, Vec<Self>>);
#[derive(Clone)]
struct Qux<'a>(Cow<'a, Box<Self>>);
fn main() {}