From a731c2d9610b7de98c8c99a78df41f077ee40957 Mon Sep 17 00:00:00 2001 From: firestar99 Date: Thu, 26 Feb 2026 13:31:36 +0100 Subject: [PATCH 1/7] update toolchain to 2025-11-13, fails --- crates/rustc_codegen_spirv/build.rs | 4 ++-- crates/rustc_codegen_spirv/src/builder/builder_methods.rs | 1 + crates/rustc_codegen_spirv/src/builder/mod.rs | 2 +- crates/rustc_codegen_spirv/src/lib.rs | 2 -- rust-toolchain.toml | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index bb6ff18619..ceaa02e462 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -19,9 +19,9 @@ use std::{env, fs, mem}; /// `cargo publish`. We need to figure out a way to do this properly, but let's hardcode it for now :/ //const REQUIRED_RUST_TOOLCHAIN: &str = include_str!("../../rust-toolchain.toml"); const REQUIRED_RUST_TOOLCHAIN: &str = r#"[toolchain] -channel = "nightly-2025-11-02" +channel = "nightly-2025-11-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = bd3ac0330018c23b111bbee176f32c377be7b319"#; +# commit_hash = 01867557cd7dbe256a031a7b8e28d05daecd75ab"#; fn rustc_output(arg: &str) -> Result> { let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index 05157d7f93..b05000bd76 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -1917,6 +1917,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { OperandRef { val, layout: place.layout, + move_annotation: None, } } diff --git a/crates/rustc_codegen_spirv/src/builder/mod.rs b/crates/rustc_codegen_spirv/src/builder/mod.rs index 7135e144c8..19eb997d60 100644 --- a/crates/rustc_codegen_spirv/src/builder/mod.rs +++ b/crates/rustc_codegen_spirv/src/builder/mod.rs @@ -174,7 +174,7 @@ impl<'a, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'tcx> { fn add_coverage(&mut self, _instance: Instance<'tcx>, _kind: &CoverageKind) {} } -impl<'a, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'tcx> { +impl<'a, 'tcx> DebugInfoBuilderMethods<'_> for Builder<'a, 'tcx> { fn dbg_var_addr( &mut self, _dbg_var: Self::DIVariable, diff --git a/crates/rustc_codegen_spirv/src/lib.rs b/crates/rustc_codegen_spirv/src/lib.rs index 76f5f5bc71..3523d3a4ac 100644 --- a/crates/rustc_codegen_spirv/src/lib.rs +++ b/crates/rustc_codegen_spirv/src/lib.rs @@ -1,5 +1,4 @@ // HACK(eddyb) start of `rustc_codegen_ssa` crate-level attributes (see `build.rs`). -#![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] #![feature(assert_matches)] @@ -7,7 +6,6 @@ #![feature(file_buffered)] #![feature(if_let_guard)] #![feature(negative_impls)] -#![feature(rustdoc_internals)] #![feature(string_from_utf8_lossy_owned)] #![feature(trait_alias)] #![feature(try_blocks)] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b27e9b9dec..4270279926 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,7 +1,7 @@ [toolchain] -channel = "nightly-2025-11-02" +channel = "nightly-2025-11-13" components = ["rust-src", "rustc-dev", "llvm-tools"] -# commit_hash = bd3ac0330018c23b111bbee176f32c377be7b319 +# commit_hash = 01867557cd7dbe256a031a7b8e28d05daecd75ab # Whenever changing the nightly channel, update the commit hash above, and # change `REQUIRED_RUST_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` too. From 8aed8dbd685a5e2c50e6f643113bbce57e7b7a99 Mon Sep 17 00:00:00 2001 From: firestar99 Date: Thu, 26 Feb 2026 13:32:30 +0100 Subject: [PATCH 2/7] adjust target declaration, conflicts with target declaration refactor see https://github.com/Rust-GPU/rust-gpu/pull/491 --- crates/rustc_codegen_spirv/src/link.rs | 10 +++++++--- crates/rustc_codegen_spirv/src/target.rs | 9 +++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/link.rs b/crates/rustc_codegen_spirv/src/link.rs index 430cbac59b..205cba0ca6 100644 --- a/crates/rustc_codegen_spirv/src/link.rs +++ b/crates/rustc_codegen_spirv/src/link.rs @@ -25,12 +25,14 @@ use rustc_session::config::{ }; use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename}; use rustc_span::Symbol; +use spirv_tools::TargetEnv; use std::collections::BTreeMap; use std::ffi::{CString, OsStr}; use std::fs::File; use std::io::{BufWriter, Read}; use std::iter; use std::path::{Path, PathBuf}; +use std::str::FromStr; use std::sync::Arc; pub fn link( @@ -337,7 +339,8 @@ fn do_spirv_opt( opt::{self, Optimizer}, }; - let mut optimizer = opt::create(sess.target.options.env.parse().ok()); + let target_env = TargetEnv::from_str(sess.target.options.env.desc()).ok(); + let mut optimizer = opt::create(target_env); match sess.opts.optimize { OptLevel::No => {} @@ -399,7 +402,8 @@ fn do_spirv_val( ) { use spirv_tools::val::{self, Validator}; - let validator = val::create(sess.target.options.env.parse().ok()); + let target_env = TargetEnv::from_str(sess.target.options.env.desc()).ok(); + let validator = val::create(target_env); if let Err(e) = validator.validate(spv_binary, Some(options)) { let mut err = sess.dcx().struct_err(e.to_string()); @@ -498,7 +502,7 @@ fn add_upstream_native_libraries( fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool { match lib.cfg { Some(ref cfg) => { - eval_config_entry(sess, cfg, CRATE_NODE_ID, None, ShouldEmit::ErrorsAndLints).as_bool() + eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool() } None => true, } diff --git a/crates/rustc_codegen_spirv/src/target.rs b/crates/rustc_codegen_spirv/src/target.rs index 71390f9b8d..08be3c27e0 100644 --- a/crates/rustc_codegen_spirv/src/target.rs +++ b/crates/rustc_codegen_spirv/src/target.rs @@ -1,5 +1,5 @@ use rspirv::spirv::MemoryModel; -use rustc_target::spec::{Cc, LinkerFlavor, PanicStrategy, Target, TargetOptions}; +use rustc_target::spec::{Arch, Cc, Env, LinkerFlavor, PanicStrategy, Target, TargetOptions}; use spirv_tools::TargetEnv; const ARCH: &str = "spirv"; @@ -61,8 +61,9 @@ impl SpirvTarget { o.emit_debug_gdb_scripts = false; o.linker_flavor = LinkerFlavor::Unix(Cc::No); o.panic_strategy = PanicStrategy::Abort; - o.env = self.env.to_string().into(); - o.vendor = self.vendor.clone().into(); + o.env = Env::Other(self.env.to_string().into()); + // Note(@firestar99): not sure if this does anything + o.is_like_gpu = true; // TODO: Investigate if main_needs_argc_argv is useful (for building exes) o.main_needs_argc_argv = false; o @@ -74,7 +75,7 @@ impl SpirvTarget { metadata: Default::default(), pointer_width: 32, data_layout: "e-m:e-p:32:32:32-i64:64-n8:16:32:64".into(), - arch: ARCH.into(), + arch: Arch::Other(ARCH.into()), options: self.init_target_opts(), } } From b4c3e49431f209c465fd86c5ac6ba10f223b47e9 Mon Sep 17 00:00:00 2001 From: David Palm Date: Fri, 14 Nov 2025 09:13:00 +0100 Subject: [PATCH 3/7] make build.rs handle macOS non-utf8 metadata files --- crates/rustc_codegen_spirv/build.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/rustc_codegen_spirv/build.rs b/crates/rustc_codegen_spirv/build.rs index ceaa02e462..e21c94726d 100644 --- a/crates/rustc_codegen_spirv/build.rs +++ b/crates/rustc_codegen_spirv/build.rs @@ -135,6 +135,10 @@ fn generate_pqp_cg_ssa() -> Result<(), Box> { } let in_path = entry.path(); + + if in_path.ends_with(".DS_Store") { + continue; + } let out_path = out_dir.join(entry.file_name()); let mut src = fs::read_to_string(in_path)?; From 74877eecbdcdd1325a66de37b85ba45016b41f2e Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Fri, 6 Mar 2026 13:36:16 -0800 Subject: [PATCH 4/7] Port backend to newer rustc ABI/target behavior - Rewrite extern C fn sigs to Rust ABI to satisfy new rustc fn_abi sanity checks. - Handle direct calls represented as ptr by recovering function signature from callee type/fn_abi. - Keep generated SPIR-V target JSON aligned with backend target options and rustc 1.93 schema expectations. --- .../src/target_spec.rs | 11 ++- crates/rustc_codegen_spirv/src/abi.rs | 9 ++- .../src/builder/builder_methods.rs | 68 +++++++++++++------ 3 files changed, 58 insertions(+), 30 deletions(-) diff --git a/crates/rustc_codegen_spirv-types/src/target_spec.rs b/crates/rustc_codegen_spirv-types/src/target_spec.rs index 3af35c8a8c..d7faf951e6 100644 --- a/crates/rustc_codegen_spirv-types/src/target_spec.rs +++ b/crates/rustc_codegen_spirv-types/src/target_spec.rs @@ -55,13 +55,10 @@ impl TargetSpecVersion { /// format the target spec json pub fn format_spec(&self, target: &SpirvTarget) -> String { let target_env = target.env(); - let extra = match self { - TargetSpecVersion::Rustc_1_76_0 => r#""os": "unknown","#, - _ => r#""crt-static-respected": true,"#, - }; - let target_pointer_width = match self { - TargetSpecVersion::Rustc_1_76_0 | TargetSpecVersion::Rustc_1_85_0 => "\"32\"", - TargetSpecVersion::Rustc_1_93_0 => "32", + let (extra, target_pointer_width) = match self { + TargetSpecVersion::Rustc_1_76_0 => (r#""os": "unknown","#, "\"32\""), + TargetSpecVersion::Rustc_1_85_0 => (r#""crt-static-respected": true,"#, "\"32\""), + TargetSpecVersion::Rustc_1_93_0 => (r#""crt-static-respected": true,"#, "32"), }; format!( r#"{{ diff --git a/crates/rustc_codegen_spirv/src/abi.rs b/crates/rustc_codegen_spirv/src/abi.rs index bcfa0d86af..e7870173f1 100644 --- a/crates/rustc_codegen_spirv/src/abi.rs +++ b/crates/rustc_codegen_spirv/src/abi.rs @@ -38,7 +38,12 @@ pub(crate) fn provide(providers: &mut Providers) { // This theoretically then should be fine to leave as C, but, there's no backend hook for // `FnAbi::adjust_for_cabi`, causing it to panic: // https://github.com/rust-lang/rust/blob/5fae56971d8487088c0099c82c0a5ce1638b5f62/compiler/rustc_target/src/abi/call/mod.rs#L603 - // So, treat any `extern "C"` functions as `extern "unadjusted"`, to be able to compile libcore with arch=spirv. + // So, treat any `extern "C"` functions as `extern "Rust"`, to be able to + // compile libcore with arch=spirv. + // + // NOTE: this used to rewrite to `extern "unadjusted"`, but rustc now + // validates `#[rustc_pass_indirectly_in_non_rustic_abis]` for non-Rust ABIs, + // and `Unadjusted` does not satisfy that requirement. providers.fn_sig = |tcx, def_id| { // We can't capture the old fn_sig and just call that, because fn_sig is a `fn`, not a `Fn`, i.e. it can't // capture variables. Fortunately, the defaults are exposed (thanks rustdoc), so use that instead. @@ -46,7 +51,7 @@ pub(crate) fn provide(providers: &mut Providers) { result.map_bound(|outer| { outer.map_bound(|mut inner| { if let Abi::C { .. } = inner.abi { - inner.abi = Abi::Unadjusted; + inner.abi = Abi::Rust; } inner }) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index b05000bd76..ccfb290336 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -3274,29 +3274,55 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { // be fixed upstream, so we never see any "function pointer" values being // created just to perform direct calls. let (callee_val, result_type, argument_types) = match self.lookup_type(callee.ty) { - SpirvType::Pointer { pointee } => match self.lookup_type(pointee) { - SpirvType::Function { - return_type, - arguments, - } => ( - if let SpirvValueKind::FnAddr { function } = callee.kind { + SpirvType::Pointer { pointee } => { + let (pointee_is_function, result_type, argument_types) = match self + .lookup_type(pointee) + { + SpirvType::Function { + return_type, + arguments, + } => (true, return_type, arguments), + // Newer rustc can represent direct call targets as `ptr`, + // with the callee signature carried separately. + _ => match self.lookup_type(callee_ty) { + SpirvType::Function { + return_type, + arguments, + } => (false, return_type, arguments), + _ => { + let Some(fn_abi) = fn_abi else { + bug!( + "call expected `fn` pointer to point to function type, got `{}`", + self.debug_type(pointee) + ); + }; + let fn_ty = fn_abi.spirv_type(self.span(), self); + match self.lookup_type(fn_ty) { + SpirvType::Function { + return_type, + arguments, + } => (false, return_type, arguments), + _ => bug!("call expected function ABI to lower to function type"), + } + } + }, + }; + + let callee_val = if let SpirvValueKind::FnAddr { function } = callee.kind { + if pointee_is_function { assert_ty_eq!(self, callee_ty, pointee); - function } - // Truly indirect call. - else { - let fn_ptr_val = callee.def(self); - self.zombie(fn_ptr_val, "indirect calls are not supported in SPIR-V"); - fn_ptr_val - }, - return_type, - arguments, - ), - _ => bug!( - "call expected `fn` pointer to point to function type, got `{}`", - self.debug_type(pointee) - ), - }, + function + } + // Truly indirect call. + else { + let fn_ptr_val = callee.def(self); + self.zombie(fn_ptr_val, "indirect calls are not supported in SPIR-V"); + fn_ptr_val + }; + + (callee_val, result_type, argument_types) + } _ => bug!( "call expected `fn` pointer type, got `{}`", From 5819774e68268cf9ff0eae479d6241fae158ac5a Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Fri, 6 Mar 2026 13:36:20 -0800 Subject: [PATCH 5/7] Update compiletest baselines for new nightly diagnostics Refresh expected stderr for debug_printf trait-path wording and unwrap_or line mapping changes. --- .../ui/arch/debug_printf_type_checking.stderr | 24 +++++++++---------- .../ui/lang/core/unwrap_or.stderr | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr index d28980af39..3e753ed396 100644 --- a/tests/compiletests/ui/arch/debug_printf_type_checking.stderr +++ b/tests/compiletests/ui/arch/debug_printf_type_checking.stderr @@ -114,21 +114,21 @@ LL - debug_printf!("%u", 11.0_f32); LL + debug_printf!("%u", 11u32); | -error[E0277]: the trait bound `{float}: Vector` is not satisfied +error[E0277]: the trait bound `{float}: spirv_std::Vector` is not satisfied --> $DIR/debug_printf_type_checking.rs:23:9 | LL | debug_printf!("%v2f", 11.0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Vector` is not implemented for `{float}` - | - = help: the following other types implement trait `Vector`: - `BVec2` implements `Vector` - `BVec3` implements `Vector` - `BVec4` implements `Vector` - `DVec2` implements `Vector` - `DVec3` implements `Vector` - `DVec4` implements `Vector` - `IVec2` implements `Vector` - `IVec3` implements `Vector` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `spirv_std::Vector` is not implemented for `{float}` + | + = help: the following other types implement trait `spirv_std::Vector`: + `BVec2` implements `spirv_std::Vector` + `BVec3` implements `spirv_std::Vector` + `BVec4` implements `spirv_std::Vector` + `DVec2` implements `spirv_std::Vector` + `DVec3` implements `spirv_std::Vector` + `DVec4` implements `spirv_std::Vector` + `IVec2` implements `spirv_std::Vector` + `IVec3` implements `spirv_std::Vector` and 8 others note: required by a bound in `assert_is_vector` --> $SPIRV_STD_SRC/debug_printf.rs:11:40 diff --git a/tests/compiletests/ui/lang/core/unwrap_or.stderr b/tests/compiletests/ui/lang/core/unwrap_or.stderr index a5bcc86afb..ef3722823c 100644 --- a/tests/compiletests/ui/lang/core/unwrap_or.stderr +++ b/tests/compiletests/ui/lang/core/unwrap_or.stderr @@ -1,8 +1,8 @@ %1 = OpFunction %2 None %3 %4 = OpLabel -OpLine %5 1041 14 +OpLine %5 1042 14 %6 = OpBitcast %7 %8 -OpLine %5 1041 8 +OpLine %5 1042 8 %9 = OpINotEqual %10 %6 %11 OpNoLine OpSelectionMerge %12 None From 3bbb1fd4a07ffa88855806adf94b6824dd640bbe Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Fri, 6 Mar 2026 13:50:54 -0800 Subject: [PATCH 6/7] Ignore is-like-gpu in target-spec JSON comparison Normalize target-spec JSON before comparing backend-expected vs provided JSON by dropping the is-like-gpu key, which rustc rejects in external target JSON for non-nvptx/amdgcn targets. --- .../rustc_codegen_spirv/src/codegen_cx/mod.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs index 9d1382b06f..64fc9d4994 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/mod.rs @@ -116,6 +116,15 @@ impl<'tcx> CodegenCx<'tcx> { // HACK(eddyb) this loads the same `serde_json` used by `rustc_target`. extern crate serde_json; + fn normalize_target_spec_json(mut json: serde_json::Value) -> serde_json::Value { + // rustc currently rejects this key in external target JSON unless + // the target is `nvptx64` or `amdgcn`, even though the in-memory + // target options for SPIR-V can set it. + if let Some(obj) = json.as_object_mut() { + obj.remove("is-like-gpu"); + } + json + } let expected = &target.rustc_target(); let found = &tcx.sess.target; @@ -128,11 +137,13 @@ impl<'tcx> CodegenCx<'tcx> { TargetTuple::TargetTuple(_) => { // FIXME(eddyb) this case should be impossible as upstream // `rustc` doesn't support `spirv-*` targets! - (expected != found).then(|| [expected, found].map(|spec| spec.to_json())) + let expected = normalize_target_spec_json(expected.to_json()); + let found = normalize_target_spec_json(found.to_json()); + (expected != found).then_some([expected, found]) } TargetTuple::TargetJson { contents, .. } => { - let expected = expected.to_json(); - let found = serde_json::from_str(contents).unwrap(); + let expected = normalize_target_spec_json(expected.to_json()); + let found = normalize_target_spec_json(serde_json::from_str(contents).unwrap()); (expected != found).then_some([expected, found]) } } From 6e009cce07d0b77c205b7c512319eb50d5a5fd57 Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Fri, 6 Mar 2026 14:11:39 -0800 Subject: [PATCH 7/7] Fix clippy single_match_else in call callee type handling --- .../src/builder/builder_methods.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index ccfb290336..c6f0fa576b 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -3284,12 +3284,14 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { } => (true, return_type, arguments), // Newer rustc can represent direct call targets as `ptr`, // with the callee signature carried separately. - _ => match self.lookup_type(callee_ty) { - SpirvType::Function { + _ => { + if let SpirvType::Function { return_type, arguments, - } => (false, return_type, arguments), - _ => { + } = self.lookup_type(callee_ty) + { + (false, return_type, arguments) + } else { let Some(fn_abi) = fn_abi else { bug!( "call expected `fn` pointer to point to function type, got `{}`", @@ -3305,7 +3307,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> { _ => bug!("call expected function ABI to lower to function type"), } } - }, + } }; let callee_val = if let SpirvValueKind::FnAddr { function } = callee.kind {