Auto merge of #144398 - fmease:rollup-z6vq7mi, r=fmease

Rollup of 15 pull requests

Successful merges:

 - rust-lang/rust#143374 (Unquerify extern_mod_stmt_cnum.)
 - rust-lang/rust#143838 (std: net: uefi: Add support to query connection data)
 - rust-lang/rust#144014 (don't link to the nightly version of the Edition Guide in stable lints)
 - rust-lang/rust#144094 (Ensure we codegen the main fn)
 - rust-lang/rust#144218 (Use serde for target spec json deserialize)
 - rust-lang/rust#144221 (generate elf symbol version in raw-dylib)
 - rust-lang/rust#144240 (Add more test case to check if the false note related to sealed trait suppressed)
 - rust-lang/rust#144247 (coretests/num: use ldexp instead of hard-coding a power of 2)
 - rust-lang/rust#144276 (Use less HIR in check_private_in_public.)
 - rust-lang/rust#144278 (add Rev::into_inner)
 - rust-lang/rust#144317 (pass build.npm from bootstrap to tidy and use it for npm install)
 - rust-lang/rust#144320 (rustdoc: avoid allocating a temp String for aliases in search index)
 - rust-lang/rust#144334 (rustc_resolve: get rid of unused rustdoc::span_of_fragments_with_expansion)
 - rust-lang/rust#144335 (Don't suggest assoc ty bound on non-angle-bracketed problematic assoc ty binding)
 - rust-lang/rust#144358 (Stop using the old `validate_attr` logic for stability attributes)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-07-24 17:15:38 +00:00
