diff options
331 files changed, 3284 insertions, 1672 deletions
diff --git a/.mailmap b/.mailmap index 56490ca5059..fdb62a9d778 100644 --- a/.mailmap +++ b/.mailmap @@ -31,6 +31,7 @@ Alexis Beingessner <a.beingessner@gmail.com> Alfie John <alfie@alfie.wtf> Alfie John <alfiej@fastmail.fm> Alona Enraght-Moony <code@alona.page> <nixon.emoony@gmail.com> Alona Enraght-Moony <code@alona.page> <nixon@caminus.local> +Alona Enraght-Moony <code@alona.page> <contact@alona.page> Amanda Stjerna <mail@amandastjerna.se> <albin.stjerna@gmail.com> Amanda Stjerna <mail@amandastjerna.se> <amanda.stjerna@it.uu.se> Amos Onn <amosonn@gmail.com> @@ -75,6 +76,7 @@ Benjamin Jackman <ben@jackman.biz> Benoît Cortier <benoit.cortier@fried-world.eu> Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca> bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.com> +bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com> Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de> blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc> blyxyas <blyxyas@gmail.com> Alejandra González <blyxyas@gmail.com> @@ -172,6 +174,7 @@ Dzmitry Malyshau <kvarkus@gmail.com> E. Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com> Ed Barnard <eabarnard@gmail.com> Eduard-Mihai Burtescu <edy.burt@gmail.com> +Eduard-Mihai Burtescu <edy.burt@gmail.com> <eddyb@lyken.rs> Eduardo Bautista <me@eduardobautista.com> <=> Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com> Eduardo Broto <ebroto@tutanota.com> @@ -186,6 +189,7 @@ Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org> Erik Desjardins <erikdesjardins@users.noreply.github.com> Erik Jensen <erikjensen@rkjnsn.net> Erin Power <xampprocky@gmail.com> +Erin Power <xampprocky@gmail.com> <xampprocky@icloud.com> Erin Power <xampprocky@gmail.com> <theaaronepower@gmail.com> Erin Power <xampprocky@gmail.com> <Aaronepower@users.noreply.github.com> Esteban Küber <esteban@kuber.com.ar> @@ -198,6 +202,7 @@ F001 <changchun.fan@qq.com> Fabian Kössel <fkjogu@users.noreply.github.com> Falco Hirschenberger <falco.hirschenberger@gmail.com> <hirschen@itwm.fhg.de> Felix S. Klock II <pnkfelix@pnkfx.org> Felix S Klock II <pnkfelix@pnkfx.org> +Felix S. Klock II <pnkfelix@pnkfx.org> <pnkfelix@mozilla.com> Félix Saparelli <felix@passcod.name> Flaper Fesp <flaper87@gmail.com> Florian Berger <fbergr@gmail.com> @@ -245,7 +250,7 @@ Irina Popa <irinagpopa@gmail.com> Ivan Ivaschenko <defuz.net@gmail.com> ivan tkachenko <me@ratijas.tk> J. J. Weber <jjweber@gmail.com> -Jack Huey <jack.huey@umassmed.edu> +Jack Huey <jack.huey@umassmed.edu> <jackh726@gmail.com> Jacob <jacob.macritchie@gmail.com> Jacob Greenfield <xales@naveria.com> Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com> @@ -292,6 +297,7 @@ John Clements <clements@racket-lang.org> <clements@brinckerhoff.org> John Hodge <acessdev@gmail.com> John Hodge <tpg@mutabah.net> John Hörnvall <trolledwoods@gmail.com> John Kåre Alsaker <john.kare.alsaker@gmail.com> +John Kåre Alsaker <john.kare.alsaker@gmail.com> <zoxc32@gmail.com> John Talling <inrustwetrust@users.noreply.github.com> John Van Enk <vanenkj@gmail.com> Jonas Tepe <jonasprogrammer@gmail.com> @@ -368,6 +374,7 @@ Lukas Lueg <lukas.lueg@gmail.com> Luke Metz <luke.metz@students.olin.edu> Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca> Luqman Aden <me@luqman.ca> <laden@mozilla.com> +Luqman Aden <me@luqman.ca> <rust@luqman.ca> Lzu Tao <taolzu@gmail.com> Maik Klein <maikklein@googlemail.com> Malo Jaffré <jaffre.malo@gmail.com> @@ -409,6 +416,7 @@ mental <m3nta1@yahoo.com> mibac138 <5672750+mibac138@users.noreply.github.com> Michael Williams <m.t.williams@live.com> Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail> +Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail.com> Michael Woerister <michaelwoerister@posteo> <michaelwoerister@users.noreply.github.com> Michael Woerister <michaelwoerister@posteo> <michaelwoerister@posteo.net> Michael Zhang <hmperson1@gmail.com> @@ -422,6 +430,7 @@ Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com> msizanoen1 <qtmlabs@protonmail.com> Mukilan Thiagarajan <mukilanthiagarajan@gmail.com> Nadrieril Feneanar <Nadrieril@users.noreply.github.com> +Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+git@gmail.com> NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com> NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm+github@gmail.com> Nathan Ringo <remexre@gmail.com> @@ -442,6 +451,8 @@ Niclas Schwarzlose <15schnic@gmail.com> Nicolas Abram <abramlujan@gmail.com> Nicole Mazzuca <npmazzuca@gmail.com> Noratrieb <48135649+Noratrieb@users.noreply.github.com> <48135649+Nilstrieb@users.noreply.github.com> +Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nilstrieb@gmail.com> +Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nora@noratrieb.dev> Nif Ward <nif.ward@gmail.com> Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com> NODA Kai <nodakai@gmail.com> @@ -460,6 +471,7 @@ Oliver Scherer <oli-obk@users.noreply.github.com> <github6541940@oli-obk.de> Oliver Scherer <oli-obk@users.noreply.github.com> <public.oliver.schneider@kit.edu> Oliver Scherer <oli-obk@users.noreply.github.com> <oliver.schneider@kit.edu> Oliver Scherer <oli-obk@users.noreply.github.com> <obk8176014uqher834@olio-obk.de> +Oliver Scherer <oli-obk@users.noreply.github.com> <rustc-contact@oli-obk.de> Oliver Scherer <oli-obk@users.noreply.github.com> Onur Özkan <onurozkan.dev@outlook.com> <work@onurozkan.dev> Onur Özkan <onurozkan.dev@outlook.com> @@ -496,6 +508,7 @@ Raphaël Huchet <rap2hpoutre@users.noreply.github.com> rChaser53 <tayoshizawa29@gmail.com> Rémy Rakic <remy.rakic@gmail.com> Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+github@gmail.com> +Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+rust@gmail.com> Renato Riccieri Santos Zannon <renato@rrsz.com.br> Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co> Ricky Hosfelt <ricky@hosfelt.io> @@ -525,6 +538,7 @@ Samuel Tardieu <sam@rfc1149.net> Santiago Pastorino <spastorino@gmail.com> Santiago Pastorino <spastorino@gmail.com> <santiago@wyeworks.com> Scott McMurray <scottmcm@users.noreply.github.com> +Scott McMurray <scottmcm@users.noreply.github.com> <smcmurray@acm.org> Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org> Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com> Seiichi Uchida <seuchida@gmail.com> @@ -536,6 +550,7 @@ Shyam Sundar B <shyambaskaran@outlook.com> Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server> Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org> Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me> +Simonas Kazlauskas <git@kazlauskas.me> <simonas+t-compiler@kazlauskas.me> Siva Prasad <sivaauturic@gmail.com> Smittyvb <me@smitop.com> Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com> @@ -556,6 +571,8 @@ Tatsuyuki Ishi <ishitatsuyuki@gmail.com> Tau Gärtli <git@tau.garden> <ruben.schmidmeister@icloud.com> Tero Hänninen <lgvz@users.noreply.github.com> Tero Hänninen <tejohann@kapsi.fi> The8472 <git@infinite-source.de> +The8472 <git@infinite-source.de> <the8472.rs@infinite-source.de> +The8472 <git@infinite-source.de> <the8472@users.noreply.github.com> Theo Belaire <theo.belaire@gmail.com> Theo Belaire <tyr.god.of.war.42@gmail.com> Theodore Luo Wang <wangtheo662@gmail.com> Thiago Pontes <email@thiago.me> thiagopnts <thiagopnts@gmail.com> @@ -593,7 +610,8 @@ Waffle Lapkin <waffle.lapkin@tasking.com> Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com> whitequark <whitequark@whitequark.org> William Ting <io@williamting.com> <william.h.ting@gmail.com> -Wim Looman <wim@nemo157.com> +Wim Looman <wim@nemo157.com> <rust-lang@nemo157.com> +Wim Looman <wim@nemo157.com> <git@nemo157.com> Without Boats <woboats@gmail.com> Without Boats <woboats@gmail.com> <boats@mozilla.com> Xinye Tao <xy.tao@outlook.com> diff --git a/Cargo.lock b/Cargo.lock index fc16ccf0a67..9fa1daf6546 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3204,9 +3204,11 @@ dependencies = [ "rand", "rand_xoshiro", "rustc_data_structures", + "rustc_feature", "rustc_index", "rustc_macros", "rustc_serialize", + "rustc_span", "tracing", ] @@ -3749,11 +3751,11 @@ dependencies = [ name = "rustc_hir_pretty" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_ast_pretty", "rustc_hir", "rustc_span", - "rustc_target", ] [[package]] @@ -3938,6 +3940,7 @@ dependencies = [ name = "rustc_lint_defs" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_data_structures", "rustc_error_messages", @@ -3945,7 +3948,6 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "rustc_target", "serde", ] @@ -4004,7 +4006,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_type_ir", - "snap", "tempfile", "tracing", ] @@ -4054,6 +4055,7 @@ version = "0.0.0" dependencies = [ "either", "itertools", + "rustc_abi", "rustc_apfloat", "rustc_arena", "rustc_ast", @@ -4069,7 +4071,6 @@ dependencies = [ "rustc_pattern_analysis", "rustc_session", "rustc_span", - "rustc_target", "rustc_trait_selection", "tracing", ] @@ -4890,12 +4891,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] name = "socket2" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 7448f066d0a..3acd25e5461 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -9,9 +9,11 @@ bitflags = "2.4.1" rand = { version = "0.8.4", default-features = false, optional = true } rand_xoshiro = { version = "0.6.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rustc_feature = { path = "../rustc_feature", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } +rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" # tidy-alphabetical-end @@ -22,8 +24,10 @@ default = ["nightly", "randomize"] # without depending on rustc_data_structures, rustc_macros and rustc_serialize nightly = [ "dep:rustc_data_structures", + "dep:rustc_feature", "dep:rustc_macros", "dep:rustc_serialize", + "dep:rustc_span", "rustc_index/nightly", ] randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"] diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_abi/src/extern_abi/mod.rs index c2095155afa..f7e41280131 100644 --- a/compiler/rustc_target/src/spec/abi/mod.rs +++ b/compiler/rustc_abi/src/extern_abi/mod.rs @@ -7,9 +7,11 @@ use rustc_span::{Span, Symbol}; #[cfg(test)] mod tests; +use ExternAbi as Abi; + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] #[derive(HashStable_Generic, Encodable, Decodable)] -pub enum Abi { +pub enum ExternAbi { // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the // hashing tests. These are used in many places, so giving them stable values reduces test // churn. The specific values are meaningless. diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs index 4823058dd69..4823058dd69 100644 --- a/compiler/rustc_target/src/spec/abi/tests.rs +++ b/compiler/rustc_abi/src/extern_abi/tests.rs diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index fac1122c4df..ec758785173 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", doc(rust_logo))] +#![cfg_attr(feature = "nightly", feature(assert_matches))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] @@ -28,8 +29,15 @@ mod layout; #[cfg(test)] mod tests; +#[cfg(feature = "nightly")] +mod extern_abi; + pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; #[cfg(feature = "nightly")] +pub use extern_abi::{ + AbiDisabled, AbiUnsupported, ExternAbi, all_names, enabled_names, is_enabled, is_stable, lookup, +}; +#[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; pub use layout::{LayoutCalculator, LayoutCalculatorError}; diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8e4f4c8e71a..ec6ca70ae0a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2810,6 +2810,8 @@ pub struct ModSpans { /// E.g., `extern { .. }` or `extern "C" { .. }`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct ForeignMod { + /// Span of the `extern` keyword. + pub extern_span: Span, /// `unsafe` keyword accepted syntactically for macro DSLs, but not /// semantically by Rust. pub safety: Safety, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2afbd979c30..44bb44cb728 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -525,7 +525,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) { } fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) { - let ForeignMod { safety, abi: _, items } = foreign_mod; + let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod; visit_safety(vis, safety); items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index eb71ec5f4ec..2f8115441de 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind { } ModKind::Unloaded => {} }, - ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => { + ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => { walk_list!(visitor, visit_foreign_item, items); } ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0a4f86d4822..dee48586f34 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -677,9 +677,8 @@ impl<'a> AstValidator<'a> { Self::check_decl_no_pat(&bfty.decl, |span, _, _| { self.dcx().emit_err(errors::PatternFnPointer { span }); }); - if let Extern::Implicit(_) = bfty.ext { - let sig_span = self.sess.source_map().next_point(ty.span.shrink_to_lo()); - self.maybe_lint_missing_abi(sig_span, ty.id); + if let Extern::Implicit(extern_span) = bfty.ext { + self.maybe_lint_missing_abi(extern_span, ty.id); } } TyKind::TraitObject(bounds, ..) => { @@ -953,7 +952,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } - ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => { + ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => { self.with_in_extern_mod(*safety, |this| { let old_item = mem::replace(&mut this.extern_mod, Some(item.span)); this.visibility_not_permitted( @@ -977,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } if abi.is_none() { - this.maybe_lint_missing_abi(item.span, item.id); + this.maybe_lint_missing_abi(*extern_span, item.id); } visit::walk_item(this, item); this.extern_mod = old_item; @@ -1350,13 +1349,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let FnKind::Fn( _, _, - FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit(_), .. }, .. }, + FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. }, _, _, _, ) = fk { - self.maybe_lint_missing_abi(*sig_span, id); + self.maybe_lint_missing_abi(*extern_span, id); } // Functions without bodies cannot have patterns. diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1bfb54a7bb7..511313cca6f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1525,7 +1525,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { matches!( adj.kind, ty::adjustment::Adjust::Borrow(ty::adjustment::AutoBorrow::Ref( - _, ty::adjustment::AutoBorrowMutability::Not | ty::adjustment::AutoBorrowMutability::Mut { allow_two_phase_borrow: ty::adjustment::AllowTwoPhase::No diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 602b1b98200..fc3bd0abd78 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -40,6 +40,7 @@ use std::sync::Arc; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::CodegenResults; +use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::ErrorGuaranteed; @@ -260,7 +261,9 @@ impl CodegenBackend for CraneliftCodegenBackend { } fn target_triple(sess: &Session) -> target_lexicon::Triple { - match sess.target.llvm_target.parse() { + // FIXME(madsmtm): Use `sess.target.llvm_target` once target-lexicon supports unversioned macOS. + // See <https://github.com/bytecodealliance/target-lexicon/pull/113> + match versioned_llvm_target(sess).parse() { Ok(triple) => triple, Err(err) => sess.dcx().fatal(format!("target not recognized: {}", err)), } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 2c5ec9dad59..64bb22e8cb2 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -232,11 +232,6 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { return None; } - // probestack doesn't play nice either with gcov profiling. - if cx.sess().opts.unstable_opts.profile { - return None; - } - let attr_value = match cx.sess().target.stack_probes { StackProbeType::None => return None, // Request LLVM to generate the probes inline. If the given LLVM version does not support diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bfa9e8b82a0..01e2c308ca4 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -9,6 +9,7 @@ use llvm::{ LLVMRustLLVMHasZlibCompressionForDebugSymbols, LLVMRustLLVMHasZstdCompressionForDebugSymbols, }; use rustc_codegen_ssa::back::link::ensure_removed; +use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, @@ -211,7 +212,7 @@ pub(crate) fn target_machine_factory( singlethread = false; } - let triple = SmallCStr::new(&sess.target.llvm_target); + let triple = SmallCStr::new(&versioned_llvm_target(sess)); let cpu = SmallCStr::new(llvm_util::target_cpu(sess)); let features = CString::new(target_features.join(",")).unwrap(); let abi = SmallCStr::new(&sess.target.llvm_abiname); @@ -591,7 +592,6 @@ pub(crate) unsafe fn llvm_optimize( pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.instrument_coverage, instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.instrument_gcov, pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.debug_info_for_profiling, llvm_selfprofiler, diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 9778ff4918c..03f4fb527a8 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell}; use std::ffi::{CStr, c_uint}; use std::str; +use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::traits::*; @@ -148,6 +149,11 @@ pub(crate) unsafe fn create_module<'ll>( target_data_layout = target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", ""); } + if sess.target.arch.starts_with("sparc") { + // LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit. + // See https://github.com/llvm/llvm-project/pull/106951 + target_data_layout = target_data_layout.replace("-i128:128", ""); + } } // Ensure the data-layout values hardcoded remain the defaults. @@ -177,7 +183,7 @@ pub(crate) unsafe fn create_module<'ll>( llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr()); } - let llvm_target = SmallCStr::new(&sess.target.llvm_target); + let llvm_target = SmallCStr::new(&versioned_llvm_target(sess)); unsafe { llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); } @@ -554,6 +560,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// Extra state that is only available when coverage instrumentation is enabled. #[inline] + #[track_caller] pub(crate) fn coverage_cx(&self) -> &coverageinfo::CrateCoverageContext<'ll, 'tcx> { self.coverage_cx.as_ref().expect("only called when coverage instrumentation is enabled") } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 8edd788ee36..f6378199fe2 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -54,7 +54,11 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { add_unused_functions(cx); } - let function_coverage_map = cx.coverage_cx().take_function_coverage_map(); + // FIXME(#132395): Can this be none even when coverage is enabled? + let function_coverage_map = match cx.coverage_cx { + Some(ref cx) => cx.take_function_coverage_map(), + None => return, + }; if function_coverage_map.is_empty() { // This module has no functions with coverage instrumentation return; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index a298ed86276..e4ff50816b9 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -152,7 +152,12 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { return; }; - let mut coverage_map = bx.coverage_cx().function_coverage_map.borrow_mut(); + // FIXME(#132395): Unwrapping `coverage_cx` here has led to ICEs in the + // wild, so keep this early-return until we understand why. + let mut coverage_map = match bx.coverage_cx { + Some(ref cx) => cx.function_coverage_map.borrow_mut(), + None => return, + }; let func_coverage = coverage_map .entry(instance) .or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info)); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 9064cfaeb29..0d1fd0163eb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -7,7 +7,6 @@ use std::{iter, ptr}; use libc::{c_char, c_longlong, c_uint}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; -use rustc_fs_util::path_to_c_string; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; @@ -979,33 +978,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( debug_name_table_kind, ); - if tcx.sess.opts.unstable_opts.profile { - let default_gcda_path = &output_filenames.with_extension("gcda"); - let gcda_path = - tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path); - - let gcov_cu_info = [ - path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")), - path_to_mdstring(debug_context.llcontext, gcda_path), - unit_metadata, - ]; - let gcov_metadata = llvm::LLVMMDNodeInContext2( - debug_context.llcontext, - gcov_cu_info.as_ptr(), - gcov_cu_info.len(), - ); - let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata); - - llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val); - } - return unit_metadata; }; - - fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata { - let path_str = path_to_c_string(path); - unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) } - } } /// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 72e723aa849..b6c20cdcf0c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -55,7 +55,6 @@ const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { - llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>, @@ -78,9 +77,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { debug!("CodegenUnitDebugContext::new"); let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; // DIBuilder inherits context from the module, so we'd better use the same one - let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; CodegenUnitDebugContext { - llcontext, llmod, builder, created_files: Default::default(), diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8fc586d2c8f..5fad7583e1a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2269,7 +2269,6 @@ unsafe extern "C" { PGOUsePath: *const c_char, InstrumentCoverage: bool, InstrProfileOutput: *const c_char, - InstrumentGCOV: bool, PGOSampleUsePath: *const c_char, DebugInfoForProfiling: bool, llvm_selfprofiler: *mut c_void, diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index d07274920fe..3b34eb063ec 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -2,6 +2,12 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not imp codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} +codegen_ssa_apple_deployment_target_invalid = + failed to parse deployment target specified in {$env_var}: {$error} + +codegen_ssa_apple_deployment_target_too_low = + deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min} + codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error} codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs new file mode 100644 index 00000000000..93d90cd16b2 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/back/apple.rs @@ -0,0 +1,171 @@ +use std::env; +use std::fmt::{Display, from_fn}; +use std::num::ParseIntError; + +use rustc_session::Session; +use rustc_target::spec::Target; + +use crate::errors::AppleDeploymentTarget; + +#[cfg(test)] +mod tests; + +pub(super) fn macho_platform(target: &Target) -> u32 { + match (&*target.os, &*target.abi) { + ("macos", _) => object::macho::PLATFORM_MACOS, + ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST, + ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR, + ("ios", _) => object::macho::PLATFORM_IOS, + ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR, + ("watchos", _) => object::macho::PLATFORM_WATCHOS, + ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR, + ("tvos", _) => object::macho::PLATFORM_TVOS, + ("visionos", "sim") => object::macho::PLATFORM_XROSSIMULATOR, + ("visionos", _) => object::macho::PLATFORM_XROS, + _ => unreachable!("tried to get Mach-O platform for non-Apple target"), + } +} + +/// Deployment target or SDK version. +/// +/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`. +type OSVersion = (u16, u8, u8); + +/// Parse an OS version triple (SDK version or deployment target). +fn parse_version(version: &str) -> Result<OSVersion, ParseIntError> { + if let Some((major, minor)) = version.split_once('.') { + let major = major.parse()?; + if let Some((minor, patch)) = minor.split_once('.') { + Ok((major, minor.parse()?, patch.parse()?)) + } else { + Ok((major, minor.parse()?, 0)) + } + } else { + Ok((version.parse()?, 0, 0)) + } +} + +pub fn pretty_version(version: OSVersion) -> impl Display { + let (major, minor, patch) = version; + from_fn(move |f| { + write!(f, "{major}.{minor}")?; + if patch != 0 { + write!(f, ".{patch}")?; + } + Ok(()) + }) +} + +/// Minimum operating system versions currently supported by `rustc`. +fn os_minimum_deployment_target(os: &str) -> OSVersion { + // When bumping a version in here, remember to update the platform-support docs too. + // + // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the + // default deployment target, prefer: + // ``` + // $ rustc --print deployment-target + // ``` + match os { + "macos" => (10, 12, 0), + "ios" => (10, 0, 0), + "tvos" => (10, 0, 0), + "watchos" => (5, 0, 0), + "visionos" => (1, 0, 0), + _ => unreachable!("tried to get deployment target for non-Apple platform"), + } +} + +/// The deployment target for the given target. +/// +/// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense +/// to raise the minimum OS version. +/// +/// This matches what LLVM does, see in part: +/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932> +fn minimum_deployment_target(target: &Target) -> OSVersion { + match (&*target.os, &*target.arch, &*target.abi) { + ("macos", "aarch64", _) => (11, 0, 0), + ("ios", "aarch64", "macabi") => (14, 0, 0), + ("ios", "aarch64", "sim") => (14, 0, 0), + ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0), + // Mac Catalyst defaults to 13.1 in Clang. + ("ios", _, "macabi") => (13, 1, 0), + ("tvos", "aarch64", "sim") => (14, 0, 0), + ("watchos", "aarch64", "sim") => (7, 0, 0), + (os, _, _) => os_minimum_deployment_target(os), + } +} + +/// Name of the environment variable used to fetch the deployment target on the given OS. +fn deployment_target_env_var(os: &str) -> &'static str { + match os { + "macos" => "MACOSX_DEPLOYMENT_TARGET", + "ios" => "IPHONEOS_DEPLOYMENT_TARGET", + "watchos" => "WATCHOS_DEPLOYMENT_TARGET", + "tvos" => "TVOS_DEPLOYMENT_TARGET", + "visionos" => "XROS_DEPLOYMENT_TARGET", + _ => unreachable!("tried to get deployment target env var for non-Apple platform"), + } +} + +/// Get the deployment target based on the standard environment variables, or fall back to the +/// minimum version supported by `rustc`. +pub fn deployment_target(sess: &Session) -> OSVersion { + let min = minimum_deployment_target(&sess.target); + let env_var = deployment_target_env_var(&sess.target.os); + + if let Ok(deployment_target) = env::var(env_var) { + match parse_version(&deployment_target) { + Ok(version) => { + let os_min = os_minimum_deployment_target(&sess.target.os); + // It is common that the deployment target is set a bit too low, for example on + // macOS Aarch64 to also target older x86_64. So we only want to warn when variable + // is lower than the minimum OS supported by rustc, not when the variable is lower + // than the minimum for a specific target. + if version < os_min { + sess.dcx().emit_warn(AppleDeploymentTarget::TooLow { + env_var, + version: pretty_version(version).to_string(), + os_min: pretty_version(os_min).to_string(), + }); + } + + // Raise the deployment target to the minimum supported. + version.max(min) + } + Err(error) => { + sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error }); + min + } + } + } else { + // If no deployment target variable is set, default to the minimum found above. + min + } +} + +pub(super) fn add_version_to_llvm_target( + llvm_target: &str, + deployment_target: OSVersion, +) -> String { + let mut components = llvm_target.split("-"); + let arch = components.next().expect("apple target should have arch"); + let vendor = components.next().expect("apple target should have vendor"); + let os = components.next().expect("apple target should have os"); + let environment = components.next(); + assert_eq!(components.next(), None, "too many LLVM triple components"); + + let (major, minor, patch) = deployment_target; + + assert!( + !os.contains(|c: char| c.is_ascii_digit()), + "LLVM target must not already be versioned" + ); + + if let Some(env) = environment { + // Insert version into OS, before environment + format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}-{env}") + } else { + format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}") + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/apple/tests.rs b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs new file mode 100644 index 00000000000..7ccda5a8190 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs @@ -0,0 +1,21 @@ +use super::{add_version_to_llvm_target, parse_version}; + +#[test] +fn test_add_version_to_llvm_target() { + assert_eq!( + add_version_to_llvm_target("aarch64-apple-macosx", (10, 14, 1)), + "aarch64-apple-macosx10.14.1" + ); + assert_eq!( + add_version_to_llvm_target("aarch64-apple-ios-simulator", (16, 1, 0)), + "aarch64-apple-ios16.1.0-simulator" + ); +} + +#[test] +fn test_parse_version() { + assert_eq!(parse_version("10"), Ok((10, 0, 0))); + assert_eq!(parse_version("10.12"), Ok((10, 12, 0))); + assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6))); + assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99))); +} diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 34dc599e4fd..b01a62b394b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -40,7 +40,7 @@ use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, - SplitDebuginfo, current_apple_deployment_target, + SplitDebuginfo, }; use tempfile::Builder as TempFileBuilder; use tracing::{debug, info, warn}; @@ -50,6 +50,7 @@ use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{MetadataPosition, create_wrapper_file}; use super::rpath::{self, RPathConfig}; +use super::{apple, versioned_llvm_target}; use crate::{ CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors, looks_like_rust_object_file, @@ -2447,7 +2448,7 @@ fn add_order_independent_options( if flavor == LinkerFlavor::Llbc { cmd.link_args(&[ "--target", - sess.target.llvm_target.as_ref(), + &versioned_llvm_target(sess), "--target-cpu", &codegen_results.crate_info.target_cpu, ]); @@ -3039,7 +3040,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo _ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"), }; - let (major, minor, patch) = current_apple_deployment_target(&sess.target); + let (major, minor, patch) = apple::deployment_target(sess); let min_version = format!("{major}.{minor}.{patch}"); // The SDK version is used at runtime when compiling with a newer SDK / version of Xcode: @@ -3109,7 +3110,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // The presence of `-mmacosx-version-min` makes CC default to // macOS, and it sets the deployment target. - let (major, minor, patch) = current_apple_deployment_target(&sess.target); + let (major, minor, patch) = apple::deployment_target(sess); // Intentionally pass this as a single argument, Clang doesn't // seem to like it otherwise. cmd.cc_arg(&format!("-mmacosx-version-min={major}.{minor}.{patch}")); @@ -3119,7 +3120,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo // // We avoid `-m32`/`-m64`, as this is already encoded by `-arch`. } else { - cmd.cc_args(&["-target", &sess.target.llvm_target]); + cmd.cc_args(&["-target", &versioned_llvm_target(sess)]); } } } @@ -3345,7 +3346,7 @@ fn add_lld_args( // targeting a different linker flavor on macOS, and that's also always // the case when targeting WASM. if sess.target.linker_flavor != sess.host.linker_flavor { - cmd.cc_arg(format!("--target={}", sess.target.llvm_target)); + cmd.cc_arg(format!("--target={}", versioned_llvm_target(sess))); } } } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 8857fda1e97..a7d95d56784 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -22,6 +22,8 @@ use rustc_span::sym; use rustc_target::abi::Endian; use rustc_target::spec::{RelocModel, Target, ef_avr_arch}; +use super::apple; + /// The default metadata loader. This is used by cg_llvm and cg_clif. /// /// # Metadata location @@ -238,7 +240,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static file.set_macho_cpu_subtype(object::macho::CPU_SUBTYPE_ARM64E); } - file.set_macho_build_version(macho_object_build_version_for_target(&sess.target)) + file.set_macho_build_version(macho_object_build_version_for_target(sess)) } if binary_format == BinaryFormat::Coff { // Disable the default mangler to avoid mangling the special "@feat.00" symbol name. @@ -322,10 +324,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static // Set the appropriate flag based on ABI // This needs to match LLVM `RISCVELFStreamer.cpp` match &*sess.target.llvm_abiname { - "" | "ilp32" | "lp64" => (), + "ilp32" | "lp64" => (), "ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE, "ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE, - "ilp32e" => e_flags |= elf::EF_RISCV_RVE, + // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. + "ilp32e" | "lp64e" => e_flags |= elf::EF_RISCV_RVE, _ => bug!("unknown RISC-V ABI name"), } @@ -391,7 +394,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static /// /// Since Xcode 15, Apple's LD apparently requires object files to use this load command, so this /// returns the `MachOBuildVersion` for the target to do so. -fn macho_object_build_version_for_target(target: &Target) -> object::write::MachOBuildVersion { +fn macho_object_build_version_for_target(sess: &Session) -> object::write::MachOBuildVersion { /// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz" /// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200 fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 { @@ -399,9 +402,8 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach (major << 16) | (minor << 8) | patch } - let platform = - rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS"); - let min_os = rustc_target::spec::current_apple_deployment_target(target); + let platform = apple::macho_platform(&sess.target); + let min_os = apple::deployment_target(sess); let mut build_version = object::write::MachOBuildVersion::default(); build_version.platform = platform; diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs index 2b3a2e3a369..64b5d4569ec 100644 --- a/compiler/rustc_codegen_ssa/src/back/mod.rs +++ b/compiler/rustc_codegen_ssa/src/back/mod.rs @@ -1,3 +1,8 @@ +use std::borrow::Cow; + +use rustc_session::Session; + +pub mod apple; pub mod archive; pub(crate) mod command; pub mod link; @@ -7,3 +12,19 @@ pub mod metadata; pub(crate) mod rpath; pub mod symbol_export; pub mod write; + +/// The target triple depends on the deployment target, and is required to +/// enable features such as cross-language LTO, and for picking the right +/// Mach-O commands. +/// +/// Certain optimizations also depend on the deployment target. +pub fn versioned_llvm_target(sess: &Session) -> Cow<'_, str> { + if sess.target.is_like_osx { + apple::add_version_to_llvm_target(&sess.target.llvm_target, apple::deployment_target(sess)) + .into() + } else { + // FIXME(madsmtm): Certain other targets also include a version, + // we might want to move that here as well. + Cow::Borrowed(&sess.target.llvm_target) + } +} diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 8445d16befb..d977cca247e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -90,7 +90,6 @@ pub struct ModuleConfig { pub pgo_sample_use: Option<PathBuf>, pub debug_info_for_profiling: bool, pub instrument_coverage: bool, - pub instrument_gcov: bool, pub sanitizer: SanitizerSet, pub sanitizer_recover: SanitizerSet, @@ -123,12 +122,7 @@ pub struct ModuleConfig { } impl ModuleConfig { - fn new( - kind: ModuleKind, - tcx: TyCtxt<'_>, - no_builtins: bool, - is_compiler_builtins: bool, - ) -> ModuleConfig { + fn new(kind: ModuleKind, tcx: TyCtxt<'_>, no_builtins: bool) -> ModuleConfig { // If it's a regular module, use `$regular`, otherwise use `$other`. // `$regular` and `$other` are evaluated lazily. macro_rules! if_regular { @@ -189,13 +183,6 @@ impl ModuleConfig { pgo_sample_use: if_regular!(sess.opts.unstable_opts.profile_sample_use.clone(), None), debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling, instrument_coverage: if_regular!(sess.instrument_coverage(), false), - instrument_gcov: if_regular!( - // compiler_builtins overrides the codegen-units settings, - // which is incompatible with -Zprofile which requires that - // only a single codegen unit is used per crate. - sess.opts.unstable_opts.profile && !is_compiler_builtins, - false - ), sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()), sanitizer_dataflow_abilist: if_regular!( @@ -473,16 +460,12 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>( let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); - let is_compiler_builtins = attr::contains_name(crate_attrs, sym::compiler_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); - let regular_config = - ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins); - let metadata_config = - ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins); - let allocator_config = - ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins); + let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins); + let metadata_config = ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins); + let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins); let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); let (codegen_worker_send, codegen_worker_receive) = channel(); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index d67cf0e3a6d..cf8d1cfa0d1 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::io::Error; +use std::num::ParseIntError; use std::path::{Path, PathBuf}; use std::process::ExitStatus; @@ -540,6 +541,14 @@ pub(crate) struct UnsupportedArch<'a> { } #[derive(Diagnostic)] +pub(crate) enum AppleDeploymentTarget { + #[diag(codegen_ssa_apple_deployment_target_invalid)] + Invalid { env_var: &'static str, error: ParseIntError }, + #[diag(codegen_ssa_apple_deployment_target_too_low)] + TooLow { env_var: &'static str, version: String, os_min: String }, +} + +#[derive(Diagnostic)] pub(crate) enum AppleSdkRootError<'a> { #[diag(codegen_ssa_apple_sdk_error_sdk_path)] SdkPath { sdk_name: &'a str, error: Error }, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 73bfa9dbd10..7dc8ab38a97 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -6,6 +6,7 @@ #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(debug_closure_helpers)] #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 5210241d5e4..303c490d827 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -11,18 +11,19 @@ use rustc_hir::def_id::DefId; use rustc_hir::{self as hir, LangItem}; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::ObligationCause; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_span::{Span, Symbol, sym}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; -use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; +use rustc_trait_selection::traits::{ + Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt, +}; use tracing::{debug, instrument, trace}; use super::ops::{self, NonConstOp, Status}; @@ -360,6 +361,73 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // end of evaluation. !is_transient } + + fn revalidate_conditional_constness( + &mut self, + callee: DefId, + callee_args: ty::GenericArgsRef<'tcx>, + call_source: CallSource, + call_span: Span, + ) { + let tcx = self.tcx; + if !tcx.is_conditionally_const(callee) { + return; + } + + let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args); + // If there are any const conditions on this fn and `const_trait_impl` + // is not enabled, simply bail. We shouldn't be able to call conditionally + // const functions on stable. + if !const_conditions.is_empty() && !tcx.features().const_trait_impl() { + self.check_op(ops::FnCallNonConst { + callee, + args: callee_args, + span: call_span, + call_source, + feature: Some(sym::const_trait_impl), + }); + return; + } + + let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx)); + let ocx = ObligationCtxt::new_with_diagnostics(&infcx); + + let body_id = self.body.source.def_id().expect_local(); + let host_polarity = match self.const_kind() { + hir::ConstContext::ConstFn => ty::BoundConstness::Maybe, + hir::ConstContext::Static(_) | hir::ConstContext::Const { .. } => { + ty::BoundConstness::Const + } + }; + let const_conditions = ocx.normalize( + &ObligationCause::misc(call_span, body_id), + self.param_env, + const_conditions, + ); + ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| { + Obligation::new( + tcx, + ObligationCause::new( + call_span, + body_id, + ObligationCauseCode::WhereClause(callee, span), + ), + self.param_env, + trait_ref.to_host_effect_clause(tcx, host_polarity), + ) + })); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + // FIXME(effects): Soon this should be unconditionally delaying a bug. + if matches!(call_source, CallSource::Normal) && tcx.features().effects() { + tcx.dcx() + .span_delayed_bug(call_span, "this should have reported a ~const error in HIR"); + } else { + infcx.err_ctxt().report_fulfillment_errors(errors); + } + } + } } impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { @@ -566,7 +634,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { }; let ConstCx { tcx, body, param_env, .. } = *self.ccx; - let caller = self.def_id(); let fn_ty = func.ty(body, tcx); @@ -584,31 +651,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } }; - // Check that all trait bounds that are marked as `~const` can be satisfied. - // - // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish - // which path expressions are getting called on and which path expressions are only used - // as function pointers. This is required for correctness. - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); - let ocx = ObligationCtxt::new_with_diagnostics(&infcx); - - let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args); - let cause = ObligationCause::new( - terminator.source_info.span, - self.body.source.def_id().expect_local(), - ObligationCauseCode::WhereClause(callee, DUMMY_SP), - ); - let normalized_predicates = ocx.normalize(&cause, param_env, predicates); - ocx.register_obligations(traits::predicates_for_generics( - |_, _| cause.clone(), - self.param_env, - normalized_predicates, - )); - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(errors); - } + self.revalidate_conditional_constness(callee, fn_args, call_source, *fn_span); let mut is_trait = false; // Attempting to call a trait method? @@ -648,7 +691,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { None }; self.check_op(ops::FnCallNonConst { - caller, callee, args: fn_args, span: *fn_span, @@ -738,7 +780,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Trait functions are not `const fn` so we have to skip them here. if !tcx.is_const_fn(callee) && !is_trait { self.check_op(ops::FnCallNonConst { - caller, callee, args: fn_args, span: *fn_span, diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 56da6791847..dcdaafaecc2 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -32,14 +32,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self { let def_id = body.source.def_id().expect_local(); let param_env = tcx.param_env(def_id); - Self::new_with_param_env(tcx, body, param_env) - } - pub fn new_with_param_env( - tcx: TyCtxt<'tcx>, - body: &'mir mir::Body<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local()); ConstCx { body, tcx, param_env, const_kind } } diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 3f977dc4b05..ce36701a942 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -1,6 +1,5 @@ //! Concrete error types for all operations which may be invalid in a certain const context. -use hir::def_id::LocalDefId; use hir::{ConstContext, LangItem}; use rustc_errors::Diag; use rustc_errors::codes::*; @@ -12,7 +11,7 @@ use rustc_middle::mir::CallSource; use rustc_middle::span_bug; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, TypingMode, + self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, suggest_constraining_type_param, }; use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind}; @@ -74,7 +73,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect { /// A function call where the callee is not marked as `const`. #[derive(Debug, Clone, Copy)] pub(crate) struct FnCallNonConst<'tcx> { - pub caller: LocalDefId, pub callee: DefId, pub args: GenericArgsRef<'tcx>, pub span: Span, @@ -87,8 +85,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> { - let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self; - let ConstCx { tcx, param_env, body, .. } = *ccx; + let FnCallNonConst { callee, args, span, call_source, feature } = *self; + let ConstCx { tcx, param_env, .. } = *ccx; + let caller = ccx.def_id(); let diag_trait = |err, self_ty: Ty<'_>, trait_id| { let trait_ref = TraitRef::from_method(tcx, trait_id, args); @@ -116,7 +115,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let implsrc = selcx.select(&obligation); @@ -289,7 +288,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { if let Some(feature) = feature { ccx.tcx.disabled_nightly_features( &mut err, - body.source.def_id().as_local().map(|local| ccx.tcx.local_def_id_to_hir_id(local)), + Some(ccx.tcx.local_def_id_to_hir_id(caller)), [(String::new(), feature)], ); } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d81368e9fcc..9043bd3e28e 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -3,7 +3,7 @@ use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::at::ToTrace; -use rustc_infer::traits::ObligationCause; +use rustc_infer::traits::{ObligationCause, Reveal}; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ @@ -116,6 +116,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { /// This test should be symmetric, as it is primarily about layout compatibility. pub(super) fn mir_assign_valid_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, src: TyAndLayout<'tcx>, dest: TyAndLayout<'tcx>, @@ -124,7 +125,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. - if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) { + if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when @@ -144,6 +145,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( #[cfg_attr(not(debug_assertions), inline(always))] pub(super) fn from_known_layout<'tcx>( tcx: TyCtxtAt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, known_layout: Option<TyAndLayout<'tcx>>, compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>, @@ -153,7 +155,13 @@ pub(super) fn from_known_layout<'tcx>( Some(known_layout) => { if cfg!(debug_assertions) { let check_layout = compute()?; - if !mir_assign_valid_types(tcx.tcx, param_env, check_layout, known_layout) { + if !mir_assign_valid_types( + tcx.tcx, + typing_mode, + param_env, + check_layout, + known_layout, + ) { span_bug!( tcx.span, "expected type differs from actual type.\nexpected: {}\nactual: {}", @@ -203,6 +211,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + pub fn typing_mode(&self) -> TypingMode<'tcx> { + debug_assert_eq!(self.param_env.reveal(), Reveal::All); + TypingMode::PostAnalysis + } + /// Returns the span of the currently executed statement/terminator. /// This is the span typically used for error reporting. #[inline(always)] @@ -327,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return true; } // Slow path: spin up an inference context to check if these traits are sufficiently equal. - let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env)); + let infcx = self.tcx.infer_ctxt().build(self.typing_mode()); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy_with_span(self.cur_span()); // equate the two trait refs after normalization diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 43ae98e74b0..a130ae89bcb 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -773,6 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { )?; if !mir_assign_valid_types( *self.tcx, + self.typing_mode(), self.param_env, self.layout_of(normalized_place_ty)?, op.layout, @@ -832,7 +833,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }) }; let layout = - from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty).into())?; + from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { + self.layout_of(ty).into() + })?; let imm = match val_val { mir::ConstValue::Indirect { alloc_id, offset } => { // This is const data, no mutation allowed. diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 139a1db60e0..cc8d1db6cfb 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -540,6 +540,7 @@ where )?; if !mir_assign_valid_types( *self.tcx, + self.typing_mode(), self.param_env, self.layout_of(normalized_place_ty)?, place.layout, @@ -870,8 +871,13 @@ where ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. - let layout_compat = - mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout()); + let layout_compat = mir_assign_valid_types( + *self.tcx, + self.typing_mode(), + self.param_env, + src.layout(), + dest.layout(), + ); if !allow_transmute && !layout_compat { span_bug!( self.cur_span(), diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 3bc9f46aea0..50c0446b3cd 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -596,12 +596,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return interp_ok(layout); } - let layout = from_known_layout(self.tcx, self.param_env, layout, || { - let local_ty = frame.body.local_decls[local].ty; - let local_ty = - self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; - self.layout_of(local_ty).into() - })?; + let layout = + from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { + let local_ty = frame.body.local_decls[local].ty; + let local_ty = + self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; + self.layout_of(local_ty).into() + })?; // Layouts of locals are requested a lot, so we cache them. state.layout.set(Some(layout)); diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 7af977bab4d..0cf27d30c36 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -8,24 +8,15 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance}; use rustc_trait_selection::traits::ObligationCtxt; -/// Returns whether the two types are equal up to subtyping. -/// -/// This is used in case we don't know the expected subtyping direction -/// and still want to check whether anything is broken. -pub fn is_equal_up_to_subtyping<'tcx>( +/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. +pub fn sub_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, src: Ty<'tcx>, dest: Ty<'tcx>, ) -> bool { - // Fast path. - if src == dest { - return true; - } - - // Check for subtyping in either direction. - relate_types(tcx, param_env, Variance::Covariant, src, dest) - || relate_types(tcx, param_env, Variance::Covariant, dest, src) + relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest) } /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. @@ -35,6 +26,7 @@ pub fn is_equal_up_to_subtyping<'tcx>( /// because we want to check for type equality. pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, variance: Variance, src: Ty<'tcx>, @@ -45,8 +37,7 @@ pub fn relate_types<'tcx>( } let mut builder = tcx.infer_ctxt().ignoring_regions(); - // FIXME(#132279): This should eventually use the already defined hidden types. - let infcx = builder.build(TypingMode::from_param_env(param_env)); + let infcx = builder.build(typing_mode); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); let src = ocx.normalize(&cause, param_env, src); diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 66a1addfb52..25a9dbb2c11 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -8,7 +8,7 @@ mod type_name; pub use self::alignment::{is_disaligned, is_within_packed}; pub use self::check_validity_requirement::check_validity_requirement; -pub use self::compare_types::{is_equal_up_to_subtyping, relate_types}; +pub use self::compare_types::{relate_types, sub_types}; pub use self::type_name::type_name; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index e2585c02388..92b622fccf2 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -33,6 +33,7 @@ use std::time::{Instant, SystemTime}; use std::{env, str}; use rustc_ast as ast; +use rustc_codegen_ssa::back::apple; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{ @@ -855,12 +856,11 @@ fn print_crate_info( } } DeploymentTarget => { - use rustc_target::spec::current_apple_deployment_target; - if sess.target.is_like_osx { - let (major, minor, patch) = current_apple_deployment_target(&sess.target); - let patch = if patch != 0 { format!(".{patch}") } else { String::new() }; - println_info!("deployment_target={major}.{minor}{patch}") + println_info!( + "deployment_target={}", + apple::pretty_version(apple::deployment_target(sess)) + ) } else { #[allow(rustc::diagnostic_outside_of_impl)] sess.dcx().fatal("only Apple targets currently support deployment version info") diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index da779a16569..0b81f469371 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -43,7 +43,7 @@ fn associated_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); } @@ -122,7 +122,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( PredicateFilter::SelfOnly => { return None; } - PredicateFilter::SelfThatDefines(_) + PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst | PredicateFilter::SelfAndAssociatedTypeBounds | PredicateFilter::ConstIfConst => { @@ -329,7 +329,7 @@ fn opaque_type_bounds<'tcx>( match filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { // Associated types are implicitly sized unless a `?Sized` bound is found icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span); diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index efe84e0006f..7ce12d48160 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -557,7 +557,11 @@ pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>( tcx: TyCtxt<'tcx>, (trait_def_id, assoc_name): (DefId, Ident), ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> { - implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name)) + implied_predicates_with_filter( + tcx, + trait_def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + ) } pub(super) fn explicit_implied_predicates_of<'tcx>( @@ -586,7 +590,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let Some(trait_def_id) = trait_def_id.as_local() else { // if `assoc_name` is None, then the query should've been redirected to an // external provider - assert_matches!(filter, PredicateFilter::SelfThatDefines(_)); + assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_)); return tcx.explicit_super_predicates_of(trait_def_id); }; @@ -606,12 +610,8 @@ pub(super) fn implied_predicates_with_filter<'tcx>( let mut bounds = Bounds::default(); icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter); - let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics( - generics, - item.owner_id.def_id, - self_param_ty, - filter, - ); + let where_bounds_that_match = + icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter); // Combine the two lists to form the complete set of superbounds: let implied_bounds = @@ -652,7 +652,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>( } // Make sure when elaborating supertraits, probing for associated types, etc., -// we really truly are elaborating clauses that have `Self` as their self type. +// we really truly are elaborating clauses that have `ty` as their self type. // This is very important since downstream code relies on this being correct. pub(super) fn assert_only_contains_predicates_from<'tcx>( filter: PredicateFilter, @@ -664,7 +664,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } match filter { - PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => { + PredicateFilter::SelfOnly => { for (clause, _) in bounds { match clause.kind().skip_binder() { ty::ClauseKind::Trait(trait_predicate) => { @@ -704,6 +704,33 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>( } } } + PredicateFilter::SelfTraitThatDefines(_) => { + for (clause, _) in bounds { + match clause.kind().skip_binder() { + ty::ClauseKind::Trait(trait_predicate) => { + assert_eq!( + trait_predicate.self_ty(), + ty, + "expected `Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + + ty::ClauseKind::Projection(_) + | ty::ClauseKind::TypeOutlives(_) + | ty::ClauseKind::RegionOutlives(_) + | ty::ClauseKind::ConstArgHasType(_, _) + | ty::ClauseKind::WellFormed(_) + | ty::ClauseKind::ConstEvaluatable(_) + | ty::ClauseKind::HostEffect(..) => { + bug!( + "unexpected non-`Self` predicate when computing \ + `{filter:?}` implied bounds: {clause:?}" + ); + } + } + } + } PredicateFilter::ConstIfConst => { for (clause, _) in bounds { match clause.kind().skip_binder() { @@ -767,21 +794,16 @@ pub(super) fn type_param_predicates<'tcx>( None => {} } - use rustc_hir::*; - use rustc_middle::ty::Ty; - // In the HIR, bounds can derive from two places. Either // written inline like `<T: Foo>` or in a where-clause like // `where T: Foo`. let param_id = tcx.local_def_id_to_hir_id(def_id); let param_owner = tcx.hir().ty_param_owner(def_id); - let generics = tcx.generics_of(param_owner); - let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - let ty = Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id)); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner { + // FIXME: Shouldn't this be unreachable? None } else { tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local()) @@ -801,8 +823,9 @@ pub(super) fn type_param_predicates<'tcx>( let Some(hir_generics) = hir_node.generics() else { return result; }; + if let Node::Item(item) = hir_node - && let ItemKind::Trait(..) = item.kind + && let hir::ItemKind::Trait(..) = item.kind // Implied `Self: Trait` and supertrait bounds. && param_id == item_hir_id { @@ -811,23 +834,34 @@ pub(super) fn type_param_predicates<'tcx>( } let icx = ItemCtxt::new(tcx, item_def_id); - let extra_predicates = extend.into_iter().chain( - icx.probe_ty_param_bounds_in_generics( - hir_generics, - def_id, - ty, - PredicateFilter::SelfThatDefines(assoc_name), - ) - .into_iter() - .filter(|(predicate, _)| match predicate.kind().skip_binder() { - ty::ClauseKind::Trait(data) => data.self_ty().is_param(index), - _ => false, - }), + let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics( + hir_generics, + def_id, + PredicateFilter::SelfTraitThatDefines(assoc_name), + )); + + let bounds = + &*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)); + + // Double check that the bounds *only* contain `SelfTy: Trait` preds. + let self_ty = match tcx.def_kind(def_id) { + DefKind::TyParam => Ty::new_param( + tcx, + tcx.generics_of(item_def_id) + .param_def_id_to_index(tcx, def_id.to_def_id()) + .expect("expected generic param to be owned by item"), + tcx.item_name(def_id.to_def_id()), + ), + DefKind::Trait | DefKind::TraitAlias => tcx.types.self_param, + _ => unreachable!(), + }; + assert_only_contains_predicates_from( + PredicateFilter::SelfTraitThatDefines(assoc_name), + bounds, + self_ty, ); - ty::EarlyBinder::bind( - tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)), - ) + ty::EarlyBinder::bind(bounds) } impl<'tcx> ItemCtxt<'tcx> { @@ -841,7 +875,6 @@ impl<'tcx> ItemCtxt<'tcx> { &self, hir_generics: &'tcx hir::Generics<'tcx>, param_def_id: LocalDefId, - ty: Ty<'tcx>, filter: PredicateFilter, ) -> Vec<(ty::Clause<'tcx>, Span)> { let mut bounds = Bounds::default(); @@ -851,13 +884,21 @@ impl<'tcx> ItemCtxt<'tcx> { continue; }; - let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) { - ty - } else if matches!(filter, PredicateFilter::All) { - self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty) - } else { - continue; - }; + match filter { + _ if predicate.is_param_bound(param_def_id.to_def_id()) => { + // Ok + } + PredicateFilter::All => { + // Ok + } + PredicateFilter::SelfOnly + | PredicateFilter::SelfTraitThatDefines(_) + | PredicateFilter::SelfConstIfConst + | PredicateFilter::SelfAndAssociatedTypeBounds => continue, + PredicateFilter::ConstIfConst => unreachable!(), + } + + let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty); let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); self.lowerer().lower_bounds( diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 9483439ae4e..dc3ef9952f0 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -571,17 +571,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { // We list scopes outwards, this causes us to see lifetime parameters in reverse // declaration order. In order to make it consistent with what `generics_of` might // give, we will reverse the IndexMap after early captures. + let mut late_depth = 0; let mut scope = self.scope; + let mut crossed_late_boundary = None; let mut opaque_capture_scopes = vec![(opaque.def_id, &captures)]; loop { match *scope { - Scope::Binder { ref bound_vars, s, .. } => { + Scope::Binder { ref bound_vars, scope_type, s, .. } => { for (&original_lifetime, &def) in bound_vars.iter().rev() { + if let ResolvedArg::LateBound(..) = def + && crossed_late_boundary.is_some() + { + continue; + } if let DefKind::LifetimeParam = self.tcx.def_kind(original_lifetime) { + let def = def.shifted(late_depth); let ident = lifetime_ident(original_lifetime); self.remap_opaque_captures(&opaque_capture_scopes, def, ident); } } + match scope_type { + BinderScopeType::Normal => late_depth += 1, + BinderScopeType::Concatenating => {} + } scope = s; } @@ -602,6 +614,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { Scope::Opaque { captures, def_id, s } => { opaque_capture_scopes.push((def_id, captures)); + late_depth = 0; scope = s; } @@ -611,8 +624,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } - | Scope::LateBoundary { s, .. } => { + | Scope::TraitRefBoundary { s, .. } => { + scope = s; + } + + Scope::LateBoundary { s, what, .. } => { + crossed_late_boundary = Some(what); scope = s; } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a5709089db6..85ba88333f9 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -152,9 +152,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 'tcx: 'hir, { for hir_bound in hir_bounds { - // In order to avoid cycles, when we're lowering `SelfThatDefines`, + // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`, // we skip over any traits that don't define the given associated type. - if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter { + if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter { if let Some(trait_ref) = hir_bound.trait_ref() && let Some(trait_did) = trait_ref.trait_def_id() && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name) @@ -168,12 +168,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match hir_bound { hir::GenericBound::Trait(poly_trait_ref) => { let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers; - let polarity = match polarity { - rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, - rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, - rustc_ast::BoundPolarity::Maybe(_) => continue, - }; - let _ = self.lower_poly_trait_ref( &poly_trait_ref.trait_ref, poly_trait_ref.span, @@ -395,7 +389,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) | PredicateFilter::SelfAndAssociatedTypeBounds => { bounds.push_projection_bound( tcx, @@ -406,6 +399,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { constraint.span, ); } + // SelfTraitThatDefines is only interested in trait predicates. + PredicateFilter::SelfTraitThatDefines(_) => {} // `ConstIfConst` is only interested in `~const` bounds. PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {} } @@ -432,7 +427,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); } PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(_) + | PredicateFilter::SelfTraitThatDefines(_) | PredicateFilter::SelfConstIfConst => {} } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 46a5cbb0af4..5e27ace4cbe 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &trait_bound.trait_ref, trait_bound.span, hir::BoundConstness::Never, - ty::PredicatePolarity::Positive, + hir::BoundPolarity::Positive, dummy_self, &mut bounds, PredicateFilter::SelfOnly, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d70e4d8345a..fb23ad1b248 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -76,7 +76,7 @@ pub enum PredicateFilter { /// Only traits that reference `Self: ..` and define an associated type /// with the given ident are implied by the trait. This mode exists to /// side-step query cycles when lowering associated types. - SelfThatDefines(Ident), + SelfTraitThatDefines(Ident), /// Only traits that reference `Self: ..` and their associated type bounds. /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr` @@ -668,7 +668,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref: &hir::TraitRef<'tcx>, span: Span, constness: hir::BoundConstness, - polarity: ty::PredicatePolarity, + polarity: hir::BoundPolarity, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, predicate_filter: PredicateFilter, @@ -690,15 +690,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), ); - if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness - && !self.tcx().is_const_trait(trait_def_id) - { - self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { - span, - modifier: constness.as_str(), - }); - } - let tcx = self.tcx(); let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); debug!(?bound_vars); @@ -708,10 +699,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_vars, ); + let polarity = match polarity { + rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, + rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, + rustc_ast::BoundPolarity::Maybe(_) => { + // Validate associated type at least. We may want to reject these + // outright in the future... + for constraint in trait_segment.args().constraints { + let _ = self.lower_assoc_item_constraint( + trait_ref.hir_ref_id, + poly_trait_ref, + constraint, + &mut Default::default(), + &mut Default::default(), + constraint.span, + predicate_filter, + ); + } + return arg_count; + } + }; + + if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness + && !self.tcx().is_const_trait(trait_def_id) + { + self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait { + span, + modifier: constness.as_str(), + }); + } + match predicate_filter { + // This is only concerned with trait predicates. + PredicateFilter::SelfTraitThatDefines(..) => { + bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); + } PredicateFilter::All | PredicateFilter::SelfOnly - | PredicateFilter::SelfThatDefines(..) | PredicateFilter::SelfAndAssociatedTypeBounds => { debug!(?poly_trait_ref); bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); @@ -763,11 +787,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // since we should have emitted an error for them earlier, and they // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { - assert!( - self.dcx().has_errors().is_some(), + self.dcx().span_delayed_bug( + constraint.span, "negative trait bounds should not have assoc item constraints", ); - continue; + break; } // Specify type to assert that error was already reported in `Err` case. diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index aacf41b6eb7..9af1fb8279e 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -5,9 +5,9 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } # tidy-alphabetical-end diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2073f2868b4..0a3aa8fec90 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -9,6 +9,7 @@ use std::cell::Cell; use std::vec; +use rustc_abi::ExternAbi; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; @@ -20,7 +21,6 @@ use rustc_hir::{ use rustc_span::FileName; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; -use rustc_target::spec::abi::Abi; use {rustc_ast as ast, rustc_hir as hir}; pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String { @@ -2240,7 +2240,7 @@ impl<'a> State<'a> { fn print_ty_fn( &mut self, - abi: Abi, + abi: ExternAbi, safety: hir::Safety, decl: &hir::FnDecl<'_>, name: Option<Symbol>, @@ -2276,7 +2276,7 @@ impl<'a> State<'a> { self.print_safety(header.safety); - if header.abi != Abi::Rust { + if header.abi != ExternAbi::Rust { self.word_nbsp("extern"); self.word_nbsp(header.abi.to_string()); } diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs index c3e095b0554..7af26623ce7 100644 --- a/compiler/rustc_hir_typeck/src/autoderef.rs +++ b/compiler/rustc_hir_typeck/src/autoderef.rs @@ -50,8 +50,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.try_overloaded_deref(autoderef.span(), source).and_then( |InferOk { value: method, obligations: o }| { obligations.extend(o); - if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() { - Some(OverloadedDeref { region, mutbl, span: autoderef.span() }) + // FIXME: we should assert the sig is &T here... there's no reason for this to be fallible. + if let ty::Ref(_, _, mutbl) = *method.sig.output().kind() { + Some(OverloadedDeref { mutbl, span: autoderef.span() }) } else { None } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 6eb6792a119..f9a21a9bef3 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -307,7 +307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if borrow { // Check for &self vs &mut self in the method signature. Since this is either // the Fn or FnMut trait, it should be one of those. - let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else { + let ty::Ref(_, _, mutbl) = method.sig.inputs()[0].kind() else { bug!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut") }; @@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::No); autoref = Some(Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: method.sig.inputs()[0], }); } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 6fa958d9496..87798ca3fd9 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -113,7 +113,7 @@ fn identity(_: Ty<'_>) -> Vec<Adjustment<'_>> { vec![] } -fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> { +fn simple<'tcx>(kind: Adjust) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> { move |target| vec![Adjustment { kind, target }] } @@ -484,14 +484,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Now apply the autoref. We have to extract the region out of // the final ref type we got. - let ty::Ref(r_borrow, _, _) = ty.kind() else { + let ty::Ref(..) = ty.kind() else { span_bug!(span, "expected a ref type, got {:?}", ty); }; let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase); - adjustments.push(Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*r_borrow, mutbl)), - target: ty, - }); + adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: ty }); debug!("coerce_borrowed_pointer: succeeded ty={:?} adjustments={:?}", ty, adjustments); @@ -547,7 +544,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No); Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(r_borrow, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b), })) } @@ -827,7 +824,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }; let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?; - let (_, b_region, _b_ty, mut_b) = extract_pin_mut(b)?; + let (_, _, _b_ty, mut_b) = extract_pin_mut(b)?; coerce_mutbls(mut_a, mut_b)?; @@ -841,7 +838,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // To complete the reborrow, we need to make sure we can unify the inner types, and if so we // add the adjustments. self.unify_and(a, b, |_inner_ty| { - vec![Adjustment { kind: Adjust::ReborrowPin(b_region, mut_b), target: b }] + vec![Adjustment { kind: Adjust::ReborrowPin(mut_b), target: b }] }) } @@ -1321,7 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let noop = match self.typeck_results.borrow().expr_adjustments(expr) { &[ Adjustment { kind: Adjust::Deref(_), .. }, - Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. }, + Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl_adj)), .. }, ] => { match *self.node_ty(expr.hir_id).kind() { ty::Ref(_, _, mt_orig) => { diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index cceaabaff65..4f579b05d83 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange { pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] - Call, + Call { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] - Method, + Method { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] - Path, + Path { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] - UnionField, + UnionField { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] - Deref, + Deref { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, } #[derive(LintDiagnostic)] @@ -191,6 +206,64 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { #[note] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, + #[subdiagnostic] + pub sugg: SuggestAnnotations, +} + +#[derive(Clone)] +pub(crate) enum SuggestAnnotation { + Unit(Span), + Path(Span), + Local(Span), + Turbo(Span, usize, usize), +} + +#[derive(Clone)] +pub(crate) struct SuggestAnnotations { + pub suggestions: Vec<SuggestAnnotation>, +} +impl Subdiagnostic for SuggestAnnotations { + fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>( + self, + diag: &mut Diag<'_, G>, + _: &F, + ) { + if self.suggestions.is_empty() { + return; + } + + let mut suggestions = vec![]; + for suggestion in self.suggestions { + match suggestion { + SuggestAnnotation::Unit(span) => { + suggestions.push((span, "()".to_string())); + } + SuggestAnnotation::Path(span) => { + suggestions.push((span.shrink_to_lo(), "<() as ".to_string())); + suggestions.push((span.shrink_to_hi(), ">".to_string())); + } + SuggestAnnotation::Local(span) => { + suggestions.push((span, ": ()".to_string())); + } + SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push(( + span, + format!( + "::<{}>", + (0..n_args) + .map(|i| if i == idx { "()" } else { "_" }) + .collect::<Vec<_>>() + .join(", "), + ), + )), + } + } + + diag.multipart_suggestion_verbose( + "use `()` annotations to avoid fallback changes", + suggestions, + Applicability::MachineApplicable, + ); + } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index bb5f3511373..041ccfcddbb 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -781,7 +781,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.walk_autoref(expr, &place_with_id, autoref); } - adjustment::Adjust::ReborrowPin(_, mutbl) => { + adjustment::Adjust::ReborrowPin(mutbl) => { // Reborrowing a Pin is like a combinations of a deref and a borrow, so we do // both. let bk = match mutbl { @@ -804,7 +804,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx &self, expr: &hir::Expr<'_>, base_place: &PlaceWithHirId<'tcx>, - autoref: &adjustment::AutoBorrow<'tcx>, + autoref: &adjustment::AutoBorrow, ) { debug!( "walk_autoref(expr.hir_id={} base_place={:?} autoref={:?})", @@ -812,7 +812,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ); match *autoref { - adjustment::AutoBorrow::Ref(_, m) => { + adjustment::AutoBorrow::Ref(m) => { self.delegate.borrow_mut().borrow( base_place, base_place.hir_id, @@ -1283,7 +1283,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx adjustment::Adjust::Deref(overloaded) => { // Equivalent to *expr or something similar. let base = if let Some(deref) = overloaded { - let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl); + let ref_ty = Ty::new_ref( + self.cx.tcx(), + self.cx.tcx().lifetimes.re_erased, + target, + deref.mutbl, + ); self.cat_rvalue(expr.hir_id, ref_ty) } else { previous()? diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 68776c52555..8d8573c65c5 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,11 +1,15 @@ use std::cell::OnceCell; +use std::ops::ControlFlow; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::iterate::DepthFirstSearch; use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::{self}; use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; @@ -14,7 +18,7 @@ use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::debug; -use crate::{FnCtxt, TypeckRootCtxt, errors}; +use crate::{FnCtxt, errors}; #[derive(Copy, Clone)] pub(crate) enum DivergingFallbackBehavior { @@ -321,7 +325,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len()); let unsafe_infer_vars = OnceCell::new(); - self.lint_obligations_broken_by_never_type_fallback_change(behavior, &diverging_vids); + self.lint_obligations_broken_by_never_type_fallback_change( + behavior, + &diverging_vids, + &coercion_graph, + ); for &diverging_vid in &diverging_vids { let diverging_ty = Ty::new_var(self.tcx, diverging_vid); @@ -419,7 +427,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { root_vid: ty::TyVid, ) { let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { - let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id); + let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id); debug!(?unsafe_infer_vars); unsafe_infer_vars }); @@ -429,19 +437,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .filter_map(|x| unsafe_infer_vars.get(&x).copied()) .collect::<Vec<_>>(); + let sugg = self.try_to_suggest_annotations(&[root_vid], coercion_graph); + for (hir_id, span, reason) in affected_unsafe_infer_vars { self.tcx.emit_node_span_lint( lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, span, match reason { - UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call, - UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method, - UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path, + UnsafeUseReason::Call => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Call { sugg: sugg.clone() } + } + UnsafeUseReason::Method => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Method { sugg: sugg.clone() } + } + UnsafeUseReason::Path => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Path { sugg: sugg.clone() } + } UnsafeUseReason::UnionField => { - errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField + errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField { + sugg: sugg.clone(), + } + } + UnsafeUseReason::Deref => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() } } - UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref, }, ); } @@ -451,6 +471,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { &self, behavior: DivergingFallbackBehavior, diverging_vids: &[ty::TyVid], + coercions: &VecGraph<ty::TyVid, true>, ) { let DivergingFallbackBehavior::ToUnit = behavior else { return }; @@ -478,13 +499,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; // If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`, - // then this code will be broken by the never type fallback change.qba + // then this code will be broken by the never type fallback change. let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit); if unit_errors.is_empty() && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) && let [ref mut never_error, ..] = never_errors.as_mut_slice() { self.adjust_fulfillment_error_for_expr_obligation(never_error); + let sugg = self.try_to_suggest_annotations(diverging_vids, coercions); self.tcx.emit_node_span_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, self.tcx.local_def_id_to_hir_id(self.body_id), @@ -492,6 +514,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { errors::DependencyOnUnitNeverTypeFallback { obligation_span: never_error.obligation.cause.span, obligation: never_error.obligation.predicate, + sugg, }, ) } @@ -541,6 +564,153 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> { Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) } + + /// Given a set of diverging vids and coercions, walk the HIR to gather a + /// set of suggestions which can be applied to preserve fallback to unit. + fn try_to_suggest_annotations( + &self, + diverging_vids: &[ty::TyVid], + coercions: &VecGraph<ty::TyVid, true>, + ) -> errors::SuggestAnnotations { + let body = + self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + // For each diverging var, look through the HIR for a place to give it + // a type annotation. We do this per var because we only really need one + // suggestion to influence a var to be `()`. + let suggestions = diverging_vids + .iter() + .copied() + .filter_map(|vid| { + let reachable_vids = + graph::depth_first_search_as_undirected(coercions, vid).collect(); + AnnotateUnitFallbackVisitor { reachable_vids, fcx: self } + .visit_expr(body.value) + .break_value() + }) + .collect(); + errors::SuggestAnnotations { suggestions } + } +} + +/// Try to walk the HIR to find a place to insert a useful suggestion +/// to preserve fallback to `()` in 2024. +struct AnnotateUnitFallbackVisitor<'a, 'tcx> { + reachable_vids: FxHashSet<ty::TyVid>, + fcx: &'a FnCtxt<'a, 'tcx>, +} +impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> { + // For a given path segment, if it's missing a turbofish, try to suggest adding + // one so we can constrain an argument to `()`. To keep the suggestion simple, + // we want to simply suggest `_` for all the other args. This (for now) only + // works when there are only type variables (and region variables, since we can + // elide them)... + fn suggest_for_segment( + &self, + arg_segment: &'tcx hir::PathSegment<'tcx>, + def_id: DefId, + id: HirId, + ) -> ControlFlow<errors::SuggestAnnotation> { + if arg_segment.args.is_none() + && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id) + && let generics = self.fcx.tcx.generics_of(def_id) + && let args = &all_args[generics.parent_count..] + // We can't turbofish consts :( + && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_))) + { + let n_tys = args + .iter() + .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_))) + .count(); + for (idx, arg) in args.iter().enumerate() { + if let Some(ty) = arg.as_type() + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Turbo( + arg_segment.ident.span.shrink_to_hi(), + n_tys, + idx, + )); + } + } + } + ControlFlow::Continue(()) + } +} +impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { + type Result = ControlFlow<errors::SuggestAnnotation>; + + fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { + // Try to replace `_` with `()`. + if let hir::TyKind::Infer = hir_ty.kind + && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span)); + } + hir::intravisit::walk_ty(self, hir_ty) + } + + fn visit_qpath( + &mut self, + qpath: &'tcx rustc_hir::QPath<'tcx>, + id: HirId, + _span: Span, + ) -> Self::Result { + let arg_segment = match qpath { + hir::QPath::Resolved(_, path) => { + path.segments.last().expect("paths should have a segment") + } + hir::QPath::TypeRelative(_, segment) => segment, + hir::QPath::LangItem(..) => { + return hir::intravisit::walk_qpath(self, qpath, id); + } + }; + // Alternatively, try to turbofish `::<_, (), _>`. + if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { + self.suggest_for_segment(arg_segment, def_id, id)?; + } + hir::intravisit::walk_qpath(self, qpath, id) + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + // Try to suggest adding an explicit qself `()` to a trait method path. + // i.e. changing `Default::default()` to `<() as Default>::default()`. + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind + && let Res::Def(DefKind::AssocFn, def_id) = path.res + && self.fcx.tcx.trait_of_item(def_id).is_some() + && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0) + && let Some(vid) = self.fcx.root_vid(self_ty) + && self.reachable_vids.contains(&vid) + && let [.., trait_segment, _method_segment] = path.segments + { + let span = path.span.shrink_to_lo().to(trait_segment.ident.span); + return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); + } + // Or else, try suggesting turbofishing the method args. + if let hir::ExprKind::MethodCall(segment, ..) = expr.kind + && let Some(def_id) = + self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + { + self.suggest_for_segment(segment, def_id, expr.hir_id)?; + } + hir::intravisit::walk_expr(self, expr) + } + + fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result { + // For a local, try suggest annotating the type if it's missing. + if let None = local.ty + && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Local( + local.pat.span.shrink_to_hi(), + )); + } + hir::intravisit::walk_local(self, local) + } } #[derive(Debug, Copy, Clone)] @@ -569,27 +739,26 @@ pub(crate) enum UnsafeUseReason { /// /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }` fn compute_unsafe_infer_vars<'a, 'tcx>( - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, body_id: LocalDefId, ) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> { - let body = - root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, res: &'a mut UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>, } impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_> { fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { - let typeck_results = self.root_ctxt.typeck_results.borrow(); + let typeck_results = self.fcx.typeck_results.borrow(); match ex.kind { hir::ExprKind::MethodCall(..) => { if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) - && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity() - && let sig = method_ty.fn_sig(self.root_ctxt.tcx) + && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() + && let sig = method_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -609,7 +778,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( let func_ty = typeck_results.expr_ty(func); if func_ty.is_fn() - && let sig = func_ty.fn_sig(self.root_ctxt.tcx) + && let sig = func_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -640,7 +809,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( // If this path refers to an unsafe function, collect inference variables which may affect it. // `is_fn` excludes closures, but those can't be unsafe. if ty.is_fn() - && let sig = ty.fn_sig(self.root_ctxt.tcx) + && let sig = ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -698,7 +867,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( } } - UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value); + UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value); debug!(?res, "collected the following unsafe vars for {body_id:?}"); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 0fc566c58f7..a1a78371fbd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let autoborrow_mut = adj.iter().any(|adj| { matches!(adj, &Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })), + kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })), .. }) }); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 92b504d10bc..3754fd02428 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -200,10 +200,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // for two-phase borrows. let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes); - adjustments.push(Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)), - target, - }); + adjustments + .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target }); if unsize { let unsized_ty = if let ty::Array(elem_ty, _) = base_ty.kind() { @@ -250,7 +248,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { _ => bug!("Cannot adjust receiver type for reborrowing pin of {target:?}"), }; - adjustments.push(Adjustment { kind: Adjust::ReborrowPin(region, mutbl), target }); + adjustments.push(Adjustment { kind: Adjust::ReborrowPin(mutbl), target }); } None => {} } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 57ac7f7d2cd..9c1459ee188 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -256,23 +256,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(method) => { let by_ref_binop = !op.node.is_by_value(); if is_assign == IsAssign::Yes || by_ref_binop { - if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() { + if let ty::Ref(_, _, mutbl) = method.sig.inputs()[0].kind() { let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes); let autoref = Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: method.sig.inputs()[0], }; self.apply_adjustments(lhs_expr, vec![autoref]); } } if by_ref_binop { - if let ty::Ref(region, _, mutbl) = method.sig.inputs()[1].kind() { + if let ty::Ref(_, _, mutbl) = method.sig.inputs()[1].kind() { // Allow two-phase borrows for binops in initial deployment // since they desugar to methods let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes); let autoref = Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: method.sig.inputs()[1], }; // HACK(eddyb) Bypass checks due to reborrows being in diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 5dd51721022..d5c7fe5fff3 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -29,9 +29,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?; let method = self.register_infer_ok_obligations(ok); - if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() { + if let ty::Ref(_, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() { self.apply_adjustments(oprnd_expr, vec![Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*region, AutoBorrowMutability::Not)), + kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)), target: method.sig.inputs()[0], }]); } else { @@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut adjustments = self.adjust_steps(autoderef); if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() { adjustments.push(Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(*region, AutoBorrowMutability::Not)), + kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)), target: Ty::new_imm_ref(self.tcx, *region, adjusted_ty), }); } else { @@ -289,9 +289,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let method = self.register_infer_ok_obligations(ok); - if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() { - *deref = OverloadedDeref { region, mutbl, span: deref.span }; - } + let ty::Ref(_, _, mutbl) = *method.sig.output().kind() else { + span_bug!( + self.tcx.def_span(method.def_id), + "expected DerefMut to return a &mut" + ); + }; + *deref = OverloadedDeref { mutbl, span: deref.span }; // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514). // This helps avoid accidental drops. if inside_union @@ -390,7 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not the case today. allow_two_phase_borrow: AllowTwoPhase::No, }; - adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)); + adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(mutbl)); adjustment.target = Ty::new_ref(self.tcx, *region, source, mutbl.into()); } source = adjustment.target; diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 2bc006c37da..d65ed72a8e8 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -432,7 +432,6 @@ where upvar.visit_with(self); } - // FIXME(async_closures): Is this the right signature to visit here? args.as_coroutine_closure().signature_parts_ty().visit_with(self); } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d3762e739db..35bba149d0a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -832,8 +832,6 @@ fn test_unstable_options_tracking_hash() { tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); tracked!(print_fuel, Some("abc".to_string())); - tracked!(profile, true); - tracked!(profile_emit, Some(PathBuf::from("abc"))); tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(regparm, Some(3)); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 3fa43296dfc..9187f6caad4 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -268,7 +268,7 @@ lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edi lint_extern_without_abi = extern declarations without an explicit ABI are deprecated .label = ABI should be specified here - .help = the default ABI is {$default_abi} + .suggestion = explicitly specify the {$default_abi} ABI lint_for_loops_over_fallibles = for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 000f4b697bd..38e52570e53 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2738,11 +2738,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub { #[derive(LintDiagnostic)] #[diag(lint_extern_without_abi)] -#[help] pub(crate) struct MissingAbi { - #[label] + #[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")] pub span: Span, - pub default_abi: &'static str, } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 3c31b879bd6..3c33b2dd478 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -151,9 +151,15 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { // }; // }; // ``` + // + // It isn't possible to mix a impl in a module with const-anon, but an item can + // be put inside a module and referenced by a impl so we also have to treat the + // item parent as transparent to module and for consistency we have to do the same + // for impl, otherwise the item-def and impl-def won't have the same parent. let outermost_impl_parent = peel_parent_while(cx.tcx, parent, |tcx, did| { - tcx.def_kind(did) == DefKind::Const - && tcx.opt_item_name(did) == Some(kw::Underscore) + tcx.def_kind(did) == DefKind::Mod + || (tcx.def_kind(did) == DefKind::Const + && tcx.opt_item_name(did) == Some(kw::Underscore)) }); // 2. We check if any of the paths reference a the `impl`-parent. diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 88878a018e7..48dd8e38a03 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -204,7 +204,10 @@ fn lint_nan<'tcx>( return false; }; - matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f32_nan | sym::f64_nan)) + matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::f16_nan | sym::f32_nan | sym::f64_nan | sym::f128_nan) + ) } _ => false, } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index bbb290c9459..b50a95e7d2b 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1610,7 +1610,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { } for adj in cx.typeck_results().expr_adjustments(e) { - if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind { + if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(m)) = adj.kind { match m { adjustment::AutoBorrowMutability::Not => { cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag); diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index eb2a184ef84..450885e7164 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } @@ -12,6 +13,5 @@ rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } serde = { version = "1.0.125", features = ["derive"] } # tidy-alphabetical-end diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 601784f9732..0caf6ef3a6d 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -2,6 +2,7 @@ #![warn(unreachable_pub)] // tidy-alphabetical-end +use rustc_abi::ExternAbi; use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; @@ -15,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::spec::abi::Abi; use serde::{Deserialize, Serialize}; pub use self::Level::*; @@ -602,7 +602,7 @@ pub enum BuiltinLintDiag { path: String, since_kind: DeprecatedSinceKind, }, - MissingAbi(Span, Abi), + MissingAbi(Span, ExternAbi), UnusedDocComment(Span), UnusedBuiltinAttribute { attr_name: Symbol, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3e906f89c15..3b7dc6de825 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -42,7 +42,6 @@ #if LLVM_VERSION_GE(19, 0) #include "llvm/Support/PGOOptions.h" #endif -#include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" @@ -714,9 +713,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, - const char *InstrProfileOutput, bool InstrumentGCOV, - const char *PGOSampleUsePath, bool DebugInfoForProfiling, - void *LlvmSelfProfiler, + const char *InstrProfileOutput, const char *PGOSampleUsePath, + bool DebugInfoForProfiling, void *LlvmSelfProfiler, LLVMRustSelfProfileBeforePassCallback BeforePassCallback, LLVMRustSelfProfileAfterPassCallback AfterPassCallback, const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins, @@ -847,13 +845,6 @@ extern "C" LLVMRustResult LLVMRustOptimize( }); } - if (InstrumentGCOV) { - PipelineStartEPCallbacks.push_back( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault())); - }); - } - if (InstrumentCoverage) { PipelineStartEPCallbacks.push_back( [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) { diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 3b0151b1f94..cece700b4dd 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -27,7 +27,6 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } -snap = "1" tempfile = "3.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 16623915c40..d2be6ae8d69 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -778,9 +778,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if self.sess.opts.unstable_opts.no_profiler_runtime - || !(self.sess.instrument_coverage() - || self.sess.opts.unstable_opts.profile - || self.sess.opts.cg.profile_generate.enabled()) + || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled()) { return; } diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a4a69ae9514..f924ed48b6f 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -213,7 +213,7 @@ //! metadata::locator or metadata::creader for all the juicy details! use std::borrow::Cow; -use std::io::{Read, Result as IoResult, Write}; +use std::io::{Result as IoResult, Write}; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::{cmp, fmt}; @@ -232,7 +232,6 @@ use rustc_session::utils::CanonicalizedPath; use rustc_span::Span; use rustc_span::symbol::Symbol; use rustc_target::spec::{Target, TargetTriple}; -use snap::read::FrameDecoder; use tracing::{debug, info}; use crate::creader::{Library, MetadataLoader}; @@ -792,7 +791,6 @@ fn get_metadata_section<'p>( CrateFlavor::Dylib => { let buf = loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?; - // The header is uncompressed let header_len = METADATA_HEADER.len(); // header + u64 length of data let data_start = header_len + 8; @@ -806,7 +804,7 @@ fn get_metadata_section<'p>( ))); } - // Length of the compressed stream - this allows linkers to pad the section if they want + // Length of the metadata - this allows linkers to pad the section if they want let Ok(len_bytes) = <[u8; 8]>::try_from(&buf[header_len..cmp::min(data_start, buf.len())]) else { @@ -814,29 +812,10 @@ fn get_metadata_section<'p>( "invalid metadata length found".to_string(), )); }; - let compressed_len = u64::from_le_bytes(len_bytes) as usize; + let metadata_len = u64::from_le_bytes(len_bytes) as usize; // Header is okay -> inflate the actual metadata - let compressed_bytes = buf.slice(|buf| &buf[data_start..(data_start + compressed_len)]); - if &compressed_bytes[..cmp::min(METADATA_HEADER.len(), compressed_bytes.len())] - == METADATA_HEADER - { - // The metadata was not actually compressed. - compressed_bytes - } else { - debug!("inflating {} bytes of compressed metadata", compressed_bytes.len()); - // Assume the decompressed data will be at least the size of the compressed data, so we - // don't have to grow the buffer as much. - let mut inflated = Vec::with_capacity(compressed_bytes.len()); - FrameDecoder::new(&*compressed_bytes).read_to_end(&mut inflated).map_err(|_| { - MetadataError::LoadFailure(format!( - "failed to decompress metadata: {}", - filename.display() - )) - })?; - - slice_owned(inflated, Deref::deref) - } + buf.slice(|buf| &buf[data_start..(data_start + metadata_len)]) } CrateFlavor::Rmeta => { // mmap the file, because only a small fraction of it is read. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index cd148aef29b..978abab8b08 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; use crate::ty::{ - self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, + self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode, UserTypeAnnotationIndex, }; @@ -452,6 +452,15 @@ impl<'tcx> Body<'tcx> { self.basic_blocks.as_mut() } + pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> { + match self.phase { + // FIXME(#132279): the MIR is quite clearly inside of a body, so we + // should instead reveal opaques defined by that body here. + MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), + MirPhase::Runtime(_) => TypingMode::PostAnalysis, + } + } + #[inline] pub fn local_kind(&self, local: Local) -> LocalKind { let index = local.as_usize(); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index e690bf74b6b..80ae5a7146d 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -762,33 +762,35 @@ where // Terminator at the bottom. extra_data(PassWhere::BeforeLocation(current_location), w)?; - let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); - if options.include_extra_comments { - writeln!( + if data.terminator.is_some() { + let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); + if options.include_extra_comments { + writeln!( + w, + "{:A$} // {}{}", + indented_terminator, + if tcx.sess.verbose_internals() { + format!("{current_location:?}: ") + } else { + String::new() + }, + comment(tcx, data.terminator().source_info), + A = ALIGN, + )?; + } else { + writeln!(w, "{indented_terminator}")?; + } + + write_extra( + tcx, w, - "{:A$} // {}{}", - indented_terminator, - if tcx.sess.verbose_internals() { - format!("{current_location:?}: ") - } else { - String::new() + |visitor| { + visitor.visit_terminator(data.terminator(), current_location); }, - comment(tcx, data.terminator().source_info), - A = ALIGN, + options, )?; - } else { - writeln!(w, "{indented_terminator}")?; } - write_extra( - tcx, - w, - |visitor| { - visitor.visit_terminator(data.terminator(), current_location); - }, - options, - )?; - extra_data(PassWhere::AfterLocation(current_location), w)?; extra_data(PassWhere::AfterTerminator(block), w)?; diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c610fac80f6..85beb6ef1e7 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -19,9 +19,8 @@ use smallvec::SmallVec; use super::{BasicBlock, Const, Local, UserTypeProjection}; use crate::mir::coverage::CoverageKind; -use crate::traits::Reveal; use crate::ty::adjustment::PointerCoercion; -use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex}; +use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex}; /// Represents the "flavors" of MIR. /// @@ -102,10 +101,10 @@ impl MirPhase { } } - pub fn reveal(&self) -> Reveal { - match *self { - MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing, - MirPhase::Runtime(_) => Reveal::All, + pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> { + match self { + MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id), + MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id), } } } diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 71833eea5c0..c56038d358c 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -82,7 +82,7 @@ pub enum PointerCoercion { /// `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`. #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub struct Adjustment<'tcx> { - pub kind: Adjust<'tcx>, + pub kind: Adjust, pub target: Ty<'tcx>, } @@ -93,20 +93,20 @@ impl<'tcx> Adjustment<'tcx> { } #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] -pub enum Adjust<'tcx> { +pub enum Adjust { /// Go from ! to any type. NeverToAny, /// Dereference once, producing a place. - Deref(Option<OverloadedDeref<'tcx>>), + Deref(Option<OverloadedDeref>), /// Take the address and produce either a `&` or `*` pointer. - Borrow(AutoBorrow<'tcx>), + Borrow(AutoBorrow), Pointer(PointerCoercion), /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. - ReborrowPin(ty::Region<'tcx>, hir::Mutability), + ReborrowPin(hir::Mutability), } /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)` @@ -115,17 +115,16 @@ pub enum Adjust<'tcx> { /// being those shared by both the receiver and the returned reference. #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] -pub struct OverloadedDeref<'tcx> { - pub region: ty::Region<'tcx>, +pub struct OverloadedDeref { pub mutbl: hir::Mutability, /// The `Span` associated with the field access or method call /// that triggered this overloaded deref. pub span: Span, } -impl<'tcx> OverloadedDeref<'tcx> { +impl OverloadedDeref { /// Get the zst function item type for this method call. - pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { + pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { let trait_def_id = match self.mutbl { hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), @@ -187,9 +186,9 @@ impl From<AutoBorrowMutability> for hir::Mutability { #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] -pub enum AutoBorrow<'tcx> { +pub enum AutoBorrow { /// Converts from T to &T. - Ref(ty::Region<'tcx>, AutoBorrowMutability), + Ref(AutoBorrowMutability), /// Converts from T to *T. RawPtr(hir::Mutability), diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 529e9cc2711..11904722743 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" # tidy-alphabetical-start either = "1.5.0" itertools = "0.12" + +rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } @@ -22,7 +24,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 9e3af891052..07964e304b9 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,3 +1,4 @@ +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; @@ -6,7 +7,6 @@ use rustc_middle::ty; use rustc_middle::ty::cast::mir_cast_kind; use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_target::abi::{FieldIdx, VariantIdx}; use super::{PResult, ParseCtxt, parse_by_kind}; use crate::build::custom::ParseError; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index ae164cf7605..3f2e3b956fc 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -1,5 +1,6 @@ //! See docs in build/expr/mod.rs +use rustc_abi::Size; use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{ @@ -11,7 +12,6 @@ use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex, }; use rustc_middle::{bug, mir, span_bug}; -use rustc_target::abi::Size; use tracing::{instrument, trace}; use crate::build::{Builder, parse_float_into_constval}; diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index c7298e3ddfa..9f6e0735b48 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -3,6 +3,7 @@ use std::assert_matches::assert_matches; use std::iter; +use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use rustc_hir::def_id::LocalDefId; use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind}; use rustc_middle::middle::region; @@ -12,7 +13,6 @@ use rustc_middle::thir::*; use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; -use rustc_target::abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use tracing::{debug, instrument, trace}; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 2357dd73490..1985dd3fca0 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -1,5 +1,6 @@ //! See docs in `build/expr/mod.rs`. +use rustc_abi::{BackendRepr, FieldIdx, Primitive}; use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::bug; @@ -13,7 +14,6 @@ use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, UpvarArgs}; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span}; -use rustc_target::abi::{BackendRepr, FieldIdx, Primitive}; use tracing::debug; use crate::build::expr::as_place::PlaceBase; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 51ead570205..a62d4e9d873 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -5,6 +5,7 @@ //! This also includes code for pattern bindings in `let` statements and //! function parameters. +use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::{BindingMode, ByRef}; @@ -15,7 +16,6 @@ use rustc_middle::thir::{self, *}; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; -use rustc_target::abi::VariantIdx; use tracing::{debug, instrument}; use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard}; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e15ea4d8d8b..46be2aee637 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use rustc_abi::{ExternAbi, FieldIdx}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_ast::attr; @@ -20,8 +21,6 @@ use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; -use rustc_target::abi::FieldIdx; -use rustc_target::spec::abi::Abi; use super::lints; use crate::build::expr::as_place::PlaceBuilder; @@ -467,7 +466,7 @@ fn construct_fn<'tcx>( if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. - abi = Abi::Rust; + abi = ExternAbi::Rust; } let arguments = &thir.params; @@ -540,7 +539,7 @@ fn construct_fn<'tcx>( let mut body = builder.finish(); - body.spread_arg = if abi == Abi::RustCall { + body.spread_arg = if abi == ExternAbi::RustCall { // RustCall pseudo-ABI untuples the last argument. Some(Local::new(arguments.len())) } else { @@ -792,12 +791,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } fn finish(self) -> Body<'tcx> { - for (index, block) in self.cfg.basic_blocks.iter().enumerate() { - if block.terminator.is_none() { - span_bug!(self.fn_span, "no terminator on block {:?}", index); - } - } - let mut body = Body::new( MirSource::item(self.def_id.to_def_id()), self.cfg.basic_blocks, @@ -811,6 +804,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, ); body.coverage_info_hi = self.coverage_info.map(|b| b.into_done()); + + for (index, block) in body.basic_blocks.iter().enumerate() { + if block.terminator.is_none() { + use rustc_middle::mir::pretty; + let options = pretty::PrettyPrintMirOptions::from_cli(self.tcx); + pretty::write_mir_fn( + self.tcx, + &body, + &mut |_, _| Ok(()), + &mut std::io::stdout(), + options, + ) + .unwrap(); + span_bug!(self.fn_span, "no terminator on block {:?}", index); + } + } + body } diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index d20e5fcf4ec..0481f715019 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use rustc_abi::{FIRST_VARIANT, FieldIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -18,7 +19,6 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, sym}; -use rustc_target::abi::{FIRST_VARIANT, FieldIdx}; use tracing::{debug, info, instrument, trace}; use crate::errors; @@ -140,7 +140,7 @@ impl<'tcx> Cx<'tcx> { expr = Expr { temp_lifetime, - ty: Ty::new_ref(self.tcx, deref.region, expr.ty, deref.mutbl), + ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl), span, kind: ExprKind::Borrow { borrow_kind: deref.mutbl.to_borrow_kind(), @@ -152,14 +152,14 @@ impl<'tcx> Cx<'tcx> { self.overloaded_place(hir_expr, adjustment.target, Some(call), expr, deref.span) } - Adjust::Borrow(AutoBorrow::Ref(_, m)) => ExprKind::Borrow { + Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow { borrow_kind: m.to_borrow_kind(), arg: self.thir.exprs.push(expr), }, Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) } } - Adjust::ReborrowPin(region, mutbl) => { + Adjust::ReborrowPin(mutbl) => { debug!("apply ReborrowPin adjustment"); // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` @@ -197,7 +197,8 @@ impl<'tcx> Cx<'tcx> { hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default }, hir::Mutability::Not => BorrowKind::Shared, }; - let new_pin_target = Ty::new_ref(self.tcx, region, ptr_target_ty, mutbl); + let new_pin_target = + Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, ptr_target_ty, mutbl); let expr = self.thir.exprs.push(Expr { temp_lifetime, ty: new_pin_target, diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c89f526aa17..983853d2de1 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,4 +1,5 @@ use either::Either; +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; use rustc_hir as hir; use rustc_index::Idx; @@ -9,7 +10,6 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree}; use rustc_span::Span; -use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 56e5156a91f..ec852add94d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -5,6 +5,7 @@ mod const_to_pat; use std::cmp::Ordering; +use rustc_abi::{FieldIdx, Integer}; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; @@ -20,7 +21,6 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisita use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; -use rustc_target::abi::{FieldIdx, Integer}; use tracing::{debug, instrument}; pub(crate) use self::check_match::check_match; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 8a646d8cbfe..274eea9563f 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1082,7 +1082,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } - if let AggregateTy::Def(_, _) = ty + // unsound: https://github.com/rust-lang/rust/issues/132353 + if tcx.sess.opts.unstable_opts.unsound_mir_opts + && let AggregateTy::Def(_, _) = ty && let Some(value) = self.simplify_aggregate_to_copy(rvalue, location, &fields, variant_index) { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 42d6bdf6cee..404470db5c5 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -244,8 +244,13 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + output_type, + destination_ty, + ) { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -275,8 +280,13 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -285,8 +295,13 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx); - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 77356723c46..8109a9b8ba0 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -5,14 +5,14 @@ use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::{Obligation, ObligationCause, Reveal}; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, - TypingMode, Variance, + Variance, }; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FIRST_VARIANT, Size}; @@ -20,7 +20,7 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::ObligationCtxt; use rustc_type_ir::Upcast; -use crate::util::{is_within_packed, relate_types}; +use crate::util::{self, is_within_packed}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -50,11 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { } let def_id = body.source.def_id(); let mir_phase = self.mir_phase; - let param_env = match mir_phase.reveal() { - Reveal::UserFacing => tcx.param_env(def_id), - Reveal::All => tcx.param_env_reveal_all_normalized(def_id), - }; - + let param_env = mir_phase.param_env(tcx, def_id); let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) { // In this case `AbortUnwindingCalls` haven't yet been executed. true @@ -587,7 +583,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Variance::Covariant }; - crate::util::relate_types(self.tcx, self.param_env, variance, src, dest) + crate::util::relate_types( + self.tcx, + self.body.typing_mode(self.tcx), + self.param_env, + variance, + src, + dest, + ) } /// Check that the given predicate definitely holds in the param-env of this MIR body. @@ -606,7 +609,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env)); + let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx)); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( self.tcx, @@ -798,10 +801,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } ProjectionElem::Subtype(ty) => { - if !relate_types( + if !util::sub_types( self.tcx, + self.body.typing_mode(self.tcx), self.param_env, - Variance::Covariant, ty, place_ref.ty(&self.body.local_decls, self.tcx).ty, ) { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 36733726564..6b4e2d0f4e2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1194,6 +1194,7 @@ impl<'a> Parser<'a> { attrs: &mut AttrVec, mut safety: Safety, ) -> PResult<'a, ItemInfo> { + let extern_span = self.prev_token.uninterpolated_span(); let abi = self.parse_abi(); // ABI? // FIXME: This recovery should be tested better. if safety == Safety::Default @@ -1205,6 +1206,7 @@ impl<'a> Parser<'a> { let _ = self.eat_keyword(kw::Unsafe); } let module = ast::ForeignMod { + extern_span, safety, abi, items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 20a1affa008..aa6e473ea6b 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2453,7 +2453,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let output_types = parse_output_types(early_dcx, &unstable_opts, matches); let mut cg = CodegenOptions::build(early_dcx, matches); - let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( + let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto( early_dcx, &output_types, matches, @@ -2480,18 +2480,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); - if unstable_opts.profile && incremental.is_some() { - early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally"); - } - if unstable_opts.profile { - match codegen_units { - Some(1) => {} - None => codegen_units = Some(1), - Some(_) => early_dcx - .early_fatal("can't instrument with gcov profiling with multiple codegen units"), - } - } - if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive"); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 17eb3870049..ae7dd96e7e0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1990,13 +1990,8 @@ options! { proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, parse_proc_macro_execution_strategy, [UNTRACKED], "how to run proc-macro code (default: same-thread)"), - profile: bool = (false, parse_bool, [TRACKED], - "insert profiling code (default: no)"), profile_closures: bool = (false, parse_no_flag, [UNTRACKED], "profile size of closures"), - profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], - "file path to emit profiling data at runtime when using 'profile' \ - (default based on relative source path)"), profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED], diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 73763cf034c..f45c8664093 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -1,10 +1,9 @@ use std::borrow::Cow; use std::env; -use std::num::ParseIntError; use crate::spec::{ Cc, DebuginfoKind, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType, StaticCow, - Target, TargetOptions, cvs, + TargetOptions, cvs, }; #[cfg(test)] @@ -97,9 +96,8 @@ impl TargetAbi { } } -/// Get the base target options, LLVM target and `target_arch` from the three -/// things that uniquely identify Rust's Apple targets: The OS, the -/// architecture, and the ABI. +/// Get the base target options, unversioned LLVM target and `target_arch` from the three +/// things that uniquely identify Rust's Apple targets: The OS, the architecture, and the ABI. pub(crate) fn base( os: &'static str, arch: Arch, @@ -155,117 +153,14 @@ pub(crate) fn base( ..Default::default() }; - (opts, llvm_target(os, arch, abi), arch.target_arch()) + (opts, unversioned_llvm_target(os, arch, abi), arch.target_arch()) } -pub fn platform(target: &Target) -> Option<u32> { - Some(match (&*target.os, &*target.abi) { - ("macos", _) => object::macho::PLATFORM_MACOS, - ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST, - ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR, - ("ios", _) => object::macho::PLATFORM_IOS, - ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR, - ("watchos", _) => object::macho::PLATFORM_WATCHOS, - ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR, - ("tvos", _) => object::macho::PLATFORM_TVOS, - // FIXME: Upgrade to `object-rs` 0.33+ implementation with visionOS platform definition - ("visionos", "sim") => 12, - ("visionos", _) => 11, - _ => return None, - }) -} - -/// Hack for calling `deployment_target` outside of this module. -pub fn deployment_target_for_target(target: &Target) -> (u16, u8, u8) { - let arch = if target.llvm_target.starts_with("arm64e") { - Arch::Arm64e - } else if target.arch == "aarch64" { - Arch::Arm64 - } else { - // Dummy architecture, only used by `deployment_target` anyhow - Arch::X86_64 - }; - let abi = match &*target.abi { - "macabi" => TargetAbi::MacCatalyst, - "sim" => TargetAbi::Simulator, - "" => TargetAbi::Normal, - abi => unreachable!("invalid abi '{abi}' for Apple target"), - }; - deployment_target(&target.os, arch, abi) -} - -/// Get the deployment target based on the standard environment variables, or -/// fall back to a sane default. -fn deployment_target(os: &str, arch: Arch, abi: TargetAbi) -> (u16, u8, u8) { - // When bumping a version in here, remember to update the platform-support - // docs too. - // - // NOTE: If you are looking for the default deployment target, prefer - // `rustc --print deployment-target`, as the default here may change in - // future `rustc` versions. - - // Minimum operating system versions currently supported by `rustc`. - let os_min = match os { - "macos" => (10, 12, 0), - "ios" => (10, 0, 0), - "tvos" => (10, 0, 0), - "watchos" => (5, 0, 0), - "visionos" => (1, 0, 0), - _ => unreachable!("tried to get deployment target for non-Apple platform"), - }; - - // On certain targets it makes sense to raise the minimum OS version. - // - // This matches what LLVM does, see: - // <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932> - let min = match (os, arch, abi) { - ("macos", Arch::Arm64 | Arch::Arm64e, _) => (11, 0, 0), - ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::MacCatalyst) => (14, 0, 0), - ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0), - ("ios", Arch::Arm64e, TargetAbi::Normal) => (14, 0, 0), - // Mac Catalyst defaults to 13.1 in Clang. - ("ios", _, TargetAbi::MacCatalyst) => (13, 1, 0), - ("tvos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0), - ("watchos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (7, 0, 0), - _ => os_min, - }; - - // The environment variable used to fetch the deployment target. - let env_var = match os { - "macos" => "MACOSX_DEPLOYMENT_TARGET", - "ios" => "IPHONEOS_DEPLOYMENT_TARGET", - "watchos" => "WATCHOS_DEPLOYMENT_TARGET", - "tvos" => "TVOS_DEPLOYMENT_TARGET", - "visionos" => "XROS_DEPLOYMENT_TARGET", - _ => unreachable!("tried to get deployment target env var for non-Apple platform"), - }; - - if let Ok(deployment_target) = env::var(env_var) { - match parse_version(&deployment_target) { - // It is common that the deployment target is set too low, e.g. on - // macOS Aarch64 to also target older x86_64, the user may set a - // lower deployment target than supported. - // - // To avoid such issues, we silently raise the deployment target - // here. - // FIXME: We want to show a warning when `version < os_min`. - Ok(version) => version.max(min), - // FIXME: Report erroneous environment variable to user. - Err(_) => min, - } - } else { - min - } -} - -/// Generate the target triple that we need to pass to LLVM and/or Clang. -fn llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> { - // The target triple depends on the deployment target, and is required to - // enable features such as cross-language LTO, and for picking the right - // Mach-O commands. - // - // Certain optimizations also depend on the deployment target. - let (major, minor, patch) = deployment_target(os, arch, abi); +/// Generate part of the LLVM target triple. +/// +/// See `rustc_codegen_ssa::back::versioned_llvm_target` for the full triple passed to LLVM and +/// Clang. +fn unversioned_llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> { let arch = arch.target_name(); // Convert to the "canonical" OS name used by LLVM: // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L236-L282 @@ -282,7 +177,7 @@ fn llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> { TargetAbi::MacCatalyst => "-macabi", TargetAbi::Simulator => "-simulator", }; - format!("{arch}-apple-{os}{major}.{minor}.{patch}{environment}").into() + format!("{arch}-apple-{os}{environment}").into() } fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> { @@ -321,20 +216,3 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> { cvs!["MACOSX_DEPLOYMENT_TARGET"] } } - -/// Parse an OS version triple (SDK version or deployment target). -/// -/// The size of the returned numbers here are limited by Mach-O's -/// `LC_BUILD_VERSION`. -fn parse_version(version: &str) -> Result<(u16, u8, u8), ParseIntError> { - if let Some((major, minor)) = version.split_once('.') { - let major = major.parse()?; - if let Some((minor, patch)) = minor.split_once('.') { - Ok((major, minor.parse()?, patch.parse()?)) - } else { - Ok((major, minor.parse()?, 0)) - } - } else { - Ok((version.parse()?, 0, 0)) - } -} diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs index 9435b9a5bad..a7335c9bcae 100644 --- a/compiler/rustc_target/src/spec/base/apple/tests.rs +++ b/compiler/rustc_target/src/spec/base/apple/tests.rs @@ -1,4 +1,3 @@ -use super::parse_version; use crate::spec::targets::{ aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_visionos_sim, aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios, @@ -40,11 +39,3 @@ fn macos_link_environment_unmodified() { ],); } } - -#[test] -fn test_parse_version() { - assert_eq!(parse_version("10"), Ok((10, 0, 0))); - assert_eq!(parse_version("10.12"), Ok((10, 12, 0))); - assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6))); - assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99))); -} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f4cbe47e0f3..d518ed60469 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -55,14 +55,16 @@ use crate::json::{Json, ToJson}; use crate::spec::abi::Abi; use crate::spec::crt_objects::CrtObjects; -pub mod abi; pub mod crt_objects; +pub mod abi { + pub use rustc_abi::{ + AbiDisabled, AbiUnsupported, ExternAbi as Abi, all_names, enabled_names, is_enabled, + is_stable, lookup, + }; +} + mod base; -pub use base::apple::{ - deployment_target_for_target as current_apple_deployment_target, - platform as current_apple_platform, -}; pub use base::avr_gnu::ef_avr_arch; /// Linker is called through a C/C++ compiler. @@ -2003,7 +2005,12 @@ impl TargetWarnings { /// Every field here must be specified, and has no default value. #[derive(PartialEq, Clone, Debug)] pub struct Target { - /// Target triple to pass to LLVM. + /// Unversioned target triple to pass to LLVM. + /// + /// Target triples can optionally contain an OS version (notably Apple targets), which rustc + /// cannot know without querying the environment. + /// + /// Use `rustc_codegen_ssa::back::versioned_llvm_target` if you need the full LLVM target. pub llvm_target: StaticCow<str>, /// Metadata about a target, for example the description or tier. /// Used for generating target documentation. diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index c60bf650311..1b8f9b71e93 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs @@ -14,8 +14,11 @@ pub(crate) fn target() -> Target { arch: "mips".into(), options: TargetOptions { - os: "none".into(), - env: "psx".into(), + // The Playstation 1 is mostly bare-metal, but the BIOS does provide some a slight bit + // of functionality post load, so we still declare it as `cfg!(target_os = "psx")`. + // + // See <https://github.com/rust-lang/rust/pull/131168> for details. + os: "psx".into(), vendor: "sony".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips1".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs index 7d089aeb787..ac2141f9b08 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs index 21f09d6428e..d16b3776cfb 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs index 12626dce477..91e64061020 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs index 08f0bb302dd..2777395757f 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), + data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(), arch: "sparc".into(), options: TargetOptions { cpu: "v9".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs index 0157d03f854..987f69429c0 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { ..Default::default() }; Target { - data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), + data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(), llvm_target: "sparc-unknown-none-elf".into(), metadata: crate::spec::TargetMetadata { description: Some("Bare 32-bit SPARC V7+".into()), diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 138ce902d5e..fdc9628f78e 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), // Use "sparc64" instead of "sparcv9" here, since the former is already // used widely in the source base. If we ever needed ABI // differentiation from the sparc64, we could, but that would probably diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index cc5931be860..bd47d12ef9f 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -165,7 +165,8 @@ impl Target { assert_matches!(&*self.llvm_abiname, "ilp32" | "ilp32f" | "ilp32d" | "ilp32e") } "riscv64" => { - assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q") + // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. + assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e") } _ => {} } diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index a6474f10d5b..af3b5e0d5d4 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -551,10 +551,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ] => "", [ .., - Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), - target: _, - }, + Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mut_)), target: _ }, ] => hir::Mutability::from(*mut_).ref_prefix_str(), _ => "", }; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 1c84f2171bc..436c0fabd29 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -411,7 +411,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()); - if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) { + if !elaborated_env.has_aliases() { return elaborated_env; } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 12e00ec79ac..954dfe93387 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,15 +1,16 @@ //! Deeply normalize types using the old trait solver. use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_infer::infer::InferOk; use rustc_infer::infer::at::At; +use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::{ FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, }; use rustc_macros::extension; -use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; +use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, + TypingMode, }; use tracing::{debug, instrument}; @@ -109,16 +110,19 @@ where } pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( + infcx: &InferCtxt<'tcx>, + param_env_for_debug_assertion: ty::ParamEnv<'tcx>, value: &T, - reveal: Reveal, ) -> bool { let mut flags = ty::TypeFlags::HAS_ALIAS; // Opaques are treated as rigid with `Reveal::UserFacing`, // so we can ignore those. - match reveal { - Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), - Reveal::All => {} + match infcx.typing_mode(param_env_for_debug_assertion) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + flags.remove(ty::TypeFlags::HAS_TY_OPAQUE) + } + TypingMode::PostAnalysis => {} } value.has_type_flags(flags) @@ -154,7 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { "Normalizing {value:?} without wrapping in a `Binder`" ); - if !needs_normalization(&value, self.param_env.reveal()) { + if !needs_normalization(self.selcx.infcx, self.param_env, &value) { value } else { value.fold_with(self) @@ -178,7 +182,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !needs_normalization(&ty, self.param_env.reveal()) { + if !needs_normalization(self.selcx.infcx, self.param_env, &ty) { return ty; } @@ -213,10 +217,11 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.super_fold_with(self), - - Reveal::All => { + match self.selcx.infcx.typing_mode(self.param_env) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + ty.super_fold_with(self) + } + TypingMode::PostAnalysis => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( @@ -403,7 +408,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); if tcx.features().generic_const_exprs() - || !needs_normalization(&constant, self.param_env.reveal()) + || !needs_normalization(self.selcx.infcx, self.param_env, &constant) { constant } else { @@ -420,7 +425,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx #[inline] fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) { + if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) { p.super_fold_with(self) } else { p diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a75c07c2e8c..aab854e9caf 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedD use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use tracing::{debug, instrument}; @@ -975,18 +975,21 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - if obligation.param_env.reveal() == Reveal::All { - // NOTE(eddyb) inference variables can resolve to parameters, so - // assume `poly_trait_ref` isn't monomorphic, if it contains any. - let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref); - !poly_trait_ref.still_further_specializable() - } else { - debug!( - assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), - ?obligation.predicate, - "assemble_candidates_from_impls: not eligible due to default", - ); - false + match selcx.infcx.typing_mode(obligation.param_env) { + TypingMode::Coherence | TypingMode::Analysis { .. } => { + debug!( + assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), + ?obligation.predicate, + "assemble_candidates_from_impls: not eligible due to default", + ); + false + } + TypingMode::PostAnalysis => { + // NOTE(eddyb) inference variables can resolve to parameters, so + // assume `poly_trait_ref` isn't monomorphic, if it contains any. + let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref); + !poly_trait_ref.still_further_specializable() + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 01e6516302c..a8d701a750d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -9,7 +9,7 @@ use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor, TypingMode}; use rustc_span::DUMMY_SP; use tracing::{debug, info, instrument}; @@ -21,7 +21,7 @@ use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; use crate::traits::normalize::needs_normalization; use crate::traits::{ - BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError, + BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError, }; #[extension(pub trait QueryNormalizeExt<'tcx>)] @@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { } } - if !needs_normalization(&value, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &value) { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } @@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - if !needs_normalization(&ty, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &ty) { return Ok(ty); } @@ -215,10 +215,12 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { let res = match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.try_super_fold_with(self)?, + match self.infcx.typing_mode(self.param_env) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + ty.try_super_fold_with(self)? + } - Reveal::All => { + TypingMode::PostAnalysis => { let args = data.args.try_fold_with(self)?; let recursion_limit = self.cx().recursion_limit(); @@ -332,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { &mut self, constant: ty::Const<'tcx>, ) -> Result<ty::Const<'tcx>, Self::Error> { - if !needs_normalization(&constant, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &constant) { return Ok(constant); } @@ -351,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> { &mut self, p: ty::Predicate<'tcx>, ) -> Result<ty::Predicate<'tcx>, Self::Error> { - if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) { + if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) { p.try_super_fold_with(self) } else { Ok(p) diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 22223e4a890..aadb64f45d7 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -12,6 +12,13 @@ use crate::{self as ty, Interner}; /// The current typing mode of an inference context. We unfortunately have some /// slightly different typing rules depending on the current context. See the /// doc comment for each variant for how and why they are used. +/// +/// In most cases you can get the correct typing mode automically via: +/// - `mir::Body::typing_mode` +/// - `rustc_lint::LateContext::typing_mode` +/// +/// If neither of these functions are available, feel free to reach out to +/// t-types for help. #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TypingMode<I: Interner> { diff --git a/config.example.toml b/config.example.toml index 9072a83551a..cd7ec6a05bc 100644 --- a/config.example.toml +++ b/config.example.toml @@ -668,8 +668,6 @@ # Flag indicating whether git info will be retrieved from .git automatically. # Having the git information can cause a lot of rebuilds during development. -# -# FIXME(#76720): this can causes bugs if different compilers reuse the same metadata cache. #omit-git-hash = if rust.channel == "dev" { true } else { false } # Whether to create a source tarball by default when running `x dist`. diff --git a/library/Cargo.lock b/library/Cargo.lock index db60a484081..5defd2950e8 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.134" +version = "0.1.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f743e6f7410a78c261505c729f389583de40eec62332cc8cdf2c8b9bf73049a" +checksum = "33ccee9dd499d7ada4c81533382ce87e88c52b0676c7320b2e617d29e1bb3a3f" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 6301ade2775..a9c375b62bd 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" [dependencies] core = { path = "../core" } -compiler_builtins = { version = "0.1.134", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "0.1.136", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 95cf9427e02..f412ca17163 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -216,7 +216,7 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")] #[must_use] pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller @@ -232,7 +232,6 @@ impl Layout { /// sentinel value. Types that lazily allocate must track initialization by /// some other means. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")] #[must_use] #[inline] pub const fn dangling(&self) -> NonNull<u8> { @@ -256,6 +255,7 @@ impl Layout { /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> { if let Some(align) = Alignment::new(align) { @@ -282,7 +282,6 @@ impl Layout { /// address for the whole allocated block of memory. One way to /// satisfy this constraint is to ensure `align <= self.align()`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use = "this returns the padding needed, \ without modifying the `Layout`"] #[inline] @@ -332,6 +331,7 @@ impl Layout { /// to the layout's current size. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[must_use = "this returns a new `Layout`, \ without modifying the original"] #[inline] @@ -374,7 +374,6 @@ impl Layout { /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8)); /// ``` #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { let padded = self.pad_to_align(); @@ -432,6 +431,7 @@ impl Layout { /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = Alignment::max(self.align, next.align); @@ -463,7 +463,6 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> { if let Some(size) = self.size.checked_mul(n) { @@ -481,7 +480,6 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> { // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the @@ -497,6 +495,7 @@ impl Layout { /// `isize::MAX`, returns `LayoutError`. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn array<T>(n: usize) -> Result<Self, LayoutError> { // Reduce the amount of code we need to monomorphize per `T`. diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 9b28b8b613e..4764d7f0b0f 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -2,7 +2,7 @@ //! //! *[See also the array primitive type](array).* -#![stable(feature = "core_array", since = "1.36.0")] +#![stable(feature = "core_array", since = "1.35.0")] use crate::borrow::{Borrow, BorrowMut}; use crate::cmp::Ordering; @@ -154,10 +154,11 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1] { /// The error type returned when a conversion from a slice to an array fails. #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_allowed_through_unstable_modules] #[derive(Debug, Copy, Clone)] pub struct TryFromSliceError(()); -#[stable(feature = "core_array", since = "1.36.0")] +#[stable(feature = "core_array", since = "1.35.0")] impl fmt::Display for TryFromSliceError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs index fa3c2075423..59fd7250e8f 100644 --- a/library/core/src/char/mod.rs +++ b/library/core/src/char/mod.rs @@ -18,7 +18,7 @@ //! functions that convert various types to `char`. #![allow(non_snake_case)] -#![stable(feature = "core_char", since = "1.2.0")] +#![stable(feature = "rust1", since = "1.0.0")] mod convert; mod decode; diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index b4252ef0103..a57e265c7cc 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -390,9 +390,6 @@ impl<T> MaybeUninit<T> { #[must_use] #[rustc_diagnostic_item = "maybe_uninit_zeroed"] #[stable(feature = "maybe_uninit", since = "1.36.0")] - // These are OK to allow since we do not leak &mut to user-visible API - #[rustc_allow_const_fn_unstable(const_mut_refs)] - #[rustc_allow_const_fn_unstable(const_ptr_write)] #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")] pub const fn zeroed() -> MaybeUninit<T> { let mut u = MaybeUninit::<T>::uninit(); diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 74b198c4fdd..4cf52042a57 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1254,11 +1254,9 @@ impl<T> SizedTypeProperties for T {} /// /// Nested field accesses may be used, but not array indexes. /// -/// Enum variants may be traversed as if they were fields. Variants themselves do -/// not have an offset. -/// -/// However, on stable only a single field name is supported, which blocks the use of -/// enum support. +/// If the nightly-only feature `offset_of_enum` is enabled, +/// variants may be traversed as if they were fields. +/// Variants themselves do not have an offset. /// /// Visibility is respected - all types and fields must be visible to the call site: /// diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 3a9060df286..72adb1bf190 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1161,7 +1161,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_neg", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { @@ -1227,8 +1227,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1294,7 +1293,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1353,8 +1352,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1420,7 +1418,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -2151,7 +2149,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2181,7 +2179,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index f6e271954fe..f04c83693ef 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1475,7 +1475,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` #[unstable(feature = "num_midpoint", issue = "110840")] #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] - #[rustc_allow_const_fn_unstable(const_num_midpoint)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index eb4ea4b3c40..ded8997c634 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1416,8 +1416,7 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1483,7 +1482,7 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1542,8 +1541,7 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1609,7 +1607,7 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -2132,7 +2130,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2165,7 +2163,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 75d681d76df..57a7c0fc092 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -582,7 +582,7 @@ impl<T: ?Sized> *const T { intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self) } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::<T>()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`, @@ -677,7 +677,7 @@ impl<T: ?Sized> *const T { unsafe { intrinsics::ptr_offset_from(self, origin) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -695,7 +695,7 @@ impl<T: ?Sized> *const T { unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`. /// @@ -790,6 +790,25 @@ impl<T: ?Sized> *const T { unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } } + /// Calculates the distance between two pointers within the same allocation, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize { + // SAFETY: the caller must uphold the safety contract for `sub_ptr`. + unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) } + } + /// Returns whether two pointers are guaranteed to be equal. /// /// At runtime this function behaves like `Some(self == other)`. @@ -1005,7 +1024,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e9f5bf4404e..7c2205fdcd1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -844,7 +844,6 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T { #[must_use] #[stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] -#[rustc_allow_const_fn_unstable(const_mut_refs)] #[rustc_never_returns_null_ptr] pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T { r diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 408e722267a..7aa6a309a06 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -746,7 +746,7 @@ impl<T: ?Sized> *mut T { (self as *const T).guaranteed_ne(other as _) } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::<T>()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`, @@ -839,7 +839,7 @@ impl<T: ?Sized> *mut T { unsafe { (self as *const T).offset_from(origin) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -857,7 +857,7 @@ impl<T: ?Sized> *mut T { unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`. /// @@ -930,6 +930,25 @@ impl<T: ?Sized> *mut T { unsafe { (self as *const T).sub_ptr(origin) } } + /// Calculates the distance between two pointers within the same allocation, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize { + // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + unsafe { (self as *const T).byte_sub_ptr(origin) } + } + /// Adds an unsigned offset to a pointer. /// /// This can only move the pointer forward (or not move it). If you need to move forward or @@ -1085,7 +1104,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 86ef1f3f005..afc0c0123fa 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -635,7 +635,7 @@ impl<T: ?Sized> NonNull<T> { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -676,7 +676,7 @@ impl<T: ?Sized> NonNull<T> { unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::<T>()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`, @@ -773,7 +773,7 @@ impl<T: ?Sized> NonNull<T> { unsafe { self.pointer.offset_from(origin.pointer) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -793,7 +793,7 @@ impl<T: ?Sized> NonNull<T> { // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`. /// @@ -866,6 +866,25 @@ impl<T: ?Sized> NonNull<T> { unsafe { self.pointer.sub_ptr(subtracted.pointer) } } + /// Calculates the distance between two pointers within the same allocation, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize { + // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + unsafe { self.pointer.byte_sub_ptr(origin.pointer) } + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 27e51afa800..52d2179b04d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -764,7 +764,6 @@ impl<T> [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(const_mut_refs)] #[rustc_never_returns_null_ptr] #[inline(always)] #[must_use] @@ -1867,7 +1866,6 @@ impl<T> [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")] - #[rustc_allow_const_fn_unstable(split_at_checked)] #[inline] #[track_caller] #[must_use] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 9ef99e9dae8..58d6e07de8d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -212,7 +212,7 @@ impl str { } } - /// Finds the closest `x` not exceeding `index` where `is_char_boundary(x)` is `true`. + /// Finds the closest `x` not exceeding `index` where [`is_char_boundary(x)`] is `true`. /// /// This method can help you truncate a string so that it's still valid UTF-8, but doesn't /// exceed a given number of bytes. Note that this is done purely at the character level @@ -220,6 +220,8 @@ impl str { /// split. For example, the emoji 🧑🔬 (scientist) could be split so that the string only /// includes 🧑 (person) instead. /// + /// [`is_char_boundary(x)`]: Self::is_char_boundary + /// /// # Examples /// /// ``` @@ -248,7 +250,7 @@ impl str { } } - /// Finds the closest `x` not below `index` where `is_char_boundary(x)` is `true`. + /// Finds the closest `x` not below `index` where [`is_char_boundary(x)`] is `true`. /// /// If `index` is greater than the length of the string, this returns the length of the string. /// @@ -256,7 +258,7 @@ impl str { /// for more details. /// /// [`floor_char_boundary`]: str::floor_char_boundary - /// + /// [`is_char_boundary(x)`]: Self::is_char_boundary /// /// # Examples /// @@ -761,7 +763,6 @@ impl str { #[must_use] #[stable(feature = "split_at_checked", since = "1.80.0")] #[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")] - #[rustc_allow_const_fn_unstable(const_is_char_boundary)] pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { @@ -2193,7 +2194,7 @@ impl str { /// Returns a string slice with the prefix removed. /// /// If the string starts with the pattern `prefix`, returns the substring after the prefix, - /// wrapped in `Some`. Unlike `trim_start_matches`, this method removes the prefix exactly once. + /// wrapped in `Some`. Unlike [`trim_start_matches`], this method removes the prefix exactly once. /// /// If the string does not start with `prefix`, returns `None`. /// @@ -2202,6 +2203,7 @@ impl str { /// /// [`char`]: prim@char /// [pattern]: self::pattern + /// [`trim_start_matches`]: Self::trim_start_matches /// /// # Examples /// @@ -2220,7 +2222,7 @@ impl str { /// Returns a string slice with the suffix removed. /// /// If the string ends with the pattern `suffix`, returns the substring before the suffix, - /// wrapped in `Some`. Unlike `trim_end_matches`, this method removes the suffix exactly once. + /// wrapped in `Some`. Unlike [`trim_end_matches`], this method removes the suffix exactly once. /// /// If the string does not end with `suffix`, returns `None`. /// @@ -2229,6 +2231,7 @@ impl str { /// /// [`char`]: prim@char /// [pattern]: self::pattern + /// [`trim_end_matches`]: Self::trim_end_matches /// /// # Examples /// diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index bfb9df7d781..9b66fc8f921 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "0.1.134" } +compiler_builtins = { version = "0.1.136" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 1de52eb7b21..d0dd991a933 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -481,7 +481,7 @@ pub mod prelude; #[stable(feature = "rust1", since = "1.0.0")] pub use core::any; -#[stable(feature = "core_array", since = "1.36.0")] +#[stable(feature = "core_array", since = "1.35.0")] pub use core::array; #[unstable(feature = "async_iterator", issue = "79024")] pub use core::async_iter; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index a9886012e8e..aca69490d7a 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -38,7 +38,7 @@ cfg_if::cfg_if! { } } -/// Map a Result<T, WinError> to io::Result<T>. +/// Map a [`Result<T, WinError>`] to [`io::Result<T>`](crate::io::Result<T>). trait IoResult<T> { fn io_result(self) -> crate::io::Result<T>; } diff --git a/library/std/src/sys/thread_local/guard/windows.rs b/library/std/src/sys/thread_local/guard/windows.rs index 7ee8e695c75..1752b0e1208 100644 --- a/library/std/src/sys/thread_local/guard/windows.rs +++ b/library/std/src/sys/thread_local/guard/windows.rs @@ -26,7 +26,7 @@ //! This apparently translates to any callbacks in the ".CRT$XLB" section //! being run on certain events. //! -//! So after all that, we use the compiler's #[link_section] feature to place +//! So after all that, we use the compiler's `#[link_section]` feature to place //! a callback pointer into the magic section so it ends up being called. //! //! # What's up with this callback? diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/config.library.toml index 5447565a4b0..3d697be8156 100644 --- a/src/bootstrap/defaults/config.library.toml +++ b/src/bootstrap/defaults/config.library.toml @@ -8,6 +8,9 @@ bench-stage = 0 [rust] # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true +# Download rustc from CI instead of building it from source. +# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree. +download-rustc = "if-unchanged" # Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown. lto = "off" diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml index efb56996bcd..27c1d1cf26d 100644 --- a/src/bootstrap/defaults/config.tools.toml +++ b/src/bootstrap/defaults/config.tools.toml @@ -4,7 +4,7 @@ # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true # Download rustc from CI instead of building it from source. -# This cuts compile times by almost 60x, but means you can't modify the compiler. +# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree. # Using these defaults will download the stage2 compiler (see `download-rustc` # setting) and the stage2 toolchain should therefore be used for these defaults. download-rustc = "if-unchanged" diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 99ddf58104c..4ab4e60773f 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1056,6 +1056,14 @@ pub fn rustc_cargo( cargo.rustflag("-l").rustflag("Enzyme-19"); } + // Building with protected visibility reduces the number of dynamic relocations needed, giving + // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object + // with direct references to protected symbols, so for now we only use protected symbols if + // linking with LLD is enabled. + if builder.build.config.lld_mode.is_used() { + cargo.rustflag("-Zdefault-visibility=protected"); + } + // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary // and may just be a time sink. if compiler.stage != 0 { diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 51964977933..704fa46ab1e 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -571,6 +571,7 @@ Select which editor you would like to set up [default: None]: "; "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", ], EditorKind::Emacs => vec![ "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 2ad1b39a87c..0a290a697e6 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1725,6 +1725,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target)); cmd.arg("--rustc-path").arg(builder.rustc(compiler)); + // Minicore auxiliary lib for `no_core` tests that need `core` stubs in cross-compilation + // scenarios. + cmd.arg("--minicore-path") + .arg(builder.src.join("tests").join("auxiliary").join("minicore.rs")); + let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js"); if mode == "run-make" { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index b9cf8f05316..0915ec15a2f 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -290,4 +290,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "New option `llvm.offload` to control whether the llvm offload runtime for GPU support is built. Implicitly enables the openmp runtime as dependency.", }, + ChangeInfo { + change_id: 132494, + severity: ChangeSeverity::Info, + summary: "`download-rustc='if-unchanged'` is now a default option for library profile.", + }, ]; diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh index 1a0b141e984..969389f92f7 100755 --- a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=1c5b42266fbfefb2337c6b2f0030a91bde15f9e9 +INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511 checkout=fuchsia jiri=.jiri_root/bin/jiri diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index a401092a3a7..c0ce358486b 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -205,7 +205,7 @@ auto: - image: dist-x86_64-musl env: CODEGEN_BACKENDS: llvm,cranelift - <<: *job-linux-8c + <<: *job-linux-4c - image: dist-x86_64-netbsd <<: *job-linux-4c @@ -232,7 +232,7 @@ auto: # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. - image: x86_64-rust-for-linux - <<: *job-linux-8c + <<: *job-linux-4c - image: x86_64-gnu <<: *job-linux-4c @@ -280,7 +280,7 @@ auto: - image: x86_64-gnu-tools env: DEPLOY_TOOLSTATES_JSON: toolstates-linux.json - <<: *job-linux-8c + <<: *job-linux-4c #################### # macOS Builders # @@ -488,7 +488,7 @@ auto: SCRIPT: python x.py dist bootstrap --include-default-paths DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift - <<: *job-windows-8c + <<: *job-windows - image: dist-x86_64-mingw env: @@ -501,10 +501,10 @@ auto: NO_DOWNLOAD_CI_LLVM: 1 DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift - <<: *job-windows-8c + <<: *job-windows - image: dist-x86_64-msvc-alt env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths - <<: *job-windows-8c + <<: *job-windows diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index ed091d8fc57..41da47e9206 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -2,12 +2,8 @@ ## Introduction -The Rust compiler includes two code coverage implementations: - -- A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo. -- A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data. - -This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag. +This document describes how to enable and use LLVM instrumentation-based coverage, +via the `-C instrument-coverage` compiler flag. ## How it works diff --git a/src/doc/rustc/src/platform-support/apple-darwin.md b/src/doc/rustc/src/platform-support/apple-darwin.md index c3a7b81f411..17ea225805b 100644 --- a/src/doc/rustc/src/platform-support/apple-darwin.md +++ b/src/doc/rustc/src/platform-support/apple-darwin.md @@ -52,5 +52,10 @@ Cross-compilation of these targets are supported using Clang, but may require Xcode or the macOS SDK (`MacOSX.sdk`) to be available to compile C code and to link. +The Clang target is suffixed with `-macosx`. Clang's `-darwin` target refers +to Darwin platforms in general (macOS/iOS/tvOS/watchOS/visionOS), and requires +the `-mmacosx-version-min=...`, `-miphoneos-version-min=...` or similar flags +to disambiguate. + The path to the SDK can be passed to `rustc` using the common `SDKROOT` environment variable. diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index 74e873e35ff..d9dba641495 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -40,8 +40,9 @@ include: of a delimited expression, delimited expressions are generally combinable, regardless of the number of members. Previously only applied with exactly one member (except for closures with explicit blocks). -- When line-breaking a binary operator, if the first operand spans multiple - lines, use the base indentation of the last line. +- When line-breaking an assignment operator, if the left-hand side spans + multiple lines, use the base indentation of the last line of the left-hand + side to indent the right-hand side. - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 3bb0ee6d5ff..4f63a632030 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -328,9 +328,9 @@ foo_bar Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather than at other binary operators. -If line-breaking at a binary operator (including assignment operators) where the -first operand spans multiple lines, use the base indentation of the *last* -line of the first operand, and indent relative to that: +If line-breaking an assignment operator where the left-hand side spans multiple +lines, use the base indentation of the *last* line of the left-hand side, and +indent the right-hand side relative to that: ```rust impl SomeType { @@ -344,12 +344,6 @@ impl SomeType { self.array[array_index as usize] .as_mut() .expect("thing must exist") - .extra_info - + long_long_long_long_long_long_long_long_long_long_long_long_long_long_long; - - self.array[array_index as usize] - .as_mut() - .expect("thing must exist") .extra_info = Some(ExtraInfo { parent, count: count as u16, diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md deleted file mode 100644 index 71303bfaff2..00000000000 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ /dev/null @@ -1,27 +0,0 @@ -# `profile` - -The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). - ------------------------- - -This feature allows the generation of code coverage reports. - -Set the `-Zprofile` compiler flag in order to enable gcov profiling. - -For example: -```Bash -cargo new testgcov --bin -cd testgcov -export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" -export CARGO_INCREMENTAL=0 -cargo build -cargo run -``` - -Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. -You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov). - -Please note that `RUSTFLAGS` by default applies to everything that cargo builds and runs during a build! -When the `--target` flag is explicitly passed to cargo, the `RUSTFLAGS` no longer apply to build scripts and procedural macros. -For more fine-grained control consider passing a `RUSTC_WRAPPER` program to cargo that only adds the profiling flags to -rustc for the specific crates you want to profile. diff --git a/src/etc/rust_analyzer_helix.toml b/src/etc/rust_analyzer_helix.toml index 642350cad34..9998ebcc03c 100644 --- a/src/etc/rust_analyzer_helix.toml +++ b/src/etc/rust_analyzer_helix.toml @@ -1,11 +1,12 @@ [language-server.rust-analyzer.config] linkedProjects = [ "Cargo.toml", - "src/tools/x/Cargo.toml", + "compiler/rustc_codegen_cranelift/Cargo.toml", + "compiler/rustc_codegen_gcc/Cargo.toml", + "library/Cargo.toml", "src/bootstrap/Cargo.toml", "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml" + "src/tools/x/Cargo.toml", ] [language-server.rust-analyzer.config.check] diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index a20105f0ef3..d1b186fd316 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -1,6 +1,5 @@ { "git.detectSubmodulesLimit": 20, - "rust-analyzer.check.invocationLocation": "root", "rust-analyzer.check.invocationStrategy": "once", "rust-analyzer.check.overrideCommand": [ "python3", @@ -24,7 +23,6 @@ "rust-analyzer.procMacro.server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv", "rust-analyzer.procMacro.enable": true, "rust-analyzer.cargo.buildScripts.enable": true, - "rust-analyzer.cargo.buildScripts.invocationLocation": "root", "rust-analyzer.cargo.buildScripts.invocationStrategy": "once", "rust-analyzer.cargo.buildScripts.overrideCommand": [ "python3", diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c62144be3da..d49b4320db6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -5,6 +5,7 @@ use std::sync::{Arc, OnceLock as OnceCell}; use std::{fmt, iter}; use arrayvec::ArrayVec; +use rustc_abi::{ExternAbi, VariantIdx}; use rustc_ast::MetaItemInner; use rustc_ast_pretty::pprust; use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; @@ -26,8 +27,6 @@ use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, FileName, Loc}; -use rustc_target::abi::VariantIdx; -use rustc_target::spec::abi::Abi; use thin_vec::ThinVec; use tracing::{debug, trace}; use {rustc_ast as ast, rustc_hir as hir}; @@ -656,7 +655,7 @@ impl Item { let def_id = self.def_id().unwrap(); let abi = tcx.fn_sig(def_id).skip_binder().abi(); hir::FnHeader { - safety: if abi == Abi::RustIntrinsic { + safety: if abi == ExternAbi::RustIntrinsic { intrinsic_operation_unsafety(tcx, def_id.expect_local()) } else { safety @@ -2342,7 +2341,7 @@ pub(crate) struct BareFunctionDecl { pub(crate) safety: hir::Safety, pub(crate) generic_params: Vec<GenericParamDef>, pub(crate) decl: FnDecl, - pub(crate) abi: Abi, + pub(crate) abi: ExternAbi, } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 47c21d89177..e9d5ba2ea57 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -13,6 +13,7 @@ use std::fmt::{self, Display, Write}; use std::iter::{self, once}; use itertools::Itertools; +use rustc_abi::ExternAbi; use rustc_attr::{ConstStability, StabilityLevel, StableSince}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -23,7 +24,6 @@ use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Symbol, sym}; -use rustc_target::spec::abi::Abi; use tracing::{debug, trace}; use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length}; @@ -1787,11 +1787,11 @@ impl clean::AssocItemConstraint { } } -pub(crate) fn print_abi_with_space(abi: Abi) -> impl Display { +pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { display_fn(move |f| { let quot = if f.alternate() { "\"" } else { """ }; match abi { - Abi::Rust => Ok(()), + ExternAbi::Rust => Ok(()), abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } }) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5e9cbef99a9..c6a2d87cbd0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use itertools::Itertools; use rinja::Template; +use rustc_abi::VariantIdx; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_hir as hir; @@ -14,7 +15,6 @@ use rustc_index::IndexVec; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_target::abi::VariantIdx; use tracing::{debug, info}; use super::type_layout::document_type_layout; diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 79209cee94f..d85ba3a2b14 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -1,13 +1,13 @@ use std::fmt; use rinja::Template; +use rustc_abi::{Primitive, TagEncoding, Variants}; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self}; use rustc_span::symbol::Symbol; -use rustc_target::abi::{Primitive, TagEncoding, Variants}; use crate::html::format::display_fn; use crate::html::render::Context; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7270f170780..1c8303d4c20 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -4,6 +4,7 @@ #![allow(rustc::default_hash_types)] +use rustc_abi::ExternAbi; use rustc_ast::ast; use rustc_attr::DeprecatedSince; use rustc_hir::def::{CtorKind, DefKind}; @@ -11,7 +12,6 @@ use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; use rustc_middle::{bug, ty}; use rustc_span::{Pos, Symbol, sym}; -use rustc_target::spec::abi::Abi as RustcAbi; use rustdoc_json_types::*; use super::FullItemId; @@ -421,17 +421,17 @@ pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader { } } -fn convert_abi(a: RustcAbi) -> Abi { +fn convert_abi(a: ExternAbi) -> Abi { match a { - RustcAbi::Rust => Abi::Rust, - RustcAbi::C { unwind } => Abi::C { unwind }, - RustcAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, - RustcAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, - RustcAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, - RustcAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, - RustcAbi::Win64 { unwind } => Abi::Win64 { unwind }, - RustcAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, - RustcAbi::System { unwind } => Abi::System { unwind }, + ExternAbi::Rust => Abi::Rust, + ExternAbi::C { unwind } => Abi::C { unwind }, + ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, + ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, + ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, + ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, + ExternAbi::Win64 { unwind } => Abi::Win64 { unwind }, + ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, + ExternAbi::System { unwind } => Abi::System { unwind }, _ => Abi::Other(a.to_string()), } } diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs index f55479687f8..a28487cc79e 100644 --- a/src/librustdoc/passes/propagate_stability.rs +++ b/src/librustdoc/passes/propagate_stability.rs @@ -9,7 +9,7 @@ use rustc_attr::{Stability, StabilityLevel}; use rustc_hir::def_id::CRATE_DEF_ID; -use crate::clean::{Crate, Item, ItemId}; +use crate::clean::{Crate, Item, ItemId, ItemKind}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::Pass; @@ -38,22 +38,45 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> { ItemId::DefId(def_id) => { let own_stability = self.cx.tcx.lookup_stability(def_id); - // If any of the item's parents was stabilized later or is still unstable, - // then use the parent's stability instead. - if let Some(own_stab) = own_stability - && let StabilityLevel::Stable { - since: own_since, - allowed_through_unstable_modules: false, - } = own_stab.level - && let Some(parent_stab) = parent_stability - && (parent_stab.is_unstable() - || parent_stab - .stable_since() - .is_some_and(|parent_since| parent_since > own_since)) - { - parent_stability - } else { - own_stability + let (ItemKind::StrippedItem(box kind) | kind) = &item.kind; + match kind { + ItemKind::ExternCrateItem { .. } + | ItemKind::ImportItem(..) + | ItemKind::StructItem(..) + | ItemKind::UnionItem(..) + | ItemKind::EnumItem(..) + | ItemKind::FunctionItem(..) + | ItemKind::ModuleItem(..) + | ItemKind::TypeAliasItem(..) + | ItemKind::StaticItem(..) + | ItemKind::TraitItem(..) + | ItemKind::TraitAliasItem(..) + | ItemKind::StructFieldItem(..) + | ItemKind::VariantItem(..) + | ItemKind::ForeignFunctionItem(..) + | ItemKind::ForeignStaticItem(..) + | ItemKind::ForeignTypeItem + | ItemKind::MacroItem(..) + | ItemKind::ProcMacroItem(..) + | ItemKind::ConstantItem(..) => { + // If any of the item's parents was stabilized later or is still unstable, + // then use the parent's stability instead. + merge_stability(own_stability, parent_stability) + } + + // Don't inherit the parent's stability for these items, because they + // are potentially accessible even if the parent is more unstable. + ItemKind::ImplItem(..) + | ItemKind::TyMethodItem(..) + | ItemKind::MethodItem(..) + | ItemKind::TyAssocConstItem(..) + | ItemKind::AssocConstItem(..) + | ItemKind::TyAssocTypeItem(..) + | ItemKind::AssocTypeItem(..) + | ItemKind::PrimitiveItem(..) + | ItemKind::KeywordItem => own_stability, + + ItemKind::StrippedItem(..) => unreachable!(), } } ItemId::Auto { .. } | ItemId::Blanket { .. } => { @@ -70,3 +93,20 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> { Some(item) } } + +fn merge_stability( + own_stability: Option<Stability>, + parent_stability: Option<Stability>, +) -> Option<Stability> { + if let Some(own_stab) = own_stability + && let StabilityLevel::Stable { since: own_since, allowed_through_unstable_modules: false } = + own_stab.level + && let Some(parent_stab) = parent_stability + && (parent_stab.is_unstable() + || parent_stab.stable_since().is_some_and(|parent_since| parent_since > own_since)) + { + parent_stability + } else { + own_stability + } +} diff --git a/src/llvm-project b/src/llvm-project -Subproject 3a17f74904a74565c54cfac0d67026362d03869 +Subproject b35599be758613448201a49f4b8c7ebfba5558a diff --git a/src/tools/cargo b/src/tools/cargo -Subproject e75214ea4936d2f2c909a71a1237042cc0e14b0 +Subproject 0310497822a7a673a330a5dd068b7aaa579a265 diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index f34f5e05606..b167d7f2208 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -418,7 +418,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> { let (required_refs, msg) = if can_auto_borrow { (1, if deref_count == 1 { borrow_msg } else { deref_msg }) } else if let Some(&Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutability)), .. }) = next_adjust && matches!(mutability, AutoBorrowMutability::Mut { .. }) diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs index 93d6b808646..d5ddc33e928 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs @@ -53,7 +53,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr< [] => AdjustKind::None, &[ Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), .. }, ] => AdjustKind::borrow(mutbl), @@ -62,7 +62,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr< kind: Adjust::Deref(_), .. }, Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target, }, ] => { diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index 022c6bcc70b..119e410b91c 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -199,7 +199,7 @@ fn is_ref_iterable<'tcx>( kind: Adjust::Deref(_), .. }, Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target, }, .., @@ -236,7 +236,7 @@ fn is_ref_iterable<'tcx>( }, &[ Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)), + kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target, }, .., diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs index 64c19c327b2..223b0630bfd 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs @@ -137,7 +137,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: _ if matches!( typeck.expr_adjustments(prev_expr).first(), Some(Adjustment { - kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)) + kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) | Adjust::Deref(_), .. }) @@ -230,7 +230,7 @@ fn check_use<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (UseKind<'tcx>, if use_cx .adjustments .first() - .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)))) => + .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)))) => { UseKind::AutoBorrowed }, diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 1c10e84d3ca..030df535c35 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { ) || cx.typeck_results().expr_adjustments(expr).first().map_or(false, |a| { matches!( a.kind, - Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })) + Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) ) }) || (matches!( cx.typeck_results().expr_ty(indexed).ref_mutability(), diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index dbadc8432f6..8f9f75d6824 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::symbol::sym; use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext}; @@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]), ); - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(obligation.param_env)); + let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { return false; diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c618bfe4488..41785e161d0 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -362,7 +362,7 @@ fn is_normalizable_helper<'tcx>( } // prevent recursive loops, false-negative is better than endless loop leading to stack overflow cache.insert(ty, false); - let infcx = cx.tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let cause = ObligationCause::dummy(); let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { match ty.kind() { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index e82b88eef79..e4f2f95a91b 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -392,6 +392,11 @@ pub struct Config { /// Command for visual diff display, e.g. `diff-tool --color=always`. pub diff_command: Option<String>, + + /// Path to minicore aux library, used for `no_core` tests that need `core` stubs in + /// cross-compilation scenarios that do not otherwise want/need to `-Zbuild-std`. Used in e.g. + /// ABI tests. + pub minicore_path: PathBuf, } impl Config { diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 4d57907f26f..980b3f6829a 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -3,6 +3,7 @@ /// a best-effort approximation for diagnostics. Add new headers to this list when needed. const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ // tidy-alphabetical-start + "add-core-stubs", "assembly-output", "aux-bin", "aux-build", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index bfcdd747eb4..300a03e5f33 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -198,6 +198,9 @@ pub struct TestProps { pub no_auto_check_cfg: bool, /// Run tests which require enzyme being build pub has_enzyme: bool, + /// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios + /// that don't otherwise want/need `-Z build-std`. + pub add_core_stubs: bool, } mod directives { @@ -243,6 +246,7 @@ mod directives { pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags"; pub const FILECHECK_FLAGS: &'static str = "filecheck-flags"; pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg"; + pub const ADD_CORE_STUBS: &'static str = "add-core-stubs"; // This isn't a real directive, just one that is probably mistyped often pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags"; } @@ -300,6 +304,7 @@ impl TestProps { filecheck_flags: vec![], no_auto_check_cfg: false, has_enzyme: false, + add_core_stubs: false, } } @@ -564,6 +569,8 @@ impl TestProps { } config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg); + + self.update_add_core_stubs(ln, config); }, ); @@ -677,6 +684,27 @@ impl TestProps { pub fn local_pass_mode(&self) -> Option<PassMode> { self.pass_mode } + + pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) { + let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS); + if add_core_stubs { + if !matches!(config.mode, Mode::Ui | Mode::Codegen | Mode::Assembly) { + panic!( + "`add-core-stubs` is currently only supported for ui, codegen and assembly test modes" + ); + } + + // FIXME(jieyouxu): this check is currently order-dependent, but we should probably + // collect all directives in one go then perform a validation pass after that. + if self.local_pass_mode().is_some_and(|pm| pm == PassMode::Run) { + // `minicore` can only be used with non-run modes, because it's `core` prelude stubs + // and can't run. + panic!("`add-core-stubs` cannot be used to run the test binary"); + } + + self.add_core_stubs = add_core_stubs; + } + } } /// If the given line begins with the appropriate comment prefix for a directive, diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 2e6effcab98..0e735dc77c4 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -152,6 +152,7 @@ impl ConfigBuilder { "--git-repository=", "--nightly-branch=", "--git-merge-commit-email=", + "--minicore-path=", ]; let mut args: Vec<String> = args.iter().map(ToString::to_string).collect(); diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index ccf8057bf5c..5c06a39c477 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -181,7 +181,8 @@ pub fn parse_config(args: Vec<String>) -> Config { "compiletest-diff-tool", "What custom diff tool to use for displaying compiletest tests.", "COMMAND", - ); + ) + .reqopt("", "minicore-path", "path to minicore aux library", "PATH"); let (argv0, args_) = args.split_first().unwrap(); if args.len() == 1 || args[1] == "-h" || args[1] == "--help" { @@ -371,7 +372,10 @@ pub fn parse_config(args: Vec<String>) -> Config { git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(), profiler_runtime: matches.opt_present("profiler-runtime"), + diff_command: matches.opt_str("compiletest-diff-tool"), + + minicore_path: opt_path(matches, "minicore-path"), } } @@ -409,6 +413,7 @@ pub fn log_config(config: &Config) { logv(c, format!("host-linker: {:?}", config.host_linker)); logv(c, format!("verbose: {}", config.verbose)); logv(c, format!("format: {:?}", config.format)); + logv(c, format!("minicore_path: {:?}", config.minicore_path.display())); logv(c, "\n".to_string()); } @@ -885,6 +890,12 @@ fn files_related_to_test( related.push(path); } + // `minicore.rs` test auxiliary: we need to make sure tests get rerun if this changes. + // + // FIXME(jieyouxu): untangle these paths, we should provide both a path to root `tests/` or + // `tests/auxiliary/` and the test suite in question. `src_base` is also a terrible name. + related.push(config.src_base.parent().unwrap().join("auxiliary").join("minicore.rs")); + related } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index a8a71c196fc..b337458f943 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1150,14 +1150,20 @@ impl<'test> TestCx<'test> { } } - /// `root_testpaths` refers to the path of the original test. - /// the auxiliary and the test with an aux-build have the same `root_testpaths`. + /// `root_testpaths` refers to the path of the original test. the auxiliary and the test with an + /// aux-build have the same `root_testpaths`. fn compose_and_run_compiler( &self, mut rustc: Command, input: Option<String>, root_testpaths: &TestPaths, ) -> ProcRes { + if self.props.add_core_stubs { + let minicore_path = self.build_minicore(); + rustc.arg("--extern"); + rustc.arg(&format!("minicore={}", minicore_path.to_str().unwrap())); + } + let aux_dir = self.aux_output_dir(); self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc); @@ -1171,6 +1177,37 @@ impl<'test> TestCx<'test> { ) } + /// Builds `minicore`. Returns the path to the minicore rlib within the base test output + /// directory. + fn build_minicore(&self) -> PathBuf { + let output_file_path = self.output_base_dir().join("libminicore.rlib"); + let mut rustc = self.make_compile_args( + &self.config.minicore_path, + TargetLocation::ThisFile(output_file_path.clone()), + Emit::None, + AllowUnused::Yes, + LinkToAux::No, + vec![], + ); + + rustc.args(&["--crate-type", "rlib"]); + rustc.arg("-Cpanic=abort"); + + let res = + self.compose_and_run(rustc, self.config.compile_lib_path.to_str().unwrap(), None, None); + if !res.status.success() { + self.fatal_proc_rec( + &format!( + "auxiliary build of {:?} failed to compile: ", + self.config.minicore_path.display() + ), + &res, + ); + } + + output_file_path + } + /// Builds an aux dependency. fn build_auxiliary( &self, @@ -1662,6 +1699,15 @@ impl<'test> TestCx<'test> { rustc.args(&self.props.compile_flags); + // FIXME(jieyouxu): we should report a fatal error or warning if user wrote `-Cpanic=` with + // something that's not `abort`, however, by moving this last we should override previous + // `-Cpanic=`s + // + // `minicore` requires `#![no_std]` and `#![no_core]`, which means no unwinding panics. + if self.props.add_core_stubs { + rustc.arg("-Cpanic=abort"); + } + rustc } @@ -1848,34 +1894,6 @@ impl<'test> TestCx<'test> { (proc_res, output_path) } - fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) { - // This works with both `--emit asm` (as default output name for the assembly) - // and `ptx-linker` because the latter can write output at requested location. - let output_path = self.output_base_name().with_extension("s"); - let input_file = &self.testpaths.file; - - // Use the `//@ assembly-output:` directive to determine how to emit assembly. - let emit = match self.props.assembly_output.as_deref() { - Some("emit-asm") => Emit::Asm, - Some("bpf-linker") => Emit::LinkArgsAsm, - Some("ptx-linker") => Emit::None, // No extra flags needed. - Some(other) => self.fatal(&format!("unknown 'assembly-output' directive: {other}")), - None => self.fatal("missing 'assembly-output' directive"), - }; - - let rustc = self.make_compile_args( - input_file, - TargetLocation::ThisFile(output_path.clone()), - emit, - AllowUnused::No, - LinkToAux::Yes, - Vec::new(), - ); - - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); - (proc_res, output_path) - } - fn verify_with_filecheck(&self, output: &Path) -> ProcRes { let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap()); filecheck.arg("--input-file").arg(output).arg(&self.testpaths.file); diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs index 430a5534da1..89d7de58c20 100644 --- a/src/tools/compiletest/src/runtest/assembly.rs +++ b/src/tools/compiletest/src/runtest/assembly.rs @@ -1,4 +1,6 @@ -use super::TestCx; +use std::path::PathBuf; + +use super::{AllowUnused, Emit, LinkToAux, ProcRes, TargetLocation, TestCx}; impl TestCx<'_> { pub(super) fn run_assembly_test(&self) { @@ -16,4 +18,32 @@ impl TestCx<'_> { self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res); } } + + fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) { + // This works with both `--emit asm` (as default output name for the assembly) + // and `ptx-linker` because the latter can write output at requested location. + let output_path = self.output_base_name().with_extension("s"); + let input_file = &self.testpaths.file; + + // Use the `//@ assembly-output:` directive to determine how to emit assembly. + let emit = match self.props.assembly_output.as_deref() { + Some("emit-asm") => Emit::Asm, + Some("bpf-linker") => Emit::LinkArgsAsm, + Some("ptx-linker") => Emit::None, // No extra flags needed. + Some(other) => self.fatal(&format!("unknown 'assembly-output' directive: {other}")), + None => self.fatal("missing 'assembly-output' directive"), + }; + + let rustc = self.make_compile_args( + input_file, + TargetLocation::ThisFile(output_path.clone()), + emit, + AllowUnused::No, + LinkToAux::Yes, + Vec::new(), + ); + + let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + (proc_res, output_path) + } } diff --git a/src/tools/miri/clippy.toml b/src/tools/miri/clippy.toml index 284e18a45a3..504be47459c 100644 --- a/src/tools/miri/clippy.toml +++ b/src/tools/miri/clippy.toml @@ -1 +1 @@ -arithmetic-side-effects-allowed = ["rustc_target::abi::Size"] +arithmetic-side-effects-allowed = ["rustc_abi::Size", "rustc_apfloat::ieee::IeeeFloat"] diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 2ec411b54b1..3ff5b22b1ca 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -75eff9a5749411ba5a0b37cc3299116c4e263075 +00ed73cdc09a6452cb58202d56a9211fb3c73031 diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 50e55268248..7b377a1c4cd 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -7,9 +7,9 @@ use std::cell::RefCell; use std::cmp::max; use rand::Rng; +use rustc_abi::{Align, Size}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_span::Span; -use rustc_target::abi::{Align, Size}; use self::reuse_pool::ReusePool; use crate::concurrency::VClock; diff --git a/src/tools/miri/src/alloc_addresses/reuse_pool.rs b/src/tools/miri/src/alloc_addresses/reuse_pool.rs index b5366d5ce92..b0c7ee7dff5 100644 --- a/src/tools/miri/src/alloc_addresses/reuse_pool.rs +++ b/src/tools/miri/src/alloc_addresses/reuse_pool.rs @@ -1,7 +1,7 @@ //! Manages a pool of addresses that can be reused. use rand::Rng; -use rustc_target::abi::{Align, Size}; +use rustc_abi::{Align, Size}; use crate::concurrency::VClock; use crate::{MemoryKind, MiriConfig, ThreadId}; diff --git a/src/tools/miri/src/alloc_bytes.rs b/src/tools/miri/src/alloc_bytes.rs index 6ada8c66fde..69ede279aa9 100644 --- a/src/tools/miri/src/alloc_bytes.rs +++ b/src/tools/miri/src/alloc_bytes.rs @@ -2,8 +2,8 @@ use std::alloc::Layout; use std::borrow::Cow; use std::{alloc, slice}; +use rustc_abi::{Align, Size}; use rustc_middle::mir::interpret::AllocBytes; -use rustc_target::abi::{Align, Size}; /// Allocation bytes that explicitly handle the layout of the data they're storing. /// This is necessary to interface with native code that accesses the program store in Miri. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 717229ba8b3..357c50889c4 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -11,6 +11,7 @@ extern crate tracing; // The rustc crates we need +extern crate rustc_abi; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_hir; @@ -21,7 +22,6 @@ extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; -extern crate rustc_target; use std::env::{self, VarError}; use std::num::NonZero; @@ -29,6 +29,7 @@ use std::path::PathBuf; use std::str::FromStr; use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields, ValidationMode}; +use rustc_abi::ExternAbi; use rustc_data_structures::sync::Lrc; use rustc_driver::Compilation; use rustc_hir::def_id::LOCAL_CRATE; @@ -47,7 +48,6 @@ use rustc_session::config::{CrateType, EntryFnType, ErrorOutputType, OptLevel}; use rustc_session::search_paths::PathKind; use rustc_session::{CtfeBacktrace, EarlyDiagCtxt}; use rustc_span::def_id::DefId; -use rustc_target::spec::abi::Abi; use tracing::debug; struct MiriCompilerCalls { @@ -368,7 +368,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, EntryFnType) { tcx.types.isize, false, hir::Safety::Safe, - Abi::Rust, + ExternAbi::Rust, )); let correct_func_sig = check_function_signature( diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 5204558f98c..72319decb94 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -2,9 +2,9 @@ use std::cell::RefCell; use std::fmt; use std::num::NonZero; +use rustc_abi::Size; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::mir::RetagKind; -use rustc_target::abi::Size; use smallvec::SmallVec; use crate::*; diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs index 5624c4c479e..63b18028a5b 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs @@ -1,8 +1,8 @@ use std::fmt; +use rustc_abi::Size; use rustc_data_structures::fx::FxHashSet; use rustc_span::{Span, SpanData}; -use rustc_target::abi::Size; use smallvec::SmallVec; use crate::borrow_tracker::{GlobalStateInner, ProtectorKind}; diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs index f024796c0a7..dc3370f1251 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs @@ -354,7 +354,7 @@ impl<'tcx> Stack { self.borrows.get(idx).cloned() } - #[allow(clippy::len_without_is_empty)] // Stacks are never empty + #[expect(clippy::len_without_is_empty)] // Stacks are never empty pub fn len(&self) -> usize { self.borrows.len() } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index a551b017dfc..61b3338e6a2 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -12,9 +12,9 @@ use std::{fmt, mem}; +use rustc_abi::Size; use rustc_data_structures::fx::FxHashSet; use rustc_span::Span; -use rustc_target::abi::Size; use smallvec::SmallVec; use crate::borrow_tracker::tree_borrows::Permission; diff --git a/src/tools/miri/src/concurrency/cpu_affinity.rs b/src/tools/miri/src/concurrency/cpu_affinity.rs index 8df26d718bf..4e6bca93c5a 100644 --- a/src/tools/miri/src/concurrency/cpu_affinity.rs +++ b/src/tools/miri/src/concurrency/cpu_affinity.rs @@ -1,5 +1,5 @@ +use rustc_abi::Endian; use rustc_middle::ty::layout::LayoutOf; -use rustc_target::abi::Endian; use crate::*; diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 797b3191d83..f86d1eb1dcb 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -44,13 +44,13 @@ use std::cell::{Cell, Ref, RefCell, RefMut}; use std::fmt::Debug; use std::mem; +use rustc_abi::{Align, HasDataLayout, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_span::Span; -use rustc_target::abi::{Align, HasDataLayout, Size}; use super::vector_clock::{VClock, VTimestamp, VectorIdx}; use super::weak_memory::EvalContextExt as _; diff --git a/src/tools/miri/src/concurrency/range_object_map.rs b/src/tools/miri/src/concurrency/range_object_map.rs index d36ed36ac1a..4c9cf3dc635 100644 --- a/src/tools/miri/src/concurrency/range_object_map.rs +++ b/src/tools/miri/src/concurrency/range_object_map.rs @@ -4,8 +4,8 @@ use std::ops::{Index, IndexMut, Range}; +use rustc_abi::Size; use rustc_const_eval::interpret::AllocRange; -use rustc_target::abi::Size; #[derive(Clone, Debug)] struct Elem<T> { diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index b6668ae5e4e..78e5ad5deb2 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -3,9 +3,9 @@ use std::collections::hash_map::Entry; use std::ops::Not; use std::time::Duration; +use rustc_abi::Size; use rustc_data_structures::fx::FxHashMap; use rustc_index::{Idx, IndexVec}; -use rustc_target::abi::Size; use super::init_once::InitOnce; use super::vector_clock::VClock; diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 3946cb5ee54..281242bf373 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -7,6 +7,7 @@ use std::task::Poll; use std::time::{Duration, SystemTime}; use either::Either; +use rustc_abi::ExternAbi; use rustc_const_eval::CTRL_C_RECEIVED; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; @@ -14,7 +15,6 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::Mutability; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::Span; -use rustc_target::spec::abi::Abi; use crate::concurrency::data_race; use crate::shims::tls; @@ -911,7 +911,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { &mut self, thread: Option<MPlaceTy<'tcx>>, start_routine: Pointer, - start_abi: Abi, + start_abi: ExternAbi, func_arg: ImmTy<'tcx>, ret_layout: TyAndLayout<'tcx>, ) -> InterpResult<'tcx, ThreadId> { diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs index 800c301a821..c610f1999f7 100644 --- a/src/tools/miri/src/concurrency/weak_memory.rs +++ b/src/tools/miri/src/concurrency/weak_memory.rs @@ -300,7 +300,6 @@ impl<'tcx> StoreBuffer { interp_ok(()) } - #[allow(clippy::if_same_then_else, clippy::needless_bool)] /// Selects a valid store element in the buffer. fn fetch_store<R: rand::Rng + ?Sized>( &self, diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index f055662891e..63591474120 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -1,9 +1,9 @@ use std::fmt::{self, Write}; use std::num::NonZero; +use rustc_abi::{Align, Size}; use rustc_errors::{Diag, DiagMessage, Level}; use rustc_span::{DUMMY_SP, SpanData, Symbol}; -use rustc_target::abi::{Align, Size}; use crate::borrow_tracker::stacked_borrows::diagnostics::TagHistory; use crate::borrow_tracker::tree_borrows::diagnostics as tree_diagnostics; diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index 9f93f151668..1e56e104918 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -6,13 +6,13 @@ use std::path::PathBuf; use std::task::Poll; use std::{iter, thread}; +use rustc_abi::ExternAbi; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::layout::{LayoutCx, LayoutOf}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; -use rustc_target::spec::abi::Abi; use crate::concurrency::thread::TlsAllocAction; use crate::diagnostics::report_leaks; @@ -391,7 +391,7 @@ pub fn create_ecx<'tcx>( ecx.call_function( start_instance, - Abi::Rust, + ExternAbi::Rust, &[ ImmTy::from_scalar( Scalar::from_pointer(main_ptr, &ecx), @@ -409,7 +409,7 @@ pub fn create_ecx<'tcx>( EntryFnType::Start => { ecx.call_function( entry_instance, - Abi::Rust, + ExternAbi::Rust, &[argc, argv], Some(&ret_place), StackPopCleanup::Root { cleanup: true }, @@ -423,7 +423,7 @@ pub fn create_ecx<'tcx>( /// Evaluates the entry function specified by `entry_id`. /// Returns `Some(return_code)` if program executed completed. /// Returns `None` if an evaluation error occurred. -#[allow(clippy::needless_lifetimes)] +#[expect(clippy::needless_lifetimes)] pub fn eval_entry<'tcx>( tcx: TyCtxt<'tcx>, entry_id: DefId, diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 17f664da853..526030bef2e 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -5,6 +5,7 @@ use std::time::Duration; use std::{cmp, iter}; use rand::RngCore; +use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_hir::Safety; @@ -18,8 +19,6 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy}; use rustc_session::config::CrateType; use rustc_span::{Span, Symbol}; -use rustc_target::abi::{Align, FieldIdx, FieldsShape, Size, Variants}; -use rustc_target::spec::abi::Abi; use crate::*; @@ -157,7 +156,7 @@ pub fn iter_exported_symbols<'tcx>( for cnum in dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| { // We add 1 to the number because that's what rustc also does everywhere it // calls `CrateNum::new`... - #[allow(clippy::arithmetic_side_effects)] + #[expect(clippy::arithmetic_side_effects)] (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1)) }) { // We can ignore `_export_info` here: we are a Rust crate, and everything is exported @@ -435,7 +434,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn call_function( &mut self, f: ty::Instance<'tcx>, - caller_abi: Abi, + caller_abi: ExternAbi, args: &[ImmTy<'tcx>], dest: Option<&MPlaceTy<'tcx>>, stack_pop: StackPopCleanup, @@ -917,7 +916,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Check that the ABI is what we expect. - fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> { + fn check_abi<'a>(&self, abi: ExternAbi, exp_abi: ExternAbi) -> InterpResult<'a, ()> { if abi != exp_abi { throw_ub_format!( "calling a function with ABI {} using caller ABI {}", @@ -953,8 +952,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_abi_and_shim_symbol_clash( &mut self, - abi: Abi, - exp_abi: Abi, + abi: ExternAbi, + exp_abi: ExternAbi, link_name: Symbol, ) -> InterpResult<'tcx, ()> { self.check_abi(abi, exp_abi)?; @@ -978,8 +977,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_shim<'a, const N: usize>( &mut self, - abi: Abi, - exp_abi: Abi, + abi: ExternAbi, + exp_abi: ExternAbi, link_name: Symbol, args: &'a [OpTy<'tcx>], ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index 776d2561b43..272dca1594e 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -4,11 +4,11 @@ mod atomic; mod simd; use rand::Rng; +use rustc_abi::Size; use rustc_apfloat::{Float, Round}; use rustc_middle::mir; use rustc_middle::ty::{self, FloatTy}; use rustc_span::{Symbol, sym}; -use rustc_target::abi::Size; use self::atomic::EvalContextExt as _; use self::helpers::{ToHost, ToSoft, check_arg_count}; @@ -292,7 +292,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let b = this.read_scalar(b)?.to_f32()?; let c = this.read_scalar(c)?.to_f32()?; let fuse: bool = this.machine.rng.get_mut().gen(); - #[allow(clippy::arithmetic_side_effects)] // float ops don't overflow let res = if fuse { // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 a.to_host().mul_add(b.to_host(), c.to_host()).to_soft() @@ -308,7 +307,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let b = this.read_scalar(b)?.to_f64()?; let c = this.read_scalar(c)?.to_f64()?; let fuse: bool = this.machine.rng.get_mut().gen(); - #[allow(clippy::arithmetic_side_effects)] // float ops don't overflow let res = if fuse { // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 a.to_host().mul_add(b.to_host(), c.to_host()).to_soft() diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index f15b83a054f..d5c417e7231 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -1,10 +1,10 @@ use either::Either; +use rustc_abi::{Endian, HasDataLayout}; use rustc_apfloat::{Float, Round}; use rustc_middle::ty::FloatTy; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::{mir, ty}; use rustc_span::{Symbol, sym}; -use rustc_target::abi::{Endian, HasDataLayout}; use crate::helpers::{ToHost, ToSoft, bool_to_simd_element, check_arg_count, simd_element_to_bool}; use crate::*; @@ -750,7 +750,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let val = if simd_element_to_bool(mask)? { // Size * u64 is implemented as always checked - #[allow(clippy::arithmetic_side_effects)] let ptr = ptr.wrapping_offset(dest.layout.size * i, this); let place = this.ptr_to_mplace(ptr, dest.layout); this.read_immediate(&place)? @@ -774,7 +773,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if simd_element_to_bool(mask)? { // Size * u64 is implemented as always checked - #[allow(clippy::arithmetic_side_effects)] let ptr = ptr.wrapping_offset(val.layout.size * i, this); let place = this.ptr_to_mplace(ptr, val.layout); this.write_immediate(*val, &place)? @@ -831,7 +829,7 @@ fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { assert!(idx < vec_len); match endianness { Endian::Little => idx, - #[allow(clippy::arithmetic_side_effects)] // idx < vec_len + #[expect(clippy::arithmetic_side_effects)] // idx < vec_len Endian::Big => vec_len - 1 - idx, // reverse order of bits } } diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 60d096b92f2..cc24094b17e 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -10,6 +10,7 @@ use std::{fmt, process}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; +use rustc_abi::{Align, ExternAbi, Size}; use rustc_attr::InlineAttr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[allow(unused)] @@ -21,8 +22,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_session::config::InliningThreshold; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::{Span, SpanData, Symbol}; -use rustc_target::abi::{Align, Size}; -use rustc_target::spec::abi::Abi; use crate::concurrency::cpu_affinity::{self, CpuAffinityMask}; use crate::concurrency::data_race::{self, NaReadType, NaWriteType}; @@ -1006,7 +1005,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn find_mir_or_eval_fn( ecx: &mut MiriInterpCx<'tcx>, instance: ty::Instance<'tcx>, - abi: Abi, + abi: ExternAbi, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -1033,7 +1032,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { fn call_extra_fn( ecx: &mut MiriInterpCx<'tcx>, fn_val: DynSym, - abi: Abi, + abi: ExternAbi, args: &[FnArg<'tcx, Provenance>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -1075,7 +1074,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { // Call the lang item. let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap(); let panic = ty::Instance::mono(ecx.tcx.tcx, panic); - ecx.call_function(panic, Abi::Rust, &[], None, StackPopCleanup::Goto { + ecx.call_function(panic, ExternAbi::Rust, &[], None, StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable, })?; diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs index 608e23fc110..0017a3991b5 100644 --- a/src/tools/miri/src/operator.rs +++ b/src/tools/miri/src/operator.rs @@ -2,9 +2,9 @@ use std::iter; use rand::Rng; use rand::seq::IteratorRandom; +use rustc_abi::Size; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir; -use rustc_target::abi::Size; use crate::*; diff --git a/src/tools/miri/src/range_map.rs b/src/tools/miri/src/range_map.rs index 4a3670b76ac..2c2484cd0bc 100644 --- a/src/tools/miri/src/range_map.rs +++ b/src/tools/miri/src/range_map.rs @@ -7,7 +7,7 @@ use std::ops; -use rustc_target::abi::Size; +use rustc_abi::Size; #[derive(Clone, Debug)] struct Elem<T> { diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index e73344367ec..25c0b52d061 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,7 +1,7 @@ use std::iter; +use rustc_abi::{Align, Size}; use rustc_ast::expand::allocator::AllocatorKind; -use rustc_target::abi::{Align, Size}; use crate::*; diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index ae2cdaa8d57..64bd546458d 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -1,9 +1,8 @@ +use rustc_abi::{ExternAbi, Size}; use rustc_ast::ast::Mutability; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{BytePos, Loc, Symbol, hygiene}; -use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; use crate::helpers::check_min_arg_count; use crate::*; @@ -12,13 +11,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_backtrace_size( &mut self, - abi: Abi, + abi: ExternAbi, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [flags] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { @@ -32,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_get_backtrace( &mut self, - abi: Abi, + abi: ExternAbi, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, @@ -73,7 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // storage for pointers is allocated by miri // deallocating the slice is undefined behavior with a custom global allocator 0 => { - let [_flags] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [_flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?; @@ -88,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // storage for pointers is allocated by the caller 1 => { - let [_flags, buf] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [_flags, buf] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let buf_place = this.deref_pointer(buf)?; @@ -138,13 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame( &mut self, - abi: Abi, + abi: ExternAbi, link_name: Symbol, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); - let [ptr, flags] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr, flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; @@ -216,14 +215,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn handle_miri_resolve_frame_names( &mut self, - abi: Abi, + abi: ExternAbi, link_name: Symbol, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx> { let this = self.eval_context_mut(); let [ptr, flags, name_ptr, filename_ptr] = - this.check_shim(abi, Abi::Rust, link_name, args)?; + this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let flags = this.read_scalar(flags)?.to_u64()?; if flags != 0 { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 12f8facfd02..8f7c56a2907 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -3,6 +3,7 @@ use std::io::Write; use std::iter; use std::path::Path; +use rustc_abi::{Align, AlignFromBytesError, ExternAbi, Size}; use rustc_apfloat::Float; use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; @@ -10,8 +11,6 @@ use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::{mir, ty}; use rustc_span::Symbol; -use rustc_target::abi::{Align, AlignFromBytesError, Size}; -use rustc_target::spec::abi::Abi; use self::helpers::{ToHost, ToSoft}; use super::alloc::EvalContextExt as _; @@ -22,7 +21,7 @@ use crate::*; #[derive(Debug, Copy, Clone)] pub struct DynSym(Symbol); -#[allow(clippy::should_implement_trait)] +#[expect(clippy::should_implement_trait)] impl DynSym { pub fn from_str(name: &str) -> Self { DynSym(Symbol::intern(name)) @@ -40,7 +39,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -107,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_dyn_sym( &mut self, sym: DynSym, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ret: Option<mir::BasicBlock>, @@ -219,7 +218,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -240,7 +239,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // When adding a new shim, you should follow the following pattern: // ``` // "shim_name" => { - // let [arg1, arg2, arg3] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + // let [arg1, arg2, arg3] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // let result = this.shim_name(arg1, arg2, arg3)?; // this.write_scalar(result, dest)?; // } @@ -278,16 +277,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miri-specific extern functions "miri_start_unwind" => { - let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [payload] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "miri_run_provenance_gc" => { - let [] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; this.run_provenance_gc(); } "miri_get_alloc_id" => { - let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| { err_machine_stop!(TerminationInfo::Abort(format!( @@ -297,7 +296,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?; } "miri_print_borrow_state" => { - let [id, show_unnamed] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [id, show_unnamed] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let id = this.read_scalar(id)?.to_u64()?; let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?; if let Some(id) = std::num::NonZero::new(id).map(AllocId) @@ -311,7 +310,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { "miri_pointer_name" => { // This associates a name to a tag. Very useful for debugging, and also makes // tests more strict. - let [ptr, nth_parent, name] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr, nth_parent, name] = + this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nth_parent = this.read_scalar(nth_parent)?.to_u8()?; let name = this.read_immediate(name)?; @@ -324,7 +324,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.give_pointer_debug_name(ptr, nth_parent, &name)?; } "miri_static_root" => { - let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?; if offset != Size::ZERO { @@ -335,7 +335,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.machine.static_roots.push(alloc_id); } "miri_host_to_target_path" => { - let [ptr, out, out_size] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr, out, out_size] = + this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let out = this.read_pointer(out)?; let out_size = this.read_scalar(out_size)?.to_target_usize(this)?; @@ -371,7 +372,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Writes some bytes to the interpreter's stdout/stderr. See the // README for details. "miri_write_to_stdout" | "miri_write_to_stderr" => { - let [msg] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [msg] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let msg = this.read_immediate(msg)?; let msg = this.read_byte_slice(&msg)?; // Note: we're ignoring errors writing to host stdout/stderr. @@ -383,9 +384,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Promises that a pointer has a given symbolic alignment. "miri_promise_symbolic_alignment" => { - use rustc_target::abi::AlignFromBytesError; + use rustc_abi::AlignFromBytesError; - let [ptr, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [ptr, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let align = this.read_target_usize(align)?; if !align.is_power_of_two() { @@ -426,12 +427,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Aborting the process. "exit" => { - let [code] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [code] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let code = this.read_scalar(code)?.to_i32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } "abort" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; throw_machine_stop!(TerminationInfo::Abort( "the program aborted execution".to_owned() )) @@ -439,7 +441,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Standard C allocation "malloc" => { - let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [size] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let size = this.read_target_usize(size)?; if size <= this.max_size_of_val().bytes() { let res = this.malloc(size, /*zero_init:*/ false)?; @@ -454,7 +457,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "calloc" => { let [items, elem_size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let items = this.read_target_usize(items)?; let elem_size = this.read_target_usize(elem_size)?; if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) { @@ -469,13 +472,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "free" => { - let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [ptr] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; this.free(ptr)?; } "realloc" => { let [old_ptr, new_size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let old_ptr = this.read_pointer(old_ptr)?; let new_size = this.read_target_usize(new_size)?; if new_size <= this.max_size_of_val().bytes() { @@ -495,7 +499,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { let default = |this: &mut MiriInterpCx<'tcx>| { // Only call `check_shim` when `#[global_allocator]` isn't used. When that // macro is used, we act like no shim exists, so that the exported function can run. - let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -529,7 +533,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.emulate_allocator(|this| { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. - let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; + let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let size = this.read_target_usize(size)?; let align = this.read_target_usize(align)?; @@ -555,7 +559,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align] = - this.check_shim(abi, Abi::Rust, link_name, args)?; + this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; @@ -590,7 +594,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // See the comment for `__rust_alloc` why `check_shim` is only called in the // default case. let [ptr, old_size, align, new_size] = - this.check_shim(abi, Abi::Rust, link_name, args)?; + this.check_shim(abi, ExternAbi::Rust, link_name, args)?; let ptr = this.read_pointer(ptr)?; let old_size = this.read_target_usize(old_size)?; let align = this.read_target_usize(align)?; @@ -614,7 +618,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // C memory handling functions "memcmp" => { let [left, right, n] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let left = this.read_pointer(left)?; let right = this.read_pointer(right)?; let n = Size::from_bytes(this.read_target_usize(n)?); @@ -639,12 +643,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memrchr" => { let [ptr, val, num] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". - #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] + #[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; // C requires that this must always be a valid pointer (C18 §7.1.4). @@ -657,7 +661,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { .position(|&c| c == val) { let idx = u64::try_from(idx).unwrap(); - #[allow(clippy::arithmetic_side_effects)] // idx < num, so this never wraps + #[expect(clippy::arithmetic_side_effects)] // idx < num, so this never wraps let new_ptr = ptr.wrapping_offset(Size::from_bytes(num - idx - 1), this); this.write_pointer(new_ptr, dest)?; } else { @@ -666,12 +670,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memchr" => { let [ptr, val, num] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let val = this.read_scalar(val)?.to_i32()?; let num = this.read_target_usize(num)?; // The docs say val is "interpreted as unsigned char". - #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] + #[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)] let val = val as u8; // C requires that this must always be a valid pointer (C18 §7.1.4). @@ -689,7 +693,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "strlen" => { - let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [ptr] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr)?.len(); @@ -699,7 +704,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { )?; } "wcslen" => { - let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [ptr] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_wchar_t_str(ptr)?.len(); @@ -710,7 +716,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "memcpy" => { let [ptr_dest, ptr_src, n] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; let n = this.read_target_usize(n)?; @@ -725,7 +731,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } "strcpy" => { let [ptr_dest, ptr_src] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr_dest = this.read_pointer(ptr_dest)?; let ptr_src = this.read_pointer(ptr_src)?; @@ -754,7 +760,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1f" | "tgammaf" => { - let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let f = this.read_scalar(f)?.to_f32()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -782,7 +788,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2f" | "fdimf" => { - let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let f1 = this.read_scalar(f1)?.to_f32()?; let f2 = this.read_scalar(f2)?.to_f32()?; // underscore case for windows, here and below @@ -811,7 +817,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "expm1" | "tgamma" => { - let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let f = this.read_scalar(f)?.to_f64()?; // Using host floats (but it's fine, these operations do not have guaranteed precision). let f_host = f.to_host(); @@ -839,7 +845,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "atan2" | "fdim" => { - let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let f1 = this.read_scalar(f1)?.to_f64()?; let f2 = this.read_scalar(f2)?.to_f64()?; // underscore case for windows, here and below @@ -860,7 +866,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ldexp" | "scalbn" => { - let [x, exp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [x, exp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same. let x = this.read_scalar(x)?.to_f64()?; let exp = this.read_scalar(exp)?.to_i32()?; @@ -870,7 +876,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgammaf_r" => { - let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [x, signp] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let x = this.read_scalar(x)?.to_f32()?; let signp = this.deref_pointer(signp)?; @@ -881,7 +888,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "lgamma_r" => { - let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [x, signp] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let x = this.read_scalar(x)?.to_f64()?; let signp = this.deref_pointer(signp)?; @@ -895,7 +903,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // LLVM intrinsics "llvm.prefetch" => { let [p, rw, loc, ty] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let _ = this.read_pointer(p)?; let rw = this.read_scalar(rw)?.to_i32()?; @@ -922,7 +930,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm // `{i,u}8x16_popcnt` functions. name if name.starts_with("llvm.ctpop.v") => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -953,7 +961,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // FIXME: Move these to an `arm` submodule. "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => { - let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; match arg { // SY ("full system scope") @@ -966,7 +974,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => { - let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; let arg = this.read_scalar(arg)?.to_i32()?; // Note that different arguments might have different target feature requirements. match arg { diff --git a/src/tools/miri/src/shims/io_error.rs b/src/tools/miri/src/shims/io_error.rs index a50bba0d2e4..0cbb4850b7f 100644 --- a/src/tools/miri/src/shims/io_error.rs +++ b/src/tools/miri/src/shims/io_error.rs @@ -188,7 +188,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// The inverse of `io_error_to_errnum`. - #[allow(clippy::needless_return)] + #[expect(clippy::needless_return)] fn try_errnum_to_io_error( &self, errnum: Scalar, diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 9bb0d7d0ce6..722c3a2f0c5 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -11,10 +11,10 @@ //! gets popped *during unwinding*, we take the panic payload and store it according to the extra //! metadata we remembered when pushing said frame. +use rustc_abi::ExternAbi; use rustc_ast::Mutability; use rustc_middle::{mir, ty}; use rustc_target::spec::PanicStrategy; -use rustc_target::spec::abi::Abi; use self::helpers::check_arg_count; use crate::*; @@ -88,7 +88,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { trace!("try_fn: {:?}", f_instance); this.call_function( f_instance, - Abi::Rust, + ExternAbi::Rust, &[data.clone()], None, // Directly return to caller. @@ -139,7 +139,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { trace!("catch_fn: {:?}", f_instance); this.call_function( f_instance, - Abi::Rust, + ExternAbi::Rust, &[catch_unwind.data, payload], None, // Directly return to caller of `try`. @@ -168,7 +168,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let panic = ty::Instance::mono(this.tcx.tcx, panic); this.call_function( panic, - Abi::Rust, + ExternAbi::Rust, &[this.mplace_to_ref(&msg)?], None, StackPopCleanup::Goto { ret: None, unwind }, @@ -187,7 +187,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let panic = ty::Instance::mono(this.tcx.tcx, panic); this.call_function( panic, - Abi::Rust, + ExternAbi::Rust, &[this.mplace_to_ref(&msg)?], None, StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable }, @@ -216,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check); this.call_function( panic_bounds_check, - Abi::Rust, + ExternAbi::Rust, &[index, len], None, StackPopCleanup::Goto { ret: None, unwind }, @@ -237,7 +237,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ty::Instance::mono(this.tcx.tcx, panic_misaligned_pointer_dereference); this.call_function( panic_misaligned_pointer_dereference, - Abi::Rust, + ExternAbi::Rust, &[required, found], None, StackPopCleanup::Goto { ret: None, unwind }, @@ -248,7 +248,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Call the lang item associated with this message. let fn_item = this.tcx.require_lang_item(msg.panic_function(), None); let instance = ty::Instance::mono(this.tcx.tcx, fn_item); - this.call_function(instance, Abi::Rust, &[], None, StackPopCleanup::Goto { + this.call_function(instance, ExternAbi::Rust, &[], None, StackPopCleanup::Goto { ret: None, unwind, })?; diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs index 94b2d1bc782..46a417689a2 100644 --- a/src/tools/miri/src/shims/tls.rs +++ b/src/tools/miri/src/shims/tls.rs @@ -4,9 +4,8 @@ use std::collections::BTreeMap; use std::collections::btree_map::Entry as BTreeEntry; use std::task::Poll; +use rustc_abi::{ExternAbi, HasDataLayout, Size}; use rustc_middle::ty; -use rustc_target::abi::{HasDataLayout, Size}; -use rustc_target::spec::abi::Abi; use crate::*; @@ -54,7 +53,7 @@ impl<'tcx> Default for TlsData<'tcx> { impl<'tcx> TlsData<'tcx> { /// Generate a new TLS key with the given destructor. /// `max_size` determines the integer size the key has to fit in. - #[allow(clippy::arithmetic_side_effects)] + #[expect(clippy::arithmetic_side_effects)] pub fn create_tls_key( &mut self, dtor: Option<ty::Instance<'tcx>>, @@ -323,7 +322,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // but both are ignored by std. this.call_function( thread_callback, - Abi::System { unwind: false }, + ExternAbi::System { unwind: false }, &[null_ptr.clone(), ImmTy::from_scalar(reason, this.machine.layouts.u32), null_ptr], None, StackPopCleanup::Root { cleanup: true }, @@ -344,7 +343,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.call_function( instance, - Abi::C { unwind: false }, + ExternAbi::C { unwind: false }, &[ImmTy::from_scalar(data, this.machine.layouts.mut_raw_ptr)], None, StackPopCleanup::Root { cleanup: true }, @@ -381,7 +380,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.call_function( instance, - Abi::C { unwind: false }, + ExternAbi::C { unwind: false }, &[ImmTy::from_scalar(ptr, this.machine.layouts.mut_raw_ptr)], None, StackPopCleanup::Root { cleanup: true }, diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs index 2e10e82d936..80ad40e1624 100644 --- a/src/tools/miri/src/shims/unix/android/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::shims::unix::android::thread::prctl; use crate::shims::unix::linux::syscall::syscall; @@ -14,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Miscellaneous "__errno" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs index 6f5f0f74a22..1da13d48252 100644 --- a/src/tools/miri/src/shims/unix/android/thread.rs +++ b/src/tools/miri/src/shims/unix/android/thread.rs @@ -1,6 +1,5 @@ +use rustc_abi::{ExternAbi, Size}; use rustc_span::Symbol; -use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; use crate::helpers::check_min_arg_count; use crate::shims::unix::thread::EvalContextExt as _; @@ -11,13 +10,13 @@ const TASK_COMM_LEN: usize = 16; pub fn prctl<'tcx>( this: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `prctl` is variadic. The argument // count is checked bellow. - this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch. let pr_set_name = 15; diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs index 96c5a9fad9b..aebb5757aec 100644 --- a/src/tools/miri/src/shims/unix/env.rs +++ b/src/tools/miri/src/shims/unix/env.rs @@ -2,10 +2,10 @@ use std::ffi::{OsStr, OsString}; use std::io::ErrorKind; use std::{env, mem}; +use rustc_abi::Size; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; -use rustc_target::abi::Size; use crate::*; diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs index f3db56695fc..27bdd508f77 100644 --- a/src/tools/miri/src/shims/unix/fd.rs +++ b/src/tools/miri/src/shims/unix/fd.rs @@ -7,7 +7,7 @@ use std::io::{self, ErrorKind, IsTerminal, Read, SeekFrom, Write}; use std::ops::Deref; use std::rc::{Rc, Weak}; -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::helpers::check_min_arg_count; use crate::shims::unix::linux::epoll::EpollReadyEvents; diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 355c93c444c..d59d6712c4f 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -1,10 +1,9 @@ use std::ffi::OsStr; use std::str; +use rustc_abi::{ExternAbi, Size}; use rustc_middle::ty::layout::LayoutOf; use rustc_span::Symbol; -use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; use self::shims::unix::android::foreign_items as android; use self::shims::unix::freebsd::foreign_items as freebsd; @@ -43,7 +42,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -54,47 +53,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // Environment related shims "getenv" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.getenv(name)?; this.write_pointer(result, dest)?; } "unsetenv" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.unsetenv(name)?; this.write_scalar(result, dest)?; } "setenv" => { - let [name, value, overwrite] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name, value, overwrite] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_scalar(overwrite)?.to_i32()?; let result = this.setenv(name, value)?; this.write_scalar(result, dest)?; } "getcwd" => { - let [buf, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [buf, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.getcwd(buf, size)?; this.write_pointer(result, dest)?; } "chdir" => { - let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.chdir(path)?; this.write_scalar(result, dest)?; } "getpid" => { - let [] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; let result = this.getpid()?; this.write_scalar(result, dest)?; } // File descriptors "read" => { - let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; this.read(fd, buf, count, None, dest)?; } "write" => { - let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, n] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -102,7 +101,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, None, dest)?; } "pread" => { - let [fd, buf, count, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -110,7 +109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite" => { - let [fd, buf, n, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -119,7 +118,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "pread64" => { - let [fd, buf, count, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(count)?; @@ -127,7 +126,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.read(fd, buf, count, Some(offset), dest)?; } "pwrite64" => { - let [fd, buf, n, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let buf = this.read_pointer(buf)?; let count = this.read_target_usize(n)?; @@ -136,32 +135,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write(fd, buf, count, Some(offset), dest)?; } "close" => { - let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.close(fd)?; this.write_scalar(result, dest)?; } "fcntl" => { // `fcntl` is variadic. The argument count is checked based on the first argument // in `this.fcntl()`, so we do not use `check_shim` here. - this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; let result = this.fcntl(args)?; this.write_scalar(result, dest)?; } "dup" => { - let [old_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [old_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.dup(old_fd)?; this.write_scalar(new_fd, dest)?; } "dup2" => { - let [old_fd, new_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [old_fd, new_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let old_fd = this.read_scalar(old_fd)?.to_i32()?; let new_fd = this.read_scalar(new_fd)?.to_i32()?; let result = this.dup2(old_fd, new_fd)?; this.write_scalar(result, dest)?; } "flock" => { - let [fd, op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let op = this.read_scalar(op)?.to_i32()?; let result = this.flock(fd, op)?; @@ -171,47 +170,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // File and file system access "open" | "open64" => { // `open` is variadic, the third argument is only present when the second argument has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set - this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; let result = this.open(args)?; this.write_scalar(result, dest)?; } "unlink" => { - let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.unlink(path)?; this.write_scalar(result, dest)?; } "symlink" => { - let [target, linkpath] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [target, linkpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.symlink(target, linkpath)?; this.write_scalar(result, dest)?; } "rename" => { - let [oldpath, newpath] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [oldpath, newpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.rename(oldpath, newpath)?; this.write_scalar(result, dest)?; } "mkdir" => { - let [path, mode] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [path, mode] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.mkdir(path, mode)?; this.write_scalar(result, dest)?; } "rmdir" => { - let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.rmdir(path)?; this.write_scalar(result, dest)?; } "opendir" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "closedir" => { - let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [dirp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.closedir(dirp)?; this.write_scalar(result, dest)?; } "lseek64" => { - let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_i64()?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -219,7 +218,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(result, dest)?; } "lseek" => { - let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let whence = this.read_scalar(whence)?.to_i32()?; @@ -228,7 +227,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate64" => { let [fd, length] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_i64()?; let result = this.ftruncate64(fd, length.into())?; @@ -236,30 +235,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "ftruncate" => { let [fd, length] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let fd = this.read_scalar(fd)?.to_i32()?; let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?; let result = this.ftruncate64(fd, length)?; this.write_scalar(result, dest)?; } "fsync" => { - let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.fsync(fd)?; this.write_scalar(result, dest)?; } "fdatasync" => { - let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.fdatasync(fd)?; this.write_scalar(result, dest)?; } "readlink" => { - let [pathname, buf, bufsize] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [pathname, buf, bufsize] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.readlink(pathname, buf, bufsize)?; this.write_scalar(Scalar::from_target_isize(result, this), dest)?; } "posix_fadvise" => { let [fd, offset, len, advice] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_scalar(fd)?.to_i32()?; this.read_target_isize(offset)?; this.read_target_isize(len)?; @@ -268,12 +267,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "realpath" => { - let [path, resolved_path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [path, resolved_path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } "mkstemp" => { - let [template] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [template] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.mkstemp(template)?; this.write_scalar(result, dest)?; } @@ -281,13 +280,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unnamed sockets and pipes "socketpair" => { let [domain, type_, protocol, sv] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.socketpair(domain, type_, protocol, sv)?; this.write_scalar(result, dest)?; } "pipe" => { let [pipefd] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pipe2(pipefd, /*flags*/ None)?; this.write_scalar(result, dest)?; } @@ -300,44 +299,44 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [pipefd, flags] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pipe2(pipefd, Some(flags))?; this.write_scalar(result, dest)?; } // Time "gettimeofday" => { - let [tv, tz] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [tv, tz] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.gettimeofday(tv, tz)?; this.write_scalar(result, dest)?; } "localtime_r" => { - let [timep, result_op] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?; + let [timep, result_op] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; let result = this.localtime_r(timep, result_op)?; this.write_pointer(result, dest)?; } "clock_gettime" => { let [clk_id, tp] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.clock_gettime(clk_id, tp)?; this.write_scalar(result, dest)?; } // Allocation "posix_memalign" => { - let [memptr, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [memptr, align, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "mmap" => { - let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?; + let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?; let ptr = this.mmap(addr, length, prot, flags, fd, offset)?; this.write_scalar(ptr, dest)?; } "munmap" => { - let [addr, length] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?; + let [addr, length] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?; let result = this.munmap(addr, length)?; this.write_scalar(result, dest)?; } @@ -351,7 +350,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, nmemb, size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let nmemb = this.read_target_usize(nmemb)?; let size = this.read_target_usize(size)?; @@ -375,14 +374,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a C11 function, we assume all Unixes have it. // (MSVC explicitly does not support this.) let [align, size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } // Dynamic symbol loading "dlsym" => { - let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [handle, symbol] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_target_usize(handle)?; let symbol = this.read_pointer(symbol)?; let name = this.read_c_str(symbol)?; @@ -396,7 +395,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "sysconf" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let name = this.read_scalar(name)?.to_i32()?; // FIXME: Which of these are POSIX, and which are GNU/Linux? // At least the names seem to all also exist on macOS. @@ -425,7 +424,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "pthread_key_create" => { - let [key, dtor] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?; let dtor = this.read_pointer(dtor)?; @@ -453,21 +452,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "pthread_key_delete" => { - let [key] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; this.machine.tls.delete_tls_key(key)?; // Return success (0) this.write_null(dest)?; } "pthread_getspecific" => { - let [key] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; this.write_scalar(ptr, dest)?; } "pthread_setspecific" => { - let [key, new_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [key, new_ptr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let key = this.read_scalar(key)?.to_bits(key.layout.size)?; let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -479,151 +478,151 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "pthread_mutexattr_init" => { - let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_mutexattr_init(attr)?; this.write_null(dest)?; } "pthread_mutexattr_settype" => { - let [attr, kind] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [attr, kind] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_mutexattr_settype(attr, kind)?; this.write_scalar(result, dest)?; } "pthread_mutexattr_destroy" => { - let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_mutexattr_destroy(attr)?; this.write_null(dest)?; } "pthread_mutex_init" => { - let [mutex, attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [mutex, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_mutex_init(mutex, attr)?; this.write_null(dest)?; } "pthread_mutex_lock" => { - let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_mutex_lock(mutex, dest)?; } "pthread_mutex_trylock" => { - let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_mutex_trylock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_unlock" => { - let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_mutex_unlock(mutex)?; this.write_scalar(result, dest)?; } "pthread_mutex_destroy" => { - let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_mutex_destroy(mutex)?; this.write_int(0, dest)?; } "pthread_rwlock_rdlock" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_rwlock_rdlock(rwlock, dest)?; } "pthread_rwlock_tryrdlock" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_rwlock_tryrdlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_wrlock" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_rwlock_wrlock(rwlock, dest)?; } "pthread_rwlock_trywrlock" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_rwlock_trywrlock(rwlock)?; this.write_scalar(result, dest)?; } "pthread_rwlock_unlock" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_rwlock_unlock(rwlock)?; this.write_null(dest)?; } "pthread_rwlock_destroy" => { - let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_rwlock_destroy(rwlock)?; this.write_null(dest)?; } "pthread_condattr_init" => { - let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_condattr_init(attr)?; this.write_null(dest)?; } "pthread_condattr_setclock" => { let [attr, clock_id] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.pthread_condattr_setclock(attr, clock_id)?; this.write_scalar(result, dest)?; } "pthread_condattr_getclock" => { let [attr, clock_id] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_condattr_getclock(attr, clock_id)?; this.write_null(dest)?; } "pthread_condattr_destroy" => { - let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_condattr_destroy(attr)?; this.write_null(dest)?; } "pthread_cond_init" => { - let [cond, attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_init(cond, attr)?; this.write_null(dest)?; } "pthread_cond_signal" => { - let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_signal(cond)?; this.write_null(dest)?; } "pthread_cond_broadcast" => { - let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_broadcast(cond)?; this.write_null(dest)?; } "pthread_cond_wait" => { - let [cond, mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond, mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_wait(cond, mutex, dest)?; } "pthread_cond_timedwait" => { - let [cond, mutex, abstime] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond, mutex, abstime] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_timedwait(cond, mutex, abstime, dest)?; } "pthread_cond_destroy" => { - let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_cond_destroy(cond)?; this.write_null(dest)?; } // Threading "pthread_create" => { - let [thread, attr, start, arg] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [thread, attr, start, arg] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_create(thread, attr, start, arg)?; this.write_null(dest)?; } "pthread_join" => { - let [thread, retval] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [thread, retval] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_join(thread, retval)?; this.write_null(dest)?; } "pthread_detach" => { - let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [thread] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.pthread_detach(thread)?; this.write_null(dest)?; } "pthread_self" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let res = this.pthread_self()?; this.write_scalar(res, dest)?; } "sched_yield" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.sched_yield()?; this.write_null(dest)?; } "nanosleep" => { - let [req, rem] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [req, rem] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.nanosleep(req, rem)?; this.write_scalar(result, dest)?; } @@ -637,7 +636,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -677,7 +676,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [pid, cpusetsize, mask] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let pid = this.read_scalar(pid)?.to_u32()?; let cpusetsize = this.read_target_usize(cpusetsize)?; let mask = this.read_pointer(mask)?; @@ -713,12 +712,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "isatty" => { - let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.isatty(fd)?; this.write_scalar(result, dest)?; } "pthread_atfork" => { - let [prepare, parent, child] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [prepare, parent, child] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_pointer(prepare)?; this.read_pointer(parent)?; this.read_pointer(child)?; @@ -726,7 +725,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_null(dest)?; } "strerror_r" | "__xpg_strerror_r" => { - let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [errnum, buf, buflen] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errnum = this.read_scalar(errnum)?; let buf = this.read_pointer(buf)?; let buflen = this.read_target_usize(buflen)?; @@ -751,7 +750,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [buf, bufsize] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let buf = this.read_pointer(buf)?; let bufsize = this.read_target_usize(bufsize)?; @@ -777,7 +776,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } let [ptr, len, flags] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; let _flags = this.read_scalar(flags)?.to_i32()?; @@ -794,7 +793,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.sess.target.os ); } - let [ptr, len] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?; + let [ptr, len] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -820,12 +819,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?; + let [payload] = this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } "getuid" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // For now, just pretend we always have this fixed UID. this.write_int(UID, dest)?; } @@ -834,7 +833,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_getguardsize" if this.frame_in_std() => { - let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [_attr, guard_size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let guard_size = this.deref_pointer(guard_size)?; let guard_size_layout = this.libc_ty_layout("size_t"); this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?; @@ -846,12 +845,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "pthread_attr_init" | "pthread_attr_destroy" if this.frame_in_std() => { - let [_] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [_] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } | "pthread_attr_setstacksize" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } @@ -860,7 +859,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here. // Hence we can mostly ignore the input `attr_place`. let [attr_place, addr_place, size_place] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?; let addr_place = this.deref_pointer(addr_place)?; let size_place = this.deref_pointer(size_place)?; @@ -881,13 +880,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "signal" | "sigaltstack" if this.frame_in_std() => { - let [_, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } | "sigaction" | "mprotect" if this.frame_in_std() => { - let [_, _, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [_, _, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } @@ -895,7 +894,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { if this.frame_in_std() => { // getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish let [uid, pwd, buf, buflen, result] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.check_no_isolation("`getpwuid_r`")?; let uid = this.read_scalar(uid)?.to_u32()?; diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs index 71953aca989..1346d8de7ea 100644 --- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::shims::unix::*; use crate::*; @@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_set_name_np" => { let [thread, name] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let max_len = usize::MAX; // FreeBSD does not seem to have a limit. // FreeBSD's pthread_set_name_np does not return anything. this.pthread_setname_np( @@ -34,7 +34,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_get_name_np" => { let [thread, name, len] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // FreeBSD's pthread_get_name_np does not return anything // and uses strlcpy, which truncates the resulting value, // but always adds a null terminator (except for zero-sized buffers). @@ -52,31 +52,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // since freebsd 12 the former form can be expected. "stat" | "stat@FBSD_1.0" => { let [path, buf] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat@FBSD_1.0" => { let [path, buf] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat@FBSD_1.0" => { - let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r@FBSD_1.0" => { let [dirp, entry, result] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } // Miscellaneous "__error" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } @@ -85,7 +86,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_attr_get_np" if this.frame_in_std() => { let [_thread, _attr] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs index f7436d7f089..091def7ac65 100644 --- a/src/tools/miri/src/shims/unix/fs.rs +++ b/src/tools/miri/src/shims/unix/fs.rs @@ -8,8 +8,8 @@ use std::io::{self, ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write}; use std::path::{Path, PathBuf}; use std::time::SystemTime; +use rustc_abi::Size; use rustc_data_structures::fx::FxHashMap; -use rustc_target::abi::Size; use self::fd::FlockOp; use self::shims::time::system_time_to_duration; @@ -385,7 +385,7 @@ pub struct DirTable { } impl DirTable { - #[allow(clippy::arithmetic_side_effects)] + #[expect(clippy::arithmetic_side_effects)] fn insert_new(&mut self, read_dir: ReadDir) -> u64 { let id = self.next_id; self.next_id += 1; diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs index a126d5b4fab..35658ebc2f2 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use self::shims::unix::linux::epoll::EvalContextExt as _; use self::shims::unix::linux::eventfd::EvalContextExt as _; @@ -23,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -34,43 +34,45 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // File related shims "readdir64" => { - let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [dirp] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.linux_readdir64(dirp)?; this.write_scalar(result, dest)?; } "sync_file_range" => { let [fd, offset, nbytes, flags] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.sync_file_range(fd, offset, nbytes, flags)?; this.write_scalar(result, dest)?; } "statx" => { let [dirfd, pathname, flags, mask, statxbuf] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?; this.write_scalar(result, dest)?; } // epoll, eventfd "epoll_create1" => { - let [flag] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [flag] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.epoll_create1(flag)?; this.write_scalar(result, dest)?; } "epoll_ctl" => { let [epfd, op, fd, event] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.epoll_ctl(epfd, op, fd, event)?; this.write_scalar(result, dest)?; } "epoll_wait" => { let [epfd, events, maxevents, timeout] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.epoll_wait(epfd, events, maxevents, timeout, dest)?; } "eventfd" => { let [val, flag] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.eventfd(val, flag)?; this.write_scalar(result, dest)?; } @@ -78,7 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { let [thread, name] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let res = this.pthread_setname_np( this.read_scalar(thread)?, this.read_scalar(name)?, @@ -90,7 +92,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of glibc, the length of the output buffer must // be not shorter than TASK_COMM_LEN. @@ -109,7 +111,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } "gettid" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.linux_gettid()?; this.write_scalar(result, dest)?; } @@ -122,29 +124,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "mmap64" => { let [addr, length, prot, flags, fd, offset] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let offset = this.read_scalar(offset)?.to_i64()?; let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?; this.write_scalar(ptr, dest)?; } "mremap" => { let [old_address, old_size, new_size, flags] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let ptr = this.mremap(old_address, old_size, new_size, flags)?; this.write_scalar(ptr, dest)?; } "__errno_location" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "__libc_current_sigrtmin" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_int(SIGRTMIN, dest)?; } "__libc_current_sigrtmax" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_int(SIGRTMAX, dest)?; } @@ -153,7 +155,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // These shims are enabled only when the caller is in the standard library. "pthread_getattr_np" if this.frame_in_std() => { let [_thread, _attr] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs index d5f9669b360..8e796d5dce5 100644 --- a/src/tools/miri/src/shims/unix/linux/mem.rs +++ b/src/tools/miri/src/shims/unix/linux/mem.rs @@ -1,7 +1,7 @@ //! This follows the pattern in src/shims/unix/mem.rs: We only support uses of mremap that would //! correspond to valid uses of realloc. -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::*; @@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let flags = this.read_scalar(flags)?.to_i32()?; // old_address must be a multiple of the page size - #[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero + #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 { this.set_last_error(LibcError("EINVAL"))?; return interp_ok(this.eval_libc("MAP_FAILED")); diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index 9fbf08b0b18..6d5747d7c15 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -182,7 +182,7 @@ pub fn futex<'tcx>( // before doing the syscall. this.atomic_fence(AtomicFenceOrd::SeqCst)?; let mut n = 0; - #[allow(clippy::arithmetic_side_effects)] + #[expect(clippy::arithmetic_side_effects)] for _ in 0..val { if this.futex_wake(addr_usize, bitset)? { n += 1; diff --git a/src/tools/miri/src/shims/unix/linux/syscall.rs b/src/tools/miri/src/shims/unix/linux/syscall.rs index 72e02447d80..0d7032adab4 100644 --- a/src/tools/miri/src/shims/unix/linux/syscall.rs +++ b/src/tools/miri/src/shims/unix/linux/syscall.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use self::shims::unix::linux::eventfd::EvalContextExt as _; use crate::helpers::check_min_arg_count; @@ -9,13 +9,13 @@ use crate::*; pub fn syscall<'tcx>( this: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx> { // We do not use `check_shim` here because `syscall` is variadic. The argument // count is checked bellow. - this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?; + this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?; // The syscall variadic function is legal to call with more arguments than needed, // extra arguments are simply ignored. The important check is that when we use an // argument, we have to also check all arguments *before* it to ensure that they diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs index cd07bc9e013..b77b46e325d 100644 --- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::sync::EvalContextExt as _; use crate::shims::unix::*; @@ -14,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,55 +25,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { // errno "__error" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } // File related shims "close$NOCANCEL" => { - let [result] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [result] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.close(result)?; this.write_scalar(result, dest)?; } "stat" | "stat64" | "stat$INODE64" => { let [path, buf] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_stat(path, buf)?; this.write_scalar(result, dest)?; } "lstat" | "lstat64" | "lstat$INODE64" => { let [path, buf] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_lstat(path, buf)?; this.write_scalar(result, dest)?; } "fstat" | "fstat64" | "fstat$INODE64" => { - let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [fd, buf] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_fstat(fd, buf)?; this.write_scalar(result, dest)?; } "opendir$INODE64" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.opendir(name)?; this.write_scalar(result, dest)?; } "readdir_r" | "readdir_r$INODE64" => { let [dirp, entry, result] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.macos_fbsd_readdir_r(dirp, entry, result)?; this.write_scalar(result, dest)?; } "realpath$DARWIN_EXTSN" => { let [path, resolved_path] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.realpath(path, resolved_path)?; this.write_scalar(result, dest)?; } // Environment related shims "_NSGetEnviron" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let environ = this.machine.env_vars.unix().environ(); this.write_pointer(environ, dest)?; } @@ -81,7 +84,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Random data generation "CCRandomGenerateBytes" => { let [bytes, count] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let bytes = this.read_pointer(bytes)?; let count = this.read_target_usize(count)?; let success = this.eval_libc_i32("kCCSuccess"); @@ -91,29 +94,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Time related shims "mach_absolute_time" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.mach_absolute_time()?; this.write_scalar(result, dest)?; } "mach_timebase_info" => { - let [info] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [info] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.mach_timebase_info(info)?; this.write_scalar(result, dest)?; } // Access to command-line arguments "_NSGetArgc" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?; } "_NSGetArgv" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?; } "_NSGetExecutablePath" => { let [buf, bufsize] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.check_no_isolation("`_NSGetExecutablePath`")?; let buf_ptr = this.read_pointer(buf)?; @@ -139,7 +143,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Thread-local storage "_tlv_atexit" => { let [dtor, data] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let dtor = this.read_pointer(dtor)?; let dtor = this.get_ptr_fn(dtor)?.as_instance()?; let data = this.read_scalar(data)?; @@ -149,13 +153,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Querying system information "pthread_get_stackaddr_np" => { - let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [thread] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_target_usize(thread)?; let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size()); this.write_scalar(stack_addr, dest)?; } "pthread_get_stacksize_np" => { - let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [thread] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.read_target_usize(thread)?; let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size()); this.write_scalar(stack_size, dest)?; @@ -163,7 +169,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { - let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [name] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // The real implementation has logic in two places: // * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200, @@ -193,7 +200,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // The function's behavior isn't portable between platforms. // In case of macOS, a truncated name (due to a too small buffer) @@ -216,23 +223,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "os_unfair_lock_lock" => { - let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [lock_op] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.os_unfair_lock_lock(lock_op)?; } "os_unfair_lock_trylock" => { - let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [lock_op] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.os_unfair_lock_trylock(lock_op, dest)?; } "os_unfair_lock_unlock" => { - let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [lock_op] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.os_unfair_lock_unlock(lock_op)?; } "os_unfair_lock_assert_owner" => { - let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [lock_op] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.os_unfair_lock_assert_owner(lock_op)?; } "os_unfair_lock_assert_not_owner" => { - let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [lock_op] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; this.os_unfair_lock_assert_not_owner(lock_op)?; } diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs index 1df1202442a..ffc8c222738 100644 --- a/src/tools/miri/src/shims/unix/macos/sync.rs +++ b/src/tools/miri/src/shims/unix/macos/sync.rs @@ -10,7 +10,7 @@ //! and we do not detect copying of the lock, but macOS doesn't guarantee anything //! in that case either. -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::*; diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs index 9371edfc83d..5531b944e17 100644 --- a/src/tools/miri/src/shims/unix/mem.rs +++ b/src/tools/miri/src/shims/unix/mem.rs @@ -14,7 +14,7 @@ //! munmap shim which would partially unmap a region of address space previously mapped by mmap will //! report UB. -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::*; @@ -132,7 +132,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // addr must be a multiple of the page size, but apart from that munmap is just implemented // as a dealloc. - #[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero + #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero if addr.addr().bytes() % this.machine.page_size != 0 { return this.set_last_error_and_return_i32(LibcError("EINVAL")); } diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs index c9c1b01b8b1..efdc64f45fc 100644 --- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::shims::unix::*; use crate::*; @@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "pthread_setname_np" => { let [thread, name] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // THREAD_NAME_MAX allows a thread name of 31+1 length // https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613 let max_len = 32; @@ -37,7 +37,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "pthread_getname_np" => { let [thread, name, len] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // https://github.com/illumos/illumos-gate/blob/c56822be04b6c157c8b6f2281e47214c3b86f657/usr/src/lib/libc/port/threads/thr.c#L2449-L2480 let res = this.pthread_getname_np( this.read_scalar(thread)?, @@ -51,13 +51,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "___errno" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let errno_place = this.last_error_place()?; this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?; } "stack_getbounds" => { - let [stack] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [stack] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?; this.write_int_fields_named( @@ -76,7 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "pset_info" => { let [pset, tpe, cpus, list] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // We do not need to handle the current process cpu mask, available_parallelism // implementation pass null anyway. We only care for the number of // cpus. diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs index a4beaa47baa..850626d89ac 100644 --- a/src/tools/miri/src/shims/unix/sync.rs +++ b/src/tools/miri/src/shims/unix/sync.rs @@ -1,6 +1,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::concurrency::sync::LAZY_INIT_COOKIE; use crate::*; @@ -685,7 +685,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let id = rwlock_get_data(this, rwlock_op)?.id; - #[allow(clippy::if_same_then_else)] if this.rwlock_reader_unlock(id)? || this.rwlock_writer_unlock(id)? { interp_ok(()) } else { diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs index 51256d800a4..52c135f8540 100644 --- a/src/tools/miri/src/shims/unix/thread.rs +++ b/src/tools/miri/src/shims/unix/thread.rs @@ -1,4 +1,4 @@ -use rustc_target::spec::abi::Abi; +use rustc_abi::ExternAbi; use crate::*; @@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.start_regular_thread( Some(thread_info_place), start_routine, - Abi::C { unwind: false }, + ExternAbi::C { unwind: false }, func_arg, this.machine.layouts.mut_raw_ptr, )?; diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs index d0eba1eacd1..8ccce7c1986 100644 --- a/src/tools/miri/src/shims/unix/unnamed_socket.rs +++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs @@ -7,7 +7,7 @@ use std::collections::VecDeque; use std::io; use std::io::{ErrorKind, Read}; -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::concurrency::VClock; use crate::shims::unix::fd::{FileDescriptionRef, WeakFileDescriptionRef}; diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs index b5de950de9a..2c349203d46 100644 --- a/src/tools/miri/src/shims/wasi/foreign_items.rs +++ b/src/tools/miri/src/shims/wasi/foreign_items.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::shims::alloc::EvalContextExt as _; use crate::*; @@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -22,13 +22,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "posix_memalign" => { let [memptr, align, size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let result = this.posix_memalign(memptr, align, size)?; this.write_scalar(result, dest)?; } "aligned_alloc" => { let [align, size] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let res = this.aligned_alloc(align, size)?; this.write_pointer(res, dest)?; } diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index e41ff022549..fe11aa8da4a 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -2,9 +2,8 @@ use std::ffi::OsStr; use std::path::{self, Path, PathBuf}; use std::{io, iter, str}; +use rustc_abi::{Align, ExternAbi, Size}; use rustc_span::Symbol; -use rustc_target::abi::{Align, Size}; -use rustc_target::spec::abi::Abi; use self::shims::windows::handle::{Handle, PseudoHandle}; use crate::shims::os_str::bytes_to_os_str; @@ -26,7 +25,7 @@ fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> { } #[cfg(unix)] -#[allow(clippy::get_first, clippy::arithmetic_side_effects)] +#[expect(clippy::get_first, clippy::arithmetic_side_effects)] fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> { // We are on Unix, so we need to implement parts of the logic ourselves. let bytes = path.as_os_str().as_encoded_bytes(); @@ -79,7 +78,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_foreign_item_inner( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -97,47 +96,49 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Environment related shims "GetEnvironmentVariableW" => { let [name, buf, size] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.GetEnvironmentVariableW(name, buf, size)?; this.write_scalar(result, dest)?; } "SetEnvironmentVariableW" => { let [name, value] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.SetEnvironmentVariableW(name, value)?; this.write_scalar(result, dest)?; } "GetEnvironmentStringsW" => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.GetEnvironmentStringsW()?; this.write_pointer(result, dest)?; } "FreeEnvironmentStringsW" => { let [env_block] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.FreeEnvironmentStringsW(env_block)?; this.write_scalar(result, dest)?; } "GetCurrentDirectoryW" => { let [size, buf] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.GetCurrentDirectoryW(size, buf)?; this.write_scalar(result, dest)?; } "SetCurrentDirectoryW" => { let [path] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.SetCurrentDirectoryW(path)?; this.write_scalar(result, dest)?; } "GetUserProfileDirectoryW" => { let [token, buf, size] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.GetUserProfileDirectoryW(token, buf, size)?; this.write_scalar(result, dest)?; } "GetCurrentProcessId" => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.GetCurrentProcessId()?; this.write_scalar(result, dest)?; } @@ -160,7 +161,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { n, byte_offset, _key, - ] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + ] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let handle = this.read_target_isize(handle)?; let buf = this.read_pointer(buf)?; let n = this.read_scalar(n)?.to_u32()?; @@ -212,7 +213,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetFullPathNameW" => { let [filename, size, buffer, filepart] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.check_no_isolation("`GetFullPathNameW`")?; let filename = this.read_pointer(filename)?; @@ -244,7 +245,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Allocation "HeapAlloc" => { let [handle, flags, size] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(handle)?; let flags = this.read_scalar(flags)?.to_u32()?; let size = this.read_target_usize(size)?; @@ -268,7 +269,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "HeapFree" => { let [handle, flags, ptr] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let ptr = this.read_pointer(ptr)?; @@ -281,7 +282,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "HeapReAlloc" => { let [handle, flags, old_ptr, size] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(handle)?; this.read_scalar(flags)?.to_u32()?; let old_ptr = this.read_pointer(old_ptr)?; @@ -300,7 +301,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest)?; } "LocalFree" => { - let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [ptr] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL." // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree) @@ -313,12 +315,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // errno "SetLastError" => { let [error] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let error = this.read_scalar(error)?; this.set_last_error(error)?; } "GetLastError" => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let last_error = this.get_last_error()?; this.write_scalar(last_error, dest)?; } @@ -327,7 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetSystemInfo" => { // Also called from `page_size` crate. let [system_info] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let system_info = this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?; // Initialize with `0`. @@ -350,12 +353,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // This just creates a key; Windows does not natively support TLS destructors. // Create key and return it. - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let key = this.machine.tls.create_tls_key(None, dest.layout.size)?; this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?; } "TlsGetValue" => { - let [key] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [key] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let ptr = this.machine.tls.load_tls(key, active_thread, this)?; @@ -363,7 +368,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "TlsSetValue" => { let [key, new_ptr] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let key = u128::from(this.read_scalar(key)?.to_u32()?); let active_thread = this.active_thread(); let new_data = this.read_scalar(new_ptr)?; @@ -375,7 +380,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Access to command-line arguments "GetCommandLineW" => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.write_pointer( this.machine.cmd_line.expect("machine must be initialized"), dest, @@ -386,32 +392,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => { #[allow(non_snake_case)] let [LPFILETIME] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?; } "QueryPerformanceCounter" => { #[allow(non_snake_case)] let [lpPerformanceCount] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.QueryPerformanceCounter(lpPerformanceCount)?; this.write_scalar(result, dest)?; } "QueryPerformanceFrequency" => { #[allow(non_snake_case)] let [lpFrequency] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.QueryPerformanceFrequency(lpFrequency)?; this.write_scalar(result, dest)?; } "Sleep" => { let [timeout] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.Sleep(timeout)?; } "CreateWaitableTimerExW" => { let [attributes, name, flags, access] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_pointer(attributes)?; this.read_pointer(name)?; this.read_scalar(flags)?.to_u32()?; @@ -425,30 +431,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Synchronization primitives "InitOnceBeginInitialize" => { let [ptr, flags, pending, context] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?; } "InitOnceComplete" => { let [ptr, flags, context] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let result = this.InitOnceComplete(ptr, flags, context)?; this.write_scalar(result, dest)?; } "WaitOnAddress" => { let [ptr_op, compare_op, size_op, timeout_op] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?; } "WakeByAddressSingle" => { let [ptr_op] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.WakeByAddressSingle(ptr_op)?; } "WakeByAddressAll" => { let [ptr_op] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.WakeByAddressAll(ptr_op)?; } @@ -457,7 +463,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetProcAddress" => { #[allow(non_snake_case)] let [hModule, lpProcName] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(hModule)?; let name = this.read_c_str(this.read_pointer(lpProcName)?)?; if let Ok(name) = str::from_utf8(name) @@ -473,7 +479,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Threading "CreateThread" => { let [security, stacksize, start, arg, flags, thread] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let thread_id = this.CreateThread(security, stacksize, start, arg, flags, thread)?; @@ -482,13 +488,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "WaitForSingleObject" => { let [handle, timeout] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let ret = this.WaitForSingleObject(handle, timeout)?; this.write_scalar(Scalar::from_u32(ret), dest)?; } "GetCurrentThread" => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.write_scalar( Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this), @@ -497,7 +504,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "SetThreadDescription" => { let [handle, name] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let handle = this.read_scalar(handle)?; let name = this.read_wide_str(this.read_pointer(name)?)?; @@ -515,7 +522,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetThreadDescription" => { let [handle, name_ptr] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let handle = this.read_scalar(handle)?; let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name @@ -540,7 +547,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Miscellaneous "ExitProcess" => { let [code] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let code = this.read_scalar(code)?.to_u32()?; throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false }); } @@ -548,7 +555,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // used by getrandom 0.1 // This is really 'RtlGenRandom'. let [ptr, len] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_scalar(len)?.to_u32()?; this.gen_random(ptr, len.into())?; @@ -557,7 +564,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "ProcessPrng" => { // used by `std` let [ptr, len] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let ptr = this.read_pointer(ptr)?; let len = this.read_target_usize(len)?; this.gen_random(ptr, len)?; @@ -566,7 +573,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "BCryptGenRandom" => { // used by getrandom 0.2 let [algorithm, ptr, len, flags] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let algorithm = this.read_scalar(algorithm)?; let algorithm = algorithm.to_target_usize(this)?; let ptr = this.read_pointer(ptr)?; @@ -601,7 +608,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetConsoleScreenBufferInfo" => { // `term` needs this, so we fake it. let [console, buffer_info] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(console)?; // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std this.deref_pointer(buffer_info)?; @@ -611,7 +618,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetStdHandle" => { let [which] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let which = this.read_scalar(which)?.to_i32()?; // We just make this the identity function, so we know later in `NtWriteFile` which // one it is. This is very fake, but libtest needs it so we cannot make it a @@ -621,7 +628,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "CloseHandle" => { let [handle] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.CloseHandle(handle)?; @@ -629,7 +636,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "GetModuleFileNameW" => { let [handle, filename, size] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.check_no_isolation("`GetModuleFileNameW`")?; let handle = this.read_target_usize(handle)?; @@ -663,7 +670,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } "FormatMessageW" => { let [flags, module, message_id, language_id, buffer, size, arguments] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; let flags = this.read_scalar(flags)?.to_u32()?; let _module = this.read_pointer(module)?; // seems to contain a module name @@ -698,7 +705,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Incomplete shims that we "stub out" just to get pre-main initialization code to work. // These shims are enabled only when the caller is in the standard library. "GetProcessHeap" if this.frame_in_std() => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // Just fake a HANDLE // It's fine to not use the Handle type here because its a stub this.write_int(1, dest)?; @@ -706,20 +714,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetModuleHandleA" if this.frame_in_std() => { #[allow(non_snake_case)] let [_lpModuleName] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // We need to return something non-null here to make `compat_fn!` work. this.write_int(1, dest)?; } "SetConsoleTextAttribute" if this.frame_in_std() => { #[allow(non_snake_case)] let [_hConsoleOutput, _wAttribute] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // Pretend these does not exist / nothing happened, by returning zero. this.write_null(dest)?; } "GetConsoleMode" if this.frame_in_std() => { let [console, mode] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.read_target_isize(console)?; this.deref_pointer(mode)?; // Indicate an error. @@ -728,27 +736,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "GetFileType" if this.frame_in_std() => { #[allow(non_snake_case)] let [_hFile] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // Return unknown file type. this.write_null(dest)?; } "AddVectoredExceptionHandler" if this.frame_in_std() => { #[allow(non_snake_case)] let [_First, _Handler] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } "SetThreadStackGuarantee" if this.frame_in_std() => { #[allow(non_snake_case)] let [_StackSizeInBytes] = - this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; // Any non zero value works for the stdlib. This is just used for stack overflows anyway. this.write_int(1, dest)?; } // this is only callable from std because we know that std ignores the return value "SwitchToThread" if this.frame_in_std() => { - let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + let [] = + this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?; this.yield_active_thread(); @@ -767,7 +776,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ); } // This function looks and behaves excatly like miri_start_unwind. - let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?; + let [payload] = + this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?; this.handle_miri_start_unwind(payload)?; return interp_ok(EmulateItemResult::NeedsUnwind); } diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs index 69d78f58bed..437a21534c9 100644 --- a/src/tools/miri/src/shims/windows/handle.rs +++ b/src/tools/miri/src/shims/windows/handle.rs @@ -1,6 +1,6 @@ use std::mem::variant_count; -use rustc_target::abi::HasDataLayout; +use rustc_abi::HasDataLayout; use crate::*; @@ -63,7 +63,7 @@ impl Handle { let floor_log2 = variant_count.ilog2(); // we need to add one for non powers of two to compensate for the difference - #[allow(clippy::arithmetic_side_effects)] // cannot overflow + #[expect(clippy::arithmetic_side_effects)] // cannot overflow if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 } } @@ -88,8 +88,7 @@ impl Handle { // packs the data into the lower `data_size` bits // and packs the discriminant right above the data - #[allow(clippy::arithmetic_side_effects)] // cannot overflow - return discriminant << data_size | data; + discriminant << data_size | data } fn new(discriminant: u32, data: u32) -> Option<Self> { @@ -107,11 +106,10 @@ impl Handle { let data_size = u32::BITS.strict_sub(disc_size); // the lower `data_size` bits of this mask are 1 - #[allow(clippy::arithmetic_side_effects)] // cannot overflow + #[expect(clippy::arithmetic_side_effects)] // cannot overflow let data_mask = 2u32.pow(data_size) - 1; // the discriminant is stored right above the lower `data_size` bits - #[allow(clippy::arithmetic_side_effects)] // cannot overflow let discriminant = handle >> data_size; // the data is stored in the lower `data_size` bits @@ -123,7 +121,7 @@ impl Handle { pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar { // 64-bit handles are sign extended 32-bit handles // see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication - #[allow(clippy::cast_possible_wrap)] // we want it to wrap + #[expect(clippy::cast_possible_wrap)] // we want it to wrap let signed_handle = self.to_packed() as i32; Scalar::from_target_isize(signed_handle.into(), cx) } @@ -134,7 +132,7 @@ impl Handle { ) -> InterpResult<'tcx, Option<Self>> { let sign_extended_handle = handle.to_target_isize(cx)?; - #[allow(clippy::cast_sign_loss)] // we want to lose the sign + #[expect(clippy::cast_sign_loss)] // we want to lose the sign let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) { signed_handle as u32 } else { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index bfc83215f9b..7263958411f 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use rustc_target::abi::Size; +use rustc_abi::Size; use crate::concurrency::init_once::InitOnceStatus; use crate::*; diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs index a920abea3a8..fd3ef1413ed 100644 --- a/src/tools/miri/src/shims/windows/thread.rs +++ b/src/tools/miri/src/shims/windows/thread.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_middle::ty::layout::LayoutOf; -use rustc_target::spec::abi::Abi; use self::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle}; use crate::*; @@ -49,7 +49,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.start_regular_thread( thread, start_routine, - Abi::System { unwind: false }, + ExternAbi::System { unwind: false }, func_arg, this.layout_of(this.tcx.types.u32)?, ) diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs index 3a8138654fd..33b1f27713c 100644 --- a/src/tools/miri/src/shims/x86/aesni.rs +++ b/src/tools/miri/src/shims/x86/aesni.rs @@ -1,7 +1,7 @@ +use rustc_abi::ExternAbi; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::*; @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_aesni_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -27,7 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128 "aesdec" | "aesdec.256" | "aesdec.512" => { let [state, key] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); @@ -45,7 +45,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128 "aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => { let [state, key] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); @@ -70,7 +70,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128 "aesenc" | "aesenc.256" | "aesenc.512" => { let [state, key] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let key = aes::Block::from(key.to_le_bytes()); @@ -88,7 +88,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128 "aesenclast" | "aesenclast.256" | "aesenclast.512" => { let [state, key] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; aes_round(this, state, key, dest, |state, key| { let mut state = aes::Block::from(state.to_le_bytes()); @@ -109,7 +109,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_aesimc_si128 function. // Performs the AES InvMixColumns operation on `op` "aesimc" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // Transmute to `u128` let op = op.transmute(this.machine.layouts.u128, this)?; diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs index 080e7c8ce0b..3971fa3b913 100644 --- a/src/tools/miri/src/shims/x86/avx.rs +++ b/src/tools/miri/src/shims/x86/avx.rs @@ -1,9 +1,9 @@ +use rustc_abi::ExternAbi; use rustc_apfloat::ieee::{Double, Single}; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, @@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.ps.256" | "max.ps.256" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.ps.256" => FloatBinOp::Min, @@ -47,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement _mm256_min_pd and _mm256_max_pd functions. "min.pd.256" | "max.pd.256" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.pd.256" => FloatBinOp::Min, @@ -61,7 +61,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Rounds the elements of `op` according to `rounding`. "round.ps.256" => { let [op, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?; } @@ -69,14 +69,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Rounds the elements of `op` according to `rounding`. "round.pd.256" => { let [op, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?; } // Used to implement _mm256_{rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps.256" | "rsqrt.ps.256" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "rcp.ps.256" => FloatUnaryOp::Rcp, @@ -89,7 +89,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_dp_ps function. "dp.ps.256" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -98,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `left` and `right`. "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add, @@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // if true. "cmp.ps.256" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -127,7 +127,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // if true. "cmp.pd.256" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -138,7 +138,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm256_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let rnd = match unprefixed_name { // "current SSE rounding mode", assume nearest @@ -157,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `control` determines which element of the current `data` array is written. "vpermilvar.ps" | "vpermilvar.ps.256" => { let [data, control] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -191,7 +191,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // written. "vpermilvar.pd" | "vpermilvar.pd.256" => { let [data, control] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (data, data_len) = this.project_to_simd(data)?; let (control, control_len) = this.project_to_simd(control)?; @@ -224,7 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // zero, according to `imm`. "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; assert_eq!(dest.layout, left.layout); assert_eq!(dest.layout, right.layout); @@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // loaded. "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => { let [ptr, mask] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => { let [ptr, mask, value] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -289,7 +289,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq.256" => { - let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [src_ptr] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; @@ -301,7 +302,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `op & mask == 0`, `op & mask == mask` or // `op & mask != 0 && op & mask != mask` "ptestz.256" | "ptestc.256" | "ptestnzc.256" => { - let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op, mask] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -324,7 +326,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd" | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256" | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => { - let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op, mask] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (direct, negated) = test_high_bits_masked(this, op, mask)?; let res = match unprefixed_name { @@ -346,7 +349,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // compiler, making these functions no-ops. // The only thing that needs to be ensured is the correct calling convention. - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; } _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs index 331b693a3e4..6aefb87d4d0 100644 --- a/src/tools/miri/src/shims/x86/avx2.rs +++ b/src/tools/miri/src/shims/x86/avx2.rs @@ -1,8 +1,8 @@ +use rustc_abi::ExternAbi; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{ ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb, @@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_avx2_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -28,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm256_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b" | "pabs.w" | "pabs.d" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; int_abs(this, op, dest)?; } @@ -37,7 +37,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // integer values in `left` and `right`. "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w" | "phadd.d" => (mir::BinOp::Add, false), @@ -58,7 +58,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "gather.d.pd.256" | "gather.q.pd" | "gather.q.pd.256" | "gather.d.ps" | "gather.d.ps.256" | "gather.q.ps" | "gather.q.ps.256" => { let [src, slice, offsets, mask, scale] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; assert_eq!(dest.layout, src.layout); @@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -153,7 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // produces the output at index `i`. "pmadd.ub.sw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -188,7 +188,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // loaded. "maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => { let [ptr, mask] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mask_load(this, ptr, mask, dest)?; } @@ -199,7 +199,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores. "maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => { let [ptr, mask, value] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mask_store(this, ptr, mask, value)?; } @@ -211,7 +211,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8 "mpsadbw" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -223,7 +223,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16 "pmul.hr.sw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -232,7 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packsswb" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -241,7 +241,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packssdw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -250,7 +250,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unsigned integer vector with saturation. "packuswb" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -259,7 +259,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -269,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // as indices. "permd" | "permps" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern. "vperm2i128" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; assert_eq!(left.layout.size.bits(), 256); assert_eq!(right.layout.size.bits(), 256); @@ -328,7 +328,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8 "psad.bw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -361,7 +361,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Each 128-bit block is shuffled independently. "pshuf.b" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -393,7 +393,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Basically, we multiply `left` with `right.signum()`. "psign.b" | "psign.w" | "psign.d" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; psign(this, left, right, dest)?; } @@ -408,7 +408,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -424,7 +424,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256" | "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left, diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs index 59e76abf179..0f9e8d6f025 100644 --- a/src/tools/miri/src/shims/x86/bmi.rs +++ b/src/tools/miri/src/shims/x86/bmi.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::*; @@ -8,7 +8,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_bmi_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -33,7 +33,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [left, right] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs index c91b8c835f2..7b92d422cc5 100644 --- a/src/tools/miri/src/shims/x86/gfni.rs +++ b/src/tools/miri/src/shims/x86/gfni.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::*; @@ -8,7 +8,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_gfni_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -30,7 +30,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_ "vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => { let [left, right, imm8] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ false)?; } // Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions. @@ -38,7 +38,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv "vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => { let [left, right, imm8] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; affine_transform(this, left, right, imm8, dest, /* inverse */ true)?; } // Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions. @@ -48,7 +48,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul "vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -136,7 +136,7 @@ fn affine_transform<'tcx>( // This is a evaluated at compile time. Trait based conversion is not available. /// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for the /// definition of `gf_inv` which was used for the creation of this table. -#[allow(clippy::cast_possible_truncation)] +#[expect(clippy::cast_possible_truncation)] static TABLE: [u8; 256] = { let mut array = [0; 256]; @@ -163,7 +163,7 @@ static TABLE: [u8; 256] = { /// polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1. /// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for details. // This is a const function. Trait based conversion is not available. -#[allow(clippy::cast_possible_truncation)] +#[expect(clippy::cast_possible_truncation)] const fn gf2p8_mul(left: u8, right: u8) -> u8 { // This implementation is based on the `gf2p8mul_byte` definition found inside the Intel intrinsics guide. // See https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs index 2f63876327f..433e9e966f2 100644 --- a/src/tools/miri/src/shims/x86/mod.rs +++ b/src/tools/miri/src/shims/x86/mod.rs @@ -1,12 +1,11 @@ use rand::Rng as _; +use rustc_abi::{ExternAbi, Size}; use rustc_apfloat::Float; use rustc_apfloat::ieee::Single; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_middle::{mir, ty}; use rustc_span::Symbol; -use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; use self::helpers::bool_to_simd_element; use crate::*; @@ -29,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -47,7 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let [cb_in, a, b] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; let op = if unprefixed_name.starts_with("add") { mir::BinOp::AddWithOverflow @@ -71,7 +70,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(EmulateItemResult::NotSupported); } - let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?; + let [c_in, a, b, out] = + this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?; let out = this.deref_pointer_as( out, if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 }, @@ -88,7 +88,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the instruction behaves like a no-op, so it is always safe to call the // intrinsic. "sse2.pause" => { - let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; // Only exhibit the spin-loop hint behavior when SSE2 is enabled. if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) { this.yield_active_thread(); @@ -108,7 +108,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; pclmulqdq(this, left, right, imm, dest, len)?; } @@ -397,7 +397,6 @@ enum FloatUnaryOp { } /// Performs `which` scalar operation on `op` and returns the result. -#[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects fn unary_op_f32<'tcx>( this: &mut crate::MiriInterpCx<'tcx>, which: FloatUnaryOp, @@ -426,7 +425,7 @@ fn unary_op_f32<'tcx>( } /// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale). -#[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic +#[expect(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic fn apply_random_float_error<F: rustc_apfloat::Float>( this: &mut crate::MiriInterpCx<'_>, val: F, @@ -1000,7 +999,6 @@ fn mask_load<'tcx>( let dest = this.project_index(&dest, i)?; if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { - #[allow(clippy::arithmetic_side_effects)] // `Size` arithmetic is checked let ptr = ptr.wrapping_offset(dest.layout.size * i, &this.tcx); // Unaligned copy, which is what we want. this.mem_copy(ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; @@ -1036,7 +1034,6 @@ fn mask_store<'tcx>( if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 { // *Non-inbounds* pointer arithmetic to compute the destination. // (That's why we can't use a place projection.) - #[allow(clippy::arithmetic_side_effects)] // `Size` arithmetic is checked let ptr = ptr.wrapping_offset(value.layout.size * i, &this.tcx); // Deref the pointer *unaligned*, and do the copy. let dest = this.ptr_to_mplace_unaligned(ptr, value.layout); @@ -1135,7 +1132,7 @@ fn pmulhrsw<'tcx>( // The result of this operation can overflow a signed 16-bit integer. // When `left` and `right` are -0x8000, the result is 0x8000. - #[allow(clippy::cast_possible_truncation)] + #[expect(clippy::cast_possible_truncation)] let res = res as i16; this.write_scalar(Scalar::from_i16(res), &dest)?; diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs index 8553771b694..964204127d9 100644 --- a/src/tools/miri/src/shims/x86/sha.rs +++ b/src/tools/miri/src/shims/x86/sha.rs @@ -4,8 +4,8 @@ //! //! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use crate::*; @@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sha_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -51,7 +51,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { match unprefixed_name { // Used to implement the _mm_sha256rnds2_epu32 function. "256rnds2" => { - let [a, b, k] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [a, b, k] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -72,7 +73,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg1_epu32 function. "256msg1" => { - let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [a, b] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; @@ -90,7 +92,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Used to implement the _mm_sha256msg2_epu32 function. "256msg2" => { - let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [a, b] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (a_reg, a_len) = this.project_to_simd(a)?; let (b_reg, b_len) = this.project_to_simd(b)?; diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs index 013900e95d3..9432b40a805 100644 --- a/src/tools/miri/src/shims/x86/sse.rs +++ b/src/tools/miri/src/shims/x86/sse.rs @@ -1,6 +1,6 @@ +use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Single; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{ FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps, @@ -13,7 +13,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -33,7 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `right` and copies the remaining components from `left`. "min.ss" | "max.ss" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.ss" => FloatBinOp::Min, @@ -50,7 +50,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.ps" | "max.ps" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.ps" => FloatBinOp::Min, @@ -64,7 +64,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Performs the operations on the first component of `op` and // copies the remaining components from `op`. "rcp.ss" | "rsqrt.ss" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "rcp.ss" => FloatUnaryOp::Rcp, @@ -77,7 +77,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement _mm_{sqrt,rcp,rsqrt}_ps functions. // Performs the operations on all components of `op`. "rcp.ps" | "rsqrt.ps" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "rcp.ps" => FloatUnaryOp::Rcp, @@ -97,7 +97,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.ss" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.ps" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -128,7 +128,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss" | "ucomineq.ss" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -156,7 +156,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtss_si64 and _mm_cvttss_si64 functions. // Converts the first component of `op` from f32 to i32/i64. "cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -185,7 +185,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.felixcloutier.com/x86/cvtsi2ss "cvtsi2ss" | "cvtsi642ss" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (dest, dest_len) = this.project_to_simd(dest)?; diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs index de72e63f8af..4ff999be7cc 100644 --- a/src/tools/miri/src/shims/x86/sse2.rs +++ b/src/tools/miri/src/shims/x86/sse2.rs @@ -1,6 +1,6 @@ +use rustc_abi::ExternAbi; use rustc_apfloat::ieee::Double; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{ FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, @@ -13,7 +13,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse2_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -40,7 +40,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // intermediate 32-bit integers, and pack the results in `dest`. "pmadd.wd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -79,7 +79,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8 "psad.bw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,7 +118,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q" | "psrl.q" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left, @@ -133,7 +133,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and _mm_cvttpd_epi32 functions. // Converts packed f32/f64 to packed i32. "cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx); let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx); @@ -171,7 +171,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packsswb.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packsswb(this, left, right, dest)?; } @@ -180,7 +180,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // unsigned integer vector with saturation. "packuswb.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packuswb(this, left, right, dest)?; } @@ -189,7 +189,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // vector with signed saturation. "packssdw.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packssdw(this, left, right, dest)?; } @@ -200,7 +200,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.sd" | "max.sd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.sd" => FloatBinOp::Min, @@ -217,7 +217,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // semantics. "min.pd" | "max.pd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "min.pd" => FloatBinOp::Min, @@ -237,7 +237,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.sd" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -254,7 +254,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // with hard-coded operations. "cmp.pd" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?; @@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd" | "ucomineq.sd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -296,7 +296,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions. // Converts the first component of `op` from f64 to i32/i64. "cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (op, _) = this.project_to_simd(op)?; let op = this.read_immediate(&this.project_index(&op, 0)?)?; @@ -323,7 +323,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the remaining elements from `left` "cvtsd2ss" | "cvtss2sd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, _) = this.project_to_simd(right)?; diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs index 9aa4dd59950..86153d71b28 100644 --- a/src/tools/miri/src/shims/x86/sse3.rs +++ b/src/tools/miri/src/shims/x86/sse3.rs @@ -1,6 +1,6 @@ +use rustc_abi::ExternAbi; use rustc_middle::mir; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::horizontal_bin_op; use crate::*; @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse3_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -25,7 +25,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // in `left` and `right`. "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let which = match unprefixed_name { "hadd.ps" | "hadd.pd" => mir::BinOp::Add, @@ -41,7 +41,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the data crosses a cache line, but for Miri this is just a regular // unaligned read. "ldu.dq" => { - let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [src_ptr] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs index 7bf8ddea2fe..b81d6f24141 100644 --- a/src/tools/miri/src/shims/x86/sse41.rs +++ b/src/tools/miri/src/shims/x86/sse41.rs @@ -1,5 +1,5 @@ +use rustc_abi::ExternAbi; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked}; use crate::*; @@ -9,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse41_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -27,7 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // `i` is zeroed. "insertps" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -63,7 +63,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // the result to a 16-bit unsigned integer vector with saturation. "packusdw" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; packusdw(this, left, right, dest)?; } @@ -74,7 +74,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // 4 bits of `imm`. "dpps" | "dppd" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; conditional_dot_product(this, left, right, imm, dest)?; } @@ -83,7 +83,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and copies the remaining elements from `left`. "round.ss" => { let [left, right, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_first::<rustc_apfloat::ieee::Single>(this, left, right, rounding, dest)?; } @@ -91,7 +91,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the elements of `op` according to `rounding`. "round.ps" => { let [op, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?; } @@ -100,7 +100,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // and copies the remaining elements from `left`. "round.sd" => { let [left, right, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_first::<rustc_apfloat::ieee::Double>(this, left, right, rounding, dest)?; } @@ -108,7 +108,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // functions. Rounds the elements of `op` according to `rounding`. "round.pd" => { let [op, rounding] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?; } @@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Find the minimum unsinged 16-bit integer in `op` and // returns its value and position. "phminposuw" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (op, op_len) = this.project_to_simd(op)?; let (dest, dest_len) = this.project_to_simd(dest)?; @@ -151,7 +151,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8 "mpsadbw" => { let [left, right, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; mpsadbw(this, left, right, imm, dest)?; } @@ -160,7 +160,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Tests `(op & mask) == 0`, `(op & mask) == mask` or // `(op & mask) != 0 && (op & mask) != mask` "ptestz" | "ptestc" | "ptestnzc" => { - let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op, mask] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (all_zero, masked_set) = test_bits_masked(this, op, mask)?; let res = match unprefixed_name { diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs index f31cd406349..cc7cfab5041 100644 --- a/src/tools/miri/src/shims/x86/sse42.rs +++ b/src/tools/miri/src/shims/x86/sse42.rs @@ -1,9 +1,8 @@ +use rustc_abi::{ExternAbi, Size}; use rustc_middle::mir; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf as _; use rustc_span::Symbol; -use rustc_target::abi::Size; -use rustc_target::spec::abi::Abi; use crate::*; @@ -69,7 +68,7 @@ const USE_SIGNED: u8 = 2; /// The mask may be negated if negation flags inside the immediate byte are set. /// /// For more information, see the Intel Software Developer's Manual, Vol. 2b, Chapter 4.1. -#[allow(clippy::arithmetic_side_effects)] +#[expect(clippy::arithmetic_side_effects)] fn compare_strings<'tcx>( this: &mut MiriInterpCx<'tcx>, str1: &OpTy<'tcx>, @@ -201,7 +200,7 @@ fn deconstruct_args<'tcx>( unprefixed_name: &str, this: &mut MiriInterpCx<'tcx>, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> { let array_layout_fn = |this: &mut MiriInterpCx<'tcx>, imm: u8| { @@ -224,7 +223,7 @@ fn deconstruct_args<'tcx>( if is_explicit { let [str1, len1, str2, len2, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let default_len = default_len::<u32>(imm); @@ -237,7 +236,8 @@ fn deconstruct_args<'tcx>( interp_ok((str1, str2, Some((len1, len2)), imm)) } else { - let [str1, str2, imm] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [str1, str2, imm] = + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let array_layout = array_layout_fn(this, imm)?; @@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_sse42_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -388,7 +388,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925 "pcmpistriz128" | "pcmpistris128" => { let [str1, str2, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let imm = this.read_scalar(imm)?.to_u8()?; let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 }; @@ -409,7 +409,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047 "pcmpestriz128" | "pcmpestris128" => { let [_, len1, _, len2, imm] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 }; let len = this.read_scalar(len)?.to_i32()?; let imm = this.read_scalar(imm)?.to_u8()?; @@ -437,14 +437,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let left = this.read_scalar(left)?; let right = this.read_scalar(right)?; let crc = if bit_size == 64 { // The 64-bit version will only consider the lower 32 bits, // while the upper 32 bits get discarded. - #[allow(clippy::cast_possible_truncation)] + #[expect(clippy::cast_possible_truncation)] u128::from((left.to_u64()? as u32).reverse_bits()) } else { u128::from(left.to_u32()?.reverse_bits()) diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs index 76a2451dea4..cdab78bc742 100644 --- a/src/tools/miri/src/shims/x86/ssse3.rs +++ b/src/tools/miri/src/shims/x86/ssse3.rs @@ -1,6 +1,6 @@ +use rustc_abi::ExternAbi; use rustc_middle::mir; use rustc_span::Symbol; -use rustc_target::spec::abi::Abi; use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; use crate::*; @@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn emulate_x86_ssse3_intrinsic( &mut self, link_name: Symbol, - abi: Abi, + abi: ExternAbi, args: &[OpTy<'tcx>], dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, EmulateItemResult> { @@ -23,7 +23,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Used to implement the _mm_abs_epi{8,16,32} functions. // Calculates the absolute value of packed 8/16/32-bit integers. "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => { - let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; int_abs(this, op, dest)?; } @@ -32,7 +32,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8 "pshuf.b.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -62,7 +62,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128" | "phsub.d.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (which, saturating) = match unprefixed_name { "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false), @@ -82,7 +82,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16 "pmadd.ub.sw.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; let (left, left_len) = this.project_to_simd(left)?; let (right, right_len) = this.project_to_simd(right)?; @@ -118,7 +118,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16 "pmul.hr.sw.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; pmulhrsw(this, left, right, dest)?; } @@ -129,7 +129,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Basically, we multiply `left` with `right.signum()`. "psign.b.128" | "psign.w.128" | "psign.d.128" => { let [left, right] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; + this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?; psign(this, left, right, dest)?; } diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs index 4e892e6e3cb..ae5731bc8a6 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs @@ -181,7 +181,7 @@ unsafe fn schedule(v0: __m128i, v1: __m128i, v2: __m128i, v3: __m128i) -> __m128 } // we use unaligned loads with `__m128i` pointers -#[allow(clippy::cast_ptr_alignment)] +#[expect(clippy::cast_ptr_alignment)] #[target_feature(enable = "sha,sse2,ssse3,sse4.1")] unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) { #[allow(non_snake_case)] diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 695c37f6d7b..424357e8473 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1364,7 +1364,6 @@ dependencies = [ "proc-macro-api", "proc-macro-test", "ra-ap-rustc_lexer", - "snap", "span", "stdx", "syntax-bridge", @@ -1889,12 +1888,6 @@ dependencies = [ ] [[package]] -name = "snap" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" - -[[package]] name = "span" version = "0.0.0" dependencies = [ diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 3aa93b7b7b4..1099d2cb918 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -145,7 +145,6 @@ smallvec = { version = "1.10.0", features = [ "const_generics", ] } smol_str = "0.3.2" -snap = "1.1.0" text-size = "1.1.1" tracing = "0.1.40" tracing-tree = "0.3.0" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml index e8d9677c928..4fabcc90067 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml @@ -16,7 +16,6 @@ doctest = false object.workspace = true libloading.workspace = true memmap2.workspace = true -snap.workspace = true stdx.workspace = true tt.workspace = true diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs index 1f7ef7914ba..7f0e95c50de 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs @@ -8,7 +8,6 @@ use std::{ use memmap2::Mmap; use object::read::{File as BinaryFile, Object, ObjectSection}; use paths::AbsPath; -use snap::read::FrameDecoder as SnapDecoder; #[derive(Debug)] #[allow(dead_code)] @@ -123,9 +122,8 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]); // Last supported version is: // https://github.com/rust-lang/rust/commit/b94cfefc860715fb2adf72a6955423d384c69318 - let (snappy_portion, bytes_before_version) = match version { - 5 | 6 => (&dot_rustc[8..], 13), - 7 | 8 => { + let (mut metadata_portion, bytes_before_version) = match version { + 8 => { let len_bytes = &dot_rustc[8..12]; let data_len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize; (&dot_rustc[12..data_len + 12], 13) @@ -143,13 +141,6 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { } }; - let mut uncompressed: Box<dyn Read> = if &snappy_portion[0..4] == b"rust" { - // Not compressed. - Box::new(snappy_portion) - } else { - Box::new(SnapDecoder::new(snappy_portion)) - }; - // We're going to skip over the bytes before the version string, so basically: // 8 bytes for [b'r',b'u',b's',b't',0,0,0,5] // 4 or 8 bytes for [crate root bytes] @@ -157,11 +148,11 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> { // so 13 or 17 bytes in total, and we should check the last of those bytes // to know the length let mut bytes = [0u8; 17]; - uncompressed.read_exact(&mut bytes[..bytes_before_version])?; + metadata_portion.read_exact(&mut bytes[..bytes_before_version])?; let length = bytes[bytes_before_version - 1]; let mut version_string_utf8 = vec![0u8; length as usize]; - uncompressed.read_exact(&mut version_string_utf8)?; + metadata_portion.read_exact(&mut version_string_utf8)?; let version_string = String::from_utf8(version_string_utf8); version_string.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 5163f039a23..f3bd72fe647 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -24,6 +24,7 @@ const LICENSES: &[&str] = &[ "BSD-2-Clause OR Apache-2.0 OR MIT", // zerocopy "ISC", "MIT / Apache-2.0", + "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)", // compiler-builtins "MIT OR Apache-2.0 OR LGPL-2.1-or-later", // r-efi, r-efi-alloc "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros "MIT OR Apache-2.0", @@ -100,7 +101,6 @@ const EXCEPTIONS: ExceptionList = &[ ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), // rustc (license is the same as LLVM uses) ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 // cargo/... (because of serde) ("self_cell", "Apache-2.0"), // rustc (fluent translations) - ("snap", "BSD-3-Clause"), // rustc ("wasi-preview1-component-adapter-provider", "Apache-2.0 WITH LLVM-exception"), // rustc // tidy-alphabetical-end ]; @@ -162,7 +162,6 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 ("scip", "Apache-2.0"), - ("snap", "BSD-3-Clause"), // tidy-alphabetical-end ]; @@ -390,7 +389,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "sharded-slab", "shlex", "smallvec", - "snap", "stable_deref_trait", "stacker", "static_assertions", diff --git a/tests/assembly/asm-comments.rs b/tests/assembly/asm/comments.rs index 557009975dd..557009975dd 100644 --- a/tests/assembly/asm-comments.rs +++ b/tests/assembly/asm/comments.rs diff --git a/tests/assembly/asm/loongarch-type.rs b/tests/assembly/asm/loongarch-type.rs index 1b097f41105..c51d35876d9 100644 --- a/tests/assembly/asm/loongarch-type.rs +++ b/tests/assembly/asm/loongarch-type.rs @@ -3,7 +3,7 @@ //@ compile-flags: -Zmerge-functions=disabled //@ needs-llvm-components: loongarch -#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)] +#![feature(no_core, lang_items, rustc_attrs)] #![crate_type = "rlib"] #![no_core] #![allow(asm_sub_register, non_camel_case_types)] diff --git a/tests/assembly/compiletest-self-test/use-minicore-no-run.rs b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs new file mode 100644 index 00000000000..0e4f05c4b37 --- /dev/null +++ b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs @@ -0,0 +1,5 @@ +//! `compiletest` self-test to check that `add-core-stubs` is incompatible with run pass modes. + +//@ add-core-stubs +//@ run-pass +//@ should-fail diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs new file mode 100644 index 00000000000..49a7580eccc --- /dev/null +++ b/tests/auxiliary/minicore.rs @@ -0,0 +1,72 @@ +//! Auxiliary `minicore` prelude which stubs out `core` items for `no_core` tests that need to work +//! in cross-compilation scenarios where no `core` is available (that don't want nor need to +//! `-Zbuild-std`). +//! +//! # Important notes +//! +//! - `minicore` is **only** intended for `core` items, and the stubs should match the actual `core` +//! items. +//! +//! # References +//! +//! This is partially adapted from `rustc_codegen_cranelift`: +//! <https://github.com/rust-lang/rust/blob/c0b5cc9003f6464c11ae1c0662c6a7e06f6f5cab/compiler/rustc_codegen_cranelift/example/mini_core.rs>. +// ignore-tidy-linelength + +#![feature(no_core, lang_items, rustc_attrs)] +#![allow(unused, improper_ctypes_definitions, internal_features)] +#![no_std] +#![no_core] + +// `core` has some exotic `marker_impls!` macro for handling the with-generics cases, but for our +// purposes, just use a simple macro_rules macro. +macro_rules! impl_marker_trait { + ($Trait:ident => [$( $ty:ident ),* $(,)?] ) => { + $( impl $Trait for $ty {} )* + } +} + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "legacy_receiver"] +pub trait LegacyReceiver {} +impl<T: ?Sized> LegacyReceiver for &T {} +impl<T: ?Sized> LegacyReceiver for &mut T {} + +#[lang = "copy"] +pub trait Copy: Sized {} + +impl_marker_trait!(Copy => [ bool, char, isize, usize, i8, i16, i32, i64, u8, u16, u32, u64 ]); +impl<'a, T: ?Sized> Copy for &'a T {} +impl<T: ?Sized> Copy for *const T {} +impl<T: ?Sized> Copy for *mut T {} + +#[lang = "phantom_data"] +pub struct PhantomData<T: ?Sized>; +impl<T: ?Sized> Copy for PhantomData<T> {} + +pub enum Option<T> { + None, + Some(T), +} +impl<T: Copy> Copy for Option<T> {} + +pub enum Result<T, E> { + Ok(T), + Err(E), +} +impl<T: Copy, E: Copy> Copy for Result<T, E> {} + +#[lang = "manually_drop"] +#[repr(transparent)] +pub struct ManuallyDrop<T: ?Sized> { + value: T, +} +impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {} + +#[lang = "unsafe_cell"] +#[repr(transparent)] +pub struct UnsafeCell<T: ?Sized> { + value: T, +} diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs index 2ec61907947..2ec61907947 100644 --- a/tests/codegen/asm-arm64ec-clobbers.rs +++ b/tests/codegen/asm/arm64ec-clobbers.rs diff --git a/tests/codegen/foo.s b/tests/codegen/asm/foo.s index 304d82aa0c6..304d82aa0c6 100644 --- a/tests/codegen/foo.s +++ b/tests/codegen/asm/foo.s diff --git a/tests/codegen/global_asm.rs b/tests/codegen/asm/global_asm.rs index 32075daa3cf..32075daa3cf 100644 --- a/tests/codegen/global_asm.rs +++ b/tests/codegen/asm/global_asm.rs diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/asm/global_asm_include.rs index 98be9c3e333..98be9c3e333 100644 --- a/tests/codegen/global_asm_include.rs +++ b/tests/codegen/asm/global_asm_include.rs diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/asm/global_asm_x2.rs index 9e3a00f0680..9e3a00f0680 100644 --- a/tests/codegen/global_asm_x2.rs +++ b/tests/codegen/asm/global_asm_x2.rs diff --git a/tests/codegen/asm-goto.rs b/tests/codegen/asm/goto.rs index e522d0da5b4..e522d0da5b4 100644 --- a/tests/codegen/asm-goto.rs +++ b/tests/codegen/asm/goto.rs diff --git a/tests/codegen/asm-may_unwind.rs b/tests/codegen/asm/may_unwind.rs index be66b3975ff..be66b3975ff 100644 --- a/tests/codegen/asm-may_unwind.rs +++ b/tests/codegen/asm/may_unwind.rs diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm/maybe-uninit.rs index 55813c35a46..55813c35a46 100644 --- a/tests/codegen/asm-maybe-uninit.rs +++ b/tests/codegen/asm/maybe-uninit.rs diff --git a/tests/codegen/asm-msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs index c00c04f3088..c00c04f3088 100644 --- a/tests/codegen/asm-msp430-clobbers.rs +++ b/tests/codegen/asm/msp430-clobbers.rs diff --git a/tests/codegen/asm-multiple-options.rs b/tests/codegen/asm/multiple-options.rs index 1ee295e32c9..1ee295e32c9 100644 --- a/tests/codegen/asm-multiple-options.rs +++ b/tests/codegen/asm/multiple-options.rs diff --git a/tests/codegen/asm-options.rs b/tests/codegen/asm/options.rs index 96a72c2f5ae..96a72c2f5ae 100644 --- a/tests/codegen/asm-options.rs +++ b/tests/codegen/asm/options.rs diff --git a/tests/codegen/asm-powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs index 0be1b66bd99..0be1b66bd99 100644 --- a/tests/codegen/asm-powerpc-clobbers.rs +++ b/tests/codegen/asm/powerpc-clobbers.rs diff --git a/tests/codegen/asm-s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs index 45f72206bdf..45f72206bdf 100644 --- a/tests/codegen/asm-s390x-clobbers.rs +++ b/tests/codegen/asm/s390x-clobbers.rs diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs index fb332f9a0f3..fb332f9a0f3 100644 --- a/tests/codegen/asm-sanitize-llvm.rs +++ b/tests/codegen/asm/sanitize-llvm.rs diff --git a/tests/codegen/asm-clobber_abi.rs b/tests/codegen/asm/x86-clobber_abi.rs index cc563474bf8..cc563474bf8 100644 --- a/tests/codegen/asm-clobber_abi.rs +++ b/tests/codegen/asm/x86-clobber_abi.rs diff --git a/tests/codegen/asm-clobbers.rs b/tests/codegen/asm/x86-clobbers.rs index 4094db74134..4094db74134 100644 --- a/tests/codegen/asm-clobbers.rs +++ b/tests/codegen/asm/x86-clobbers.rs diff --git a/tests/codegen/asm-target-clobbers.rs b/tests/codegen/asm/x86-target-clobbers.rs index 119372491ff..119372491ff 100644 --- a/tests/codegen/asm-target-clobbers.rs +++ b/tests/codegen/asm/x86-target-clobbers.rs diff --git a/tests/codegen/clone_as_copy.rs b/tests/codegen/clone_as_copy.rs index 36a59ae56b7..6ba198297e2 100644 --- a/tests/codegen/clone_as_copy.rs +++ b/tests/codegen/clone_as_copy.rs @@ -1,4 +1,6 @@ //@ revisions: DEBUGINFO NODEBUGINFO +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see <https://github.com/rust-lang/rust/issues/132353> //@ compile-flags: -O -Cno-prepopulate-passes //@ [DEBUGINFO] compile-flags: -Cdebuginfo=full diff --git a/tests/codegen/compiletest-self-test/minicore-smoke-test.rs b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs new file mode 100644 index 00000000000..9dd1bf29c6c --- /dev/null +++ b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs @@ -0,0 +1,20 @@ +//! Basic smoke test for `minicore` test auxiliary. + +//@ add-core-stubs +//@ compile-flags: --target=x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 + +#![crate_type = "lib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Meow; +impl Copy for Meow {} + +// CHECK-LABEL: meow +#[no_mangle] +fn meow() {} diff --git a/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs b/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs new file mode 100644 index 00000000000..86d020e1751 --- /dev/null +++ b/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs @@ -0,0 +1,19 @@ +//! Test for https://github.com/rust-lang/rust/issues/64219 +//! Check if `noreturn` attribute is applied on calls to +//! function pointers returning `!` (never type). + +#![crate_type = "lib"] + +extern "C" { + static FOO: fn() -> !; +} + +// CHECK-LABEL: @foo +#[no_mangle] +pub unsafe fn foo() { + // CHECK: call + // CHECK-SAME: [[NUM:#[0-9]+$]] + FOO(); +} + +// CHECK: attributes [[NUM]] = {{{.*}} noreturn {{.*}}} diff --git a/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs b/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs new file mode 100644 index 00000000000..a8fab61b13e --- /dev/null +++ b/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs @@ -0,0 +1,26 @@ +//@ compile-flags: -O +//! Test for https://github.com/rust-lang/rust/issues/86109 +//! Check LLVM can eliminate the impossible division by zero check by +//! ensuring there is no call (to panic) instruction. +//! +//! This has been fixed since `rustc 1.70.0`. + +#![crate_type = "lib"] + +type T = i16; + +// CHECK-LABEL: @foo +#[no_mangle] +pub fn foo(start: T) -> T { + // CHECK-NOT: panic + if start <= 0 { + return 0; + } + let mut count = 0; + for i in start..10_000 { + if 752 % i != 0 { + count += 1; + } + } + count +} diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs index 65167f5c5af..bbab0d9eb1d 100644 --- a/tests/codegen/try_question_mark_nop.rs +++ b/tests/codegen/try_question_mark_nop.rs @@ -1,10 +1,7 @@ //@ compile-flags: -O -Z merge-functions=disabled --edition=2021 //@ only-x86_64 // FIXME: Remove the `min-llvm-version`. -//@ revisions: NINETEEN TWENTY -//@[NINETEEN] min-llvm-version: 19 -//@[NINETEEN] ignore-llvm-version: 20-99 -//@[TWENTY] min-llvm-version: 20 +//@ min-llvm-version: 19 #![crate_type = "lib"] #![feature(try_blocks)] @@ -16,12 +13,9 @@ use std::ptr::NonNull; #[no_mangle] pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> { // CHECK: start: - // NINETEEN-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 - // NINETEEN-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0 - // NINETEEN-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]], 0 - // TWENTY-NEXT: insertvalue { i32, i32 } poison, i32 %0, 0 - // CHECK-NEXT: insertvalue { i32, i32 } - // CHECK-NEXT: ret { i32, i32 } + // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1 + // CHECK-NEXT: ret { i32, i32 } [[REG2]] match x { Some(x) => Some(x), None => None, diff --git a/tests/crashes/126268.rs b/tests/crashes/126268.rs new file mode 100644 index 00000000000..82e52fa115d --- /dev/null +++ b/tests/crashes/126268.rs @@ -0,0 +1,18 @@ +//@ known-bug: #126268 +#![feature(min_specialization)] + +trait Trait {} + +impl<T> Trait for T {} + +trait Data { + type Elem; +} + +struct DatasetIter<'a, R: Data> { + data: &'a R::Elem, +} + +pub struct ArrayBase {} + +impl<'a> Trait for DatasetIter<'a, ArrayBase> {} diff --git a/tests/crashes/131050.rs b/tests/crashes/131050.rs index 07f8662d016..3e3a600ef3d 100644 --- a/tests/crashes/131050.rs +++ b/tests/crashes/131050.rs @@ -1,25 +1,21 @@ //@ known-bug: #131050 //@ compile-flags: --edition=2021 -fn query_as<D>() {} +use std::future::Future; -async fn create_user() { - query_as(); -} +fn invalid_future() -> impl Future {} -async fn post_user_filter() -> impl Filter { - AndThen(&(), || async { create_user().await }) +fn create_complex_future() -> impl Future<Output = impl ReturnsSend> { + async { &|| async { invalid_future().await } } } -async fn get_app() -> impl Send { - post_user_filter().await +fn coerce_impl_trait() -> impl Future<Output = impl Send> { + create_complex_future() } -trait Filter {} - -struct AndThen<T, F>(T, F); +trait ReturnsSend {} -impl<T, F, R> Filter for AndThen<T, F> +impl<F, R> ReturnsSend for F where F: Fn() -> R, R: Send, diff --git a/tests/crashes/132126.rs b/tests/crashes/132126.rs new file mode 100644 index 00000000000..6a42853d469 --- /dev/null +++ b/tests/crashes/132126.rs @@ -0,0 +1,2 @@ +//@ known-bug: #132126 +trait UnsafeCopy where Self: use<Self> {} diff --git a/tests/mir-opt/gvn_clone.rs b/tests/mir-opt/gvn_clone.rs index 08938c0e1b4..c16b665fbd3 100644 --- a/tests/mir-opt/gvn_clone.rs +++ b/tests/mir-opt/gvn_clone.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see <https://github.com/rust-lang/rust/issues/132353> //@ test-mir-pass: GVN //@ compile-flags: -Zmir-enable-passes=+InstSimplify-before-inline diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff index 57b0980a0bd..8d5991872e1 100644 --- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff +++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff @@ -1,7 +1,7 @@ -- // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` before GVN -+ // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` after GVN +- // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` before GVN ++ // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` after GVN - fn <impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone(_1: &AllCopy) -> AllCopy { + fn <impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone(_1: &AllCopy) -> AllCopy { debug self => _1; let mut _0: AllCopy; let mut _2: i32; diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs index c9473025a15..7c181d1ad37 100644 --- a/tests/mir-opt/gvn_copy_aggregate.rs +++ b/tests/mir-opt/gvn_copy_aggregate.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see <https://github.com/rust-lang/rust/issues/132353. //@ test-mir-pass: GVN //@ compile-flags: -Cpanic=abort diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs index f5ff1854d38..ae4661e93fd 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.rs +++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs @@ -1,3 +1,5 @@ +//@ compile-flags: -Zunsound-mir-opts +// FIXME: see <https://github.com/rust-lang/rust/issues/132353> //@ compile-flags: -Cdebuginfo=full // Check if we have transformed the nested clone to the copy in the complete pipeline. diff --git a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir index 9020cf1ef37..62a9cd9131f 100644 --- a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir @@ -3,9 +3,13 @@ fn <impl at $DIR/no_inlined_clone.rs:9:10: 9:15>::clone(_1: &Foo) -> Foo { debug self => _1; let mut _0: Foo; + let mut _2: i32; bb0: { - _0 = copy (*_1); + StorageLive(_2); + _2 = copy ((*_1).0: i32); + _0 = Foo { a: move _2 }; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir index 889e80d26e1..ac485f485b1 100644 --- a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir @@ -19,14 +19,14 @@ fn old(_1: Result<T, E>) -> Result<T, E> { } bb1: { - _3 = copy ((_1 as Ok).0: T); - _0 = copy _1; + _3 = move ((_1 as Ok).0: T); + _0 = Result::<T, E>::Ok(copy _3); goto -> bb3; } bb2: { - _4 = copy ((_1 as Err).0: E); - _0 = copy _1; + _4 = move ((_1 as Err).0: E); + _0 = Result::<T, E>::Err(copy _4); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir index 4d964b0afb7..c3091bd4395 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir @@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug self => _1; scope 2 (inlined Vec::<u8>::as_slice) { debug self => _1; - let mut _6: usize; + let mut _7: usize; scope 3 (inlined Vec::<u8>::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec<u8>; @@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { debug self => _3; + let mut _6: std::ptr::NonNull<u8>; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { debug self => _3; let mut _4: std::ptr::NonNull<u8>; @@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } } scope 10 (inlined Unique::<u8>::as_non_null_ptr) { - debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4; + debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; } } scope 11 (inlined NonNull::<u8>::as_ptr) { - debug self => _4; + debug self => _6; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { debug data => _5; - debug len => _6; - let _7: *const [u8]; + debug len => _7; + let _8: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } scope 17 (inlined slice_from_raw_parts::<u8>) { debug data => _5; - debug len => _6; + debug len => _7; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { debug data_pointer => _5; - debug metadata => _6; + debug metadata => _7; } } } @@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); + StorageLive(_6); + StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); _5 = copy (_4.0: *const u8); + _6 = NonNull::<u8> { pointer: copy _5 }; + StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageDead(_2); - StorageLive(_6); - _6 = copy ((*_1).1: usize); StorageLive(_7); - _7 = *const [u8] from (copy _5, copy _6); - _0 = &(*_7); + _7 = copy ((*_1).1: usize); + StorageLive(_8); + _8 = *const [u8] from (copy _5, copy _7); + _0 = &(*_8); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); return; } } diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir index 4d964b0afb7..c3091bd4395 100644 --- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir @@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { debug self => _1; scope 2 (inlined Vec::<u8>::as_slice) { debug self => _1; - let mut _6: usize; + let mut _7: usize; scope 3 (inlined Vec::<u8>::as_ptr) { debug self => _1; let mut _2: &alloc::raw_vec::RawVec<u8>; @@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { let mut _3: &alloc::raw_vec::RawVecInner; scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) { debug self => _3; + let mut _6: std::ptr::NonNull<u8>; scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) { debug self => _3; let mut _4: std::ptr::NonNull<u8>; @@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } } scope 10 (inlined Unique::<u8>::as_non_null_ptr) { - debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4; + debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6; debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>; } } scope 11 (inlined NonNull::<u8>::as_ptr) { - debug self => _4; + debug self => _6; } } } } scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) { debug data => _5; - debug len => _6; - let _7: *const [u8]; + debug len => _7; + let _8: *const [u8]; scope 13 (inlined core::ub_checks::check_language_ub) { scope 14 (inlined core::ub_checks::check_language_ub::runtime) { } @@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { } scope 17 (inlined slice_from_raw_parts::<u8>) { debug data => _5; - debug len => _6; + debug len => _7; scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) { debug data_pointer => _5; - debug metadata => _6; + debug metadata => _7; } } } @@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] { _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>); StorageLive(_3); _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner); + StorageLive(_6); + StorageLive(_4); _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>); _5 = copy (_4.0: *const u8); + _6 = NonNull::<u8> { pointer: copy _5 }; + StorageDead(_4); + StorageDead(_6); StorageDead(_3); StorageDead(_2); - StorageLive(_6); - _6 = copy ((*_1).1: usize); StorageLive(_7); - _7 = *const [u8] from (copy _5, copy _6); - _0 = &(*_7); + _7 = copy ((*_1).1: usize); + StorageLive(_8); + _8 = *const [u8] from (copy _5, copy _7); + _0 = &(*_8); + StorageDead(_8); StorageDead(_7); - StorageDead(_6); return; } } diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff new file mode 100644 index 00000000000..22d4277ee45 --- /dev/null +++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff @@ -0,0 +1,72 @@ +- // MIR for `foo` before GVN ++ // MIR for `foo` after GVN + + fn foo(_1: &mut Option<i32>) -> Option<i32> { + debug v => _1; + let mut _0: std::option::Option<i32>; + let mut _2: &std::option::Option<i32>; + let mut _3: &std::option::Option<i32>; + let _4: &&mut std::option::Option<i32>; + let mut _5: isize; + let mut _7: !; + let mut _8: std::option::Option<i32>; + let mut _9: i32; + let mut _10: !; + let mut _11: &mut std::option::Option<i32>; + scope 1 { + debug col => _6; + let _6: i32; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + StorageLive(_4); + _4 = &_1; +- _11 = deref_copy (*_4); +- _3 = &(*_11); ++ _11 = copy _1; ++ _3 = &(*_1); + _2 = get(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); + _5 = discriminant((*_2)); + switchInt(move _5) -> [1: bb2, otherwise: bb3]; + } + + bb2: { +- StorageLive(_6); ++ nop; + _6 = copy (((*_2) as Some).0: i32); + StorageLive(_8); +- _8 = Option::<i32>::None; +- (*_1) = move _8; ++ _8 = const Option::<i32>::None; ++ (*_1) = const Option::<i32>::None; + StorageDead(_8); + StorageLive(_9); + _9 = copy _6; +- _0 = Option::<i32>::Some(move _9); ++ _0 = copy (*_2); + StorageDead(_9); +- StorageDead(_6); ++ nop; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + + bb3: { + StorageLive(_10); + unreachable; + } ++ } ++ ++ ALLOC0 (size: 8, align: 4) { ++ 00 00 00 00 __ __ __ __ │ ....░░░░ + } + diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs new file mode 100644 index 00000000000..47721b768be --- /dev/null +++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs @@ -0,0 +1,32 @@ +//! The `simplify_aggregate_to_copy` mir-opt introduced in +//! <https://github.com/rust-lang/rust/pull/128299> caused a miscompile because the initial +//! implementation +//! +//! > introduce[d] new dereferences without checking for aliasing +//! +//! This test demonstrates the behavior, and should be adjusted or removed when fixing and relanding +//! the mir-opt. +#![crate_type = "lib"] +// skip-filecheck +//@ compile-flags: -O -Zunsound-mir-opts +//@ test-mir-pass: GVN +#![allow(internal_features)] +#![feature(rustc_attrs, core_intrinsics)] + +// EMIT_MIR simplify_aggregate_to_copy_miscompile.foo.GVN.diff +#[no_mangle] +fn foo(v: &mut Option<i32>) -> Option<i32> { + if let &Some(col) = get(&v) { + *v = None; + return Some(col); + } else { + unsafe { std::intrinsics::unreachable() } + } +} + +#[no_mangle] +#[inline(never)] +#[rustc_nounwind] +fn get(v: &Option<i32>) -> &Option<i32> { + v +} diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs deleted file mode 100644 index 58a1b53c040..00000000000 --- a/tests/run-make/profile/rmake.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This test revolves around the rustc flag -Z profile, which should -// generate a .gcno file (initial profiling information) as well -// as a .gcda file (branch counters). The path where these are emitted -// should also be configurable with -Z profile-emit. This test checks -// that the files are produced, and then that the latter flag is respected. -// See https://github.com/rust-lang/rust/pull/42433 - -//@ ignore-cross-compile -//@ needs-profiler-runtime - -use run_make_support::{path, run, rustc}; - -fn main() { - rustc().arg("-g").arg("-Zprofile").input("test.rs").run(); - run("test"); - assert!(path("test.gcno").exists(), "no .gcno file"); - assert!(path("test.gcda").exists(), "no .gcda file"); - rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run(); - run("test"); - assert!(path("abc/abc.gcda").exists(), "gcda file not emitted to defined path"); -} diff --git a/tests/run-make/profile/test.rs b/tests/run-make/profile/test.rs deleted file mode 100644 index f328e4d9d04..00000000000 --- a/tests/run-make/profile/test.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs index fc72154cad8..550eb0bc137 100644 --- a/tests/rustdoc/stability.rs +++ b/tests/rustdoc/stability.rs @@ -1,6 +1,8 @@ #![feature(staged_api)] +#![feature(rustc_attrs)] +#![feature(rustdoc_internals)] -#![stable(feature = "rust1", since = "1.0.0")] +#![stable(feature = "core", since = "1.6.0")] //@ has stability/index.html //@ has - '//ul[@class="item-table"]/li[1]//a' AaStable @@ -26,7 +28,7 @@ pub struct ZzStable; #[unstable(feature = "unstable", issue = "none")] pub mod unstable { //@ !hasraw stability/unstable/struct.StableInUnstable.html \ - // '//span[@class="since"]' + // '//div[@class="main-heading"]//span[@class="since"]' //@ has - '//div[@class="stab unstable"]' 'experimental' #[stable(feature = "rust1", since = "1.0.0")] pub struct StableInUnstable; @@ -34,52 +36,136 @@ pub mod unstable { #[stable(feature = "rust1", since = "1.0.0")] pub mod stable_in_unstable { //@ !hasraw stability/unstable/stable_in_unstable/struct.Inner.html \ - // '//span[@class="since"]' + // '//div[@class="main-heading"]//span[@class="since"]' //@ has - '//div[@class="stab unstable"]' 'experimental' #[stable(feature = "rust1", since = "1.0.0")] pub struct Inner; } + + //@ has stability/struct.AaStable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '2.2.2' + impl super::AaStable { + #[stable(feature = "rust2", since = "2.2.2")] + pub fn foo() {} + } + + //@ has stability/unstable/struct.StableInUnstable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' + impl StableInUnstable { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn foo() {} + } +} + +#[unstable(feature = "unstable", issue = "none")] +#[doc(hidden)] +pub mod unstable_stripped { + //@ has stability/struct.AaStable.html \ + // '//*[@id="method.foo"]//span[@class="since"]' '2.2.2' + impl super::AaStable { + #[stable(feature = "rust2", since = "2.2.2")] + pub fn foo() {} + } } #[stable(feature = "rust2", since = "2.2.2")] pub mod stable_later { //@ has stability/stable_later/struct.StableInLater.html \ - // '//span[@class="since"]' '2.2.2' + // '//div[@class="main-heading"]//span[@class="since"]' '2.2.2' #[stable(feature = "rust1", since = "1.0.0")] pub struct StableInLater; #[stable(feature = "rust1", since = "1.0.0")] pub mod stable_in_later { //@ has stability/stable_later/stable_in_later/struct.Inner.html \ - // '//span[@class="since"]' '2.2.2' + // '//div[@class="main-heading"]//span[@class="since"]' '2.2.2' #[stable(feature = "rust1", since = "1.0.0")] pub struct Inner; } } #[stable(feature = "rust1", since = "1.0.0")] -pub mod stable_earlier { - //@ has stability/stable_earlier/struct.StableInUnstable.html \ - // '//span[@class="since"]' '1.0.0' +#[rustc_allowed_through_unstable_modules] +pub mod stable_earlier1 { + //@ has stability/stable_earlier1/struct.StableInUnstable.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::unstable::StableInUnstable; + + //@ has stability/stable_earlier1/stable_in_unstable/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::unstable::stable_in_unstable; + + //@ has stability/stable_earlier1/struct.StableInLater.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::stable_later::StableInLater; + + //@ has stability/stable_earlier1/stable_in_later/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' + #[doc(inline)] + #[stable(feature = "rust1", since = "1.0.0")] + pub use crate::stable_later::stable_in_later; +} + +/// These will inherit the crate stability. +#[stable(feature = "rust1", since = "1.0.0")] +pub mod stable_earlier2 { + //@ has stability/stable_earlier2/struct.StableInUnstable.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' + //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::unstable::StableInUnstable; - //@ has stability/stable_earlier/stable_in_unstable/struct.Inner.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/stable_in_unstable/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::unstable::stable_in_unstable; - //@ has stability/stable_earlier/struct.StableInLater.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/struct.StableInLater.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::stable_later::StableInLater; - //@ has stability/stable_earlier/stable_in_later/struct.Inner.html \ - // '//span[@class="since"]' '1.0.0' + //@ has stability/stable_earlier2/stable_in_later/struct.Inner.html \ + // '//div[@class="main-heading"]//span[@class="since"]' '1.6.0' #[doc(inline)] #[stable(feature = "rust1", since = "1.0.0")] pub use crate::stable_later::stable_in_later; } + +//@ !hasraw stability/trait.UnstableTraitWithStableMethod.html \ +// '//div[@class="main-heading"]//span[@class="since"]' +//@ has - '//*[@id="tymethod.foo"]//span[@class="since"]' '1.0.0' +//@ has - '//*[@id="method.bar"]//span[@class="since"]' '1.0.0' +#[unstable(feature = "unstable", issue = "none")] +pub trait UnstableTraitWithStableMethod { + #[stable(feature = "rust1", since = "1.0.0")] + fn foo(); + #[stable(feature = "rust1", since = "1.0.0")] + fn bar() {} +} + +//@ has stability/primitive.i32.html \ +// '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' +#[rustc_doc_primitive = "i32"] +// +/// `i32` is always stable in 1.0, even if you look at it from core. +#[stable(feature = "rust1", since = "1.0.0")] +mod prim_i32 {} + +//@ has stability/keyword.if.html \ +// '//div[@class="main-heading"]//span[@class="since"]' '1.0.0' +#[doc(keyword = "if")] +// +/// We currently don't document stability for keywords, but let's test it anyway. +#[stable(feature = "rust1", since = "1.0.0")] +mod if_keyword {} diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 408dbea4ae8..01d90717107 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -1,4 +1,5 @@ //@ check-pass +//@ add-core-stubs //@ revisions: host //@ revisions: i686 //@[i686] compile-flags: --target i686-unknown-linux-gnu @@ -58,8 +59,10 @@ //@ revisions: nvptx64 //@[nvptx64] compile-flags: --target nvptx64-nvidia-cuda //@[nvptx64] needs-llvm-components: nvptx -#![feature(rustc_attrs, unsized_fn_params, transparent_unions)] -#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)] +#![feature(no_core, rustc_attrs, lang_items)] +#![feature(unsized_fn_params, transparent_unions)] +#![no_std] +#![no_core] #![allow(unused, improper_ctypes_definitions, internal_features)] // FIXME: some targets are broken in various ways. @@ -67,67 +70,24 @@ // sparc64: https://github.com/rust-lang/rust/issues/115336 // mips64: https://github.com/rust-lang/rust/issues/115404 -#[cfg(host)] -use std::{ - any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZero, ptr::NonNull, rc::Rc, sync::Arc, -}; +extern crate minicore; +use minicore::*; -/// To work cross-target this test must be no_core. -/// This little prelude supplies what we need. -#[cfg(not(host))] +/// To work cross-target this test must be no_core. This little prelude supplies what we need. +/// +/// Note that `minicore` provides a very minimal subset of `core` items (not yet complete). This +/// prelude contains `alloc` and non-`core` (but in `std`) items that minicore does not stub out. mod prelude { - #[lang = "sized"] - pub trait Sized {} + use minicore::*; - #[lang = "legacy_receiver"] - pub trait LegacyReceiver {} - impl<T: ?Sized> LegacyReceiver for &T {} - impl<T: ?Sized> LegacyReceiver for &mut T {} - - #[lang = "copy"] - pub trait Copy: Sized {} - impl Copy for i32 {} - impl Copy for f32 {} - impl<T: ?Sized> Copy for &T {} - impl<T: ?Sized> Copy for *const T {} - impl<T: ?Sized> Copy for *mut T {} + // Trait stub, no `type_id` method. + pub trait Any: 'static {} #[lang = "clone"] pub trait Clone: Sized { fn clone(&self) -> Self; } - #[lang = "phantom_data"] - pub struct PhantomData<T: ?Sized>; - impl<T: ?Sized> Copy for PhantomData<T> {} - - #[lang = "unsafe_cell"] - #[repr(transparent)] - pub struct UnsafeCell<T: ?Sized> { - value: T, - } - - pub trait Any: 'static {} - - pub enum Option<T> { - None, - Some(T), - } - impl<T: Copy> Copy for Option<T> {} - - pub enum Result<T, E> { - Ok(T), - Err(E), - } - impl<T: Copy, E: Copy> Copy for Result<T, E> {} - - #[lang = "manually_drop"] - #[repr(transparent)] - pub struct ManuallyDrop<T: ?Sized> { - value: T, - } - impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {} - #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] #[rustc_nonnull_optimization_guaranteed] @@ -185,7 +145,6 @@ mod prelude { alloc: A, } } -#[cfg(not(host))] use prelude::*; macro_rules! test_abi_compatible { diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs index 632f1657436..a428905e40b 100644 --- a/tests/ui/async-await/async-closures/mangle.rs +++ b/tests/ui/async-await/async-closures/mangle.rs @@ -5,9 +5,6 @@ //@[v0] compile-flags: -Csymbol-mangling-version=v0 //@[legacy] compile-flags: -Csymbol-mangling-version=legacy -Zunstable-options -// FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this. -//@ ignore-pass (test emits codegen-time warnings) - #![feature(async_closure, noop_waker)] extern crate block_on; diff --git a/tests/ui/async-await/async-closures/no-borrow-from-env.rs b/tests/ui/async-await/async-closures/no-borrow-from-env.rs index fe84aeeb32f..3f9d26b9713 100644 --- a/tests/ui/async-await/async-closures/no-borrow-from-env.rs +++ b/tests/ui/async-await/async-closures/no-borrow-from-env.rs @@ -38,7 +38,10 @@ fn through_field_and_ref<'a>(x: &S<'a>) { let c = async move || { println!("{}", *x.0); }; outlives::<'a>(c()); - // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails + + // outlives::<'a>(call_once(c)); + // The above fails b/c the by-move coroutine of `c` captures `x` in its entirety. + // Since we have not asserted that the borrow for `&S<'a>` outlives `'a`, it'll fail. } fn main() {} diff --git a/tests/ui/async-await/async-closures/not-fn.rs b/tests/ui/async-await/async-closures/not-fn.rs index 5322a6d5d7a..5f2d047c3e9 100644 --- a/tests/ui/async-await/async-closures/not-fn.rs +++ b/tests/ui/async-await/async-closures/not-fn.rs @@ -9,7 +9,7 @@ fn main() { let mut x = 1; needs_fn(async || { - //~^ ERROR async closure does not implement `FnMut` because it captures state from its environment + //~^ ERROR async closure does not implement `FnMut` because it captures state from its environment x += 1; }); } diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs index e82dd1dbaf0..c4c67df544f 100644 --- a/tests/ui/async-await/async-closures/precise-captures.rs +++ b/tests/ui/async-await/async-closures/precise-captures.rs @@ -126,7 +126,7 @@ async fn async_main() { { let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") }; let c = guidance!(async move || { - // s.a = 2; // FIXME(async_closures): Figure out why this fails + s.a = 2; drop(s.b); }); s.c.0 = "uncaptured"; @@ -141,7 +141,7 @@ async fn async_main() { { let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") }; let c = guidance!(async move || { - // s.a = 2; // FIXME(async_closures): Figure out why this fails + s.a = 2; drop(s.b); }); s.c.0 = "uncaptured"; diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index 18f16ca4b2d..be3f032b8ff 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -38,10 +38,12 @@ fn through_field_and_ref<'a>(x: &S<'a>) { let c = async || { println!("{}", *x.0); }; //~ ERROR `x` does not live long enough outlives::<'a>(c()); outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` +} +fn through_field_and_ref_move<'a>(x: &S<'a>) { let c = async move || { println!("{}", *x.0); }; outlives::<'a>(c()); //~ ERROR `c` does not live long enough - // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails + outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` } fn main() {} diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index 1df5abdbb18..a70aece2dea 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -100,7 +100,6 @@ LL | let c = async || { println!("{}", *x.0); }; LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); | ------------ argument requires that `x` is borrowed for `'a` -... LL | } | - `x` dropped here while still borrowed @@ -114,11 +113,10 @@ LL | outlives::<'a>(call_once(c)); | ^^^^^^^^^^^^ lifetime `'a` required error[E0597]: `c` does not live long enough - --> $DIR/without-precise-captures-we-are-powerless.rs:43:20 + --> $DIR/without-precise-captures-we-are-powerless.rs:45:20 | -LL | fn through_field_and_ref<'a>(x: &S<'a>) { - | -- lifetime `'a` defined here -... +LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { + | -- lifetime `'a` defined here LL | let c = async move || { println!("{}", *x.0); }; | - binding `c` declared here LL | outlives::<'a>(c()); @@ -126,11 +124,20 @@ LL | outlives::<'a>(c()); | | | borrowed value does not live long enough | argument requires that `c` is borrowed for `'a` -LL | // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails +LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed -error: aborting due to 9 previous errors +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/without-precise-captures-we-are-powerless.rs:46:20 + | +LL | fn through_field_and_ref_move<'a>(x: &S<'a>) { + | ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>` +... +LL | outlives::<'a>(call_once(c)); + | ^^^^^^^^^^^^ lifetime `'a` required + +error: aborting due to 10 previous errors Some errors have detailed explanations: E0505, E0597, E0621. For more information about an error, try `rustc --explain E0505`. diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index b0ca09a59ed..37d2b0343c9 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 30 warnings emitted diff --git a/tests/ui/compiletest-self-test/minicore-smoke-test.rs b/tests/ui/compiletest-self-test/minicore-smoke-test.rs new file mode 100644 index 00000000000..ec879f2852e --- /dev/null +++ b/tests/ui/compiletest-self-test/minicore-smoke-test.rs @@ -0,0 +1,20 @@ +//! Basic smoke test for `minicore` test auxiliary. +//! +//! This test is duplicated between ui/codegen/assembly because they have different runtest +//! codepaths. + +//@ add-core-stubs +//@ check-pass +//@ compile-flags: --target=x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 + +#![crate_type = "lib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; +use minicore::*; + +struct Meow; +impl Copy for Meow {} diff --git a/tests/ui/consts/promote-not.rs b/tests/ui/consts/promote-not.rs index 80912937f31..207baccd6ab 100644 --- a/tests/ui/consts/promote-not.rs +++ b/tests/ui/consts/promote-not.rs @@ -23,7 +23,7 @@ pub const fn promote_cal(b: bool) -> i32 { 13 } -// We do not promote union field accesses in `fn. +// We do not promote union field accesses in `fn`. union U { x: i32, y: i32 } pub const fn promote_union() { let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 134fd098b7e..79eee2a3def 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let x: () = match true { + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/never-type-fallback-breaking.rs:27:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs new file mode 100644 index 00000000000..83466535e13 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs @@ -0,0 +1,13 @@ +// Test for issue #132429 +//@compile-flags: -Zunstable-options --edition=2024 +//@check-pass + +use std::future::Future; + +trait Test { + fn foo<'a>(&'a self) -> Box<dyn Future<Output = impl IntoIterator<Item = u32>>> { + Box::new(async { [] }) + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 47695814668..46121308fa0 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -3,8 +3,6 @@ fn polarity() -> impl Sized + ?use<> {} //~^ ERROR expected identifier, found keyword `use` //~| ERROR cannot find trait `r#use` in this scope -//~| WARN relaxing a default bound only does something for `?Sized` -//~| WARN relaxing a default bound only does something for `?Sized` fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index aaebfe2a86e..16e7470debf 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -5,19 +5,19 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ expected identifier, found keyword @@ -29,25 +29,25 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope error[E0658]: async closures are unstable - --> $DIR/bound-modifiers.rs:9:32 + --> $DIR/bound-modifiers.rs:7:32 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^^^ @@ -58,7 +58,7 @@ LL | fn asyncness() -> impl Sized + async use<> {} = help: to use an async block, remove the `||`: `async {` error[E0658]: const trait impls are experimental - --> $DIR/bound-modifiers.rs:14:32 + --> $DIR/bound-modifiers.rs:12:32 | LL | fn constness() -> impl Sized + const use<> {} | ^^^^^ @@ -67,21 +67,7 @@ LL | fn constness() -> impl Sized + const use<> {} = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 2 warnings emitted +error: aborting due to 10 previous errors Some errors have detailed explanations: E0405, E0658. For more information about an error, try `rustc --explain E0405`. diff --git a/tests/ui/issues/issue-37534.rs b/tests/ui/issues/issue-37534.rs index 40f7186db09..dff89d3888d 100644 --- a/tests/ui/issues/issue-37534.rs +++ b/tests/ui/issues/issue-37534.rs @@ -1,6 +1,5 @@ struct Foo<T: ?Hash> {} //~^ ERROR expected trait, found derive macro `Hash` -//~^^ ERROR parameter `T` is never used -//~^^^ WARN relaxing a default bound only does something for `?Sized` +//~| WARN relaxing a default bound only does something for `?Sized` fn main() {} diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index a687e733d3d..8747bd5ac6f 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -15,15 +15,6 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr LL | struct Foo<T: ?Hash> {} | ^^^^^ -error[E0392]: type parameter `T` is never used - --> $DIR/issue-37534.rs:1:12 - | -LL | struct Foo<T: ?Hash> {} - | ^ unused type parameter - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -Some errors have detailed explanations: E0392, E0404. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr index d8c75c33b0c..169be997b48 100644 --- a/tests/ui/lint/cli-lint-override.forbid_warn.stderr +++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `-F missing-abi` error: aborting due to 1 previous error diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr index 779c24c93f2..574f2ca66a4 100644 --- a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr @@ -2,9 +2,8 @@ warning: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `--force-warn missing-abi` warning: 1 warning emitted diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr index 1ba42e9ce32..bfec37ada95 100644 --- a/tests/ui/lint/cli-lint-override.warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `-D missing-abi` error: aborting due to 1 previous error diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed index 46b2d4e9c3f..2d88c274080 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x.is_nan(); //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = !x.is_nan(); //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if !b.is_nan() {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.rs b/tests/ui/lint/invalid-nan-comparison-suggestion.rs index 558b433d794..91753447869 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.rs +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.rs @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x == f16::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f16::NAN; + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x == f32::NAN; //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = x != f64::NAN; //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x == f128::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f128::NAN; + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if b != &f32::NAN {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr index c310341de07..9d07d3f9240 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr @@ -1,18 +1,42 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:6:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 | -LL | let _ = x == f32::NAN; +LL | let _ = x == f16::NAN; | ^^^^^^^^^^^^^ | = note: `#[warn(invalid_nan_comparisons)]` on by default help: use `f32::is_nan()` or `f64::is_nan()` instead | +LL - let _ = x == f16::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:10:13 + | +LL | let _ = x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f16::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + | +LL | let _ = x == f32::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | LL - let _ = x == f32::NAN; LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:16:13 | LL | let _ = x != f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +48,7 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:12:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:20:13 | LL | let _ = x == f64::NAN; | ^^^^^^^^^^^^^ @@ -36,7 +60,7 @@ LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:22:13 | LL | let _ = x != f64::NAN; | ^^^^^^^^^^^^^ @@ -48,7 +72,31 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:18:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:26:13 + | +LL | let _ = x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x == f128::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:28:13 + | +LL | let _ = x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f128::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:32:8 | LL | if b != &f32::NAN {} | ^^^^^^^^^^^^^^ @@ -60,7 +108,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:22:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:36:8 | LL | if b != { &f32::NAN } {} | ^^^^^^^^^^^^^^^^^^ @@ -72,7 +120,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:26:9 + --> $DIR/invalid-nan-comparison-suggestion.rs:40:9 | LL | / b != { LL | | @@ -87,7 +135,7 @@ LL + !b.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:35:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:49:13 | LL | let _ = nan!() == number!(); | ^^^^^^^^^^^^^^^^^^^ @@ -99,7 +147,7 @@ LL + let _ = number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:37:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:51:13 | LL | let _ = number!() != nan!(); | ^^^^^^^^^^^^^^^^^^^ @@ -110,5 +158,5 @@ LL - let _ = number!() != nan!(); LL + let _ = !number!().is_nan(); | -warning: 9 warnings emitted +warning: 13 warnings emitted diff --git a/tests/ui/lint/invalid-nan-comparison.rs b/tests/ui/lint/invalid-nan-comparison.rs index 202a5e27e8e..1a2c8a7c5a0 100644 --- a/tests/ui/lint/invalid-nan-comparison.rs +++ b/tests/ui/lint/invalid-nan-comparison.rs @@ -1,13 +1,38 @@ //@ check-pass +#![feature(f16, f128)] + fn main() { + f16(); f32(); f64(); + f128(); } const TEST: bool = 5f32 == f32::NAN; //~^ WARN incorrect NaN comparison +fn f16() { + macro_rules! number { () => { 5f16 }; } + let x = number!(); + x == f16::NAN; + //~^ WARN incorrect NaN comparison + x != f16::NAN; + //~^ WARN incorrect NaN comparison + x < f16::NAN; + //~^ WARN incorrect NaN comparison + x > f16::NAN; + //~^ WARN incorrect NaN comparison + x <= f16::NAN; + //~^ WARN incorrect NaN comparison + x >= f16::NAN; + //~^ WARN incorrect NaN comparison + number!() == f16::NAN; + //~^ WARN incorrect NaN comparison + f16::NAN != number!(); + //~^ WARN incorrect NaN comparison +} + fn f32() { macro_rules! number { () => { 5f32 }; } let x = number!(); @@ -49,3 +74,24 @@ fn f64() { f64::NAN != number!(); //~^ WARN incorrect NaN comparison } + +fn f128() { + macro_rules! number { () => { 5f128 }; } + let x = number!(); + x == f128::NAN; + //~^ WARN incorrect NaN comparison + x != f128::NAN; + //~^ WARN incorrect NaN comparison + x < f128::NAN; + //~^ WARN incorrect NaN comparison + x > f128::NAN; + //~^ WARN incorrect NaN comparison + x <= f128::NAN; + //~^ WARN incorrect NaN comparison + x >= f128::NAN; + //~^ WARN incorrect NaN comparison + number!() == f128::NAN; + //~^ WARN incorrect NaN comparison + f128::NAN != number!(); + //~^ WARN incorrect NaN comparison +} diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr index 054c06d38b3..486d2a9636c 100644 --- a/tests/ui/lint/invalid-nan-comparison.stderr +++ b/tests/ui/lint/invalid-nan-comparison.stderr @@ -1,5 +1,5 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:8:20 + --> $DIR/invalid-nan-comparison.rs:12:20 | LL | const TEST: bool = 5f32 == f32::NAN; | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,79 @@ LL + const TEST: bool = 5f32.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:14:5 + --> $DIR/invalid-nan-comparison.rs:18:5 + | +LL | x == f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f16::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:20:5 + | +LL | x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f16::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:22:5 + | +LL | x < f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:24:5 + | +LL | x > f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:26:5 + | +LL | x <= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:28:5 + | +LL | x >= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:30:5 + | +LL | number!() == f16::NAN; + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f16::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:32:5 + | +LL | f16::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f16::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:39:5 | LL | x == f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +96,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:16:5 + --> $DIR/invalid-nan-comparison.rs:41:5 | LL | x != f32::NAN; | ^^^^^^^^^^^^^ @@ -36,31 +108,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:18:5 + --> $DIR/invalid-nan-comparison.rs:43:5 | LL | x < f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:20:5 + --> $DIR/invalid-nan-comparison.rs:45:5 | LL | x > f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:22:5 + --> $DIR/invalid-nan-comparison.rs:47:5 | LL | x <= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:24:5 + --> $DIR/invalid-nan-comparison.rs:49:5 | LL | x >= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:26:5 + --> $DIR/invalid-nan-comparison.rs:51:5 | LL | number!() == f32::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +144,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:28:5 + --> $DIR/invalid-nan-comparison.rs:53:5 | LL | f32::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +156,7 @@ LL + !number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:35:5 + --> $DIR/invalid-nan-comparison.rs:60:5 | LL | x == f64::NAN; | ^^^^^^^^^^^^^ @@ -96,7 +168,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:37:5 + --> $DIR/invalid-nan-comparison.rs:62:5 | LL | x != f64::NAN; | ^^^^^^^^^^^^^ @@ -108,31 +180,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:39:5 + --> $DIR/invalid-nan-comparison.rs:64:5 | LL | x < f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:41:5 + --> $DIR/invalid-nan-comparison.rs:66:5 | LL | x > f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:43:5 + --> $DIR/invalid-nan-comparison.rs:68:5 | LL | x <= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:45:5 + --> $DIR/invalid-nan-comparison.rs:70:5 | LL | x >= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:47:5 + --> $DIR/invalid-nan-comparison.rs:72:5 | LL | number!() == f64::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +216,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:49:5 + --> $DIR/invalid-nan-comparison.rs:74:5 | LL | f64::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -155,5 +227,77 @@ LL - f64::NAN != number!(); LL + !number!().is_nan(); | -warning: 17 warnings emitted +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:81:5 + | +LL | x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f128::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:83:5 + | +LL | x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f128::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:85:5 + | +LL | x < f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:87:5 + | +LL | x > f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:89:5 + | +LL | x <= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:91:5 + | +LL | x >= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:93:5 + | +LL | number!() == f128::NAN; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f128::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:95:5 + | +LL | f128::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f128::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: 33 warnings emitted diff --git a/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs b/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs new file mode 100644 index 00000000000..5732e048ae3 --- /dev/null +++ b/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs @@ -0,0 +1,64 @@ +// Regression tests for https://github.com/rust-lang/rust/issues/132427 + +//@ check-pass + +// original +mod auth { + const _: () = { + pub enum ArbitraryContext {} + + const _: () = { + impl ArbitraryContext {} + }; + }; +} + +mod z { + pub enum ArbitraryContext {} + + const _: () = { + const _: () = { + impl ArbitraryContext {} + }; + }; +} + +const _: () = { + mod auth { + const _: () = { + pub enum ArbitraryContext {} + + const _: () = { + impl ArbitraryContext {} + }; + }; + } +}; + +mod a { + mod b { + const _: () = { + pub enum ArbitraryContext {} + + const _: () = { + impl ArbitraryContext {} + }; + }; + } +} + +mod foo { + const _: () = { + mod auth { + const _: () = { + pub enum ArbitraryContext {} + + const _: () = { + impl ArbitraryContext {} + }; + }; + } + }; +} + +fn main() {} diff --git a/tests/ui/mir/clone-canonicalization-miscompile-132353.rs b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs new file mode 100644 index 00000000000..ba740c10f90 --- /dev/null +++ b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs @@ -0,0 +1,25 @@ +//! The mir-opt added in <https://github.com/rust-lang/rust/pull/128299> unfortunately seems to lead +//! to a miscompile (reported in <https://github.com/rust-lang/rust/issues/132353>, minimization +//! reproduced in this test file). +//@ revisions: release debug +// Note: it's not strictly cargo's release profile, but any non-zero opt-level was sufficient to +// reproduce the miscompile. +//@[release] compile-flags: -C opt-level=1 +//@[debug] compile-flags: -C opt-level=0 +//@ run-pass + +fn pop_min(mut score2head: Vec<Option<usize>>) -> Option<usize> { + loop { + if let Some(col) = score2head[0] { + score2head[0] = None; + return Some(col); + } + } +} + +fn main() { + let min = pop_min(vec![Some(1)]); + println!("min: {:?}", min); + // panic happened on 1.83.0 beta in release mode but not debug mode. + let _ = min.unwrap(); +} diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index d88615186dd..6bc4501b6a3 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f LL | foo(_x); | ^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _x: () = return; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index ec49137ba79..79f47bb5fbc 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | false => <_>::default(), | ^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | false => <()>::default(), + | ~~ warning: this function depends on never type fallback being `()` --> $DIR/dependency-on-fallback-to-unit.rs:19:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index 2a3c5edc218..d40d1da76f9 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let x: (); + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-control-flow.rs:42:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail | LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | let x: (); + | ++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr index 11245cc7aab..d11c21d9573 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Test` will fail LL | unconstrained_arg(return); | ^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unconstrained_arg::<()>(return); + | ++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index b485c94df4d..30a5e60a758 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr index 3fb5536dee7..fb0166dd9e0 100644 --- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr +++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Bar` will fail LL | foo(|| panic!()); | ^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | foo::<(), _>(|| panic!()); + | +++++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index a75039b8237..6a48a7b9b47 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ warning: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ warning: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 @@ -102,6 +130,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: 10 warnings emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 4138e9f8c86..844cd62c267 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ error: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ error: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 @@ -102,6 +130,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748> = help: specify the type explicitly = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: the type `!` does not permit zero-initialization --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 diff --git a/tests/ui/target-feature/wasm-disable-simd.rs b/tests/ui/target-feature/wasm-disable-simd.rs new file mode 100644 index 00000000000..998c8674823 --- /dev/null +++ b/tests/ui/target-feature/wasm-disable-simd.rs @@ -0,0 +1,12 @@ +//@ only-wasm32-wasip1 +//@ compile-flags: -Ctarget-feature=-simd128 --crate-type=lib +//@ build-pass + +// This is a regression test of #131031. + +use std::arch::wasm32::*; + +#[target_feature(enable = "simd128")] +pub unsafe fn some_simd128_fn(chunk: v128) -> bool { + u8x16_all_true(chunk) +} diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.rs b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs new file mode 100644 index 00000000000..dfa8e9886b6 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs @@ -0,0 +1,4 @@ +fn uwu<T: ?Sized<i32>>() {} +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr new file mode 100644 index 00000000000..3297eb6279f --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr @@ -0,0 +1,11 @@ +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/maybe-bound-generics-deny.rs:1:12 + | +LL | fn uwu<T: ?Sized<i32>>() {} + | ^^^^^----- help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs new file mode 100644 index 00000000000..2cb63f25d06 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs @@ -0,0 +1,7 @@ +trait Trait {} + +fn test<T: ?self::<i32>::Trait>() {} +//~^ ERROR type arguments are not allowed on this type +//~| WARN relaxing a default bound only does something for `?Sized` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr new file mode 100644 index 00000000000..701e493f5a5 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr @@ -0,0 +1,17 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-has-path-args.rs:3:12 + | +LL | fn test<T: ?self::<i32>::Trait>() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/maybe-bound-has-path-args.rs:3:20 + | +LL | fn test<T: ?self::<i32>::Trait>() {} + | ---- ^^^ type argument not allowed + | | + | not allowed on this type + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs new file mode 100644 index 00000000000..b6b2551e463 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs @@ -0,0 +1,12 @@ +trait HasAssoc { + type Assoc; +} +fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {} +//~^ WARN relaxing a default bound + +trait NoAssoc {} +fn noassoc<T: ?NoAssoc<Missing = ()>>() {} +//~^ WARN relaxing a default bound +//~| ERROR associated type `Missing` not found for `NoAssoc` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr new file mode 100644 index 00000000000..91d78e59cd5 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr @@ -0,0 +1,21 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:4:16 + | +LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {} + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:8:15 + | +LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0220]: associated type `Missing` not found for `NoAssoc` + --> $DIR/maybe-bound-with-assoc.rs:8:24 + | +LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {} + | ^^^^^^^ associated type `Missing` not found + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0220`. diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr index 82d6412ded0..102dbb1a599 100644 --- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr +++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr @@ -29,6 +29,12 @@ LL | const fn check<T: ~const Destruct>(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions +error[E0277]: the trait bound `T: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:41:9 + | +LL | T::a(); + | ^^^^^^ + error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions --> $DIR/const-drop-fail-2.rs:41:9 | @@ -41,7 +47,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0015, E0493. +Some errors have detailed explanations: E0015, E0277, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr index 381e4d78c28..7471b200c33 100644 --- a/tests/ui/traits/const-traits/const-drop.precise.stderr +++ b/tests/ui/traits/const-traits/const-drop.precise.stderr @@ -78,6 +78,12 @@ error[E0493]: destructor of `T` cannot be evaluated at compile-time LL | const fn a<T: ~const Destruct>(_: T) {} | ^ the destructor for this type cannot be evaluated in constant functions +error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied + --> $DIR/const-drop.rs:69:13 + | +LL | T::foo(); + | ^^^^^^^^ + error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions --> $DIR/const-drop.rs:69:13 | @@ -90,7 +96,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0015, E0277, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr index 399e7849673..71378349161 100644 --- a/tests/ui/traits/const-traits/const-drop.stock.stderr +++ b/tests/ui/traits/const-traits/const-drop.stock.stderr @@ -80,6 +80,12 @@ LL | const fn a<T: ~const Destruct>(_: T) {} | | | the destructor for this type cannot be evaluated in constant functions +error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied + --> $DIR/const-drop.rs:69:13 + | +LL | T::foo(); + | ^^^^^^^^ + error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions --> $DIR/const-drop.rs:69:13 | @@ -92,7 +98,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors Some errors have detailed explanations: E0015, E0277, E0493. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs index cfcada9c828..30d2260a744 100644 --- a/tests/ui/traits/const-traits/cross-crate.rs +++ b/tests/ui/traits/const-traits/cross-crate.rs @@ -18,10 +18,11 @@ const fn const_context() { #[cfg(any(stocknc, gatednc))] NonConst.func(); //[stocknc]~^ ERROR: cannot call - //[gatednc]~^^ ERROR: the trait bound + //[stocknc]~| ERROR: cannot call + //[gatednc]~^^^ ERROR: the trait bound Const.func(); - //[stock]~^ ERROR: cannot call - //[stocknc]~^^ ERROR: cannot call + //[stock,stocknc]~^ ERROR: cannot call + //[stock,stocknc]~| ERROR: cannot call } fn main() {} diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr index b481bdc470c..b35891071b0 100644 --- a/tests/ui/traits/const-traits/cross-crate.stock.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr @@ -1,5 +1,5 @@ error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions - --> $DIR/cross-crate.rs:22:11 + --> $DIR/cross-crate.rs:23:11 | LL | Const.func(); | ^^^^^^ @@ -10,6 +10,19 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | -error: aborting due to 1 previous error +error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions + --> $DIR/cross-crate.rs:23:11 + | +LL | Const.func(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + | +LL + #![feature(const_trait_impl)] + | + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr index 5c3e3b6ff40..89de89159db 100644 --- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr +++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr @@ -10,18 +10,44 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | +error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions + --> $DIR/cross-crate.rs:19:14 + | +LL | NonConst.func(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + | +LL + #![feature(const_trait_impl)] + | + +error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions + --> $DIR/cross-crate.rs:23:11 + | +LL | Const.func(); + | ^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + | +LL + #![feature(const_trait_impl)] + | + error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions - --> $DIR/cross-crate.rs:22:11 + --> $DIR/cross-crate.rs:23:11 | LL | Const.func(); | ^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` help: add `#![feature(const_trait_impl)]` to the crate attributes to enable | LL + #![feature(const_trait_impl)] | -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs index b534d23b107..96acdc300e0 100644 --- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs +++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs @@ -1,6 +1,3 @@ -//@ known-bug: #110395 -//@ check-pass - #![feature(const_trait_impl)] #[const_trait] @@ -13,7 +10,7 @@ const fn foo<T>() where T: ~const Tr {} pub trait Foo { fn foo() { foo::<()>(); - //FIXME ~^ ERROR the trait bound `(): Tr` is not satisfied + //~^ ERROR the trait bound `(): ~const Tr` is not satisfied } } diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr new file mode 100644 index 00000000000..308a60c08d3 --- /dev/null +++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): ~const Tr` is not satisfied + --> $DIR/default-method-body-is-const-body-checking.rs:12:9 + | +LL | foo::<()>(); + | ^^^^^^^^^^^ + | +note: required by a bound in `foo` + --> $DIR/default-method-body-is-const-body-checking.rs:7:28 + | +LL | const fn foo<T>() where T: ~const Tr {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr index 8e6f6945a1b..98a9de2324a 100644 --- a/tests/ui/traits/const-traits/specializing-constness-2.stderr +++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr @@ -1,3 +1,9 @@ +error[E0277]: the trait bound `T: ~const A` is not satisfied + --> $DIR/specializing-constness-2.rs:27:5 + | +LL | <T as A>::a(); + | ^^^^^^^^^^^^^ + error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions --> $DIR/specializing-constness-2.rs:27:5 | @@ -10,6 +16,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable LL + #![feature(effects)] | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.rs b/tests/ui/traits/const-traits/staged-api-user-crate.rs index c4ecb8f67a1..c820d1ff47c 100644 --- a/tests/ui/traits/const-traits/staged-api-user-crate.rs +++ b/tests/ui/traits/const-traits/staged-api-user-crate.rs @@ -11,6 +11,7 @@ fn non_const_context() { const fn stable_const_context() { Unstable::func(); //~^ ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions + //~| ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions } fn main() {} diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr index 781191ec97c..24cdb1d3d5a 100644 --- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr +++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr @@ -10,6 +10,19 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable LL + #![feature(const_trait_impl)] | -error: aborting due to 1 previous error +error[E0015]: cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions + --> $DIR/staged-api-user-crate.rs:12:5 + | +LL | Unstable::func(); + | ^^^^^^^^^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + | +LL + #![feature(const_trait_impl)] + | + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0015`. |
