Update to nightly-2023-08-29

This commit is contained in:
Christian Legnitto 2023-08-30 16:09:46 -04:00 committed by Eduard-Mihai Burtescu
parent e87c324bfd
commit 9b587c1712
16 changed files with 137 additions and 111 deletions

5
Cargo.lock generated
View File

@ -2041,6 +2041,7 @@ dependencies = [
"spirv-tools",
"syn",
"tempfile",
"termcolor",
]
[[package]]
@ -2473,9 +2474,9 @@ dependencies = [
[[package]]
name = "termcolor"
version = "1.1.2"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]

View File

@ -62,6 +62,13 @@ spirt = "0.3.0"
lazy_static = "1.4.0"
itertools = "0.10.5"
# `termcolor` is needed because we cannot construct an Emitter after it was added in
# https://github.com/rust-lang/rust/pull/114104. This can be removed when
# https://github.com/rust-lang/rust/pull/115393 lands.
# We need to construct an emitter as yet another workaround,
# see https://github.com/rust-lang/rust/pull/102992.
termcolor = "1.2"
[dev-dependencies]
pipe = "0.4"
pretty_assertions = "1.0"

View File

@ -10,9 +10,9 @@ use std::process::{Command, ExitCode};
/// `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-2023-07-08"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
# commit_hash = cb80ff132a0e9aa71529b701427e4e6c243b58df"#;
channel = "nightly-2023-08-29"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = 4e78abb437a0478d1f42115198ee45888e5330fd"#;
fn get_rustc_commit_hash() -> Result<String, Box<dyn Error>> {
let rustc = std::env::var("RUSTC").unwrap_or_else(|_| String::from("rustc"));

View File

@ -10,9 +10,9 @@ use rustc_errors::ErrorGuaranteed;
use rustc_index::Idx;
use rustc_middle::query::{ExternProviders, Providers};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{
self, Const, FloatTy, GeneratorSubsts, IntTy, ParamEnv, PolyFnSig, Ty, TyCtxt, TyKind,
self, Const, FloatTy, GeneratorArgs, IntTy, ParamEnv, PolyFnSig, Ty, TyCtxt, TyKind,
TypeAndMut, UintTy,
};
use rustc_middle::{bug, span_bug};
@ -104,6 +104,8 @@ pub(crate) fn provide(providers: &mut Providers) {
largest_niche,
align,
size,
max_repr_align,
unadjusted_abi_align,
} = *layout;
LayoutS {
fields: match *fields {
@ -147,6 +149,8 @@ pub(crate) fn provide(providers: &mut Providers) {
largest_niche,
align,
size,
max_repr_align,
unadjusted_abi_align,
}
}
providers.layout_of = |tcx, key| {
@ -343,7 +347,7 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
fn spirv_type(&self, mut span: Span, cx: &CodegenCx<'tcx>) -> Word {
if let TyKind::Adt(adt, substs) = *self.ty.kind() {
if let TyKind::Adt(adt, args) = *self.ty.kind() {
if span == DUMMY_SP {
span = cx.tcx.def_span(adt.did());
}
@ -352,7 +356,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
if let Some(intrinsic_type_attr) = attrs.intrinsic_type.map(|attr| attr.value) {
if let Ok(spirv_type) =
trans_intrinsic_type(cx, span, *self, substs, intrinsic_type_attr)
trans_intrinsic_type(cx, span, *self, args, intrinsic_type_attr)
{
return spirv_type;
}
@ -782,7 +786,7 @@ impl fmt::Display for TyLayoutNameKey<'_> {
}
}
if let (TyKind::Generator(_, _, _), Some(index)) = (self.ty.kind(), self.variant) {
write!(f, "::{}", GeneratorSubsts::variant_name(index))?;
write!(f, "::{}", GeneratorArgs::variant_name(index))?;
}
Ok(())
}
@ -792,7 +796,7 @@ fn trans_intrinsic_type<'tcx>(
cx: &CodegenCx<'tcx>,
span: Span,
ty: TyAndLayout<'tcx>,
substs: SubstsRef<'tcx>,
args: GenericArgsRef<'tcx>,
intrinsic_type_attr: IntrinsicType,
) -> Result<Word, ErrorGuaranteed> {
match intrinsic_type_attr {
@ -817,7 +821,7 @@ fn trans_intrinsic_type<'tcx>(
// <_>::from_u64(value).unwrap()
// }
let sampled_type = match substs.type_at(0).kind() {
let sampled_type = match args.type_at(0).kind() {
TyKind::Int(int) => match int {
IntTy::Isize => {
SpirvType::Integer(cx.tcx.data_layout.pointer_size.bits() as u32, true)
@ -850,13 +854,13 @@ fn trans_intrinsic_type<'tcx>(
}
};
// let dim: spirv::Dim = type_from_variant_discriminant(cx, substs.const_at(1));
// let depth: u32 = type_from_variant_discriminant(cx, substs.const_at(2));
// let arrayed: u32 = type_from_variant_discriminant(cx, substs.const_at(3));
// let multisampled: u32 = type_from_variant_discriminant(cx, substs.const_at(4));
// let sampled: u32 = type_from_variant_discriminant(cx, substs.const_at(5));
// let dim: spirv::Dim = type_from_variant_discriminant(cx, args.const_at(1));
// let depth: u32 = type_from_variant_discriminant(cx, args.const_at(2));
// let arrayed: u32 = type_from_variant_discriminant(cx, args.const_at(3));
// let multisampled: u32 = type_from_variant_discriminant(cx, args.const_at(4));
// let sampled: u32 = type_from_variant_discriminant(cx, args.const_at(5));
// let image_format: spirv::ImageFormat =
// type_from_variant_discriminant(cx, substs.const_at(6));
// type_from_variant_discriminant(cx, args.const_at(6));
fn const_int_value<'tcx, P: FromPrimitive>(
cx: &CodegenCx<'tcx>,
@ -873,12 +877,12 @@ fn trans_intrinsic_type<'tcx>(
}
}
let dim = const_int_value(cx, substs.const_at(1))?;
let depth = const_int_value(cx, substs.const_at(2))?;
let arrayed = const_int_value(cx, substs.const_at(3))?;
let multisampled = const_int_value(cx, substs.const_at(4))?;
let sampled = const_int_value(cx, substs.const_at(5))?;
let image_format = const_int_value(cx, substs.const_at(6))?;
let dim = const_int_value(cx, args.const_at(1))?;
let depth = const_int_value(cx, args.const_at(2))?;
let arrayed = const_int_value(cx, args.const_at(3))?;
let multisampled = const_int_value(cx, args.const_at(4))?;
let sampled = const_int_value(cx, args.const_at(5))?;
let image_format = const_int_value(cx, args.const_at(6))?;
let ty = SpirvType::Image {
sampled_type,
@ -913,7 +917,7 @@ fn trans_intrinsic_type<'tcx>(
// We use a generic to indicate the underlying image type of the sampled image.
// The spirv type of it will be generated by querying the type of the first generic.
if let Some(image_ty) = substs.types().next() {
if let Some(image_ty) = args.types().next() {
// TODO: enforce that the generic param is an image type?
let image_type = cx.layout_of(image_ty).spirv_type(span, cx);
Ok(SpirvType::SampledImage { image_type }.def(span, cx))
@ -934,7 +938,7 @@ fn trans_intrinsic_type<'tcx>(
// We use a generic to indicate the underlying element type.
// The spirv type of it will be generated by querying the type of the first generic.
if let Some(elem_ty) = substs.types().next() {
if let Some(elem_ty) = args.types().next() {
let element = cx.layout_of(elem_ty).spirv_type(span, cx);
Ok(SpirvType::RuntimeArray { element }.def(span, cx))
} else {

View File

@ -7,7 +7,7 @@ use crate::symbols::Symbols;
use rspirv::spirv::{BuiltIn, ExecutionMode, ExecutionModel, StorageClass};
use rustc_ast::Attribute;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{HirId, MethodKind, Target, CRATE_HIR_ID};
use rustc_middle::hir::nested_filter;
@ -484,7 +484,7 @@ impl<'tcx> Visitor<'tcx> for CheckSpirvAttrVisitor<'tcx> {
}
// FIXME(eddyb) DRY this somehow and make it reusable from somewhere in `rustc`.
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
let check_spirv_attr_visitor = &mut CheckSpirvAttrVisitor {
tcx,
sym: Symbols::get(),
@ -498,10 +498,10 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
check_mod_attrs: |tcx, def_id| {
check_mod_attrs: |tcx, module_def_id| {
// Run both the default checks, and our `#[spirv(...)]` ones.
(rustc_interface::DEFAULT_QUERY_PROVIDERS.check_mod_attrs)(tcx, def_id);
check_mod_attrs(tcx, def_id);
(rustc_interface::DEFAULT_QUERY_PROVIDERS.check_mod_attrs)(tcx, module_def_id);
check_mod_attrs(tcx, module_def_id);
},
..*providers
};

View File

@ -2,7 +2,7 @@ use super::Builder;
use crate::builder_spirv::{SpirvValue, SpirvValueExt, SpirvValueKind};
use crate::spirv_type::SpirvType;
use rspirv::spirv::Word;
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
use rustc_codegen_ssa::traits::BuilderMethods;
use rustc_errors::ErrorGuaranteed;
use rustc_span::DUMMY_SP;
use rustc_target::abi::call::PassMode;

View File

@ -74,8 +74,8 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
) {
let callee_ty = instance.ty(self.tcx, ParamEnv::reveal_all());
let (def_id, substs) = match *callee_ty.kind() {
FnDef(def_id, substs) => (def_id, substs),
let (def_id, fn_args) = match *callee_ty.kind() {
FnDef(def_id, fn_args) => (def_id, fn_args),
_ => bug!("expected fn item type, found {}", callee_ty),
};
@ -103,7 +103,7 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
sym::volatile_load | sym::unaligned_volatile_load => {
let ptr = args[0].immediate();
let layout = self.layout_of(substs.type_at(0));
let layout = self.layout_of(fn_args.type_at(0));
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
self.to_immediate(load, layout)
}

View File

@ -660,7 +660,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
/// `leftover_operands` is used for `IndexComposite` patterns, if any exist.
/// If the pattern isn't constraining enough to determine an unique type,
/// `Err(Ambiguous)` is returned instead.
fn subst_ty_pat(
fn arg_ty_pat(
cx: &CodegenCx<'_>,
pat: &TyPat<'_>,
ty_vars: &[Option<Word>],
@ -673,23 +673,23 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
},
TyPat::Pointer(_, pat) => SpirvType::Pointer {
pointee: subst_ty_pat(cx, pat, ty_vars, leftover_operands)?,
pointee: arg_ty_pat(cx, pat, ty_vars, leftover_operands)?,
}
.def(DUMMY_SP, cx),
TyPat::Vector4(pat) => SpirvType::Vector {
element: subst_ty_pat(cx, pat, ty_vars, leftover_operands)?,
element: arg_ty_pat(cx, pat, ty_vars, leftover_operands)?,
count: 4,
}
.def(DUMMY_SP, cx),
TyPat::SampledImage(pat) => SpirvType::SampledImage {
image_type: subst_ty_pat(cx, pat, ty_vars, leftover_operands)?,
image_type: arg_ty_pat(cx, pat, ty_vars, leftover_operands)?,
}
.def(DUMMY_SP, cx),
TyPat::IndexComposite(pat) => {
let mut ty = subst_ty_pat(cx, pat, ty_vars, leftover_operands)?;
let mut ty =arg_ty_pat(cx, pat, ty_vars, leftover_operands)?;
for index in leftover_operands {
let index_to_usize = || match *index {
// FIXME(eddyb) support more than just literals,
@ -780,7 +780,7 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
_ => return None,
}
match subst_ty_pat(
match arg_ty_pat(
self,
sig.output_type.unwrap(),
&combined_ty_vars,

View File

@ -3,7 +3,7 @@ use crate::abi::ConvSpirvType;
use crate::builder_spirv::{SpirvConst, SpirvValue, SpirvValueExt, SpirvValueKind};
use crate::spirv_type::SpirvType;
use rspirv::spirv::Word;
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, MiscMethods, StaticMethods};
use rustc_codegen_ssa::traits::{ConstMethods, MiscMethods, StaticMethods};
use rustc_middle::bug;
use rustc_middle::mir::interpret::{alloc_range, ConstAllocation, GlobalAlloc, Scalar};
use rustc_middle::ty::layout::LayoutOf;
@ -361,18 +361,6 @@ impl<'tcx> ConstMethods<'tcx> for CodegenCx<'tcx> {
self.def_constant(void_type, SpirvConst::ConstDataFromAlloc(alloc))
}
// FIXME(eddyb) is this just redundant with `const_bitcast`?!
fn const_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
if val.ty == ty {
val
} else {
// FIXME(eddyb) implement via `OpSpecConstantOp`.
// FIXME(eddyb) this zombies the original value without creating a new one.
let result = val.def_cx(self).with_type(ty);
self.zombie_no_span(result.def_cx(self), "const_ptrcast");
result
}
}
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value {
// HACK(eddyb) special-case `const_data_from_alloc` + `static_addr_of`
// as the old `from_const_alloc` (now `OperandRef::from_const_alloc`).

View File

@ -7,7 +7,7 @@ use crate::spirv_type::SpirvType;
use itertools::Itertools;
use rspirv::spirv::{FunctionControl, LinkageType, StorageClass, Word};
use rustc_attr::InlineAttr;
use rustc_codegen_ssa::traits::{BaseTypeMethods, PreDefineMethods, StaticMethods};
use rustc_codegen_ssa::traits::{PreDefineMethods, StaticMethods};
use rustc_hir::def::DefKind;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@ -37,8 +37,8 @@ fn attrs_to_spirv(attrs: &CodegenFnAttrs) -> FunctionControl {
impl<'tcx> CodegenCx<'tcx> {
/// Returns a function if it already exists, or declares a header if it doesn't.
pub fn get_fn_ext(&self, instance: Instance<'tcx>) -> SpirvValue {
assert!(!instance.substs.has_infer());
assert!(!instance.substs.has_escaping_bound_vars());
assert!(!instance.args.has_infer());
assert!(!instance.args.has_escaping_bound_vars());
if let Some(&func) = self.instances.borrow().get(&instance) {
return func;
@ -214,7 +214,7 @@ impl<'tcx> CodegenCx<'tcx> {
})
});
if let Some(spec) = spec {
if let Some((ty,)) = instance.substs.types().collect_tuple() {
if let Some((ty,)) = instance.args.types().collect_tuple() {
self.fmt_rt_arg_new_fn_ids_to_ty_and_spec
.borrow_mut()
.insert(fn_id, (ty, spec));

View File

@ -26,7 +26,7 @@ use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_span::{SourceFile, Span, DUMMY_SP};
use rustc_target::abi::call::{FnAbi, PassMode};
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
use rustc_target::abi::{AddressSpace, HasDataLayout, TargetDataLayout};
use rustc_target::spec::{HasTargetSpec, Target};
use std::cell::RefCell;
use std::collections::BTreeSet;
@ -162,6 +162,14 @@ impl<'tcx> CodegenCx<'tcx> {
self.lookup_type(ty).debug(ty, self)
}
pub fn type_ptr_to(&self, ty: Word) -> Word {
SpirvType::Pointer { pointee: ty }.def(DUMMY_SP, self)
}
pub fn type_ptr_to_ext(&self, ty: Word, _address_space: AddressSpace) -> Word {
SpirvType::Pointer { pointee: ty }.def(DUMMY_SP, self)
}
/// Zombie system:
///
/// If something unrepresentable is encountered, we don't want to fail

View File

@ -194,7 +194,7 @@ impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> {
align,
size,
field_types: els,
field_offsets: &field_offsets,
field_offsets: &field_offsets.as_slice(),
field_names: None,
}
.def(DUMMY_SP, self)
@ -230,11 +230,11 @@ impl<'tcx> BaseTypeMethods<'tcx> for CodegenCx<'tcx> {
=> TypeKind::Token,
}
}
fn type_ptr_to(&self, ty: Self::Type) -> Self::Type {
SpirvType::Pointer { pointee: ty }.def(DUMMY_SP, self)
fn type_ptr(&self) -> Self::Type {
self.type_ptr_to(SpirvType::Void.def(DUMMY_SP, self))
}
fn type_ptr_to_ext(&self, ty: Self::Type, _address_space: AddressSpace) -> Self::Type {
SpirvType::Pointer { pointee: ty }.def(DUMMY_SP, self)
fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type {
self.type_ptr_to_ext(SpirvType::Void.def(DUMMY_SP, self), address_space)
}
fn element_type(&self, ty: Self::Type) -> Self::Type {
match self.lookup_type(ty) {

View File

@ -88,7 +88,7 @@ use rspirv::binary::Assemble;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use rustc_codegen_ssa::back::write::{
CodegenContext, FatLTOInput, ModuleConfig, OngoingCodegen, TargetMachineFactoryConfig,
CodegenContext, FatLtoInput, ModuleConfig, OngoingCodegen, TargetMachineFactoryConfig,
};
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
use rustc_codegen_ssa::mono_item::MonoItemExt;
@ -101,7 +101,7 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{ErrorGuaranteed, FatalError, Handler};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
use rustc_middle::mir::mono::{MonoItem, MonoItemData};
use rustc_middle::mir::pretty::write_mir_pretty;
use rustc_middle::query;
use rustc_middle::ty::print::with_no_trimmed_paths;
@ -117,10 +117,10 @@ use std::io::Write;
use std::path::Path;
use std::sync::Arc;
fn dump_mir(tcx: TyCtxt<'_>, mono_items: &[(MonoItem<'_>, (Linkage, Visibility))], path: &Path) {
fn dump_mir(tcx: TyCtxt<'_>, mono_items: &[(MonoItem<'_>, MonoItemData)], path: &Path) {
create_dir_all(path.parent().unwrap()).unwrap();
let mut file = File::create(path).unwrap();
for &(mono_item, (_, _)) in mono_items {
for &(mono_item, _) in mono_items {
if let MonoItem::Fn(instance) = mono_item {
if matches!(instance.def, InstanceDef::Item(_)) {
let mut mir = Cursor::new(Vec::new());
@ -306,7 +306,7 @@ impl WriteBackendMethods for SpirvCodegenBackend {
fn run_fat_lto(
_: &CodegenContext<Self>,
_: Vec<FatLTOInput<Self>>,
_: Vec<FatLtoInput<Self>>,
_: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
) -> Result<LtoModuleCodegen<Self>, FatalError> {
todo!()
@ -324,6 +324,10 @@ impl WriteBackendMethods for SpirvCodegenBackend {
println!("TODO: Implement print_pass_timings");
}
fn print_statistics(&self) {
println!("TODO: Implement print_statistics")
}
unsafe fn optimize(
_: &CodegenContext<Self>,
_: &Handler,
@ -416,16 +420,20 @@ impl ExtraBackendMethods for SpirvCodegenBackend {
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
if let Some(dir) = &cx.codegen_args.dump_mir {
dump_mir(tcx, &mono_items, &dir.join(cgu_name.to_string()));
dump_mir(tcx, mono_items.as_slice(), &dir.join(cgu_name.to_string()));
}
for &(mono_item, (linkage, visibility)) in mono_items.iter() {
for &(mono_item, mono_item_data) in mono_items.iter() {
if let MonoItem::Fn(instance) = mono_item {
if is_blocklisted_fn(cx.tcx, &cx.sym, instance) {
continue;
}
}
mono_item.predefine::<Builder<'_, '_>>(&cx, linkage, visibility);
mono_item.predefine::<Builder<'_, '_>>(
&cx,
mono_item_data.linkage,
mono_item_data.visibility,
);
}
// ... and now that we have everything pre-defined, fill out those definitions.

View File

@ -36,7 +36,7 @@ pub fn link(
crate_name: &str,
) {
let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata);
for &crate_type in sess.crate_types().iter() {
for &crate_type in sess.opts.crate_types.iter() {
if (sess.opts.unstable_opts.no_codegen || !sess.opts.output_types.should_codegen())
&& !output_metadata
&& crate_type == CrateType::Executable
@ -601,7 +601,7 @@ fn do_link(
Ok(v) => v,
Err(rustc_errors::ErrorGuaranteed { .. }) => {
sess.abort_if_errors();
bug!("Linker errored, but no error reported")
bug!("Linker errored, but no error reported");
}
}
}

View File

@ -1,11 +1,12 @@
use super::{link, LinkResult};
use pipe::pipe;
use rspirv::dr::{Loader, Module};
use rustc_errors::{registry::Registry, TerminalUrl};
use rustc_errors::registry::Registry;
use rustc_session::config::{Input, OutputFilenames, OutputTypes};
use rustc_session::CompilerIO;
use rustc_span::FileName;
use std::io::Read;
use std::io::Write;
use std::sync::{Arc, Mutex};
use termcolor::{ColorSpec, WriteColor};
// https://github.com/colin-kiegel/rust-pretty-assertions/issues/24
#[derive(PartialEq, Eq)]
@ -75,20 +76,40 @@ fn link_with_linker_opts(
) -> Result<Module, PrettyString> {
let modules = binaries.iter().cloned().map(load).collect::<Vec<_>>();
// FIXME(eddyb) this seems ridiculous, we should be able to write to
// some kind of `Arc<Mutex<Vec<u8>>>` without a separate thread.
//
// need pipe here because the writer must be 'static.
let (mut read_diags, write_diags) = pipe();
let read_diags_thread = std::thread::spawn(move || {
// must spawn thread because pipe crate is synchronous
let mut diags = String::new();
read_diags.read_to_string(&mut diags).unwrap();
if let Some(diags_without_trailing_newlines) = diags.strip_suffix("\n\n") {
diags.truncate(diags_without_trailing_newlines.len());
// A threadsafe buffer for writing.
#[derive(Default, Clone)]
struct BufWriter(Arc<Mutex<Vec<u8>>>);
impl BufWriter {
fn to_string(self) -> String {
let x = self.0.into_inner().expect("diagnostics unlocked");
String::from_utf8(x).expect("conversion to string")
}
diags
});
}
impl Write for BufWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.lock().unwrap().write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
self.0.lock().unwrap().flush()
}
}
impl WriteColor for BufWriter {
fn supports_color(&self) -> bool {
false
}
fn set_color(&mut self, _spec: &ColorSpec) -> std::io::Result<()> {
Ok(())
}
fn reset(&mut self) -> std::io::Result<()> {
Ok(())
}
}
let buf = BufWriter::default();
let output = buf.clone();
// NOTE(eddyb) without `catch_fatal_errors`, you'd get the really strange
// effect of test failures with no output (because the `FatalError` "panic"
@ -126,6 +147,7 @@ fn link_with_linker_opts(
None,
None,
rustc_interface::util::rustc_version_str().unwrap_or("unknown"),
None,
);
// HACK(eddyb) inject `write_diags` into `sess`, to work around
@ -138,24 +160,12 @@ fn link_with_linker_opts(
sess.opts.unstable_opts.translate_directionality_markers,
)
};
let emitter = rustc_errors::emitter::EmitterWriter::new(
Box::new(write_diags),
Some(sess.parse_sess.clone_source_map()),
None,
fallback_bundle,
false,
false,
false,
None,
false,
false,
TerminalUrl::No,
);
let emitter =
rustc_errors::emitter::EmitterWriter::new(Box::new(buf), fallback_bundle)
.sm(Some(sess.parse_sess.clone_source_map()));
rustc_errors::Handler::with_emitter_and_flags(
Box::new(emitter),
sess.opts.unstable_opts.diagnostic_handler_flags(true),
)
rustc_errors::Handler::with_emitter(Box::new(emitter))
.with_flags(sess.opts.unstable_opts.diagnostic_handler_flags(true))
};
let res = link(
@ -180,7 +190,7 @@ fn link_with_linker_opts(
})
})
.flatten()
.map_err(|_e| read_diags_thread.join().unwrap())
.map_err(|_e| buf.to_string())
.map_err(PrettyString)
}

View File

@ -1,7 +1,7 @@
[toolchain]
channel = "nightly-2023-07-08"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
# commit_hash = cb80ff132a0e9aa71529b701427e4e6c243b58df
channel = "nightly-2023-08-29"
components = ["rust-src", "rustc-dev", "llvm-tools"]
# commit_hash = 4e78abb437a0478d1f42115198ee45888e5330fd
# Whenever changing the nightly channel, update the commit hash above, and make
# sure to change `REQUIRED_TOOLCHAIN` in `crates/rustc_codegen_spirv/build.rs` also.