189 changed files with 1862 additions and 1601 deletions
+13
View File
@@ -4563,7 +4563,10 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"serde",
"serde_derive",
"serde_json",
"serde_path_to_error",
"tracing",
]
@@ -4955,6 +4958,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.9"
@@ -74,8 +74,15 @@ impl<S: Stage> AttributeParser<S> for StabilityParser {
template!(NameValueStr: "deprecation message"),
|this, cx, args| {
reject_outside_std!(cx);
this.allowed_through_unstable_modules =
args.name_value().and_then(|i| i.value_as_str())
let Some(nv) = args.name_value() else {
cx.expected_name_value(cx.attr_span, None);
return;
};
let Some(value_str) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return;
};
this.allowed_through_unstable_modules = Some(value_str);
},
),
];
@@ -247,7 +254,12 @@ pub(crate) fn parse_stability<S: Stage>(
let mut feature = None;
let mut since = None;
for param in args.list()?.mixed() {
let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span);
return None;
};
for param in list.mixed() {
let param_span = param.span();
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
@@ -322,7 +334,13 @@ pub(crate) fn parse_unstability<S: Stage>(
let mut is_soft = false;
let mut implied_by = None;
let mut old_name = None;
for param in args.list()?.mixed() {
let ArgParser::List(list) = args else {
cx.expected_list(cx.attr_span);
return None;
};
for param in list.mixed() {
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
span: param.span(),
@@ -4,7 +4,7 @@
use rustc_abi::Endian;
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_hashes::Hash128;
use rustc_session::Session;
@@ -214,7 +214,7 @@ pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>(
/// It exports all the provided symbols, but is otherwise empty.
fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]) -> Vec<u8> {
use object::write::elf as write;
use object::{Architecture, elf};
use object::{AddressSize, Architecture, elf};
let mut stub_buf = Vec::new();
@@ -226,47 +226,6 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
// It is important that the order of reservation matches the order of writing.
// The object crate contains many debug asserts that fire if you get this wrong.
let endianness = match sess.target.options.endian {
Endian::Little => object::Endianness::Little,
Endian::Big => object::Endianness::Big,
};
let mut stub = write::Writer::new(endianness, true, &mut stub_buf);
// These initial reservations don't reserve any bytes in the binary yet,
// they just allocate in the internal data structures.
// First, we crate the dynamic symbol table. It starts with a null symbol
// and then all the symbols and their dynamic strings.
stub.reserve_null_dynamic_symbol_index();
let dynstrs = symbols
.iter()
.map(|sym| {
stub.reserve_dynamic_symbol_index();
(sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
})
.collect::<Vec<_>>();
let soname = stub.add_dynamic_string(soname.as_bytes());
// Reserve the sections.
// We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
stub.reserve_shstrtab_section_index();
let text_section_name = stub.add_section_name(".text".as_bytes());
let text_section = stub.reserve_section_index();
stub.reserve_dynstr_section_index();
stub.reserve_dynsym_section_index();
stub.reserve_dynamic_section_index();
// These reservations now determine the actual layout order of the object file.
stub.reserve_file_header();
stub.reserve_shstrtab();
stub.reserve_section_headers();
stub.reserve_dynstr();
stub.reserve_dynsym();
stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
// First write the ELF header with the arch information.
let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
else {
sess.dcx().fatal(format!(
@@ -274,6 +233,87 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sess.target.arch
));
};
let endianness = match sess.target.options.endian {
Endian::Little => object::Endianness::Little,
Endian::Big => object::Endianness::Big,
};
let is_64 = match arch.address_size() {
Some(AddressSize::U8 | AddressSize::U16 | AddressSize::U32) => false,
Some(AddressSize::U64) => true,
_ => sess.dcx().fatal(format!(
"raw-dylib is not supported for the architecture `{}`",
sess.target.arch
)),
};
let mut stub = write::Writer::new(endianness, is_64, &mut stub_buf);
let mut vers = Vec::new();
let mut vers_map = FxHashMap::default();
let mut syms = Vec::new();
for symbol in symbols {
let symbol_name = symbol.name.as_str();
if let Some((name, version_name)) = symbol_name.split_once('@') {
assert!(!version_name.contains('@'));
let dynstr = stub.add_dynamic_string(name.as_bytes());
let ver = if let Some(&ver_id) = vers_map.get(version_name) {
ver_id
} else {
let id = vers.len();
vers_map.insert(version_name, id);
let dynstr = stub.add_dynamic_string(version_name.as_bytes());
vers.push((version_name, dynstr));
id
};
syms.push((name, dynstr, Some(ver)));
} else {
let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
syms.push((symbol_name, dynstr, None));
}
}
let soname = stub.add_dynamic_string(soname.as_bytes());
// These initial reservations don't reserve any bytes in the binary yet,
// they just allocate in the internal data structures.
// First, we create the dynamic symbol table. It starts with a null symbol
// and then all the symbols and their dynamic strings.
stub.reserve_null_dynamic_symbol_index();
for _ in syms.iter() {
stub.reserve_dynamic_symbol_index();
}
// Reserve the sections.
// We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
stub.reserve_shstrtab_section_index();
let text_section_name = stub.add_section_name(".text".as_bytes());
let text_section = stub.reserve_section_index();
stub.reserve_dynsym_section_index();
stub.reserve_dynstr_section_index();
if !vers.is_empty() {
stub.reserve_gnu_versym_section_index();
stub.reserve_gnu_verdef_section_index();
}
stub.reserve_dynamic_section_index();
// These reservations now determine the actual layout order of the object file.
stub.reserve_file_header();
stub.reserve_shstrtab();
stub.reserve_section_headers();
stub.reserve_dynsym();
stub.reserve_dynstr();
if !vers.is_empty() {
stub.reserve_gnu_versym();
stub.reserve_gnu_verdef(1 + vers.len(), 1 + vers.len());
}
stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
// First write the ELF header with the arch information.
let e_machine = match (arch, sub_arch) {
(Architecture::Aarch64, None) => elf::EM_AARCH64,
(Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64,
@@ -342,18 +382,19 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sh_addralign: 1,
sh_entsize: 0,
});
stub.write_dynstr_section_header(0);
stub.write_dynsym_section_header(0, 1);
stub.write_dynstr_section_header(0);
if !vers.is_empty() {
stub.write_gnu_versym_section_header(0);
stub.write_gnu_verdef_section_header(0);
}
stub.write_dynamic_section_header(0);
// .dynstr
stub.write_dynstr();
// .dynsym
stub.write_null_dynamic_symbol();
for (_, name) in dynstrs {
for (_name, dynstr, _ver) in syms.iter().copied() {
stub.write_dynamic_symbol(&write::Sym {
name: Some(name),
name: Some(dynstr),
st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
st_other: elf::STV_DEFAULT,
section: Some(text_section),
@@ -363,10 +404,47 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
});
}
// .dynstr
stub.write_dynstr();
// ld.bfd is unhappy if these sections exist without any symbols, so we only generate them when necessary.
if !vers.is_empty() {
// .gnu_version
stub.write_null_gnu_versym();
for (_name, _dynstr, ver) in syms.iter().copied() {
stub.write_gnu_versym(if let Some(ver) = ver {
assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
elf::VERSYM_HIDDEN | (2 + ver as u16)
} else {
1
});
}
// .gnu_version_d
stub.write_align_gnu_verdef();
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: elf::VER_FLG_BASE,
index: 1,
aux_count: 1,
name: soname,
});
for (ver, (_name, dynstr)) in vers.into_iter().enumerate() {
stub.write_gnu_verdef(&write::Verdef {
version: elf::VER_DEF_CURRENT,
flags: 0,
index: 2 + ver as u16,
aux_count: 1,
name: dynstr,
});
}
}
// .dynamic
// the DT_SONAME will be used by the linker to populate DT_NEEDED
// which the loader uses to find the library.
// DT_NULL terminates the .dynamic table.
stub.write_align_dynamic();
stub.write_dynamic_string(elf::DT_SONAME, soname);
stub.write_dynamic(elf::DT_NULL, 0);
@@ -447,17 +447,30 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
let mut parents = self.tcx().hir_parent_iter(self_ty.hir_id);
if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next()
if let Some((c_hir_id, hir::Node::AssocItemConstraint(constraint))) = parents.next()
&& let Some(obj_ty) = constraint.ty()
&& let Some((_, hir::Node::TraitRef(trait_ref))) = parents.next()
{
if let Some((_, hir::Node::TraitRef(..))) = parents.next()
&& let Some((_, hir::Node::Ty(ty))) = parents.next()
if let Some((_, hir::Node::Ty(ty))) = parents.next()
&& let hir::TyKind::TraitObject(..) = ty.kind
{
// Assoc ty bounds aren't permitted inside trait object types.
return;
}
if trait_ref
.path
.segments
.iter()
.find_map(|seg| {
seg.args.filter(|args| args.constraints.iter().any(|c| c.hir_id == c_hir_id))
})
.is_none_or(|args| args.parenthesized != hir::GenericArgsParentheses::No)
{
// Only consider angle-bracketed args (where we have a `=` to replace with `:`).
return;
}
let lo = if constraint.gen_args.span_ext.is_dummy() {
constraint.ident.span
} else {
+1 -1
View File
@@ -1047,7 +1047,7 @@ fn perform_2229_migration_analysis(
}
}
}
lint.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
lint.note("for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
let diagnostic_msg = format!(
"add a dummy let to cause {migrated_variables_concat} to be fully captured"
+1 -1
View File
@@ -593,7 +593,7 @@ lint_non_camel_case_type = {$sort} `{$name}` should have an upper camel case nam
lint_non_fmt_panic = panic message is not a string literal
.note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
.more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
.more_info_note = for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
.supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
.supports_fmt_suggestion = remove the `format!(..)` macro call
.display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
+2 -2
View File
@@ -1654,7 +1654,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
"`...` range patterns are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>",
};
}
@@ -1835,7 +1835,7 @@ fn check_pat_post(&mut self, _cx: &EarlyContext<'_>, pat: &ast::Pat) {
"detects edition keywords being used as an identifier",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>",
};
}
+1 -1
View File
@@ -87,7 +87,7 @@
rewriting in `match` is an option to preserve the semantics up to Edition 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>",
};
}
@@ -71,7 +71,7 @@
"`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>",
};
}
@@ -65,7 +65,7 @@
/// to ensure the macros implement the desired behavior.
///
/// [editions]: https://doc.rust-lang.org/edition-guide/
/// [macro matcher fragment specifiers]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html
/// [macro matcher fragment specifiers]: https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html
/// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
pub EDITION_2024_EXPR_FRAGMENT_SPECIFIER,
Allow,
@@ -73,7 +73,7 @@
To keep the existing behavior, use the `expr_2021` fragment specifier.",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html>",
reference: "Migration Guide <https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html>",
};
}
@@ -32,7 +32,7 @@
"detects calling `into_iter` on arrays in Rust 2015 and 2018",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>",
};
}
@@ -61,7 +61,7 @@
"detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>"
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>"
};
}
+1 -1
View File
@@ -54,7 +54,7 @@
"creating a shared reference to mutable static",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>",
explain_reason: false,
};
@edition Edition2024 => Deny;
+13 -13
View File
@@ -1814,7 +1814,7 @@
"suggest using `dyn Trait` for trait objects",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>",
};
}
@@ -2472,7 +2472,7 @@
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>",
explain_reason: false
};
@edition Edition2024 => Warn;
@@ -3445,7 +3445,7 @@
"detects usage of old versions of or-patterns",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>",
};
}
@@ -3494,7 +3494,7 @@
prelude in future editions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>",
};
}
@@ -3534,7 +3534,7 @@
prelude in future editions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>",
};
}
@@ -3571,7 +3571,7 @@
"identifiers that will be parsed as a prefix in Rust 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>",
};
crate_level_only
}
@@ -4100,7 +4100,7 @@
"never type fallback affecting unsafe function calls",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
report_in_deps: true,
};
@edition Edition2024 => Deny;
@@ -4155,7 +4155,7 @@
"never type fallback affecting unsafe function calls",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
report_in_deps: true,
};
report_in_external_macro
@@ -4740,7 +4740,7 @@
"detects unsafe functions being used as safe functions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/newly-unsafe-functions.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html>",
};
}
@@ -4776,7 +4776,7 @@
"detects missing unsafe keyword on extern declarations",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html>",
};
}
@@ -4817,7 +4817,7 @@
"detects unsafe attributes outside of unsafe",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>",
};
}
@@ -5014,7 +5014,7 @@
"Detect and warn on significant change in drop order in tail expression location",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>",
};
}
@@ -5053,7 +5053,7 @@
"will be parsed as a guarded string in Rust 2024",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>",
reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>",
};
crate_level_only
}
+3
View File
@@ -330,3 +330,6 @@ metadata_wasm_import_form =
metadata_whole_archive_needs_static =
linking modifier `whole-archive` is only compatible with `static` linking kind
metadata_raw_dylib_malformed =
link name must be well-formed if link kind is `raw-dylib`
+7
View File
@@ -815,3 +815,10 @@ pub struct AsyncDropTypesInDependency {
pub extern_crate: Symbol,
pub local_crate: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_raw_dylib_malformed)]
pub struct RawDylibMalformed {
#[primary_span]
pub span: Span,
}
+14 -1
View File
@@ -700,8 +700,21 @@ fn build_dll_import(
.link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
let name = name.as_str();
if name.contains('\0') {
self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
} else if let Some((left, right)) = name.split_once('@')
&& (left.is_empty() || right.is_empty() || right.contains('@'))
{
self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
}
}
DllImport {
name: codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item)),
name,
import_name_type,
calling_convention,
span,
+2 -4
View File
@@ -143,10 +143,8 @@ pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
};
// Similarly, the executable entrypoint must be instantiated exactly once.
if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
if instance.def_id() == entry_def_id {
return InstantiationMode::GloballyShared { may_conflict: false };
}
if tcx.is_entrypoint(instance.def_id()) {
return InstantiationMode::GloballyShared { may_conflict: false };
}
// If the function is #[naked] or contains any other attribute that requires exactly-once
-3
View File
@@ -2152,9 +2152,6 @@
desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
}
/// Gets the number of definitions in a foreign crate.
///
+19 -2
View File
@@ -3377,6 +3377,11 @@ pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
}
/// Return the crate imported by given use item.
pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
self.resolutions(()).extern_crate_map.get(&def_id).copied()
}
pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
self.resolver_for_lowering_raw(()).0
}
@@ -3414,6 +3419,20 @@ pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
}
/// Whether this def is one of the special bin crate entrypoint functions that must have a
/// monomorphization and also not be internalized in the bin crate.
pub fn is_entrypoint(self, def_id: DefId) -> bool {
if self.is_lang_item(def_id, LangItem::Start) {
return true;
}
if let Some((entry_def_id, _)) = self.entry_fn(())
&& entry_def_id == def_id
{
return true;
}
false
}
}
/// Parameter attributes that can only be determined by examining the body of a function instead
@@ -3432,8 +3451,6 @@ pub struct DeducedParamAttrs {
}
pub fn provide(providers: &mut Providers) {
providers.extern_mod_stmt_cnum =
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
providers.is_panic_runtime =
|tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
providers.is_compiler_builtins =
@@ -1575,6 +1575,15 @@ fn push_extra_entry_roots(&mut self) {
return;
};
let main_instance = Instance::mono(self.tcx, main_def_id);
if self.tcx.should_codegen_locally(main_instance) {
self.output.push(create_fn_mono_item(
self.tcx,
main_instance,
self.tcx.def_span(main_def_id),
));
}
let Some(start_def_id) = self.tcx.lang_items().start_fn() else {
self.tcx.dcx().emit_fatal(errors::StartNotFound);
};
@@ -223,11 +223,7 @@ fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> Pl
// So even if its mode is LocalCopy, we need to treat it like a root.
match mono_item.instantiation_mode(cx.tcx) {
InstantiationMode::GloballyShared { .. } => {}
InstantiationMode::LocalCopy => {
if !cx.tcx.is_lang_item(mono_item.def_id(), LangItem::Start) {
continue;
}
}
InstantiationMode::LocalCopy => continue,
}
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
@@ -821,10 +817,9 @@ fn mono_item_visibility<'tcx>(
| InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden,
};
// The `start_fn` lang item is actually a monomorphized instance of a
// function in the standard library, used for the `main` function. We don't
// want to export it so we tag it with `Hidden` visibility but this symbol
// is only referenced from the actual `main` symbol which we unfortunately
// Both the `start_fn` lang item and `main` itself should not be exported,
// so we give them with `Hidden` visibility but these symbols are
// only referenced from the actual `main` symbol which we unfortunately
// don't know anything about during partitioning/collection. As a result we
// forcibly keep this symbol out of the `internalization_candidates` set.
//
@@ -834,7 +829,7 @@ fn mono_item_visibility<'tcx>(
// from the `main` symbol we'll generate later.
//
// This may be fixable with a new `InstanceKind` perhaps? Unsure!
if tcx.is_lang_item(def_id, LangItem::Start) {
if tcx.is_entrypoint(def_id) {
*can_be_internalized = false;
return Visibility::Hidden;
}
@@ -285,6 +285,9 @@ pub fn check_builtin_meta_item(
| sym::rustc_do_not_implement_via_object
| sym::rustc_coinductive
| sym::const_trait
| sym::stable
| sym::unstable
| sym::rustc_allowed_through_unstable_modules
| sym::rustc_specialization_trait
| sym::rustc_unsafe_specialization_marker
| sym::rustc_allow_incoherent_impl
+1 -1
View File
@@ -1258,7 +1258,7 @@ fn check_doc_masked(
return;
}
if self.tcx.extern_mod_stmt_cnum(hir_id.owner).is_none() {
if self.tcx.extern_mod_stmt_cnum(hir_id.owner.def_id).is_none() {
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
+45 -77
View File
@@ -26,7 +26,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor};
use rustc_hir::{AmbigArg, ForeignItemKind, ItemId, ItemKind, PatKind};
use rustc_hir::{AmbigArg, ForeignItemId, ItemId, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
@@ -599,18 +599,13 @@ fn update_macro_reachable_def(
DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do not.
let item = self.tcx.hir_expect_item(def_id);
if let hir::ItemKind::Struct(_, _, ref struct_def)
| hir::ItemKind::Union(_, _, ref struct_def) = item.kind
{
for field in struct_def.fields() {
let field_vis = self.tcx.local_visibility(field.def_id);
if field_vis.is_accessible_from(module, self.tcx) {
self.reach(field.def_id, macro_ev).ty();
}
let struct_def = self.tcx.adt_def(def_id);
for field in struct_def.non_enum_variant().fields.iter() {
let def_id = field.did.expect_local();
let field_vis = self.tcx.local_visibility(def_id);
if field_vis.is_accessible_from(module, self.tcx) {
self.reach(def_id, macro_ev).ty();
}
} else {
bug!("item {:?} with DefKind {:?}", item, def_kind);
}
}
@@ -1644,66 +1639,29 @@ fn check_item(&mut self, id: ItemId) {
self.check(def_id, item_visibility, effective_vis).generics().predicates();
}
DefKind::Enum => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Enum(_, _, ref def) = item.kind {
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check_unnameable(def_id, effective_vis);
self.check(def_id, item_visibility, effective_vis).generics().predicates();
self.check(item.owner_id.def_id, item_visibility, effective_vis)
.generics()
.predicates();
for variant in def.variants {
for field in variant.data.fields() {
self.check(field.def_id, item_visibility, effective_vis).ty();
}
}
}
}
// Subitems of foreign modules have their own publicity.
DefKind::ForeignMod => {
let item = tcx.hir_item(id);
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
for &foreign_item in items {
let foreign_item = tcx.hir_foreign_item(foreign_item);
let ev = self.get(foreign_item.owner_id.def_id);
let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
if let ForeignItemKind::Type = foreign_item.kind {
self.check_unnameable(foreign_item.owner_id.def_id, ev);
}
self.check(foreign_item.owner_id.def_id, vis, ev)
.generics()
.predicates()
.ty();
}
let adt = tcx.adt_def(id.owner_id);
for field in adt.all_fields() {
self.check(field.did.expect_local(), item_visibility, effective_vis).ty();
}
}
// Subitems of structs and unions have their own publicity.
DefKind::Struct | DefKind::Union => {
let item = tcx.hir_item(id);
if let hir::ItemKind::Struct(_, _, ref struct_def)
| hir::ItemKind::Union(_, _, ref struct_def) = item.kind
{
self.check_unnameable(item.owner_id.def_id, effective_vis);
self.check(item.owner_id.def_id, item_visibility, effective_vis)
.generics()
.predicates();
self.check_unnameable(def_id, effective_vis);
self.check(def_id, item_visibility, effective_vis).generics().predicates();
for field in struct_def.fields() {
let field_visibility = tcx.local_visibility(field.def_id);
let field_ev = self.get(field.def_id);
let adt = tcx.adt_def(id.owner_id);
for field in adt.all_fields() {
let visibility = min(item_visibility, field.vis.expect_local(), tcx);
let field_ev = self.get(field.did.expect_local());
self.check(
field.def_id,
min(item_visibility, field_visibility, tcx),
field_ev,
)
.ty();
}
self.check(field.did.expect_local(), visibility, field_ev).ty();
}
}
// Subitems of foreign modules have their own publicity.
DefKind::ForeignMod => {}
// An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
@@ -1763,6 +1721,19 @@ fn check_item(&mut self, id: ItemId) {
_ => {}
}
}
fn check_foreign_item(&mut self, id: ForeignItemId) {
let tcx = self.tcx;
let def_id = id.owner_id.def_id;
let item_visibility = tcx.local_visibility(def_id);
let effective_vis = self.get(def_id);
if let DefKind::ForeignTy = self.tcx.def_kind(def_id) {
self.check_unnameable(def_id, effective_vis);
}
self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
}
}
pub fn provide(providers: &mut Providers) {
@@ -1791,20 +1762,13 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) {
visitor.visit_nested_body(body_id.id());
}
}
for id in module.free_items() {
if let ItemKind::Impl(i) = tcx.hir_item(id).kind {
if let Some(item) = i.of_trait {
let trait_ref = tcx.impl_trait_ref(id.owner_id.def_id).unwrap();
let trait_ref = trait_ref.instantiate_identity();
visitor.span = item.path.span;
let _ = visitor.visit_def_id(
trait_ref.def_id,
"trait",
&trait_ref.print_only_trait_path(),
);
}
if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) {
let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
let trait_ref = trait_ref.instantiate_identity();
visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().path.span;
let _ =
visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path());
}
}
}
@@ -1895,7 +1859,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
// Check for private types in public interfaces.
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
for id in tcx.hir_free_items() {
let crate_items = tcx.hir_crate_items(());
for id in crate_items.free_items() {
checker.check_item(id);
}
for id in crate_items.foreign_items() {
checker.check_foreign_item(id);
}
}
+4 -13
View File
@@ -509,9 +509,8 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>(
display_text.map(String::into_boxed_str)
}
/// Returns a tuple containing a span encompassing all the document fragments and a boolean that is
/// `true` if any of the fragments are from a macro expansion.
pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> {
/// Returns a span encompassing all the document fragments.
pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
let (first_fragment, last_fragment) = match fragments {
[] => return None,
[first, .., last] => (first, last),
@@ -520,15 +519,7 @@ pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Sp
if first_fragment.span == DUMMY_SP {
return None;
}
Some((
first_fragment.span.to(last_fragment.span),
fragments.iter().any(|frag| frag.from_expansion),
))
}
/// Returns a span encompassing all the document fragments.
pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
span_of_fragments_with_expansion(fragments).map(|(sp, _)| sp)
Some(first_fragment.span.to(last_fragment.span))
}
/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
@@ -686,7 +677,7 @@ pub fn source_span_for_markdown_range_inner(
}
}
let (span, _) = span_of_fragments_with_expansion(fragments)?;
let span = span_of_fragments(fragments)?;
let src_span = span.from_inner(InnerSpan::new(
md_range.start + start_bytes,
md_range.end + start_bytes + end_bytes,
+2 -2
View File
@@ -343,12 +343,12 @@ pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
if let Some(component_to_enable) = component.strip_prefix('+') {
self.explicitly_set = None;
self.enabled_components
.insert(LinkSelfContainedComponents::from_str(component_to_enable)?);
.insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
Some(())
} else if let Some(component_to_disable) = component.strip_prefix('-') {
self.explicitly_set = None;
self.disabled_components
.insert(LinkSelfContainedComponents::from_str(component_to_disable)?);
.insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
Some(())
} else {
None
+1 -1
View File
@@ -1296,7 +1296,7 @@ pub(crate) fn parse_mir_strip_debuginfo(slot: &mut MirStripDebugInfo, v: Option<
}
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
match v.and_then(LinkerFlavorCli::from_str) {
match v.and_then(|v| LinkerFlavorCli::from_str(v).ok()) {
Some(lf) => *slot = Some(lf),
_ => return false,
}
+3
View File
@@ -12,7 +12,10 @@ rustc_fs_util = { path = "../rustc_fs_util" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
serde = "1.0.219"
serde_derive = "1.0.219"
serde_json = "1.0.59"
serde_path_to_error = "0.1.17"
tracing = "0.1"
# tidy-alphabetical-end
+15
View File
@@ -114,3 +114,18 @@ fn to_json(&self) -> Json {
self.to_string().to_json()
}
}
macro_rules! serde_deserialize_from_str {
($ty:ty) => {
impl<'de> serde::Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
FromStr::from_str(&s).map_err(serde::de::Error::custom)
}
}
};
}
pub(crate) use serde_deserialize_from_str;
+375 -654
View File
@@ -1,60 +1,47 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::str::FromStr;
use rustc_abi::{Align, AlignFromBytesError, ExternAbi};
use serde_json::Value;
use rustc_abi::{Align, AlignFromBytesError};
use super::{Target, TargetKind, TargetOptions, TargetWarnings};
use super::crt_objects::CrtObjects;
use super::{
BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli,
LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor,
MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet,
SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target,
TargetKind, TargetOptions, TargetWarnings, TlsModel,
};
use crate::json::{Json, ToJson};
use crate::spec::AbiMap;
impl Target {
/// Loads a target descriptor from a JSON object.
pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> {
// While ugly, this code must remain this way to retain
// compatibility with existing JSON fields and the internal
// expected naming of the Target and TargetOptions structs.
// To ensure compatibility is retained, the built-in targets
// are round-tripped through this code to catch cases where
// the JSON parser is not updated to match the structs.
pub fn from_json(json: &str) -> Result<(Target, TargetWarnings), String> {
let json_deserializer = &mut serde_json::Deserializer::from_str(json);
let mut obj = match obj {
Value::Object(obj) => obj,
_ => return Err("Expected JSON object for target")?,
};
let mut get_req_field = |name: &str| {
obj.remove(name)
.and_then(|j| j.as_str().map(str::to_string))
.ok_or_else(|| format!("Field {name} in target specification is required"))
};
let json: TargetSpecJson =
serde_path_to_error::deserialize(json_deserializer).map_err(|err| err.to_string())?;
let mut base = Target {
llvm_target: get_req_field("llvm-target")?.into(),
llvm_target: json.llvm_target,
metadata: Default::default(),
pointer_width: get_req_field("target-pointer-width")?
.parse::<u32>()
.map_err(|_| "target-pointer-width must be an integer".to_string())?,
data_layout: get_req_field("data-layout")?.into(),
arch: get_req_field("arch")?.into(),
pointer_width: json
.target_pointer_width
.parse()
.map_err(|err| format!("invalid target-pointer-width: {err}"))?,
data_layout: json.data_layout,
arch: json.arch,
options: Default::default(),
};
// FIXME: This doesn't properly validate anything and just ignores the data if it's invalid.
// That's okay for now, the only use of this is when generating docs, which we don't do for
// custom targets.
if let Some(Json::Object(mut metadata)) = obj.remove("metadata") {
base.metadata.description = metadata
.remove("description")
.and_then(|desc| desc.as_str().map(|desc| desc.to_owned().into()));
base.metadata.tier = metadata
.remove("tier")
.and_then(|tier| tier.as_u64())
.filter(|tier| (1..=3).contains(tier));
base.metadata.host_tools =
metadata.remove("host_tools").and_then(|host| host.as_bool());
base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool());
if let Some(metadata) = json.metadata {
base.metadata.description = metadata.description;
base.metadata.tier = metadata.tier.filter(|tier| (1..=3).contains(tier));
base.metadata.host_tools = metadata.host_tools;
base.metadata.std = metadata.std;
}
let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String {
@@ -65,640 +52,188 @@ pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> {
format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8)
};
let mut incorrect_type = vec![];
macro_rules! key {
($key_name:ident) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) {
base.$key_name = s;
macro_rules! forward {
($name:ident) => {
if let Some($name) = json.$name {
base.$name = $name;
}
} );
($key_name:ident = $json_name:expr) => ( {
let name = $json_name;
if let Some(s) = obj.remove(name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) {
base.$key_name = s;
};
}
macro_rules! forward_opt {
($name:ident) => {
if let Some($name) = json.$name {
base.$name = Some($name);
}
} );
($key_name:ident = $json_name:expr, u64 as $int_ty:ty) => ( {
let name = $json_name;
if let Some(s) = obj.remove(name).and_then(|b| b.as_u64()) {
base.$key_name = s as $int_ty;
}
} );
($key_name:ident, bool) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
base.$key_name = s;
}
} );
($key_name:ident = $json_name:expr, bool) => ( {
let name = $json_name;
if let Some(s) = obj.remove(name).and_then(|b| b.as_bool()) {
base.$key_name = s;
}
} );
($key_name:ident, u32) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
if s < 1 || s > 5 {
return Err("Not a valid DWARF version number".into());
}
base.$key_name = s as u32;
}
} );
($key_name:ident, Option<bool>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
base.$key_name = Some(s);
}
} );
($key_name:ident, Option<u64>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
base.$key_name = Some(s);
}
} );
($key_name:ident, Option<StaticCow<str>>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|b| Some(b.as_str()?.to_string())) {
base.$key_name = Some(s.into());
}
} );
($key_name:ident, Option<Align>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(b) = obj.remove(&name).and_then(|b| b.as_u64()) {
match Align::from_bits(b) {
Ok(align) => base.$key_name = Some(align),
Err(e) => return Err(alignment_error(&name, e)),
}
}
} );
($key_name:ident, BinaryFormat) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
match s.parse::<super::BinaryFormat>() {
Ok(binary_format) => base.$key_name = binary_format,
_ => return Some(Err(format!(
"'{s}' is not a valid value for binary_format. \
Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, MergeFunctions) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::MergeFunctions>() {
Ok(mergefunc) => base.$key_name = mergefunc,
_ => return Some(Err(format!("'{}' is not a valid value for \
merge-functions. Use 'disabled', \
'trampolines', or 'aliases'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, FloatAbi) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::FloatAbi>() {
Ok(float_abi) => base.$key_name = Some(float_abi),
_ => return Some(Err(format!("'{}' is not a valid value for \
llvm-floatabi. Use 'soft' or 'hard'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, RustcAbi) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::RustcAbi>() {
Ok(rustc_abi) => base.$key_name = Some(rustc_abi),
_ => return Some(Err(format!(
"'{s}' is not a valid value for rustc-abi. \
Use 'x86-softfloat' or leave the field unset."
))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, RelocModel) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::RelocModel>() {
Ok(relocation_model) => base.$key_name = relocation_model,
_ => return Some(Err(format!("'{}' is not a valid relocation model. \
Run `rustc --print relocation-models` to \
see the list of supported values.", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, CodeModel) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::CodeModel>() {
Ok(code_model) => base.$key_name = Some(code_model),
_ => return Some(Err(format!("'{}' is not a valid code model. \
Run `rustc --print code-models` to \
see the list of supported values.", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, TlsModel) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::TlsModel>() {
Ok(tls_model) => base.$key_name = tls_model,
_ => return Some(Err(format!("'{}' is not a valid TLS model. \
Run `rustc --print tls-models` to \
see the list of supported values.", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, SmallDataThresholdSupport) => ( {
obj.remove("small-data-threshold-support").and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::SmallDataThresholdSupport>() {
Ok(support) => base.small_data_threshold_support = support,
_ => return Some(Err(format!("'{s}' is not a valid value for small-data-threshold-support."))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, PanicStrategy) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s {
"unwind" => base.$key_name = super::PanicStrategy::Unwind,
"abort" => base.$key_name = super::PanicStrategy::Abort,
_ => return Some(Err(format!("'{}' is not a valid value for \
panic-strategy. Use 'unwind' or 'abort'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, RelroLevel) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::RelroLevel>() {
Ok(level) => base.$key_name = level,
_ => return Some(Err(format!("'{}' is not a valid value for \
relro-level. Use 'full', 'partial, or 'off'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, Option<SymbolVisibility>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::SymbolVisibility>() {
Ok(level) => base.$key_name = Some(level),
_ => return Some(Err(format!("'{}' is not a valid value for \
symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, DebuginfoKind) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::DebuginfoKind>() {
Ok(level) => base.$key_name = level,
_ => return Some(Err(
format!("'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
'dwarf-dsym' or 'pdb'.")
)),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, SplitDebuginfo) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::SplitDebuginfo>() {
Ok(level) => base.$key_name = level,
_ => return Some(Err(format!("'{}' is not a valid value for \
split-debuginfo. Use 'off' or 'dsymutil'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(j) = obj.remove(&name) {
if let Some(v) = j.as_array() {
base.$key_name = v.iter()
.map(|a| a.as_str().unwrap().to_string().into())
.collect();
} else {
incorrect_type.push(name)
}
}
} );
($key_name:ident, opt_list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(j) = obj.remove(&name) {
if let Some(v) = j.as_array() {
base.$key_name = Some(v.iter()
.map(|a| a.as_str().unwrap().to_string().into())
.collect());
} else {
incorrect_type.push(name)
}
}
} );
($key_name:ident, fallible_list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|j| {
if let Some(v) = j.as_array() {
match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() {
Ok(l) => { base.$key_name = l },
// FIXME: `fallible_list` can't re-use the `key!` macro for list
// elements and the error messages from that macro, so it has a bad
// generic message instead
Err(_) => return Some(Err(
format!("`{:?}` is not a valid value for `{}`", j, name)
)),
}
} else {
incorrect_type.push(name)
}
Some(Ok(()))
}).unwrap_or(Ok(()))
} );
($key_name:ident, optional) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.remove(&name) {
base.$key_name = o
.as_str()
.map(|s| s.to_string().into());
}
} );
($key_name:ident = $json_name:expr, LldFlavor) => ( {
let name = $json_name;
obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
if let Some(flavor) = super::LldFlavor::from_str(&s) {
base.$key_name = flavor;
} else {
return Some(Err(format!(
"'{}' is not a valid value for lld-flavor. \
Use 'darwin', 'gnu', 'link' or 'wasm'.",
s)))
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident = $json_name:expr, LinkerFlavorCli) => ( {
let name = $json_name;
obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
match super::LinkerFlavorCli::from_str(s) {
Some(linker_flavor) => base.$key_name = linker_flavor,
_ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
Use {}", s, super::LinkerFlavorCli::one_of()))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, StackProbeType) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.remove(&name).and_then(|o| match super::StackProbeType::from_json(&o) {
Ok(v) => {
base.$key_name = v;
Some(Ok(()))
},
Err(s) => Some(Err(
format!("`{:?}` is not a valid value for `{}`: {}", o, name, s)
)),
}).unwrap_or(Ok(()))
} );
($key_name:ident, SanitizerSet) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.remove(&name) {
if let Some(a) = o.as_array() {
for s in a {
use super::SanitizerSet;
base.$key_name |= match s.as_str() {
Some("address") => SanitizerSet::ADDRESS,
Some("cfi") => SanitizerSet::CFI,
Some("dataflow") => SanitizerSet::DATAFLOW,
Some("kcfi") => SanitizerSet::KCFI,
Some("kernel-address") => SanitizerSet::KERNELADDRESS,
Some("leak") => SanitizerSet::LEAK,
Some("memory") => SanitizerSet::MEMORY,
Some("memtag") => SanitizerSet::MEMTAG,
Some("safestack") => SanitizerSet::SAFESTACK,
Some("shadow-call-stack") => SanitizerSet::SHADOWCALLSTACK,
Some("thread") => SanitizerSet::THREAD,
Some("hwaddress") => SanitizerSet::HWADDRESS,
Some(s) => return Err(format!("unknown sanitizer {}", s)),
_ => return Err(format!("not a string: {:?}", s)),
};
}
} else {
incorrect_type.push(name)
}
}
Ok::<(), String>(())
} );
($key_name:ident, link_self_contained_components) => ( {
// Skeleton of what needs to be parsed:
//
// ```
// $name: {
// "components": [
// <array of strings>
// ]
// }
// ```
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.remove(&name) {
if let Some(o) = o.as_object() {
let component_array = o.get("components")
.ok_or_else(|| format!("{name}: expected a \
JSON object with a `components` field."))?;
let component_array = component_array.as_array()
.ok_or_else(|| format!("{name}.components: expected a JSON array"))?;
let mut components = super::LinkSelfContainedComponents::empty();
for s in component_array {
components |= match s.as_str() {
Some(s) => {
super::LinkSelfContainedComponents::from_str(s)
.ok_or_else(|| format!("unknown \
`-Clink-self-contained` component: {s}"))?
},
_ => return Err(format!("not a string: {:?}", s)),
};
}
base.$key_name = super::LinkSelfContainedDefault::WithComponents(components);
} else {
incorrect_type.push(name)
}
}
Ok::<(), String>(())
} );
($key_name:ident = $json_name:expr, link_self_contained_backwards_compatible) => ( {
let name = $json_name;
obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<super::LinkSelfContainedDefault>() {
Ok(lsc_default) => base.$key_name = lsc_default,
_ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \
Use 'false', 'true', 'musl' or 'mingw'", s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident = $json_name:expr, link_objects) => ( {
let name = $json_name;
if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per CRT object kind.", name))?;
let mut args = super::CrtObjects::new();
for (k, v) in obj {
let kind = super::LinkOutputKind::from_str(&k).ok_or_else(|| {
format!("{}: '{}' is not a valid value for CRT object kind. \
Use '(dynamic,static)-(nopic,pic)-exe' or \
'(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k)
})?;
let v = v.as_array().ok_or_else(||
format!("{}.{}: expected a JSON array", name, k)
)?.iter().enumerate()
.map(|(i,s)| {
let s = s.as_str().ok_or_else(||
format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
Ok(s.to_string().into())
})
.collect::<Result<Vec<_>, String>>()?;
args.insert(kind, v);
}
base.$key_name = args;
}
} );
($key_name:ident = $json_name:expr, link_args) => ( {
let name = $json_name;
if let Some(val) = obj.remove(name) {
let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
JSON object with fields per linker-flavor.", name))?;
let mut args = super::LinkArgsCli::new();
for (k, v) in obj {
let flavor = super::LinkerFlavorCli::from_str(&k).ok_or_else(|| {
format!("{}: '{}' is not a valid value for linker-flavor. \
Use 'em', 'gcc', 'ld' or 'msvc'", name, k)
})?;
let v = v.as_array().ok_or_else(||
format!("{}.{}: expected a JSON array", name, k)
)?.iter().enumerate()
.map(|(i,s)| {
let s = s.as_str().ok_or_else(||
format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
Ok(s.to_string().into())
})
.collect::<Result<Vec<_>, String>>()?;
args.insert(flavor, v);
}
base.$key_name = args;
}
} );
($key_name:ident, env) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(o) = obj.remove(&name) {
if let Some(a) = o.as_array() {
for o in a {
if let Some(s) = o.as_str() {
if let [k, v] = *s.split('=').collect::<Vec<_>>() {
base.$key_name
.to_mut()
.push((k.to_string().into(), v.to_string().into()))
}
}
}
} else {
incorrect_type.push(name)
}
}
} );
($key_name:ident, target_families) => ( {
if let Some(value) = obj.remove("target-family") {
if let Some(v) = value.as_array() {
base.$key_name = v.iter()
.map(|a| a.as_str().unwrap().to_string().into())
.collect();
} else if let Some(v) = value.as_str() {
base.$key_name = vec![v.to_string().into()].into();
}
}
} );
};
}
if let Some(j) = obj.remove("target-endian") {
if let Some(s) = j.as_str() {
base.endian = s.parse()?;
} else {
incorrect_type.push("target-endian".into())
}
if let Some(target_endian) = json.target_endian {
base.endian = target_endian.0;
}
if let Some(fp) = obj.remove("frame-pointer") {
if let Some(s) = fp.as_str() {
base.frame_pointer = s
.parse()
.map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?;
} else {
incorrect_type.push("frame-pointer".into())
}
}
forward!(frame_pointer);
forward!(c_int_width);
forward_opt!(c_enum_min_bits); // if None, matches c_int_width
forward!(os);
forward!(env);
forward!(abi);
forward!(vendor);
forward_opt!(linker);
forward!(linker_flavor_json);
forward!(lld_flavor_json);
forward!(linker_is_gnu_json);
forward!(pre_link_objects);
forward!(post_link_objects);
forward!(pre_link_objects_self_contained);
forward!(post_link_objects_self_contained);
key!(c_int_width = "target-c-int-width", u64 as u16);
key!(c_enum_min_bits, Option<u64>); // if None, matches c_int_width
key!(os);
key!(env);
key!(abi);
key!(vendor);
key!(linker, optional);
key!(linker_flavor_json = "linker-flavor", LinkerFlavorCli)?;
key!(lld_flavor_json = "lld-flavor", LldFlavor)?;
key!(linker_is_gnu_json = "linker-is-gnu", bool);
key!(pre_link_objects = "pre-link-objects", link_objects);
key!(post_link_objects = "post-link-objects", link_objects);
key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
// Deserializes the backwards-compatible variants of `-Clink-self-contained`
key!(
link_self_contained = "crt-objects-fallback",
link_self_contained_backwards_compatible
)?;
if let Some(link_self_contained) = json.link_self_contained_backwards_compatible {
base.link_self_contained = link_self_contained;
}
// Deserializes the components variant of `-Clink-self-contained`
key!(link_self_contained, link_self_contained_components)?;
key!(pre_link_args_json = "pre-link-args", link_args);
key!(late_link_args_json = "late-link-args", link_args);
key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args);
key!(late_link_args_static_json = "late-link-args-static", link_args);
key!(post_link_args_json = "post-link-args", link_args);
key!(link_script, optional);
key!(link_env, env);
key!(link_env_remove, list);
key!(asm_args, list);
key!(cpu);
key!(need_explicit_cpu, bool);
key!(features);
key!(dynamic_linking, bool);
key!(direct_access_external_data, Option<bool>);
key!(dll_tls_export, bool);
key!(only_cdylib, bool);
key!(executables, bool);
key!(relocation_model, RelocModel)?;
key!(code_model, CodeModel)?;
key!(tls_model, TlsModel)?;
key!(disable_redzone, bool);
key!(function_sections, bool);
key!(dll_prefix);
key!(dll_suffix);
key!(exe_suffix);
key!(staticlib_prefix);
key!(staticlib_suffix);
key!(families, target_families);
key!(abi_return_struct_as_int, bool);
key!(is_like_aix, bool);
key!(is_like_darwin, bool);
key!(is_like_solaris, bool);
key!(is_like_windows, bool);
key!(is_like_msvc, bool);
key!(is_like_wasm, bool);
key!(is_like_android, bool);
key!(binary_format, BinaryFormat)?;
key!(default_dwarf_version, u32);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
key!(no_default_libraries, bool);
key!(position_independent_executables, bool);
key!(static_position_independent_executables, bool);
key!(plt_by_default, bool);
key!(relro_level, RelroLevel)?;
key!(archive_format);
key!(allow_asm, bool);
key!(main_needs_argc_argv, bool);
key!(has_thread_local, bool);
key!(obj_is_bitcode, bool);
key!(bitcode_llvm_cmdline);
key!(max_atomic_width, Option<u64>);
key!(min_atomic_width, Option<u64>);
key!(atomic_cas, bool);
key!(panic_strategy, PanicStrategy)?;
key!(crt_static_allows_dylibs, bool);
key!(crt_static_default, bool);
key!(crt_static_respected, bool);
key!(stack_probes, StackProbeType)?;
key!(min_global_align, Option<Align>);
key!(default_codegen_units, Option<u64>);
key!(default_codegen_backend, Option<StaticCow<str>>);
key!(trap_unreachable, bool);
key!(requires_lto, bool);
key!(singlethread, bool);
key!(no_builtins, bool);
key!(default_visibility, Option<SymbolVisibility>)?;
key!(emit_debug_gdb_scripts, bool);
key!(requires_uwtable, bool);
key!(default_uwtable, bool);
key!(simd_types_indirect, bool);
key!(limit_rdylib_exports, bool);
key!(override_export_symbols, opt_list);
key!(merge_functions, MergeFunctions)?;
key!(mcount = "target-mcount");
key!(llvm_mcount_intrinsic, optional);
key!(llvm_abiname);
key!(llvm_floatabi, FloatAbi)?;
key!(rustc_abi, RustcAbi)?;
key!(relax_elf_relocations, bool);
key!(llvm_args, list);
key!(use_ctors_section, bool);
key!(eh_frame_header, bool);
key!(has_thumb_interworking, bool);
key!(debuginfo_kind, DebuginfoKind)?;
key!(split_debuginfo, SplitDebuginfo)?;
key!(supported_split_debuginfo, fallible_list)?;
key!(supported_sanitizers, SanitizerSet)?;
key!(generate_arange_section, bool);
key!(supports_stack_protector, bool);
key!(small_data_threshold_support, SmallDataThresholdSupport)?;
key!(entry_name);
key!(supports_xray, bool);
if let Some(link_self_contained) = json.link_self_contained {
let components = link_self_contained
.components
.into_iter()
.fold(LinkSelfContainedComponents::empty(), |a, b| a | b);
base.link_self_contained = LinkSelfContainedDefault::WithComponents(components);
}
forward!(pre_link_args_json);
forward!(late_link_args_json);
forward!(late_link_args_dynamic_json);
forward!(late_link_args_static_json);
forward!(post_link_args_json);
forward_opt!(link_script);
if let Some(link_env) = json.link_env {
for s in link_env {
if let [k, v] = *s.split('=').collect::<Vec<_>>() {
base.link_env.to_mut().push((k.to_string().into(), v.to_string().into()))
} else {
return Err(format!("link-env value '{s}' must be of the pattern 'KEY=VALUE'"));
}
}
}
forward!(link_env_remove);
forward!(asm_args);
forward!(cpu);
forward!(need_explicit_cpu);
forward!(features);
forward!(dynamic_linking);
forward_opt!(direct_access_external_data);
forward!(dll_tls_export);
forward!(only_cdylib);
forward!(executables);
forward!(relocation_model);
forward_opt!(code_model);
forward!(tls_model);
forward!(disable_redzone);
forward!(function_sections);
forward!(dll_prefix);
forward!(dll_suffix);
forward!(exe_suffix);
forward!(staticlib_prefix);
forward!(staticlib_suffix);
if let Some(target_family) = json.target_family {
match target_family {
TargetFamiliesJson::Array(families) => base.families = families,
TargetFamiliesJson::String(family) => base.families = vec![family].into(),
}
}
forward!(abi_return_struct_as_int);
forward!(is_like_aix);
forward!(is_like_darwin);
forward!(is_like_solaris);
forward!(is_like_windows);
forward!(is_like_msvc);
forward!(is_like_wasm);
forward!(is_like_android);
forward!(binary_format);
forward!(default_dwarf_version);
forward!(allows_weak_linkage);
forward!(has_rpath);
forward!(no_default_libraries);
forward!(position_independent_executables);
forward!(static_position_independent_executables);
forward!(plt_by_default);
forward!(relro_level);
forward!(archive_format);
forward!(allow_asm);
forward!(main_needs_argc_argv);
forward!(has_thread_local);
forward!(obj_is_bitcode);
forward!(bitcode_llvm_cmdline);
forward_opt!(max_atomic_width);
forward_opt!(min_atomic_width);
forward!(atomic_cas);
forward!(panic_strategy);
forward!(crt_static_allows_dylibs);
forward!(crt_static_default);
forward!(crt_static_respected);
forward!(stack_probes);
if let Some(min_global_align) = json.min_global_align {
match Align::from_bits(min_global_align) {
Ok(align) => base.min_global_align = Some(align),
Err(e) => return Err(alignment_error("min-global-align", e)),
}
}
forward_opt!(default_codegen_units);
forward_opt!(default_codegen_backend);
forward!(trap_unreachable);
forward!(requires_lto);
forward!(singlethread);
forward!(no_builtins);
forward_opt!(default_visibility);
forward!(emit_debug_gdb_scripts);
forward!(requires_uwtable);
forward!(default_uwtable);
forward!(simd_types_indirect);
forward!(limit_rdylib_exports);
forward_opt!(override_export_symbols);
forward!(merge_functions);
forward!(mcount);
forward_opt!(llvm_mcount_intrinsic);
forward!(llvm_abiname);
forward_opt!(llvm_floatabi);
forward_opt!(rustc_abi);
forward!(relax_elf_relocations);
forward!(llvm_args);
forward!(use_ctors_section);
forward!(eh_frame_header);
forward!(has_thumb_interworking);
forward!(debuginfo_kind);
forward!(split_debuginfo);
forward!(supported_split_debuginfo);
if let Some(supported_sanitizers) = json.supported_sanitizers {
base.supported_sanitizers =
supported_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
}
forward!(generate_arange_section);
forward!(supports_stack_protector);
forward!(small_data_threshold_support);
forward!(entry_name);
forward!(supports_xray);
// we're going to run `update_from_cli`, but that won't change the target's AbiMap
// FIXME: better factor the Target definition so we enforce this on a type level
let abi_map = AbiMap::from_target(&base);
if let Some(abi_str) = obj.remove("entry-abi") {
if let Json::String(abi_str) = abi_str {
match abi_str.parse::<ExternAbi>() {
Ok(abi) => base.options.entry_abi = abi_map.canonize_abi(abi, false).unwrap(),
Err(_) => return Err(format!("{abi_str} is not a valid ExternAbi")),
}
} else {
incorrect_type.push("entry-abi".to_owned())
}
if let Some(entry_abi) = json.entry_abi {
base.options.entry_abi = abi_map.canonize_abi(entry_abi.0, false).unwrap();
}
base.update_from_cli();
base.check_consistency(TargetKind::Json)?;
// Each field should have been read using `Json::remove` so any keys remaining are unused.
let remaining_keys = obj.keys();
Ok((
base,
TargetWarnings { unused_fields: remaining_keys.cloned().collect(), incorrect_type },
))
Ok((base, TargetWarnings { unused_fields: vec![] }))
}
}
@@ -877,3 +412,189 @@ macro_rules! target_option_val {
Json::Object(d)
}
}
#[derive(serde_derive::Deserialize)]
struct LinkSelfContainedComponentsWrapper {
components: Vec<LinkSelfContainedComponents>,
}
#[derive(serde_derive::Deserialize)]
#[serde(untagged)]
enum TargetFamiliesJson {
Array(StaticCow<[StaticCow<str>]>),
String(StaticCow<str>),
}
/// `Endian` is in `rustc_abi`, which doesn't have access to the macro and serde.
struct EndianWrapper(rustc_abi::Endian);
impl FromStr for EndianWrapper {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
rustc_abi::Endian::from_str(s).map(Self)
}
}
crate::json::serde_deserialize_from_str!(EndianWrapper);
/// `ExternAbi` is in `rustc_abi`, which doesn't have access to the macro and serde.
struct ExternAbiWrapper(rustc_abi::ExternAbi);
impl FromStr for ExternAbiWrapper {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
rustc_abi::ExternAbi::from_str(s)
.map(Self)
.map_err(|_| format!("{s} is not a valid extern ABI"))
}
}
crate::json::serde_deserialize_from_str!(ExternAbiWrapper);
#[derive(serde_derive::Deserialize)]
struct TargetSpecJsonMetadata {
description: Option<StaticCow<str>>,
tier: Option<u64>,
host_tools: Option<bool>,
std: Option<bool>,
}
#[derive(serde_derive::Deserialize)]
#[serde(rename_all = "kebab-case")]
// Ensure that all unexpected fields get turned into errors.
// This helps users stay up to date when the schema changes instead of silently
// ignoring their old values.
#[serde(deny_unknown_fields)]
struct TargetSpecJson {
llvm_target: StaticCow<str>,
target_pointer_width: String,
data_layout: StaticCow<str>,
arch: StaticCow<str>,
metadata: Option<TargetSpecJsonMetadata>,
// options:
target_endian: Option<EndianWrapper>,
frame_pointer: Option<FramePointer>,
#[serde(rename = "target-c-int-width")]
c_int_width: Option<u16>,
c_enum_min_bits: Option<u64>,
os: Option<StaticCow<str>>,
env: Option<StaticCow<str>>,
abi: Option<StaticCow<str>>,
vendor: Option<StaticCow<str>>,
linker: Option<StaticCow<str>>,
#[serde(rename = "linker-flavor")]
linker_flavor_json: Option<LinkerFlavorCli>,
#[serde(rename = "lld-flavor")]
lld_flavor_json: Option<LldFlavor>,
#[serde(rename = "linker-is-gnu")]
linker_is_gnu_json: Option<bool>,
#[serde(rename = "pre-link-objects")]
pre_link_objects: Option<CrtObjects>,
#[serde(rename = "post-link-objects")]
post_link_objects: Option<CrtObjects>,
#[serde(rename = "pre-link-objects-fallback")]
pre_link_objects_self_contained: Option<CrtObjects>,
#[serde(rename = "post-link-objects-fallback")]
post_link_objects_self_contained: Option<CrtObjects>,
#[serde(rename = "crt-objects-fallback")]
link_self_contained_backwards_compatible: Option<LinkSelfContainedDefault>,
link_self_contained: Option<LinkSelfContainedComponentsWrapper>,
#[serde(rename = "pre-link-args")]
pre_link_args_json: Option<LinkArgsCli>,
#[serde(rename = "late-link-args")]
late_link_args_json: Option<LinkArgsCli>,
#[serde(rename = "late-link-args-dynamic")]
late_link_args_dynamic_json: Option<LinkArgsCli>,
#[serde(rename = "late-link-args-static")]
late_link_args_static_json: Option<LinkArgsCli>,
#[serde(rename = "post-link-args")]
post_link_args_json: Option<LinkArgsCli>,
link_script: Option<StaticCow<str>>,
link_env: Option<Vec<StaticCow<str>>>,
link_env_remove: Option<StaticCow<[StaticCow<str>]>>,
asm_args: Option<StaticCow<[StaticCow<str>]>>,
cpu: Option<StaticCow<str>>,
need_explicit_cpu: Option<bool>,
features: Option<StaticCow<str>>,
dynamic_linking: Option<bool>,
direct_access_external_data: Option<bool>,
dll_tls_export: Option<bool>,
only_cdylib: Option<bool>,
executables: Option<bool>,
relocation_model: Option<RelocModel>,
code_model: Option<CodeModel>,
tls_model: Option<TlsModel>,
disable_redzone: Option<bool>,
function_sections: Option<bool>,
dll_prefix: Option<StaticCow<str>>,
dll_suffix: Option<StaticCow<str>>,
exe_suffix: Option<StaticCow<str>>,
staticlib_prefix: Option<StaticCow<str>>,
staticlib_suffix: Option<StaticCow<str>>,
target_family: Option<TargetFamiliesJson>,
abi_return_struct_as_int: Option<bool>,
is_like_aix: Option<bool>,
is_like_darwin: Option<bool>,
is_like_solaris: Option<bool>,
is_like_windows: Option<bool>,
is_like_msvc: Option<bool>,
is_like_wasm: Option<bool>,
is_like_android: Option<bool>,
binary_format: Option<BinaryFormat>,
default_dwarf_version: Option<u32>,
allows_weak_linkage: Option<bool>,
has_rpath: Option<bool>,
no_default_libraries: Option<bool>,
position_independent_executables: Option<bool>,
static_position_independent_executables: Option<bool>,
plt_by_default: Option<bool>,
relro_level: Option<RelroLevel>,
archive_format: Option<StaticCow<str>>,
allow_asm: Option<bool>,
main_needs_argc_argv: Option<bool>,
has_thread_local: Option<bool>,
obj_is_bitcode: Option<bool>,
bitcode_llvm_cmdline: Option<StaticCow<str>>,
max_atomic_width: Option<u64>,
min_atomic_width: Option<u64>,
atomic_cas: Option<bool>,
panic_strategy: Option<PanicStrategy>,
crt_static_allows_dylibs: Option<bool>,
crt_static_default: Option<bool>,
crt_static_respected: Option<bool>,
stack_probes: Option<StackProbeType>,
min_global_align: Option<u64>,
default_codegen_units: Option<u64>,
default_codegen_backend: Option<StaticCow<str>>,
trap_unreachable: Option<bool>,
requires_lto: Option<bool>,
singlethread: Option<bool>,
no_builtins: Option<bool>,
default_visibility: Option<SymbolVisibility>,
emit_debug_gdb_scripts: Option<bool>,
requires_uwtable: Option<bool>,
default_uwtable: Option<bool>,
simd_types_indirect: Option<bool>,
limit_rdylib_exports: Option<bool>,
override_export_symbols: Option<StaticCow<[StaticCow<str>]>>,
merge_functions: Option<MergeFunctions>,
#[serde(rename = "target-mcount")]
mcount: Option<StaticCow<str>>,
llvm_mcount_intrinsic: Option<StaticCow<str>>,
llvm_abiname: Option<StaticCow<str>>,
llvm_floatabi: Option<FloatAbi>,
rustc_abi: Option<RustcAbi>,
relax_elf_relocations: Option<bool>,
llvm_args: Option<StaticCow<[StaticCow<str>]>>,
use_ctors_section: Option<bool>,
eh_frame_header: Option<bool>,
has_thumb_interworking: Option<bool>,
debuginfo_kind: Option<DebuginfoKind>,
split_debuginfo: Option<SplitDebuginfo>,
supported_split_debuginfo: Option<StaticCow<[SplitDebuginfo]>>,
supported_sanitizers: Option<Vec<SanitizerSet>>,
generate_arange_section: Option<bool>,
supports_stack_protector: Option<bool>,
small_data_threshold_support: Option<SmallDataThresholdSupport>,
entry_name: Option<StaticCow<str>>,
supports_xray: Option<bool>,
entry_abi: Option<ExternAbiWrapper>,
}
+258 -130
View File
@@ -37,6 +37,7 @@
//!
//! [JSON]: https://json.org
use core::result::Result;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};
@@ -198,18 +199,29 @@ pub fn as_str(&self) -> &'static str {
LldFlavor::Link => "link",
}
}
}
fn from_str(s: &str) -> Option<Self> {
Some(match s {
impl FromStr for LldFlavor {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"darwin" => LldFlavor::Ld64,
"gnu" => LldFlavor::Ld,
"link" => LldFlavor::Link,
"wasm" => LldFlavor::Wasm,
_ => return None,
_ => {
return Err(
"invalid value for lld flavor: '{s}', expected one of 'darwin', 'gnu', 'link', 'wasm'"
.into(),
);
}
})
}
}
crate::json::serde_deserialize_from_str!(LldFlavor);
impl ToJson for LldFlavor {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -494,19 +506,23 @@ pub const fn one_of() -> &'static str {
concat!("one of: ", $($string, " ",)*)
}
pub fn from_str(s: &str) -> Option<LinkerFlavorCli> {
Some(match s {
$($string => $($flavor)*,)*
_ => return None,
})
}
pub fn desc(self) -> &'static str {
match self {
$($($flavor)* => $string,)*
}
}
}
impl FromStr for LinkerFlavorCli {
type Err = String;
fn from_str(s: &str) -> Result<LinkerFlavorCli, Self::Err> {
Ok(match s {
$($string => $($flavor)*,)*
_ => return Err(format!("invalid linker flavor, allowed values: {}", Self::one_of())),
})
}
}
)
}
@@ -540,6 +556,8 @@ pub fn desc(self) -> &'static str {
(LinkerFlavorCli::Em) "em"
}
crate::json::serde_deserialize_from_str!(LinkerFlavorCli);
impl ToJson for LinkerFlavorCli {
fn to_json(&self) -> Json {
self.desc().to_json()
@@ -573,19 +591,26 @@ pub enum LinkSelfContainedDefault {
/// Parses a backwards-compatible `-Clink-self-contained` option string, without components.
impl FromStr for LinkSelfContainedDefault {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
fn from_str(s: &str) -> Result<LinkSelfContainedDefault, Self::Err> {
Ok(match s {
"false" => LinkSelfContainedDefault::False,
"true" | "wasm" => LinkSelfContainedDefault::True,
"musl" => LinkSelfContainedDefault::InferredForMusl,
"mingw" => LinkSelfContainedDefault::InferredForMingw,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid `-Clink-self-contained` default. \
Use 'false', 'true', 'wasm', 'musl' or 'mingw'",
));
}
})
}
}
crate::json::serde_deserialize_from_str!(LinkSelfContainedDefault);
impl ToJson for LinkSelfContainedDefault {
fn to_json(&self) -> Json {
match *self {
@@ -652,19 +677,6 @@ pub struct LinkSelfContainedComponents: u8 {
rustc_data_structures::external_bitflags_debug! { LinkSelfContainedComponents }
impl LinkSelfContainedComponents {
/// Parses a single `-Clink-self-contained` well-known component, not a set of flags.
pub fn from_str(s: &str) -> Option<LinkSelfContainedComponents> {
Some(match s {
"crto" => LinkSelfContainedComponents::CRT_OBJECTS,
"libc" => LinkSelfContainedComponents::LIBC,
"unwind" => LinkSelfContainedComponents::UNWIND,
"linker" => LinkSelfContainedComponents::LINKER,
"sanitizers" => LinkSelfContainedComponents::SANITIZERS,
"mingw" => LinkSelfContainedComponents::MINGW,
_ => return None,
})
}
/// Return the component's name.
///
/// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags).
@@ -708,6 +720,29 @@ pub fn is_crt_objects_enabled(self) -> bool {
}
}
impl FromStr for LinkSelfContainedComponents {
type Err = String;
/// Parses a single `-Clink-self-contained` well-known component, not a set of flags.
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"crto" => LinkSelfContainedComponents::CRT_OBJECTS,
"libc" => LinkSelfContainedComponents::LIBC,
"unwind" => LinkSelfContainedComponents::UNWIND,
"linker" => LinkSelfContainedComponents::LINKER,
"sanitizers" => LinkSelfContainedComponents::SANITIZERS,
"mingw" => LinkSelfContainedComponents::MINGW,
_ => {
return Err(format!(
"'{s}' is not a valid link-self-contained component, expected 'crto', 'libc', 'unwind', 'linker', 'sanitizers', 'mingw'"
));
}
})
}
}
crate::json::serde_deserialize_from_str!(LinkSelfContainedComponents);
impl ToJson for LinkSelfContainedComponents {
fn to_json(&self) -> Json {
let components: Vec<_> = Self::all_components()
@@ -821,6 +856,25 @@ pub const fn desc_symbol(&self) -> Symbol {
}
}
impl FromStr for PanicStrategy {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"unwind" => PanicStrategy::Unwind,
"abort" => PanicStrategy::Abort,
_ => {
return Err(format!(
"'{}' is not a valid value for \
panic-strategy. Use 'unwind' or 'abort'.",
s
));
}
})
}
}
crate::json::serde_deserialize_from_str!(PanicStrategy);
impl ToJson for PanicStrategy {
fn to_json(&self) -> Json {
match *self {
@@ -867,18 +921,24 @@ pub fn desc(&self) -> &str {
}
impl FromStr for SymbolVisibility {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<SymbolVisibility, ()> {
fn from_str(s: &str) -> Result<SymbolVisibility, Self::Err> {
match s {
"hidden" => Ok(SymbolVisibility::Hidden),
"protected" => Ok(SymbolVisibility::Protected),
"interposable" => Ok(SymbolVisibility::Interposable),
_ => Err(()),
_ => Err(format!(
"'{}' is not a valid value for \
symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
s
)),
}
}
}
crate::json::serde_deserialize_from_str!(SymbolVisibility);
impl ToJson for SymbolVisibility {
fn to_json(&self) -> Json {
match *self {
@@ -890,19 +950,25 @@ fn to_json(&self) -> Json {
}
impl FromStr for RelroLevel {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<RelroLevel, ()> {
fn from_str(s: &str) -> Result<RelroLevel, Self::Err> {
match s {
"full" => Ok(RelroLevel::Full),
"partial" => Ok(RelroLevel::Partial),
"off" => Ok(RelroLevel::Off),
"none" => Ok(RelroLevel::None),
_ => Err(()),
_ => Err(format!(
"'{}' is not a valid value for \
relro-level. Use 'full', 'partial, 'off', or 'none'.",
s
)),
}
}
}
crate::json::serde_deserialize_from_str!(RelroLevel);
impl ToJson for RelroLevel {
fn to_json(&self) -> Json {
match *self {
@@ -923,7 +989,7 @@ pub enum SmallDataThresholdSupport {
}
impl FromStr for SmallDataThresholdSupport {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "none" {
@@ -935,11 +1001,13 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
} else if let Some(arg) = s.strip_prefix("llvm-arg=") {
Ok(Self::LlvmArg(arg.to_string().into()))
} else {
Err(())
Err(format!("'{s}' is not a valid value for small-data-threshold-support."))
}
}
}
crate::json::serde_deserialize_from_str!(SmallDataThresholdSupport);
impl ToJson for SmallDataThresholdSupport {
fn to_json(&self) -> Value {
match self {
@@ -969,18 +1037,25 @@ pub fn desc(&self) -> &str {
}
impl FromStr for MergeFunctions {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<MergeFunctions, ()> {
fn from_str(s: &str) -> Result<MergeFunctions, Self::Err> {
match s {
"disabled" => Ok(MergeFunctions::Disabled),
"trampolines" => Ok(MergeFunctions::Trampolines),
"aliases" => Ok(MergeFunctions::Aliases),
_ => Err(()),
_ => Err(format!(
"'{}' is not a valid value for \
merge-functions. Use 'disabled', \
'trampolines', or 'aliases'.",
s
)),
}
}
}
crate::json::serde_deserialize_from_str!(MergeFunctions);
impl ToJson for MergeFunctions {
fn to_json(&self) -> Json {
match *self {
@@ -1040,9 +1115,9 @@ pub const fn desc_symbol(&self) -> Symbol {
}
impl FromStr for RelocModel {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<RelocModel, ()> {
fn from_str(s: &str) -> Result<RelocModel, Self::Err> {
Ok(match s {
"static" => RelocModel::Static,
"pic" => RelocModel::Pic,
@@ -1051,11 +1126,19 @@ fn from_str(s: &str) -> Result<RelocModel, ()> {
"ropi" => RelocModel::Ropi,
"rwpi" => RelocModel::Rwpi,
"ropi-rwpi" => RelocModel::RopiRwpi,
_ => return Err(()),
_ => {
return Err(format!(
"invalid relocation model '{s}'.
Run `rustc --print relocation-models` to \
see the list of supported values.'"
));
}
})
}
}
crate::json::serde_deserialize_from_str!(RelocModel);
impl ToJson for RelocModel {
fn to_json(&self) -> Json {
self.desc().to_json()
@@ -1072,20 +1155,28 @@ pub enum CodeModel {
}
impl FromStr for CodeModel {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<CodeModel, ()> {
fn from_str(s: &str) -> Result<CodeModel, Self::Err> {
Ok(match s {
"tiny" => CodeModel::Tiny,
"small" => CodeModel::Small,
"kernel" => CodeModel::Kernel,
"medium" => CodeModel::Medium,
"large" => CodeModel::Large,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid code model. \
Run `rustc --print code-models` to \
see the list of supported values."
));
}
})
}
}
crate::json::serde_deserialize_from_str!(CodeModel);
impl ToJson for CodeModel {
fn to_json(&self) -> Json {
match *self {
@@ -1107,17 +1198,25 @@ pub enum FloatAbi {
}
impl FromStr for FloatAbi {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<FloatAbi, ()> {
fn from_str(s: &str) -> Result<FloatAbi, Self::Err> {
Ok(match s {
"soft" => FloatAbi::Soft,
"hard" => FloatAbi::Hard,
_ => return Err(()),
_ => {
return Err(format!(
"'{}' is not a valid value for \
llvm-floatabi. Use 'soft' or 'hard'.",
s
));
}
})
}
}
crate::json::serde_deserialize_from_str!(FloatAbi);
impl ToJson for FloatAbi {
fn to_json(&self) -> Json {
match *self {
@@ -1138,17 +1237,24 @@ pub enum RustcAbi {
}
impl FromStr for RustcAbi {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<RustcAbi, ()> {
fn from_str(s: &str) -> Result<RustcAbi, Self::Err> {
Ok(match s {
"x86-sse2" => RustcAbi::X86Sse2,
"x86-softfloat" => RustcAbi::X86Softfloat,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid value for rustc-abi. \
Use 'x86-softfloat' or leave the field unset."
));
}
})
}
}
crate::json::serde_deserialize_from_str!(RustcAbi);
impl ToJson for RustcAbi {
fn to_json(&self) -> Json {
match *self {
@@ -1169,9 +1275,9 @@ pub enum TlsModel {
}
impl FromStr for TlsModel {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<TlsModel, ()> {
fn from_str(s: &str) -> Result<TlsModel, Self::Err> {
Ok(match s {
// Note the difference "general" vs "global" difference. The model name is "general",
// but the user-facing option name is "global" for consistency with other compilers.
@@ -1180,11 +1286,19 @@ fn from_str(s: &str) -> Result<TlsModel, ()> {
"initial-exec" => TlsModel::InitialExec,
"local-exec" => TlsModel::LocalExec,
"emulated" => TlsModel::Emulated,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid TLS model. \
Run `rustc --print tls-models` to \
see the list of supported values."
));
}
})
}
}
crate::json::serde_deserialize_from_str!(TlsModel);
impl ToJson for TlsModel {
fn to_json(&self) -> Json {
match *self {
@@ -1230,19 +1344,6 @@ fn as_str(&self) -> &'static str {
}
}
pub(super) fn from_str(s: &str) -> Option<LinkOutputKind> {
Some(match s {
"dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
"dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
"static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
"static-pic-exe" => LinkOutputKind::StaticPicExe,
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
"static-dylib" => LinkOutputKind::StaticDylib,
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
_ => return None,
})
}
pub fn can_link_dylib(self) -> bool {
match self {
LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false,
@@ -1255,6 +1356,31 @@ pub fn can_link_dylib(self) -> bool {
}
}
impl FromStr for LinkOutputKind {
type Err = String;
fn from_str(s: &str) -> Result<LinkOutputKind, Self::Err> {
Ok(match s {
"dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
"dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
"static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
"static-pic-exe" => LinkOutputKind::StaticPicExe,
"dynamic-dylib" => LinkOutputKind::DynamicDylib,
"static-dylib" => LinkOutputKind::StaticDylib,
"wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
_ => {
return Err(format!(
"invalid value for CRT object kind. \
Use '(dynamic,static)-(nopic,pic)-exe' or \
'(dynamic,static)-dylib' or 'wasi-reactor-exe'"
));
}
})
}
}
crate::json::serde_deserialize_from_str!(LinkOutputKind);
impl fmt::Display for LinkOutputKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
@@ -1290,18 +1416,25 @@ fn as_str(&self) -> &'static str {
}
impl FromStr for DebuginfoKind {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<Self, ()> {
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"dwarf" => DebuginfoKind::Dwarf,
"dwarf-dsym" => DebuginfoKind::DwarfDsym,
"pdb" => DebuginfoKind::Pdb,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
'dwarf-dsym' or 'pdb'."
));
}
})
}
}
crate::json::serde_deserialize_from_str!(DebuginfoKind);
impl ToJson for DebuginfoKind {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -1354,18 +1487,25 @@ fn as_str(&self) -> &'static str {
}
impl FromStr for SplitDebuginfo {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<Self, ()> {
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"off" => SplitDebuginfo::Off,
"unpacked" => SplitDebuginfo::Unpacked,
"packed" => SplitDebuginfo::Packed,
_ => return Err(()),
_ => {
return Err(format!(
"'{s}' is not a valid value for \
split-debuginfo. Use 'off', 'unpacked', or 'packed'.",
));
}
})
}
}
crate::json::serde_deserialize_from_str!(SplitDebuginfo);
impl ToJson for SplitDebuginfo {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -1378,7 +1518,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize)]
#[serde(tag = "kind")]
#[serde(rename_all = "kebab-case")]
pub enum StackProbeType {
/// Don't emit any stack probes.
None,
@@ -1390,44 +1532,10 @@ pub enum StackProbeType {
Call,
/// Use inline option for LLVM versions later than specified in `min_llvm_version_for_inline`
/// and call `__rust_probestack` otherwise.
InlineOrCall { min_llvm_version_for_inline: (u32, u32, u32) },
}
impl StackProbeType {
fn from_json(json: &Json) -> Result<Self, String> {
let object = json.as_object().ok_or_else(|| "expected a JSON object")?;
let kind = object
.get("kind")
.and_then(|o| o.as_str())
.ok_or_else(|| "expected `kind` to be a string")?;
match kind {
"none" => Ok(StackProbeType::None),
"inline" => Ok(StackProbeType::Inline),
"call" => Ok(StackProbeType::Call),
"inline-or-call" => {
let min_version = object
.get("min-llvm-version-for-inline")
.and_then(|o| o.as_array())
.ok_or_else(|| "expected `min-llvm-version-for-inline` to be an array")?;
let mut iter = min_version.into_iter().map(|v| {
let int = v.as_u64().ok_or_else(
|| "expected `min-llvm-version-for-inline` values to be integers",
)?;
u32::try_from(int)
.map_err(|_| "`min-llvm-version-for-inline` values don't convert to u32")
});
let min_llvm_version_for_inline = (
iter.next().unwrap_or(Ok(11))?,
iter.next().unwrap_or(Ok(0))?,
iter.next().unwrap_or(Ok(0))?,
);
Ok(StackProbeType::InlineOrCall { min_llvm_version_for_inline })
}
_ => Err(String::from(
"`kind` expected to be one of `none`, `inline`, `call` or `inline-or-call`",
)),
}
}
InlineOrCall {
#[serde(rename = "min-llvm-version-for-inline")]
min_llvm_version_for_inline: (u32, u32, u32),
},
}
impl ToJson for StackProbeType {
@@ -1549,6 +1657,29 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
impl FromStr for SanitizerSet {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"address" => SanitizerSet::ADDRESS,
"cfi" => SanitizerSet::CFI,
"dataflow" => SanitizerSet::DATAFLOW,
"kcfi" => SanitizerSet::KCFI,
"kernel-address" => SanitizerSet::KERNELADDRESS,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,
"safestack" => SanitizerSet::SAFESTACK,
"shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
"thread" => SanitizerSet::THREAD,
"hwaddress" => SanitizerSet::HWADDRESS,
s => return Err(format!("unknown sanitizer {s}")),
})
}
}
crate::json::serde_deserialize_from_str!(SanitizerSet);
impl ToJson for SanitizerSet {
fn to_json(&self) -> Json {
self.into_iter()
@@ -1587,17 +1718,19 @@ pub fn ratchet(&mut self, rhs: FramePointer) -> FramePointer {
}
impl FromStr for FramePointer {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"always" => Self::Always,
"non-leaf" => Self::NonLeaf,
"may-omit" => Self::MayOmit,
_ => return Err(()),
_ => return Err(format!("'{s}' is not a valid value for frame-pointer")),
})
}
}
crate::json::serde_deserialize_from_str!(FramePointer);
impl ToJson for FramePointer {
fn to_json(&self) -> Json {
match *self {
@@ -1685,7 +1818,7 @@ pub fn to_object(&self) -> object::BinaryFormat {
}
impl FromStr for BinaryFormat {
type Err = ();
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"coff" => Ok(Self::Coff),
@@ -1693,11 +1826,16 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
"mach-o" => Ok(Self::MachO),
"wasm" => Ok(Self::Wasm),
"xcoff" => Ok(Self::Xcoff),
_ => Err(()),
_ => Err(format!(
"'{s}' is not a valid value for binary_format. \
Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
)),
}
}
}
crate::json::serde_deserialize_from_str!(BinaryFormat);
impl ToJson for BinaryFormat {
fn to_json(&self) -> Json {
match self {
@@ -2130,12 +2268,11 @@ macro_rules! cvs {
#[derive(Debug, PartialEq)]
pub struct TargetWarnings {
unused_fields: Vec<String>,
incorrect_type: Vec<String>,
}
impl TargetWarnings {
pub fn empty() -> Self {
Self { unused_fields: Vec::new(), incorrect_type: Vec::new() }
Self { unused_fields: Vec::new() }
}
pub fn warning_messages(&self) -> Vec<String> {
@@ -2146,12 +2283,6 @@ pub fn warning_messages(&self) -> Vec<String> {
self.unused_fields.join(", ")
));
}
if !self.incorrect_type.is_empty() {
warnings.push(format!(
"target json file contains fields whose value doesn't have the correct json type: {}",
self.incorrect_type.join(", ")
));
}
warnings
}
}
@@ -3325,7 +3456,8 @@ macro_rules! check_matches {
/// Test target self-consistency and JSON encoding/decoding roundtrip.
#[cfg(test)]
fn test_target(mut self) {
let recycled_target = Target::from_json(self.to_json()).map(|(j, _)| j);
let recycled_target =
Target::from_json(&serde_json::to_string(&self.to_json()).unwrap()).map(|(j, _)| j);
self.update_to_cli();
self.check_consistency(TargetKind::Builtin).unwrap();
assert_eq!(recycled_target, Ok(self));
@@ -3373,8 +3505,7 @@ pub fn search(
fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
let contents = fs::read_to_string(path).map_err(|e| e.to_string())?;
let obj = serde_json::from_str(&contents).map_err(|e| e.to_string())?;
Target::from_json(obj)
Target::from_json(&contents)
}
match *target_tuple {
@@ -3422,10 +3553,7 @@ fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
Err(format!("could not find specification for target {target_tuple:?}"))
}
}
TargetTuple::TargetJson { ref contents, .. } => {
let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?;
Target::from_json(obj)
}
TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents),
}
}
+5 -45
View File
@@ -2,8 +2,7 @@
#[test]
fn report_unused_fields() {
let json = serde_json::from_str(
r#"
let json = r#"
{
"arch": "powerpc64",
"data-layout": "e-m:e-i64:64-n32:64",
@@ -11,47 +10,8 @@ fn report_unused_fields() {
"target-pointer-width": "64",
"code-mode": "foo"
}
"#,
)
.unwrap();
let warnings = Target::from_json(json).unwrap().1;
assert_eq!(warnings.warning_messages().len(), 1);
assert!(warnings.warning_messages().join("\n").contains("code-mode"));
}
#[test]
fn report_incorrect_json_type() {
let json = serde_json::from_str(
r#"
{
"arch": "powerpc64",
"data-layout": "e-m:e-i64:64-n32:64",
"llvm-target": "powerpc64le-elf",
"target-pointer-width": "64",
"link-env-remove": "foo"
}
"#,
)
.unwrap();
let warnings = Target::from_json(json).unwrap().1;
assert_eq!(warnings.warning_messages().len(), 1);
assert!(warnings.warning_messages().join("\n").contains("link-env-remove"));
}
#[test]
fn no_warnings_for_valid_target() {
let json = serde_json::from_str(
r#"
{
"arch": "powerpc64",
"data-layout": "e-m:e-i64:64-n32:64",
"llvm-target": "powerpc64le-elf",
"target-pointer-width": "64",
"link-env-remove": ["foo"]
}
"#,
)
.unwrap();
let warnings = Target::from_json(json).unwrap().1;
assert_eq!(warnings.warning_messages().len(), 0);
"#;
let result = Target::from_json(json);
eprintln!("{result:#?}");
assert!(result.is_err());
}
+19
View File
@@ -20,6 +20,25 @@ impl<T> Rev<T> {
pub(in crate::iter) fn new(iter: T) -> Rev<T> {
Rev { iter }
}
/// Consumes the `Rev`, returning the inner iterator.
///
/// # Examples
///
/// ```rust
/// #![feature(rev_into_inner)]
///
/// let s = "foobar";
/// let mut rev = s.chars().rev();
/// assert_eq!(rev.next(), Some('r'));
/// assert_eq!(rev.next(), Some('a'));
/// assert_eq!(rev.next(), Some('b'));
/// assert_eq!(rev.into_inner().collect::<String>(), "foo");
/// ```
#[unstable(feature = "rev_into_inner", issue = "144277")]
pub fn into_inner(self) -> T {
self.iter
}
}
#[stable(feature = "rust1", since = "1.0.0")]
+5 -6
View File
@@ -1,13 +1,14 @@
use core::num::dec2flt::float::RawFloat;
use crate::num::{ldexp_f32, ldexp_f64};
// FIXME(f16_f128): enable on all targets once possible.
#[test]
#[cfg(target_has_reliable_f16)]
fn test_f16_integer_decode() {
assert_eq!(3.14159265359f16.integer_decode(), (1608, -9, 1));
assert_eq!((-8573.5918555f16).integer_decode(), (1072, 3, -1));
#[cfg(not(miri))] // miri doesn't have powf16
assert_eq!(2f16.powf(14.0).integer_decode(), (1 << 10, 4, 1));
assert_eq!(crate::num::ldexp_f16(1.0, 14).integer_decode(), (1 << 10, 4, 1));
assert_eq!(0f16.integer_decode(), (0, -25, 1));
assert_eq!((-0f16).integer_decode(), (0, -25, -1));
assert_eq!(f16::INFINITY.integer_decode(), (1 << 10, 6, 1));
@@ -23,8 +24,7 @@ fn test_f16_integer_decode() {
fn test_f32_integer_decode() {
assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
// Set 2^100 directly instead of using powf, because it doesn't guarantee precision
assert_eq!(1.2676506e30_f32.integer_decode(), (8388608, 77, 1));
assert_eq!(ldexp_f32(1.0, 100).integer_decode(), (8388608, 77, 1));
assert_eq!(0f32.integer_decode(), (0, -150, 1));
assert_eq!((-0f32).integer_decode(), (0, -150, -1));
assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
@@ -40,8 +40,7 @@ fn test_f32_integer_decode() {
fn test_f64_integer_decode() {
assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
// Set 2^100 directly instead of using powf, because it doesn't guarantee precision
assert_eq!(1.2676506002282294e30_f64.integer_decode(), (4503599627370496, 48, 1));
assert_eq!(ldexp_f64(1.0, 100).integer_decode(), (4503599627370496, 48, 1));
assert_eq!(0f64.integer_decode(), (0, -1075, 1));
assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));
@@ -1,5 +1,7 @@
use core::num::flt2dec::estimator::*;
use crate::num::ldexp_f64;
#[test]
fn test_estimate_scaling_factor() {
macro_rules! assert_almost_eq {
@@ -56,7 +58,7 @@ macro_rules! assert_almost_eq {
let step = if cfg!(miri) { 37 } else { 1 };
for i in (-1074..972).step_by(step) {
let expected = super::ldexp_f64(1.0, i).log10().ceil();
let expected = ldexp_f64(1.0, i).log10().ceil();
assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
}
}
+9 -25
View File
@@ -6,6 +6,8 @@
use std::mem::MaybeUninit;
use std::{fmt, str};
use crate::num::{ldexp_f32, ldexp_f64};
mod estimator;
mod strategy {
mod dragon;
@@ -75,24 +77,6 @@ macro_rules! try_fixed {
})
}
#[cfg(target_has_reliable_f16)]
fn ldexp_f16(a: f16, b: i32) -> f16 {
ldexp_f64(a as f64, b) as f16
}
fn ldexp_f32(a: f32, b: i32) -> f32 {
ldexp_f64(a as f64, b) as f32
}
fn ldexp_f64(a: f64, b: i32) -> f64 {
unsafe extern "C" {
fn ldexp(x: f64, n: i32) -> f64;
}
// SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
// cause undefined behavior
unsafe { ldexp(a, b) }
}
fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
where
T: DecodableFloat,
@@ -268,7 +252,7 @@ pub fn f16_shortest_sanity_test<F>(mut f: F)
// 10^2 * 0.31984375
// 10^2 * 0.32
// 10^2 * 0.3203125
check_shortest!(f(ldexp_f16(1.0, 5)) => b"32", 2);
check_shortest!(f(crate::num::ldexp_f16(1.0, 5)) => b"32", 2);
// 10^5 * 0.65472
// 10^5 * 0.65504
@@ -283,7 +267,7 @@ pub fn f16_shortest_sanity_test<F>(mut f: F)
// 10^-9 * 0
// 10^-9 * 0.59604644775390625
// 10^-8 * 0.11920928955078125
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
check_shortest!(f(minf16) => b"6", -7);
}
@@ -292,7 +276,7 @@ pub fn f16_exact_sanity_test<F>(mut f: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
check_exact!(f(0.1f16) => b"999755859375 ", -1);
check_exact!(f(0.5f16) => b"5 ", 0);
@@ -642,7 +626,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
assert_eq!(to_string(f, f16::MAX, Minus, 1), "65500.0");
assert_eq!(to_string(f, f16::MAX, Minus, 8), "65500.00000000");
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 0), "0.00000006");
assert_eq!(to_string(f, minf16, Minus, 8), "0.00000006");
assert_eq!(to_string(f, minf16, Minus, 9), "0.000000060");
@@ -766,7 +750,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: b
assert_eq!(to_string(f, f16::MAX, Minus, (-4, 4), false), "6.55e4");
assert_eq!(to_string(f, f16::MAX, Minus, (-5, 5), false), "65500");
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, (-2, 2), false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, (-7, 7), false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, (-8, 8), false), "0.00000006");
@@ -922,7 +906,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) ->
assert_eq!(to_string(f, f16::MAX, Minus, 6, false), "6.55040e4");
assert_eq!(to_string(f, f16::MAX, Minus, 16, false), "6.550400000000000e4");
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 1, false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, 2, false), "6.0e-8");
assert_eq!(to_string(f, minf16, Minus, 4, false), "5.960e-8");
@@ -1229,7 +1213,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
#[cfg(target_has_reliable_f16)]
{
let minf16 = ldexp_f16(1.0, -24);
let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 0), "0");
assert_eq!(to_string(f, minf16, Minus, 1), "0.0");
assert_eq!(to_string(f, minf16, Minus, 2), "0.00");
+21
View File
@@ -54,6 +54,27 @@ macro_rules! assume_usize_width {
}
}
/// Return `a * 2^b`.
#[cfg(target_has_reliable_f16)]
fn ldexp_f16(a: f16, b: i32) -> f16 {
ldexp_f64(a as f64, b) as f16
}
/// Return `a * 2^b`.
fn ldexp_f32(a: f32, b: i32) -> f32 {
ldexp_f64(a as f64, b) as f32
}
/// Return `a * 2^b`.
fn ldexp_f64(a: f64, b: i32) -> f64 {
unsafe extern "C" {
fn ldexp(x: f64, n: i32) -> f64;
}
// SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
// cause undefined behavior
unsafe { ldexp(a, b) }
}
/// Helper function for testing numeric operations
pub fn test_num<T>(ten: T, two: T)
where
+17 -15
View File
@@ -86,11 +86,11 @@ pub fn is_write_vectored(&self) -> bool {
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
unsupported()
self.inner.peer_addr()
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
unsupported()
self.inner.socket_addr()
}
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
@@ -114,7 +114,7 @@ pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
}
pub fn nodelay(&self) -> io::Result<bool> {
unsupported()
self.inner.nodelay()
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
@@ -122,7 +122,7 @@ pub fn set_ttl(&self, _: u32) -> io::Result<()> {
}
pub fn ttl(&self) -> io::Result<u32> {
unsupported()
self.inner.ttl()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -140,7 +140,9 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
pub struct TcpListener(!);
pub struct TcpListener {
inner: tcp::Tcp,
}
impl TcpListener {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
@@ -148,45 +150,45 @@ pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
self.0
unsupported()
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
self.0
unsupported()
}
pub fn duplicate(&self) -> io::Result<TcpListener> {
self.0
unsupported()
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
self.0
unsupported()
}
pub fn ttl(&self) -> io::Result<u32> {
self.0
self.inner.ttl()
}
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
self.0
unsupported()
}
pub fn only_v6(&self) -> io::Result<bool> {
self.0
unsupported()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
self.0
unsupported()
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
self.0
unsupported()
}
}
impl fmt::Debug for TcpListener {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0
todo!()
}
}
@@ -1,6 +1,8 @@
use super::tcp4;
use crate::io;
use crate::net::SocketAddr;
use crate::ptr::NonNull;
use crate::sys::{helpers, unsupported};
use crate::time::Duration;
pub(crate) enum Tcp {
@@ -31,4 +33,44 @@ pub(crate) fn read(&self, buf: &mut [u8], timeout: Option<Duration>) -> io::Resu
Self::V4(client) => client.read(buf, timeout),
}
}
pub(crate) fn ttl(&self) -> io::Result<u32> {
match self {
Self::V4(client) => client.get_mode_data().map(|x| x.time_to_live.into()),
}
}
pub(crate) fn nodelay(&self) -> io::Result<bool> {
match self {
Self::V4(client) => {
let temp = client.get_mode_data()?;
match NonNull::new(temp.control_option) {
Some(x) => unsafe { Ok(x.as_ref().enable_nagle.into()) },
None => unsupported(),
}
}
}
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
match self {
Self::V4(client) => client.get_mode_data().map(|x| {
SocketAddr::new(
helpers::ipv4_from_r_efi(x.access_point.remote_address).into(),
x.access_point.remote_port,
)
}),
}
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self {
Self::V4(client) => client.get_mode_data().map(|x| {
SocketAddr::new(
helpers::ipv4_from_r_efi(x.access_point.station_address).into(),
x.access_point.station_port,
)
}),
}
}
}
@@ -67,6 +67,24 @@ pub(crate) fn configure(
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
}
pub(crate) fn get_mode_data(&self) -> io::Result<tcp4::ConfigData> {
let mut config_data = tcp4::ConfigData::default();
let protocol = self.protocol.as_ptr();
let r = unsafe {
((*protocol).get_mode_data)(
protocol,
crate::ptr::null_mut(),
&mut config_data,
crate::ptr::null_mut(),
crate::ptr::null_mut(),
crate::ptr::null_mut(),
)
};
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(config_data) }
}
pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> {
let evt = unsafe { self.create_evt() }?;
let completion_token =
+4
View File
@@ -761,3 +761,7 @@ fn drop(&mut self) {
pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Address {
efi::Ipv4Address { addr: addr.octets() }
}
pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr {
crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3])
}
@@ -1113,6 +1113,12 @@ fn run(self, builder: &Builder<'_>) {
8 * std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
});
cmd.arg(jobs.to_string());
// pass the path to the npm command used for installing js deps.
if let Some(npm) = &builder.config.npm {
cmd.arg(npm);
} else {
cmd.arg("npm");
}
if builder.is_verbose() {
cmd.arg("--verbose");
}
+1 -1
View File
@@ -444,7 +444,7 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String {
let exe_suffix = match target {
TargetTuple::TargetTuple(_) => Target::expect_builtin(target).options.exe_suffix,
TargetTuple::TargetJson { contents, .. } => {
Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
Target::from_json(contents).unwrap().0.options.exe_suffix
}
};
input + &exe_suffix
+16 -3
View File
@@ -100,9 +100,22 @@ pub(crate) fn build_index(
let crate_doc =
short_markdown_summary(&krate.module.doc_value(), &krate.module.link_names(cache));
#[derive(Eq, Ord, PartialEq, PartialOrd)]
struct SerSymbolAsStr(Symbol);
impl Serialize for SerSymbolAsStr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.as_str().serialize(serializer)
}
}
type AliasMap = BTreeMap<SerSymbolAsStr, Vec<usize>>;
// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
// we need the alias element to have an array of items.
let mut aliases: BTreeMap<String, Vec<usize>> = BTreeMap::new();
let mut aliases: AliasMap = BTreeMap::new();
// Sort search index items. This improves the compressibility of the search index.
cache.search_index.sort_unstable_by(|k1, k2| {
@@ -116,7 +129,7 @@ pub(crate) fn build_index(
// Set up alias indexes.
for (i, item) in cache.search_index.iter().enumerate() {
for alias in &item.aliases[..] {
aliases.entry(alias.to_string()).or_default().push(i);
aliases.entry(SerSymbolAsStr(*alias)).or_default().push(i);
}
}
@@ -474,7 +487,7 @@ struct CrateData<'a> {
// The String is alias name and the vec is the list of the elements with this alias.
//
// To be noted: the `usize` elements are indexes to `items`.
aliases: &'a BTreeMap<String, Vec<usize>>,
aliases: &'a AliasMap,
// Used when a type has more than one impl with an associated item with the same name.
associated_item_disambiguators: &'a Vec<(usize, String)>,
// A list of shard lengths encoded as vlqhex. See the comment in write_vlqhex_to_string
@@ -328,7 +328,7 @@ error: creating a shared reference to mutable static
LL | if X.is_some() {
| ^^^^^^^^^^^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[deny(static_mut_refs)]` on by default
+1
View File
@@ -378,6 +378,7 @@
"serde",
"serde_derive",
"serde_json",
"serde_path_to_error",
"sha1",
"sha2",
"sharded-slab",
+4 -1
View File
@@ -50,6 +50,7 @@ pub fn check(
ci_info: &CiInfo,
librustdoc_path: &Path,
tools_path: &Path,
npm: &Path,
bless: bool,
extra_checks: Option<&str>,
pos_args: &[String],
@@ -61,6 +62,7 @@ pub fn check(
ci_info,
librustdoc_path,
tools_path,
npm,
bless,
extra_checks,
pos_args,
@@ -75,6 +77,7 @@ fn check_impl(
ci_info: &CiInfo,
librustdoc_path: &Path,
tools_path: &Path,
npm: &Path,
bless: bool,
extra_checks: Option<&str>,
pos_args: &[String],
@@ -293,7 +296,7 @@ macro_rules! extra_check {
}
if js_lint || js_typecheck {
rustdoc_js::npm_install(root_path, outdir)?;
rustdoc_js::npm_install(root_path, outdir, npm)?;
}
if js_lint {
@@ -23,9 +23,8 @@ fn spawn_cmd(cmd: &mut Command) -> Result<Child, io::Error> {
}
/// install all js dependencies from package.json.
pub(super) fn npm_install(root_path: &Path, outdir: &Path) -> Result<(), super::Error> {
// FIXME(lolbinarycat): make this obey build.npm bootstrap option
npm::install(root_path, outdir, Path::new("npm"))?;
pub(super) fn npm_install(root_path: &Path, outdir: &Path, npm: &Path) -> Result<(), super::Error> {
npm::install(root_path, outdir, npm)?;
Ok(())
}
+2
View File
@@ -29,6 +29,7 @@ fn main() {
let concurrency: NonZeroUsize =
FromStr::from_str(&env::args().nth(4).expect("need concurrency"))
.expect("concurrency must be a number");
let npm: PathBuf = env::args_os().nth(5).expect("need name/path of npm command").into();
let root_manifest = root_path.join("Cargo.toml");
let src_path = root_path.join("src");
@@ -182,6 +183,7 @@ macro_rules! check {
&ci_info,
&librustdoc_path,
&tools_path,
&npm,
bless,
extra_checks,
pos_args
@@ -6,7 +6,6 @@
"dynamic-linking": true,
"env": "gnu",
"executables": true,
"has-elf-tls": true,
"has-rpath": true,
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
@@ -5,7 +5,6 @@
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "big",
"target-pointer-width": "64",
"target-c-int-width": "32",
"arch": "x86_64",
"os": "linux"
}
@@ -4,8 +4,6 @@
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"arch": "x86",
"os": "linux",
"morestack": false
"os": "linux"
}
@@ -3,8 +3,6 @@
"linker-flavor": "gcc",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"arch": "x86",
"os": "foo",
"morestack": false
"os": "foo"
}
@@ -5,8 +5,6 @@
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"arch": "x86_64",
"os": "linux",
"morestack": false
"os": "linux"
}
@@ -4,7 +4,6 @@
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"arch": "x86",
"os": "linux",
"need-explicit-cpu": true
+1 -3
View File
@@ -8,8 +8,6 @@
use run_make_support::{diff, rfs, rustc};
fn main() {
rustc().input("foo.rs").target("my-awesome-platform.json").crate_type("lib").emit("asm").run();
assert!(!rfs::read_to_string("foo.s").contains("morestack"));
rustc()
.input("foo.rs")
.target("my-invalid-platform.json")
@@ -19,7 +17,7 @@ fn main() {
.input("foo.rs")
.target("my-incomplete-platform.json")
.run_fail()
.assert_stderr_contains("Field llvm-target");
.assert_stderr_contains("missing field `llvm-target`");
rustc()
.env("RUST_TARGET_PATH", ".")
.input("foo.rs")
@@ -1,4 +1,4 @@
// Regression test for issue #105056.
// issue: <https://github.com/rust-lang/rust/issues/105056>
//@ edition: 2021
fn f(_: impl Trait<T = Copy>) {}
@@ -23,4 +23,11 @@ fn h(_: impl Trait<T<> = 'static + for<'a> Fn(&'a ())>) {}
trait Trait { type T; }
// Don't suggest assoc ty bounds when we have parenthesized args (the underlying assoc type
// binding `Output` isn't introduced by `=` but by `->`, suggesting `:` wouldn't be valid).
// issue: <https://github.com/rust-lang/rust/issues/140543>
fn i(_: impl Fn() -> std::fmt::Debug) {}
//~^ ERROR expected a type, found a trait
//~| HELP you can add the `dyn` keyword if you want a trait object
fn main() {}
@@ -57,6 +57,17 @@ help: you can add the `dyn` keyword if you want a trait object
LL | type Obj = dyn Trait<T = dyn Clone>;
| +++
error: aborting due to 4 previous errors
error[E0782]: expected a type, found a trait
--> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:29:22
|
LL | fn i(_: impl Fn() -> std::fmt::Debug) {}
| ^^^^^^^^^^^^^^^
|
help: you can add the `dyn` keyword if you want a trait object
|
LL | fn i(_: impl Fn() -> dyn std::fmt::Debug) {}
| +++
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0782`.
@@ -4,7 +4,7 @@ warning: creating a mutable reference to mutable static
LL | let sfoo: *mut Foo = &mut SFOO;
| ^^^^^^^^^ mutable reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw mut` instead to create a raw pointer
@@ -4,7 +4,6 @@
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "ericos",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
@@ -10,7 +10,7 @@ LL | let _ = f0;
LL | }
| - in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/issue-90465.rs:3:9
|
@@ -7,7 +7,7 @@ LL | thread::spawn(move || unsafe {
LL | *fptr.0 = 20;
| ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/auto_traits.rs:2:9
|
@@ -34,7 +34,7 @@ LL | thread::spawn(move || unsafe {
LL | *fptr.0.0 = 20;
| --------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `fptr` to be fully captured
|
LL ~ thread::spawn(move || { let _ = &fptr; unsafe {
@@ -56,7 +56,7 @@ LL | let f_1 = f.1;
LL | }
| - in Rust 2018, `f` is dropped here, but in Rust 2021, only `f.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f` to be fully captured
|
LL ~ let c = || {
@@ -15,7 +15,7 @@ LL | | println!("{:?}", x);
LL | | });
| |______- in this macro invocation
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/closure-body-macro-fragment.rs:4:9
|
@@ -10,7 +10,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/insignificant_drop_attr_migrations.rs:3:9
|
@@ -34,7 +34,7 @@ LL | let _t = t.1;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = move || {
@@ -7,7 +7,7 @@ LL | let _ = || dbg!(a.0);
LL | }
| - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/macro.rs:5:9
|
@@ -10,7 +10,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/migrations_rustfix.rs:2:9
|
@@ -31,7 +31,7 @@ LL | let c = || t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL | let c = || { let _ = &t; t.0 };
@@ -10,7 +10,7 @@ LL | let result = panic::catch_unwind(move || {
LL | f.0()
| --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/mir_calls_to_shims.rs:4:9
|
@@ -13,7 +13,7 @@ LL | let _f_2 = f2.1;
LL | }
| - in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/multi_diagnostics.rs:2:9
|
@@ -34,7 +34,7 @@ LL | let c = || {
LL | let _f_1 = f1.0;
| ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -56,7 +56,7 @@ LL |
LL | let _f_2 = f1.2;
| ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.2`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -81,7 +81,7 @@ LL | }
| in Rust 2018, `f1` is dropped here, but in Rust 2021, only `f1.0` will be dropped here as part of the closure
| in Rust 2018, `f1` is dropped here, but in Rust 2021, only `f1.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -104,7 +104,7 @@ LL |
LL | *fptr2.0 = 20;
| -------- in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0`
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
|
LL ~ thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
@@ -10,7 +10,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/precise.rs:3:9
|
@@ -44,7 +44,7 @@ LL | }
| in Rust 2018, `u` is dropped here, but in Rust 2021, only `u.0.1` will be dropped here as part of the closure
| in Rust 2018, `u` is dropped here, but in Rust 2021, only `u.1.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `u` to be fully captured
|
LL ~ let c = || {
@@ -20,7 +20,7 @@ LL | }
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
| in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/significant_drop.rs:2:9
|
@@ -50,7 +50,7 @@ LL | }
| in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t`, `t1` to be fully captured
|
LL ~ let c = || {
@@ -69,7 +69,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -88,7 +88,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -107,7 +107,7 @@ LL | let _t = t.0;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -126,7 +126,7 @@ LL | let _t = t.1;
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -150,7 +150,7 @@ LL | }
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
| in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t1`, `t` to be fully captured
|
LL ~ let c = move || {
@@ -169,7 +169,7 @@ LL | tuple.0;
LL | }
| - in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tuple` to be fully captured
|
LL ~ let c = || {
@@ -188,7 +188,7 @@ LL | tuple.0;
LL | };
| - in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tuple` to be fully captured
|
LL ~ let c = || {
@@ -204,7 +204,7 @@ LL | let _c = || tup.0;
LL | }
| - in Rust 2018, `tup` is dropped here, but in Rust 2021, only `tup.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tup` to be fully captured
|
LL | let _c = || { let _ = &tup; tup.0 };
@@ -4,7 +4,6 @@
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
@@ -5,6 +5,7 @@
//@ compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options
//@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`"
//@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`"
//@ normalize-stderr: "`mismatched-data-layout-\d+`" -> "`mismatched-data-layout-<hash>`"
#![feature(lang_items, no_core, auto_traits)]
#![no_core]
@@ -1,4 +1,4 @@
error: data-layout for target `mismatched-data-layout-7193370089426056427`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout`
error: data-layout for target `mismatched-data-layout-<hash>`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout`
error: aborting due to 1 previous error
@@ -5,7 +5,7 @@ LL | panic!({ "foo" });
| ^^^^^^^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: `#[warn(non_fmt_panics)]` on by default
help: add a "{}" format string to `Display` the message
|
+1 -1
View File
@@ -4,7 +4,7 @@ warning: creating a mutable reference to mutable static
LL | let ptr = unsafe { &mut BB };
| ^^^^^^^ mutable reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw mut` instead to create a raw pointer
@@ -16,7 +16,7 @@ LL | static FOO: Sync = AtomicUsize::new(0);
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -186,7 +186,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
| ^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -27,7 +27,7 @@ LL | | }, e.mark(3), e.ok(4));
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#3` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -75,7 +75,7 @@ LL | | }, e.mark(1), e.ok(4));
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -107,7 +107,7 @@ LL | | }, e.mark(1), e.ok(4));
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -139,7 +139,7 @@ LL | | }, e.mark(2), e.ok(3));
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -171,7 +171,7 @@ LL | | }, e.mark(2), e.ok(3));
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -193,7 +193,7 @@ LL | _ = (if let Ok(_) = e.ok(4).as_ref() {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -223,7 +223,7 @@ LL | _ = (if let Ok(_) = e.err(4).as_ref() {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -252,7 +252,7 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -281,7 +281,7 @@ LL | if let true = e.err(9).is_ok() {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -310,7 +310,7 @@ LL | if let Ok(_v) = e.err(8) {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -339,7 +339,7 @@ LL | if let Ok(_) = e.err(7) {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -368,7 +368,7 @@ LL | if let Ok(_) = e.err(6).as_ref() {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -397,7 +397,7 @@ LL | if let Ok(_v) = e.err(5) {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -426,7 +426,7 @@ LL | if let Ok(_) = e.err(4) {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -455,7 +455,7 @@ LL | if let Ok(_) = e.err(4).as_ref() {} else {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -7,7 +7,7 @@ LL | if let Some(_value) = Droppy.get() {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-gated.rs:14:1
|
@@ -14,7 +14,7 @@ LL | | };
| |_____- in this macro invocation
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-with-macro.rs:22:1
|
+8 -8
View File
@@ -7,7 +7,7 @@ LL | if let Some(_value) = droppy().get() {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -47,7 +47,7 @@ LL | } else if let Some(_value) = droppy().get() {
| -------- this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -89,7 +89,7 @@ LL | } else if let Some(_value) = droppy().get() {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -120,7 +120,7 @@ LL | if let Some(1) = { if let Some(_value) = Droppy.get() { Some(1) } else
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -146,7 +146,7 @@ LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -172,7 +172,7 @@ LL | } else if (((if let Some(_value) = droppy().get() { true } else { false
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -198,7 +198,7 @@ LL | while (if let Some(_value) = droppy().get() { false } else { true }) {
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -224,7 +224,7 @@ LL | if let Some(_value) = Some((droppy(), ()).1) {} else {}
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:97:51
|
@@ -7,7 +7,7 @@ LL | let _ = { String::new().as_str() }.len();
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: the lint level is defined here
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:6:9
|
@@ -23,7 +23,7 @@ LL | f(unsafe { String::new().as_str() }.len());
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:31:9
@@ -35,7 +35,7 @@ LL | &mut || 0
| borrow later used here
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:43:9
@@ -46,7 +46,7 @@ LL | g({ &f() });
| borrow later used by call
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: aborting due to 4 previous errors
@@ -17,7 +17,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -54,7 +54,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -86,7 +86,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -118,7 +118,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -145,7 +145,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -167,7 +167,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -199,7 +199,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:193:5
|
@@ -231,7 +231,7 @@ LL | ));
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -23,7 +23,7 @@ LL | }
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:9:1
|
@@ -5,7 +5,7 @@ LL | fn id<F>(f: Copy) -> usize {
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@ LL | fn id<F>(f: Copy) -> usize {
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -5,7 +5,7 @@ LL | trait B { fn f(a: A) -> A; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@ LL | trait B { fn f(a: A) -> A; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait B { fn f(a: A) -> dyn A; }
@@ -32,7 +32,7 @@ LL | trait A { fn g(b: B) -> B; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait A { fn g(b: dyn B) -> B; }
@@ -45,7 +45,7 @@ LL | trait A { fn g(b: B) -> B; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait A { fn g(b: B) -> dyn B; }
@@ -58,7 +58,7 @@ LL | trait B { fn f(a: A) -> A; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -100,7 +100,7 @@ LL | trait A { fn g(b: B) -> B; }
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -23,7 +23,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -5,7 +5,7 @@ LL | fn ord_prefer_dot(s: String) -> Ord {
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/bare-trait-dont-suggest-dyn.rs:5:9
|
@@ -5,7 +5,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/dyn-2018-edition-lint.rs:2:8
|
@@ -23,7 +23,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
@@ -36,7 +36,7 @@ LL | let _x: &SomeTrait = todo!();
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let _x: &dyn SomeTrait = todo!();
@@ -5,7 +5,7 @@ LL | <fmt::Debug>::fmt(self, f)
| ^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/dyn-angle-brackets.rs:4:9
|
@@ -5,7 +5,7 @@ LL | fn m() {
| ^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:22:17
@@ -25,7 +25,7 @@ LL | fn q() -> Option<()> {
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:37:5
@@ -44,7 +44,7 @@ LL | fn meow() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:50:5
@@ -63,7 +63,7 @@ LL | pub fn fallback_return() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:62:19
@@ -82,7 +82,7 @@ LL | fn fully_apit() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:76:17
@@ -104,7 +104,7 @@ LL | fn m() {
| ^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:22:17
@@ -125,7 +125,7 @@ LL | fn q() -> Option<()> {
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:37:5
@@ -146,7 +146,7 @@ LL | fn meow() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:50:5
@@ -167,7 +167,7 @@ LL | pub fn fallback_return() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:62:19
@@ -188,7 +188,7 @@ LL | fn fully_apit() -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:76:17
@@ -1 +1,4 @@
pub fn boilerplate() {}
#[inline]
pub fn local_codegen() {}
@@ -0,0 +1,11 @@
//@ run-pass
//@ aux-build:main_functions.rs
//@ compile-flags: -Ccodegen-units=1024
// This is a regression test for https://github.com/rust-lang/rust/issues/144052.
// Entrypoint functions call each other in ways that CGU partitioning doesn't know about. So there
// is a special check to not internalize any of them. But internalizing them can be okay if there
// are few enough CGUs, so we use a lot of CGUs in this test to hit the bad case.
extern crate main_functions;
pub use main_functions::local_codegen as main;
@@ -10,7 +10,7 @@ LL | let x = a.0;
LL | }
| - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/rfc2229-migration.rs:5:9
|
@@ -5,7 +5,7 @@ LL | let _ = MyIterator::next;
| ^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -5,7 +5,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -5,7 +5,7 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024-machine-applicable.rs:9:10
|
@@ -5,7 +5,7 @@ LL | fn named<'a>(x: &'a i32) -> impl Sized { *x }
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:7:10
|
@@ -29,7 +29,7 @@ LL | fn implicit(x: &i32) -> impl Sized { *x }
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:11:16
|
@@ -48,7 +48,7 @@ LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self }
| ^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:17:24
|
@@ -67,7 +67,7 @@ LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {}
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:29:23
|
@@ -86,7 +86,7 @@ LL | fn apit(_: &impl Sized) -> impl Sized {}
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:33:12
|
@@ -111,7 +111,7 @@ LL | fn apit2<U>(_: &impl Sized, _: U) -> impl Sized {}
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:37:16
|
@@ -136,7 +136,7 @@ LL | async fn async_fn<'a>(x: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:41:19
|
@@ -155,7 +155,7 @@ LL | pub fn parens(x: &i32) -> &impl Clone { x }
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:45:18
|
+2 -2
View File
@@ -5,7 +5,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -25,7 +25,7 @@ LL | let g = BitXor::bitor;
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let g = <dyn BitXor>::bitor;
+1 -1
View File
@@ -9,7 +9,7 @@ LL | | (Box::new(__static_ref_initialize()));
LL | | });
| |______________^ shared reference to mutable static
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
= note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default

Some files were not shown because too many files have changed in this diff Show More