Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2025-07-22 05:06:42 +00:00
commit 4d62686f4f
280 changed files with 3258 additions and 2820 deletions

View file

@ -874,25 +874,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
/// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
/// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
/// parameters will be successful.
#[instrument(level = "debug", skip(self))]
#[instrument(level = "debug", skip(self), ret)]
#[inline]
fn lower_lifetime_binder(
&mut self,
binder: NodeId,
generic_params: &[GenericParam],
) -> &'hir [hir::GenericParam<'hir>] {
let mut generic_params: Vec<_> = self
.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder)
.collect();
// Start by creating params for extra lifetimes params, as this creates the definitions
// that may be referred to by the AST inside `generic_params`.
let extra_lifetimes = self.resolver.extra_lifetime_params(binder);
debug!(?extra_lifetimes);
generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(ident, node_id, res, hir::GenericParamSource::Binder)
}));
let generic_params = self.arena.alloc_from_iter(generic_params);
debug!(?generic_params);
generic_params
let extra_lifetimes: Vec<_> = extra_lifetimes
.into_iter()
.filter_map(|(ident, node_id, res)| {
self.lifetime_res_to_generic_param(
ident,
node_id,
res,
hir::GenericParamSource::Binder,
)
})
.collect();
let arena = self.arena;
let explicit_generic_params =
self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);
arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))
}
fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {

View file

@ -234,6 +234,7 @@ pub enum CfgEntry {
pub enum AttributeKind {
// tidy-alphabetical-start
/// Represents `#[align(N)]`.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
Align { align: Align, span: Span },
/// Represents `#[rustc_allow_const_fn_unstable]`.

View file

@ -177,7 +177,8 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
sym::instruction_set,
sym::repr,
sym::rustc_std_internal_symbol,
sym::align,
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
sym::rustc_align,
// obviously compatible with self
sym::naked,
// documentation

View file

@ -274,7 +274,7 @@ fn parse_alignment(node: &LitKind) -> Result<Align, &'static str> {
pub(crate) struct AlignParser(Option<(Align, Span)>);
impl AlignParser {
const PATH: &'static [Symbol] = &[sym::align];
const PATH: &'static [Symbol] = &[sym::rustc_align];
const TEMPLATE: AttributeTemplate = template!(List: "<alignment in bytes>");
fn parse<'c, S: Stage>(

View file

@ -11,6 +11,12 @@
#[derive(Copy, Clone, PartialEq, Debug)]
struct f32x4(pub [f32; 4]);
impl f32x4 {
fn into_array(self) -> [f32; 4] {
unsafe { std::mem::transmute(self) }
}
}
use std::intrinsics::simd::*;
fn main() {
@ -29,22 +35,22 @@ fn main() {
unsafe {
let min0 = simd_fmin(x, y);
let min1 = simd_fmin(y, x);
assert_eq!(min0, min1);
assert_eq!(min0.into_array(), min1.into_array());
let e = f32x4([1.0, 1.0, 3.0, 3.0]);
assert_eq!(min0, e);
assert_eq!(min0.into_array(), e.into_array());
let minn = simd_fmin(x, n);
assert_eq!(minn, x);
assert_eq!(minn.into_array(), x.into_array());
let minn = simd_fmin(y, n);
assert_eq!(minn, y);
assert_eq!(minn.into_array(), y.into_array());
let max0 = simd_fmax(x, y);
let max1 = simd_fmax(y, x);
assert_eq!(max0, max1);
assert_eq!(max0.into_array(), max1.into_array());
let e = f32x4([2.0, 2.0, 4.0, 4.0]);
assert_eq!(max0, e);
assert_eq!(max0.into_array(), e.into_array());
let maxn = simd_fmax(x, n);
assert_eq!(maxn, x);
assert_eq!(maxn.into_array(), x.into_array());
let maxn = simd_fmax(y, n);
assert_eq!(maxn, y);
assert_eq!(maxn.into_array(), y.into_array());
}
}

View file

@ -348,7 +348,8 @@ fn main() {
struct V([f64; 2]);
let f = V([0.0, 1.0]);
let _a = f.0[0];
let fp = (&raw const f) as *const [f64; 2];
let _a = (unsafe { &*fp })[0];
stack_val_align();
}

View file

@ -654,6 +654,7 @@ pub(crate) fn run_pass_manager(
// We then run the llvm_optimize function a second time, to optimize the code which we generated
// in the enzyme differentiation pass.
let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable);
let enable_gpu = config.offload.contains(&config::Offload::Enable);
let stage = if thin {
write::AutodiffStage::PreAD
} else {
@ -668,6 +669,12 @@ pub(crate) fn run_pass_manager(
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?;
}
if enable_gpu && !thin {
let cx =
SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size);
crate::builder::gpu_offload::handle_gpu_code(cgcx, &cx);
}
if cfg!(llvm_enzyme) && enable_ad && !thin {
let cx =
SimpleCx::new(module.module_llvm.llmod(), &module.module_llvm.llcx, cgcx.pointer_size);

View file

@ -3,6 +3,7 @@ use std::ops::Deref;
use std::{iter, ptr};
pub(crate) mod autodiff;
pub(crate) mod gpu_offload;
use libc::{c_char, c_uint, size_t};
use rustc_abi as abi;
@ -117,6 +118,74 @@ impl<'a, 'll, CX: Borrow<SCx<'ll>>> GenericBuilder<'a, 'll, CX> {
}
bx
}
// The generic builder has less functionality and thus (unlike the other alloca) we can not
// easily jump to the beginning of the function to place our allocas there. We trust the user
// to manually do that. FIXME(offload): improve the genericCx and add more llvm wrappers to
// handle this.
pub(crate) fn direct_alloca(&mut self, ty: &'ll Type, align: Align, name: &str) -> &'ll Value {
let val = unsafe {
let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
// Cast to default addrspace if necessary
llvm::LLVMBuildPointerCast(self.llbuilder, alloca, self.cx.type_ptr(), UNNAMED)
};
if name != "" {
let name = std::ffi::CString::new(name).unwrap();
llvm::set_value_name(val, &name.as_bytes());
}
val
}
pub(crate) fn inbounds_gep(
&mut self,
ty: &'ll Type,
ptr: &'ll Value,
indices: &[&'ll Value],
) -> &'ll Value {
unsafe {
llvm::LLVMBuildGEPWithNoWrapFlags(
self.llbuilder,
ty,
ptr,
indices.as_ptr(),
indices.len() as c_uint,
UNNAMED,
GEPNoWrapFlags::InBounds,
)
}
}
pub(crate) fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
debug!("Store {:?} -> {:?}", val, ptr);
assert_eq!(self.cx.type_kind(self.cx.val_ty(ptr)), TypeKind::Pointer);
unsafe {
let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
llvm::LLVMSetAlignment(store, align.bytes() as c_uint);
store
}
}
pub(crate) fn load(&mut self, ty: &'ll Type, ptr: &'ll Value, align: Align) -> &'ll Value {
unsafe {
let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED);
llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
load
}
}
fn memset(&mut self, ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, align: Align) {
unsafe {
llvm::LLVMRustBuildMemSet(
self.llbuilder,
ptr,
align.bytes() as c_uint,
fill_byte,
size,
false,
);
}
}
}
/// Empty string, to be used where LLVM expects an instruction name, indicating

View file

@ -0,0 +1,439 @@
use std::ffi::CString;
use llvm::Linkage::*;
use rustc_abi::Align;
use rustc_codegen_ssa::back::write::CodegenContext;
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
use crate::builder::SBuilder;
use crate::common::AsCCharPtr;
use crate::llvm::AttributePlace::Function;
use crate::llvm::{self, Linkage, Type, Value};
use crate::{LlvmCodegenBackend, SimpleCx, attributes};
pub(crate) fn handle_gpu_code<'ll>(
_cgcx: &CodegenContext<LlvmCodegenBackend>,
cx: &'ll SimpleCx<'_>,
) {
// The offload memory transfer type for each kernel
let mut o_types = vec![];
let mut kernels = vec![];
let offload_entry_ty = add_tgt_offload_entry(&cx);
for num in 0..9 {
let kernel = cx.get_function(&format!("kernel_{num}"));
if let Some(kernel) = kernel {
o_types.push(gen_define_handling(&cx, kernel, offload_entry_ty, num));
kernels.push(kernel);
}
}
gen_call_handling(&cx, &kernels, &o_types);
}
// What is our @1 here? A magic global, used in our data_{begin/update/end}_mapper:
// @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
// @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8
fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value {
// @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
let unknown_txt = ";unknown;unknown;0;0;;";
let c_entry_name = CString::new(unknown_txt).unwrap();
let c_val = c_entry_name.as_bytes_with_nul();
let initializer = crate::common::bytes_in_context(cx.llcx, c_val);
let at_zero = add_unnamed_global(&cx, &"", initializer, PrivateLinkage);
llvm::set_alignment(at_zero, Align::ONE);
// @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8
let struct_ident_ty = cx.type_named_struct("struct.ident_t");
let struct_elems = vec![
cx.get_const_i32(0),
cx.get_const_i32(2),
cx.get_const_i32(0),
cx.get_const_i32(22),
at_zero,
];
let struct_elems_ty: Vec<_> = struct_elems.iter().map(|&x| cx.val_ty(x)).collect();
let initializer = crate::common::named_struct(struct_ident_ty, &struct_elems);
cx.set_struct_body(struct_ident_ty, &struct_elems_ty, false);
let at_one = add_unnamed_global(&cx, &"", initializer, PrivateLinkage);
llvm::set_alignment(at_one, Align::EIGHT);
at_one
}
pub(crate) fn add_tgt_offload_entry<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type {
let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry");
let tptr = cx.type_ptr();
let ti64 = cx.type_i64();
let ti32 = cx.type_i32();
let ti16 = cx.type_i16();
// For each kernel to run on the gpu, we will later generate one entry of this type.
// copied from LLVM
// typedef struct {
// uint64_t Reserved;
// uint16_t Version;
// uint16_t Kind;
// uint32_t Flags; Flags associated with the entry (see Target Region Entry Flags)
// void *Address; Address of global symbol within device image (function or global)
// char *SymbolName;
// uint64_t Size; Size of the entry info (0 if it is a function)
// uint64_t Data;
// void *AuxAddr;
// } __tgt_offload_entry;
let entry_elements = vec![ti64, ti16, ti16, ti32, tptr, tptr, ti64, ti64, tptr];
cx.set_struct_body(offload_entry_ty, &entry_elements, false);
offload_entry_ty
}
fn gen_tgt_kernel_global<'ll>(cx: &'ll SimpleCx<'_>) {
let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments");
let tptr = cx.type_ptr();
let ti64 = cx.type_i64();
let ti32 = cx.type_i32();
let tarr = cx.type_array(ti32, 3);
// Taken from the LLVM APITypes.h declaration:
//struct KernelArgsTy {
// uint32_t Version = 0; // Version of this struct for ABI compatibility.
// uint32_t NumArgs = 0; // Number of arguments in each input pointer.
// void **ArgBasePtrs =
// nullptr; // Base pointer of each argument (e.g. a struct).
// void **ArgPtrs = nullptr; // Pointer to the argument data.
// int64_t *ArgSizes = nullptr; // Size of the argument data in bytes.
// int64_t *ArgTypes = nullptr; // Type of the data (e.g. to / from).
// void **ArgNames = nullptr; // Name of the data for debugging, possibly null.
// void **ArgMappers = nullptr; // User-defined mappers, possibly null.
// uint64_t Tripcount =
// 0; // Tripcount for the teams / distribute loop, 0 otherwise.
// struct {
// uint64_t NoWait : 1; // Was this kernel spawned with a `nowait` clause.
// uint64_t IsCUDA : 1; // Was this kernel spawned via CUDA.
// uint64_t Unused : 62;
// } Flags = {0, 0, 0};
// // The number of teams (for x,y,z dimension).
// uint32_t NumTeams[3] = {0, 0, 0};
// // The number of threads (for x,y,z dimension).
// uint32_t ThreadLimit[3] = {0, 0, 0};
// uint32_t DynCGroupMem = 0; // Amount of dynamic cgroup memory requested.
//};
let kernel_elements =
vec![ti32, ti32, tptr, tptr, tptr, tptr, tptr, tptr, ti64, ti64, tarr, tarr, ti32];
cx.set_struct_body(kernel_arguments_ty, &kernel_elements, false);
// For now we don't handle kernels, so for now we just add a global dummy
// to make sure that the __tgt_offload_entry is defined and handled correctly.
cx.declare_global("my_struct_global2", kernel_arguments_ty);
}
fn gen_tgt_data_mappers<'ll>(
cx: &'ll SimpleCx<'_>,
) -> (&'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Value, &'ll llvm::Type) {
let tptr = cx.type_ptr();
let ti64 = cx.type_i64();
let ti32 = cx.type_i32();
let args = vec![tptr, ti64, ti32, tptr, tptr, tptr, tptr, tptr, tptr];
let mapper_fn_ty = cx.type_func(&args, cx.type_void());
let mapper_begin = "__tgt_target_data_begin_mapper";
let mapper_update = "__tgt_target_data_update_mapper";
let mapper_end = "__tgt_target_data_end_mapper";
let begin_mapper_decl = declare_offload_fn(&cx, mapper_begin, mapper_fn_ty);
let update_mapper_decl = declare_offload_fn(&cx, mapper_update, mapper_fn_ty);
let end_mapper_decl = declare_offload_fn(&cx, mapper_end, mapper_fn_ty);
let nounwind = llvm::AttributeKind::NoUnwind.create_attr(cx.llcx);
attributes::apply_to_llfn(begin_mapper_decl, Function, &[nounwind]);
attributes::apply_to_llfn(update_mapper_decl, Function, &[nounwind]);
attributes::apply_to_llfn(end_mapper_decl, Function, &[nounwind]);
(begin_mapper_decl, update_mapper_decl, end_mapper_decl, mapper_fn_ty)
}
fn add_priv_unnamed_arr<'ll>(cx: &SimpleCx<'ll>, name: &str, vals: &[u64]) -> &'ll llvm::Value {
let ti64 = cx.type_i64();
let mut size_val = Vec::with_capacity(vals.len());
for &val in vals {
size_val.push(cx.get_const_i64(val));
}
let initializer = cx.const_array(ti64, &size_val);
add_unnamed_global(cx, name, initializer, PrivateLinkage)
}
pub(crate) fn add_unnamed_global<'ll>(
cx: &SimpleCx<'ll>,
name: &str,
initializer: &'ll llvm::Value,
l: Linkage,
) -> &'ll llvm::Value {
let llglobal = add_global(cx, name, initializer, l);
llvm::LLVMSetUnnamedAddress(llglobal, llvm::UnnamedAddr::Global);
llglobal
}
pub(crate) fn add_global<'ll>(
cx: &SimpleCx<'ll>,
name: &str,
initializer: &'ll llvm::Value,
l: Linkage,
) -> &'ll llvm::Value {
let c_name = CString::new(name).unwrap();
let llglobal: &'ll llvm::Value = llvm::add_global(cx.llmod, cx.val_ty(initializer), &c_name);
llvm::set_global_constant(llglobal, true);
llvm::set_linkage(llglobal, l);
llvm::set_initializer(llglobal, initializer);
llglobal
}
fn gen_define_handling<'ll>(
cx: &'ll SimpleCx<'_>,
kernel: &'ll llvm::Value,
offload_entry_ty: &'ll llvm::Type,
num: i64,
) -> &'ll llvm::Value {
let types = cx.func_params_types(cx.get_type_of_global(kernel));
// It seems like non-pointer values are automatically mapped. So here, we focus on pointer (or
// reference) types.
let num_ptr_types = types
.iter()
.map(|&x| matches!(cx.type_kind(x), rustc_codegen_ssa::common::TypeKind::Pointer))
.count();
// We do not know their size anymore at this level, so hardcode a placeholder.
// A follow-up pr will track these from the frontend, where we still have Rust types.
// Then, we will be able to figure out that e.g. `&[f32;256]` will result in 4*256 bytes.
// I decided that 1024 bytes is a great placeholder value for now.
add_priv_unnamed_arr(&cx, &format!(".offload_sizes.{num}"), &vec![1024; num_ptr_types]);
// Here we figure out whether something needs to be copied to the gpu (=1), from the gpu (=2),
// or both to and from the gpu (=3). Other values shouldn't affect us for now.
// A non-mutable reference or pointer will be 1, an array that's not read, but fully overwritten
// will be 2. For now, everything is 3, until we have our frontend set up.
let o_types =
add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{num}"), &vec![3; num_ptr_types]);
// Next: For each function, generate these three entries. A weak constant,
// the llvm.rodata entry name, and the omp_offloading_entries value
let name = format!(".kernel_{num}.region_id");
let initializer = cx.get_const_i8(0);
let region_id = add_unnamed_global(&cx, &name, initializer, WeakAnyLinkage);
let c_entry_name = CString::new(format!("kernel_{num}")).unwrap();
let c_val = c_entry_name.as_bytes_with_nul();
let offload_entry_name = format!(".offloading.entry_name.{num}");
let initializer = crate::common::bytes_in_context(cx.llcx, c_val);
let llglobal = add_unnamed_global(&cx, &offload_entry_name, initializer, InternalLinkage);
llvm::set_alignment(llglobal, Align::ONE);
llvm::set_section(llglobal, c".llvm.rodata.offloading");
// Not actively used yet, for calling real kernels
let name = format!(".offloading.entry.kernel_{num}");
// See the __tgt_offload_entry documentation above.
let reserved = cx.get_const_i64(0);
let version = cx.get_const_i16(1);
let kind = cx.get_const_i16(1);
let flags = cx.get_const_i32(0);
let size = cx.get_const_i64(0);
let data = cx.get_const_i64(0);
let aux_addr = cx.const_null(cx.type_ptr());
let elems = vec![reserved, version, kind, flags, region_id, llglobal, size, data, aux_addr];
let initializer = crate::common::named_struct(offload_entry_ty, &elems);
let c_name = CString::new(name).unwrap();
let llglobal = llvm::add_global(cx.llmod, offload_entry_ty, &c_name);
llvm::set_global_constant(llglobal, true);
llvm::set_linkage(llglobal, WeakAnyLinkage);
llvm::set_initializer(llglobal, initializer);
llvm::set_alignment(llglobal, Align::ONE);
let c_section_name = CString::new(".omp_offloading_entries").unwrap();
llvm::set_section(llglobal, &c_section_name);
o_types
}
fn declare_offload_fn<'ll>(
cx: &'ll SimpleCx<'_>,
name: &str,
ty: &'ll llvm::Type,
) -> &'ll llvm::Value {
crate::declare::declare_simple_fn(
cx,
name,
llvm::CallConv::CCallConv,
llvm::UnnamedAddr::No,
llvm::Visibility::Default,
ty,
)
}
// For each kernel *call*, we now use some of our previous declared globals to move data to and from
// the gpu. We don't have a proper frontend yet, so we assume that every call to a kernel function
// from main is intended to run on the GPU. For now, we only handle the data transfer part of it.
// If two consecutive kernels use the same memory, we still move it to the host and back to the gpu.
// Since in our frontend users (by default) don't have to specify data transfer, this is something
// we should optimize in the future! We also assume that everything should be copied back and forth,
// but sometimes we can directly zero-allocate on the device and only move back, or if something is
// immutable, we might only copy it to the device, but not back.
//
// Current steps:
// 0. Alloca some variables for the following steps
// 1. set insert point before kernel call.
// 2. generate all the GEPS and stores, to be used in 3)
// 3. generate __tgt_target_data_begin calls to move data to the GPU
//
// unchanged: keep kernel call. Later move the kernel to the GPU
//
// 4. set insert point after kernel call.
// 5. generate all the GEPS and stores, to be used in 6)
// 6. generate __tgt_target_data_end calls to move data from the GPU
fn gen_call_handling<'ll>(
cx: &'ll SimpleCx<'_>,
_kernels: &[&'ll llvm::Value],
o_types: &[&'ll llvm::Value],
) {
// %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr }
let tptr = cx.type_ptr();
let ti32 = cx.type_i32();
let tgt_bin_desc_ty = vec![ti32, tptr, tptr, tptr];
let tgt_bin_desc = cx.type_named_struct("struct.__tgt_bin_desc");
cx.set_struct_body(tgt_bin_desc, &tgt_bin_desc_ty, false);
gen_tgt_kernel_global(&cx);
let (begin_mapper_decl, _, end_mapper_decl, fn_ty) = gen_tgt_data_mappers(&cx);
let main_fn = cx.get_function("main");
let Some(main_fn) = main_fn else { return };
let kernel_name = "kernel_1";
let call = unsafe {
llvm::LLVMRustGetFunctionCall(main_fn, kernel_name.as_c_char_ptr(), kernel_name.len())
};
let Some(kernel_call) = call else {
return;
};
let kernel_call_bb = unsafe { llvm::LLVMGetInstructionParent(kernel_call) };
let called = unsafe { llvm::LLVMGetCalledValue(kernel_call).unwrap() };
let mut builder = SBuilder::build(cx, kernel_call_bb);
let types = cx.func_params_types(cx.get_type_of_global(called));
let num_args = types.len() as u64;
// Step 0)
// %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr }
// %6 = alloca %struct.__tgt_bin_desc, align 8
unsafe { llvm::LLVMRustPositionBuilderPastAllocas(builder.llbuilder, main_fn) };
let tgt_bin_desc_alloca = builder.direct_alloca(tgt_bin_desc, Align::EIGHT, "EmptyDesc");
let ty = cx.type_array(cx.type_ptr(), num_args);
// Baseptr are just the input pointer to the kernel, stored in a local alloca
let a1 = builder.direct_alloca(ty, Align::EIGHT, ".offload_baseptrs");
// Ptrs are the result of a gep into the baseptr, at least for our trivial types.
let a2 = builder.direct_alloca(ty, Align::EIGHT, ".offload_ptrs");
// These represent the sizes in bytes, e.g. the entry for `&[f64; 16]` will be 8*16.
let ty2 = cx.type_array(cx.type_i64(), num_args);
let a4 = builder.direct_alloca(ty2, Align::EIGHT, ".offload_sizes");
// Now we allocate once per function param, a copy to be passed to one of our maps.
let mut vals = vec![];
let mut geps = vec![];
let i32_0 = cx.get_const_i32(0);
for (index, in_ty) in types.iter().enumerate() {
// get function arg, store it into the alloca, and read it.
let p = llvm::get_param(called, index as u32);
let name = llvm::get_value_name(p);
let name = str::from_utf8(&name).unwrap();
let arg_name = format!("{name}.addr");
let alloca = builder.direct_alloca(in_ty, Align::EIGHT, &arg_name);
builder.store(p, alloca, Align::EIGHT);
let val = builder.load(in_ty, alloca, Align::EIGHT);
let gep = builder.inbounds_gep(cx.type_f32(), val, &[i32_0]);
vals.push(val);
geps.push(gep);
}
// Step 1)
unsafe { llvm::LLVMRustPositionBefore(builder.llbuilder, kernel_call) };
builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT);
let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void());
let register_lib_decl = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty);
let unregister_lib_decl = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty);
let init_ty = cx.type_func(&[], cx.type_void());
let init_rtls_decl = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty);
// call void @__tgt_register_lib(ptr noundef %6)
builder.call(mapper_fn_ty, register_lib_decl, &[tgt_bin_desc_alloca], None);
// call void @__tgt_init_all_rtls()
builder.call(init_ty, init_rtls_decl, &[], None);
for i in 0..num_args {
let idx = cx.get_const_i32(i);
let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, idx]);
builder.store(vals[i as usize], gep1, Align::EIGHT);
let gep2 = builder.inbounds_gep(ty, a2, &[i32_0, idx]);
builder.store(geps[i as usize], gep2, Align::EIGHT);
let gep3 = builder.inbounds_gep(ty2, a4, &[i32_0, idx]);
// As mentioned above, we don't use Rust type information yet. So for now we will just
// assume that we have 1024 bytes, 256 f32 values.
// FIXME(offload): write an offload frontend and handle arbitrary types.
builder.store(cx.get_const_i64(1024), gep3, Align::EIGHT);
}
// For now we have a very simplistic indexing scheme into our
// offload_{baseptrs,ptrs,sizes}. We will probably improve this along with our gpu frontend pr.
fn get_geps<'a, 'll>(
builder: &mut SBuilder<'a, 'll>,
cx: &'ll SimpleCx<'ll>,
ty: &'ll Type,
ty2: &'ll Type,
a1: &'ll Value,
a2: &'ll Value,
a4: &'ll Value,
) -> (&'ll Value, &'ll Value, &'ll Value) {
let i32_0 = cx.get_const_i32(0);
let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, i32_0]);
let gep2 = builder.inbounds_gep(ty, a2, &[i32_0, i32_0]);
let gep3 = builder.inbounds_gep(ty2, a4, &[i32_0, i32_0]);
(gep1, gep2, gep3)
}
fn generate_mapper_call<'a, 'll>(
builder: &mut SBuilder<'a, 'll>,
cx: &'ll SimpleCx<'ll>,
geps: (&'ll Value, &'ll Value, &'ll Value),
o_type: &'ll Value,
fn_to_call: &'ll Value,
fn_ty: &'ll Type,
num_args: u64,
s_ident_t: &'ll Value,
) {
let nullptr = cx.const_null(cx.type_ptr());
let i64_max = cx.get_const_i64(u64::MAX);
let num_args = cx.get_const_i32(num_args);
let args =
vec![s_ident_t, i64_max, num_args, geps.0, geps.1, geps.2, o_type, nullptr, nullptr];
builder.call(fn_ty, fn_to_call, &args, None);
}
// Step 2)
let s_ident_t = generate_at_one(&cx);
let o = o_types[0];
let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4);
generate_mapper_call(&mut builder, &cx, geps, o, begin_mapper_decl, fn_ty, num_args, s_ident_t);
// Step 3)
// Here we will add code for the actual kernel launches in a follow-up PR.
// FIXME(offload): launch kernels
// Step 4)
unsafe { llvm::LLVMRustPositionAfter(builder.llbuilder, kernel_call) };
let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4);
generate_mapper_call(&mut builder, &cx, geps, o, end_mapper_decl, fn_ty, num_args, s_ident_t);
builder.call(mapper_fn_ty, unregister_lib_decl, &[tgt_bin_desc_alloca], None);
// With this we generated the following begin and end mappers. We could easily generate the
// update mapper in an update.
// call void @__tgt_target_data_begin_mapper(ptr @1, i64 -1, i32 3, ptr %27, ptr %28, ptr %29, ptr @.offload_maptypes, ptr null, ptr null)
// call void @__tgt_target_data_update_mapper(ptr @1, i64 -1, i32 2, ptr %46, ptr %47, ptr %48, ptr @.offload_maptypes.1, ptr null, ptr null)
// call void @__tgt_target_data_end_mapper(ptr @1, i64 -1, i32 3, ptr %49, ptr %50, ptr %51, ptr @.offload_maptypes, ptr null, ptr null)
}

View file

@ -118,6 +118,10 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
r
}
}
pub(crate) fn const_null(&self, t: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMConstNull(t) }
}
}
impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> {
@ -377,6 +381,11 @@ pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> &
}
}
pub(crate) fn named_struct<'ll>(ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value {
let len = c_uint::try_from(elts.len()).expect("LLVMConstStructInContext elements len overflow");
unsafe { llvm::LLVMConstNamedStruct(ty, elts.as_ptr(), len) }
}
fn struct_in_context<'ll>(
llcx: &'ll llvm::Context,
elts: &[&'ll Value],

View file

@ -216,7 +216,7 @@ pub(crate) unsafe fn create_module<'ll>(
// Ensure the data-layout values hardcoded remain the defaults.
{
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
let tm = crate::back::write::create_informational_target_machine(sess, false);
unsafe {
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
}
@ -685,6 +685,22 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
unsafe { llvm::LLVMConstInt(ty, val, llvm::False) }
}
pub(crate) fn get_const_i64(&self, n: u64) -> &'ll Value {
self.get_const_int(self.type_i64(), n)
}
pub(crate) fn get_const_i32(&self, n: u64) -> &'ll Value {
self.get_const_int(self.type_i32(), n)
}
pub(crate) fn get_const_i16(&self, n: u64) -> &'ll Value {
self.get_const_int(self.type_i16(), n)
}
pub(crate) fn get_const_i8(&self, n: u64) -> &'ll Value {
self.get_const_int(self.type_i8(), n)
}
pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> {
let name = SmallCStr::new(name);
unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) }

View file

@ -215,7 +215,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
llfn
}
}
impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
/// Declare a global with an intention to define it.
///
/// Use this function when you intend to define a global. This function will
@ -234,13 +236,13 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
///
/// Use this function when you intend to define a global without a name.
pub(crate) fn define_private_global(&self, ty: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod, ty) }
unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod(), ty) }
}
/// Gets declared value by name.
pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> {
debug!("get_declared_value(name={:?})", name);
unsafe { llvm::LLVMRustGetNamedValue(self.llmod, name.as_c_char_ptr(), name.len()) }
unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_c_char_ptr(), name.len()) }
}
/// Gets defined or externally defined (AvailableExternally linkage) value by

View file

@ -412,6 +412,20 @@ impl ModuleLlvm {
}
}
fn tm_from_cgcx(
cgcx: &CodegenContext<LlvmCodegenBackend>,
name: &str,
dcx: DiagCtxtHandle<'_>,
) -> Result<OwnedTargetMachine, FatalError> {
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name);
match (cgcx.tm_factory)(tm_factory_config) {
Ok(m) => Ok(m),
Err(e) => {
return Err(dcx.emit_almost_fatal(ParseTargetMachineConfig(e)));
}
}
}
fn parse(
cgcx: &CodegenContext<LlvmCodegenBackend>,
name: &CStr,
@ -421,13 +435,7 @@ impl ModuleLlvm {
unsafe {
let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx)?;
let tm_factory_config = TargetMachineFactoryConfig::new(cgcx, name.to_str().unwrap());
let tm = match (cgcx.tm_factory)(tm_factory_config) {
Ok(m) => m,
Err(e) => {
return Err(dcx.emit_almost_fatal(ParseTargetMachineConfig(e)));
}
};
let tm = ModuleLlvm::tm_from_cgcx(cgcx, name.to_str().unwrap(), dcx)?;
Ok(ModuleLlvm { llmod_raw, llcx, tm: ManuallyDrop::new(tm) })
}

View file

@ -4,7 +4,7 @@ use libc::{c_char, c_uint};
use super::MetadataKindId;
use super::ffi::{AttributeKind, BasicBlock, Metadata, Module, Type, Value};
use crate::llvm::Bool;
use crate::llvm::{Bool, Builder};
#[link(name = "llvm-wrapper", kind = "static")]
unsafe extern "C" {
@ -31,6 +31,14 @@ unsafe extern "C" {
index: c_uint,
kind: AttributeKind,
);
pub(crate) fn LLVMRustPositionBefore<'a>(B: &'a Builder<'_>, I: &'a Value);
pub(crate) fn LLVMRustPositionAfter<'a>(B: &'a Builder<'_>, I: &'a Value);
pub(crate) fn LLVMRustGetFunctionCall(
F: &Value,
name: *const c_char,
NameLen: libc::size_t,
) -> Option<&Value>;
}
unsafe extern "C" {

View file

@ -1138,6 +1138,11 @@ unsafe extern "C" {
Count: c_uint,
Packed: Bool,
) -> &'a Value;
pub(crate) fn LLVMConstNamedStruct<'a>(
StructTy: &'a Type,
ConstantVals: *const &'a Value,
Count: c_uint,
) -> &'a Value;
pub(crate) fn LLVMConstVector(ScalarConstantVals: *const &Value, Size: c_uint) -> &Value;
// Constant expressions
@ -1217,6 +1222,8 @@ unsafe extern "C" {
) -> &'a BasicBlock;
// Operations on instructions
pub(crate) fn LLVMGetInstructionParent(Inst: &Value) -> &BasicBlock;
pub(crate) fn LLVMGetCalledValue(CallInst: &Value) -> Option<&Value>;
pub(crate) fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>;
pub(crate) fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock;
pub(crate) fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>;
@ -2557,6 +2564,7 @@ unsafe extern "C" {
pub(crate) fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine);
pub(crate) fn LLVMRustPositionBuilderPastAllocas<'a>(B: &Builder<'a>, Fn: &'a Value);
pub(crate) fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock);
pub(crate) fn LLVMRustSetModulePICLevel(M: &Module);

View file

@ -120,6 +120,7 @@ pub struct ModuleConfig {
pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>,
pub autodiff: Vec<config::AutoDiff>,
pub offload: Vec<config::Offload>,
}
impl ModuleConfig {
@ -268,6 +269,7 @@ impl ModuleConfig {
emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
autodiff: if_regular!(sess.opts.unstable_opts.autodiff.clone(), vec![]),
offload: if_regular!(sess.opts.unstable_opts.offload.clone(), vec![]),
}
}

View file

@ -329,20 +329,11 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
let offset = self.layout.fields.offset(i);
if !bx.is_backend_ref(self.layout) && bx.is_backend_ref(field) {
if let BackendRepr::SimdVector { count, .. } = self.layout.backend_repr
&& let BackendRepr::Memory { sized: true } = field.backend_repr
&& count.is_power_of_two()
{
assert_eq!(field.size, self.layout.size);
// This is being deprecated, but for now stdarch still needs it for
// Newtype vector of array, e.g. #[repr(simd)] struct S([i32; 4]);
let place = PlaceRef::alloca(bx, field);
self.val.store(bx, place.val.with_type(self.layout));
return bx.load_operand(place);
} else {
// Part of https://github.com/rust-lang/compiler-team/issues/838
bug!("Non-ref type {self:?} cannot project to ref field type {field:?}");
}
// Part of https://github.com/rust-lang/compiler-team/issues/838
span_bug!(
fx.mir.span,
"Non-ref type {self:?} cannot project to ref field type {field:?}",
);
}
let val = if field.is_zst() {

View file

@ -279,23 +279,15 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> {
interp_ok(match (a, b) {
// Comparisons between integers are always known.
(Scalar::Int { .. }, Scalar::Int { .. }) => {
if a == b {
1
} else {
0
}
}
// Comparisons of abstract pointers with null pointers are known if the pointer
// is in bounds, because if they are in bounds, the pointer can't be null.
// Inequality with integers other than null can never be known for sure.
(Scalar::Int(int), ptr @ Scalar::Ptr(..))
| (ptr @ Scalar::Ptr(..), Scalar::Int(int))
(Scalar::Int(a), Scalar::Int(b)) => (a == b) as u8,
// Comparisons of null with an arbitrary scalar can be known if `scalar_may_be_null`
// indicates that the scalar can definitely *not* be null.
(Scalar::Int(int), ptr) | (ptr, Scalar::Int(int))
if int.is_null() && !self.scalar_may_be_null(ptr)? =>
{
0
}
// Equality with integers can never be known for sure.
// Other ways of comparing integers and pointers can never be known for sure.
(Scalar::Int { .. }, Scalar::Ptr(..)) | (Scalar::Ptr(..), Scalar::Int { .. }) => 2,
// FIXME: return a `1` for when both sides are the same pointer, *except* that
// some things (like functions and vtables) do not have stable addresses

View file

@ -67,8 +67,10 @@ pub enum AllocKind {
LiveData,
/// A function allocation (that fn ptrs point to).
Function,
/// A "virtual" allocation, used for vtables and TypeId.
Virtual,
/// A vtable allocation.
VTable,
/// A TypeId allocation.
TypeId,
/// A dead allocation.
Dead,
}
@ -952,7 +954,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let kind = match global_alloc {
GlobalAlloc::Static { .. } | GlobalAlloc::Memory { .. } => AllocKind::LiveData,
GlobalAlloc::Function { .. } => bug!("We already checked function pointers above"),
GlobalAlloc::VTable { .. } | GlobalAlloc::TypeId { .. } => AllocKind::Virtual,
GlobalAlloc::VTable { .. } => AllocKind::VTable,
GlobalAlloc::TypeId { .. } => AllocKind::TypeId,
};
return AllocInfo::new(size, align, kind, mutbl);
}
@ -1617,6 +1620,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
match self.ptr_try_get_alloc_id(ptr, 0) {
Ok((alloc_id, offset, _)) => {
let info = self.get_alloc_info(alloc_id);
if matches!(info.kind, AllocKind::TypeId) {
// We *could* actually precisely answer this question since here,
// the offset *is* the integer value. But the entire point of making
// this a pointer is not to leak the integer value, so we say everything
// might be null.
return interp_ok(true);
}
// If the pointer is in-bounds (including "at the end"), it is definitely not null.
if offset <= info.size {
return interp_ok(false);

View file

@ -490,7 +490,8 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
gated!(align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(align)),
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
gated!(rustc_align, Normal, template!(List: "alignment"), DuplicatesOk, EncodeCrossCrate::No, fn_align, experimental!(rustc_align)),
ungated!(unsafe(Edition2024) export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),

View file

@ -345,9 +345,6 @@ language_item_table! {
OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
GlobalAlloc, sym::global_alloc_ty, global_alloc_ty, Target::Struct, GenericRequirement::None;
// Experimental lang item for Miri
PtrUnique, sym::ptr_unique, ptr_unique, Target::Struct, GenericRequirement::Exact(1);
PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);
ManuallyDrop, sym::manually_drop, manually_drop, Target::Struct, GenericRequirement::None;

View file

@ -13,10 +13,10 @@ use rustc_session::config::{
CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation,
Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage,
InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans,
NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options,
rustc_optgroups,
NextSolverConfig, Offload, OomStrategy, Options, OutFileName, OutputType, OutputTypes,
PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip,
SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, build_configuration,
build_session_options, rustc_optgroups,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
@ -833,6 +833,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(no_profiler_runtime, true);
tracked!(no_trait_vptr, true);
tracked!(no_unique_section_names, true);
tracked!(offload, vec![Offload::Enable]);
tracked!(on_broken_pipe, OnBrokenPipe::Kill);
tracked!(oom, OomStrategy::Panic);
tracked!(osx_rpath_install_name, true);

View file

@ -1591,12 +1591,49 @@ extern "C" LLVMValueRef LLVMRustBuildMemSet(LLVMBuilderRef B, LLVMValueRef Dst,
MaybeAlign(DstAlign), IsVolatile));
}
extern "C" void LLVMRustPositionBuilderPastAllocas(LLVMBuilderRef B,
LLVMValueRef Fn) {
Function *F = unwrap<Function>(Fn);
unwrap(B)->SetInsertPointPastAllocas(F);
}
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
LLVMBasicBlockRef BB) {
auto Point = unwrap(BB)->getFirstInsertionPt();
unwrap(B)->SetInsertPoint(unwrap(BB), Point);
}
extern "C" void LLVMRustPositionBefore(LLVMBuilderRef B, LLVMValueRef Instr) {
if (auto I = dyn_cast<Instruction>(unwrap<Value>(Instr))) {
unwrap(B)->SetInsertPoint(I);
}
}
extern "C" void LLVMRustPositionAfter(LLVMBuilderRef B, LLVMValueRef Instr) {
if (auto I = dyn_cast<Instruction>(unwrap<Value>(Instr))) {
auto J = I->getNextNonDebugInstruction();
unwrap(B)->SetInsertPoint(J);
}
}
extern "C" LLVMValueRef
LLVMRustGetFunctionCall(LLVMValueRef Fn, const char *Name, size_t NameLen) {
auto targetName = StringRef(Name, NameLen);
Function *F = unwrap<Function>(Fn);
for (auto &BB : *F) {
for (auto &I : BB) {
if (auto *callInst = llvm::dyn_cast<llvm::CallBase>(&I)) {
const llvm::Function *calledFunc = callInst->getCalledFunction();
if (calledFunc && calledFunc->getName() == targetName) {
// Found a call to the target function
return wrap(callInst);
}
}
}
}
return nullptr;
}
extern "C" bool LLVMRustConstIntGetZExtValue(LLVMValueRef CV, uint64_t *value) {
auto C = unwrap<llvm::ConstantInt>(CV);
if (C->getBitWidth() > 64)

View file

@ -70,6 +70,7 @@ pub struct CodegenFnAttrs {
/// switching between multiple instruction sets.
pub instruction_set: Option<InstructionSetAttr>,
/// The `#[align(...)]` attribute. Determines the alignment of the function body.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
pub alignment: Option<Align>,
/// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around
/// the function entry.

View file

@ -43,7 +43,6 @@
//! This code should only compile in modules where the uninhabitedness of `Foo`
//! is visible.
use rustc_span::sym;
use rustc_type_ir::TyKind::*;
use tracing::instrument;
@ -85,21 +84,6 @@ impl<'tcx> VariantDef {
InhabitedPredicate::all(
tcx,
self.fields.iter().map(|field| {
// Unstable fields are always considered to be inhabited. In the future,
// this could be extended to be conditional on the field being unstable
// only within the module that's querying the inhabitedness, like:
// `let pred = pred.or(InhabitedPredicate::IsUnstable(field.did));`
// but this is unnecessary for now, since it would only affect nightly-only
// code or code within the standard library itself.
// HACK: We filter out `rustc_private` fields since with the flag
// `-Zforce-unstable-if-unmarked` we consider all unmarked fields to be
// unstable when building the compiler.
if tcx
.lookup_stability(field.did)
.is_some_and(|stab| stab.is_unstable() && stab.feature != sym::rustc_private)
{
return InhabitedPredicate::True;
}
let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx);
if adt.is_enum() {
return pred;

View file

@ -4,7 +4,6 @@
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.
use rustc_hir::LangItem;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -28,7 +27,6 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
// References and Boxes (`noalias` sources)
ty::Ref(..) => true,
ty::Adt(..) if ty.is_box() => true,
ty::Adt(adt, _) if tcx.is_lang_item(adt.did(), LangItem::PtrUnique) => true,
// Compound types: recurse
ty::Array(ty, _) | ty::Slice(ty) => {
// This does not branch so we keep the depth the same.

View file

@ -253,8 +253,8 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
}
impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ElaborateDropsCtxt").finish_non_exhaustive()
}
}

View file

@ -434,8 +434,8 @@ pub(super) struct DropShimElaborator<'a, 'tcx> {
}
impl fmt::Debug for DropShimElaborator<'_, '_> {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
Ok(())
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("DropShimElaborator").finish_non_exhaustive()
}
}

View file

@ -721,6 +721,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
);
}
if adt_def.repr().simd() {
self.fail(
location,
format!(
"Projecting into SIMD type {adt_def:?} is banned by MCP#838"
),
);
}
let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT);
let Some(field) = adt_def.variant(var).fields.get(f) else {
fail_out_of_bounds(self, location);

View file

@ -294,7 +294,9 @@ pub fn check_builtin_meta_item(
| sym::rustc_paren_sugar
| sym::type_const
| sym::repr
| sym::align
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres
// ambiguity
| sym::rustc_align
| sym::deprecated
| sym::optimize
| sym::pointee

View file

@ -14,7 +14,7 @@ passes_abi_of =
fn_abi_of({$fn_name}) = {$fn_abi}
passes_align_attr_application =
`#[align(...)]` should be applied to a function item
`#[rustc_align(...)]` should be applied to a function item
.label = not a function item
passes_align_on_fields =
@ -22,7 +22,7 @@ passes_align_on_fields =
.warn = {-passes_previously_accepted}
passes_align_should_be_repr_align =
`#[align(...)]` is not supported on {$item} items
`#[rustc_align(...)]` is not supported on {$item} items
.suggestion = use `#[repr(align(...))]` instead
passes_allow_incoherent_impl =
@ -605,7 +605,7 @@ passes_repr_align_greater_than_target_max =
passes_repr_align_should_be_align =
`#[repr(align(...))]` is not supported on {$item} items
.help = use `#[align(...)]` instead
.help = use `#[rustc_align(...)]` instead
passes_repr_conflicting =
conflicting representation hints

View file

@ -1970,6 +1970,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
/// Checks if the `#[align]` attributes on `item` are valid.
// FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity
fn check_align(
&self,
span: Span,

View file

@ -16,7 +16,7 @@ use rustc_middle::ty::{
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
use crate::constructor::Constructor::*;
use crate::constructor::{
@ -238,10 +238,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
let is_visible =
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = cx.is_uninhabited(*ty);
let is_unstable = cx.tcx.lookup_stability(field.did).is_some_and(|stab| {
stab.is_unstable() && stab.feature != sym::rustc_private
});
let skip = is_uninhabited && (!is_visible || is_unstable);
let skip = is_uninhabited && !is_visible;
(ty, PrivateUninhabitedField(skip))
});
cx.dropless_arena.alloc_from_iter(tys)

View file

@ -1,4 +1,4 @@
//! Memory allocation implementation for StableMIR.
//! Memory allocation implementation for rustc_public.
//!
//! This module is responsible for constructing stable components.
//! All operations requiring rustc queries must be delegated
@ -7,8 +7,8 @@
use rustc_abi::Align;
use rustc_middle::mir::ConstValue;
use rustc_middle::mir::interpret::AllocRange;
use rustc_public_bridge::bridge::SmirError;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::bridge::Error as _;
use rustc_public_bridge::context::CompilerCtxt;
use rustc_public_bridge::{Tables, alloc};
use super::Error;
@ -35,7 +35,7 @@ pub(crate) fn new_allocation<'tcx>(
ty: rustc_middle::ty::Ty<'tcx>,
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
cx: &CompilerCtxt<'tcx, BridgeTys>,
) -> Allocation {
try_new_allocation(ty, const_value, tables, cx)
.unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}"))
@ -46,7 +46,7 @@ pub(crate) fn try_new_allocation<'tcx>(
ty: rustc_middle::ty::Ty<'tcx>,
const_value: ConstValue<'tcx>,
tables: &mut Tables<'tcx, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
cx: &CompilerCtxt<'tcx, BridgeTys>,
) -> Result<Allocation, Error> {
let layout = alloc::create_ty_and_layout(cx, ty).map_err(|e| Error::from_internal(e))?;
match const_value {
@ -59,7 +59,7 @@ pub(crate) fn try_new_allocation<'tcx>(
}
ConstValue::Indirect { alloc_id, offset } => {
let alloc = alloc::try_new_indirect(alloc_id, cx);
use rustc_public_bridge::context::SmirAllocRange;
use rustc_public_bridge::context::AllocRangeHelpers;
Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx))
}
}
@ -70,7 +70,7 @@ pub(super) fn allocation_filter<'tcx>(
alloc: &rustc_middle::mir::interpret::Allocation,
alloc_range: AllocRange,
tables: &mut Tables<'tcx, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
cx: &CompilerCtxt<'tcx, BridgeTys>,
) -> Allocation {
alloc::allocation_filter(alloc, alloc_range, tables, cx)
}

View file

@ -1,13 +1,13 @@
//! Define the interface with the Rust compiler.
//!
//! StableMIR users should not use any of the items in this module directly.
//! rustc_public users should not use any of the items in this module directly.
//! These APIs have no stability guarantee.
use std::cell::Cell;
use rustc_hir::def::DefKind;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::{Bridge, SmirContainer};
use rustc_public_bridge::context::CompilerCtxt;
use rustc_public_bridge::{Bridge, Container};
use tracing::debug;
use crate::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
@ -66,13 +66,13 @@ impl Bridge for BridgeTys {
type Allocation = crate::ty::Allocation;
}
/// Stable public API for querying compiler information.
/// Public API for querying compiler information.
///
/// All queries are delegated to [`rustc_public_bridge::context::SmirCtxt`] that provides
/// All queries are delegated to [`rustc_public_bridge::context::CompilerCtxt`] that provides
/// similar APIs but based on internal rustc constructs.
///
/// Do not use this directly. This is currently used in the macro expansion.
pub(crate) trait SmirInterface {
pub(crate) trait CompilerInterface {
fn entry_fn(&self) -> Option<CrateItem>;
/// Retrieve all items of the local crate that have a MIR associated with them.
fn all_local_items(&self) -> CrateItems;
@ -316,7 +316,7 @@ pub(crate) trait SmirInterface {
fn associated_items(&self, def_id: DefId) -> AssocItems;
}
impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
impl<'tcx> CompilerInterface for Container<'tcx, BridgeTys> {
fn entry_fn(&self) -> Option<CrateItem> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
@ -567,7 +567,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)),
DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)),
DefKind::ForeignTy => {
use rustc_public_bridge::context::SmirTy;
use rustc_public_bridge::context::TyHelpers;
ForeignItemKind::Type(tables.intern_ty(cx.new_foreign(def_id)))
}
def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind),
@ -1059,36 +1059,36 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
}
}
// A thread local variable that stores a pointer to [`SmirInterface`].
// A thread local variable that stores a pointer to [`CompilerInterface`].
scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>);
pub(crate) fn run<F, T>(interface: &dyn SmirInterface, f: F) -> Result<T, Error>
pub(crate) fn run<F, T>(interface: &dyn CompilerInterface, f: F) -> Result<T, Error>
where
F: FnOnce() -> T,
{
if TLV.is_set() {
Err(Error::from("StableMIR already running"))
Err(Error::from("rustc_public already running"))
} else {
let ptr: *const () = (&raw const interface) as _;
TLV.set(&Cell::new(ptr), || Ok(f()))
}
}
/// Execute the given function with access the [`SmirInterface`].
/// Execute the given function with access the [`CompilerInterface`].
///
/// I.e., This function will load the current interface and calls a function with it.
/// Do not nest these, as that will ICE.
pub(crate) fn with<R>(f: impl FnOnce(&dyn SmirInterface) -> R) -> R {
pub(crate) fn with<R>(f: impl FnOnce(&dyn CompilerInterface) -> R) -> R {
assert!(TLV.is_set());
TLV.with(|tlv| {
let ptr = tlv.get();
assert!(!ptr.is_null());
f(unsafe { *(ptr as *const &dyn SmirInterface) })
f(unsafe { *(ptr as *const &dyn CompilerInterface) })
})
}
fn smir_crate<'tcx>(
cx: &SmirCtxt<'tcx, BridgeTys>,
cx: &CompilerCtxt<'tcx, BridgeTys>,
crate_num: rustc_span::def_id::CrateNum,
) -> Crate {
let name = cx.crate_name(crate_num);

View file

@ -1,5 +1,5 @@
//! When things go wrong, we need some error handling.
//! There are a few different types of errors in StableMIR:
//! There are a few different types of errors in rustc_public:
//!
//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
@ -7,7 +7,7 @@
use std::fmt::{Debug, Display, Formatter};
use std::{fmt, io};
use rustc_public_bridge::bridge::SmirError;
use rustc_public_bridge::bridge;
macro_rules! error {
($fmt: literal $(,)?) => { Error(format!($fmt)) };
@ -32,7 +32,7 @@ pub enum CompilerError<T> {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Error(pub(crate) String);
impl SmirError for Error {
impl bridge::Error for Error {
fn new(msg: String) -> Self {
Self(msg)
}

View file

@ -24,7 +24,7 @@ use std::{fmt, io};
pub(crate) use rustc_public_bridge::IndexedVal;
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
/// Export the rustc_internal APIs. Note that this module has no stability
/// guarantees and it is not taken into account for semver.
#[cfg(feature = "rustc_internal")]
@ -288,7 +288,7 @@ impl rustc_public_bridge::bridge::Allocation<compiler_interface::BridgeTys>
align: u64,
mutability: rustc_middle::mir::Mutability,
tables: &mut Tables<'tcx, compiler_interface::BridgeTys>,
cx: &SmirCtxt<'tcx, compiler_interface::BridgeTys>,
cx: &CompilerCtxt<'tcx, compiler_interface::BridgeTys>,
) -> Self {
Self {
bytes,

View file

@ -9,7 +9,7 @@ use crate::target::{Endian, MachineInfo};
use crate::ty::{Allocation, Binder, ExistentialTraitRef, Ty};
use crate::{Error, IndexedVal, with};
/// An allocation in the SMIR global memory can be either a function pointer,
/// An allocation in the rustc_public's IR global memory can be either a function pointer,
/// a static, or a "real" allocation with some data in it.
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub enum GlobalAlloc {

View file

@ -10,7 +10,7 @@ use crate::ty::{
};
use crate::{Error, Opaque, Span, Symbol};
/// The SMIR representation of a single function.
/// The rustc_public's IR representation of a single function.
#[derive(Clone, Debug, Serialize)]
pub struct Body {
pub blocks: Vec<BasicBlock>,
@ -771,8 +771,8 @@ pub enum VarDebugInfoContents {
// In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This
// is so it can be used for both Places (for which the projection elements are of type
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
// ProjectionElem for Places.
// are of type ProjectionElem<(), ()>).
// In rustc_public's IR we don't need this generality, so we just use ProjectionElem for Places.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum ProjectionElem {
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.

View file

@ -1,7 +1,7 @@
use std::fmt::{Debug, Formatter};
use std::io;
use rustc_public_bridge::bridge::SmirError;
use rustc_public_bridge::bridge;
use serde::Serialize;
use crate::abi::FnAbi;
@ -62,7 +62,7 @@ impl Instance {
/// For more information on fallback body, see <https://github.com/rust-lang/rust/issues/93145>.
///
/// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build
/// the StableMIR body.
/// the rustc_public's IR body.
pub fn has_body(&self) -> bool {
with(|cx| cx.has_body(self.def.def_id()))
}
@ -120,9 +120,9 @@ impl Instance {
/// Resolve an instance starting from a function definition and generic arguments.
pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
with(|context| {
context
.resolve_instance(def, args)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
context.resolve_instance(def, args).ok_or_else(|| {
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
})
}
@ -134,9 +134,9 @@ impl Instance {
/// Resolve an instance for a given function pointer.
pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
with(|context| {
context
.resolve_for_fn_ptr(def, args)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
})
}
@ -147,9 +147,9 @@ impl Instance {
kind: ClosureKind,
) -> Result<Instance, Error> {
with(|context| {
context
.resolve_closure(def, args, kind)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
context.resolve_closure(def, args, kind).ok_or_else(|| {
bridge::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
})
}
@ -157,7 +157,7 @@ impl Instance {
///
/// Allow users to check if this shim can be ignored when called directly.
///
/// We have decided not to export different types of Shims to StableMIR users, however, this
/// We have decided not to export different types of Shims to rustc_public users, however, this
/// is a query that can be very helpful for users when processing DropGlue.
///
/// When generating code for a Drop terminator, users can ignore an empty drop glue.
@ -201,7 +201,7 @@ impl TryFrom<CrateItem> for Instance {
if !context.requires_monomorphization(def_id) {
Ok(context.mono_instance(def_id))
} else {
Err(Error::new("Item requires monomorphization".to_string()))
Err(bridge::Error::new("Item requires monomorphization".to_string()))
}
})
}
@ -217,7 +217,7 @@ impl TryFrom<Instance> for CrateItem {
if value.kind == InstanceKind::Item && context.has_body(value.def.def_id()) {
Ok(CrateItem(context.instance_def_id(value.def)))
} else {
Err(Error::new(format!("Item kind `{:?}` cannot be converted", value.kind)))
Err(bridge::Error::new(format!("Item kind `{:?}` cannot be converted", value.kind)))
}
})
}
@ -263,7 +263,7 @@ impl TryFrom<CrateItem> for StaticDef {
if matches!(value.kind(), ItemKind::Static) {
Ok(StaticDef(value.0))
} else {
Err(Error::new(format!("Expected a static item, but found: {value:?}")))
Err(bridge::Error::new(format!("Expected a static item, but found: {value:?}")))
}
}
}

View file

@ -1,4 +1,4 @@
//! Implement methods to pretty print stable MIR body.
//! Implement methods to pretty print rustc_public's IR body.
use std::fmt::Debug;
use std::io::Write;
use std::{fmt, io, iter};

View file

@ -1,4 +1,4 @@
//! # The Stable MIR Visitor
//! # The rustc_public's IR Visitor
//!
//! ## Overview
//!

View file

@ -1,13 +1,13 @@
//! Module that implements the bridge between Stable MIR and internal compiler MIR.
//! Module that implements the bridge between rustc_public's IR and internal compiler MIR.
//!
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
//! until stable MIR is complete.
//! until rustc_public's IR is complete.
use std::cell::{Cell, RefCell};
use rustc_middle::ty::TyCtxt;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::{Bridge, SmirContainer, Tables};
use rustc_public_bridge::context::CompilerCtxt;
use rustc_public_bridge::{Bridge, Container, Tables};
use rustc_span::def_id::CrateNum;
use scoped_tls::scoped_thread_local;
@ -26,7 +26,7 @@ pub mod pretty;
///
/// # Panics
///
/// This function will panic if StableMIR has not been properly initialized.
/// This function will panic if rustc_public has not been properly initialized.
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
with_container(|tables, cx| item.stable(tables, cx))
}
@ -41,7 +41,7 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
///
/// # Panics
///
/// This function will panic if StableMIR has not been properly initialized.
/// This function will panic if rustc_public has not been properly initialized.
pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx>
where
S: RustcInternal,
@ -57,10 +57,10 @@ pub fn crate_num(item: &crate::Crate) -> CrateNum {
}
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
// datastructures and stable MIR datastructures
// datastructures and rustc_public's IR datastructures
scoped_thread_local! (static TLV: Cell<*const ()>);
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &SmirContainer<'tcx, B>, f: F) -> T
pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &Container<'tcx, B>, f: F) -> T
where
F: FnOnce() -> T,
{
@ -72,13 +72,13 @@ where
/// Loads the current context and calls a function with it.
/// Do not nest these, as that will ICE.
pub(crate) fn with_container<R, B: Bridge>(
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &CompilerCtxt<'tcx, B>) -> R,
) -> R {
assert!(TLV.is_set());
TLV.with(|tlv| {
let ptr = tlv.get();
assert!(!ptr.is_null());
let container = ptr as *const SmirContainer<'_, B>;
let container = ptr as *const Container<'_, B>;
let mut tables = unsafe { (*container).tables.borrow_mut() };
let cx = unsafe { (*container).cx.borrow() };
f(&mut *tables, &*cx)
@ -89,8 +89,8 @@ pub fn run<F, T>(tcx: TyCtxt<'_>, f: F) -> Result<T, Error>
where
F: FnOnce() -> T,
{
let smir_cx = RefCell::new(SmirCtxt::new(tcx));
let container = SmirContainer { tables: RefCell::new(Tables::default()), cx: smir_cx };
let compiler_cx = RefCell::new(CompilerCtxt::new(tcx));
let container = Container { tables: RefCell::new(Tables::default()), cx: compiler_cx };
crate::compiler_interface::run(&container, || init(&container, f))
}
@ -176,7 +176,7 @@ macro_rules! optional {
/// Prefer using [run!] and [run_with_tcx] instead.
///
/// This macro implements the instantiation of a StableMIR driver, and it will invoke
/// This macro implements the instantiation of a rustc_public driver, and it will invoke
/// the given callback after the compiler analyses.
///
/// The third argument determines whether the callback requires `tcx` as an argument.
@ -191,7 +191,7 @@ macro_rules! run_driver {
use rustc_public::CompilerError;
use std::ops::ControlFlow;
pub struct StableMir<B = (), C = (), F = fn($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C>>
pub struct RustcPublic<B = (), C = (), F = fn($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C>>
where
B: Send,
C: Send,
@ -201,15 +201,15 @@ macro_rules! run_driver {
result: Option<ControlFlow<B, C>>,
}
impl<B, C, F> StableMir<B, C, F>
impl<B, C, F> RustcPublic<B, C, F>
where
B: Send,
C: Send,
F: FnOnce($($crate::optional!($with_tcx TyCtxt))?) -> ControlFlow<B, C> + Send,
{
/// Creates a new `StableMir` instance, with given test_function and arguments.
/// Creates a new `RustcPublic` instance, with given test_function and arguments.
pub fn new(callback: F) -> Self {
StableMir { callback: Some(callback), result: None }
RustcPublic { callback: Some(callback), result: None }
}
/// Runs the compiler against given target and tests it with `test_function`
@ -236,7 +236,7 @@ macro_rules! run_driver {
}
}
impl<B, C, F> Callbacks for StableMir<B, C, F>
impl<B, C, F> Callbacks for RustcPublic<B, C, F>
where
B: Send,
C: Send,
@ -265,6 +265,6 @@ macro_rules! run_driver {
}
}
StableMir::new($callback).run($args)
RustcPublic::new($callback).run($args)
}};
}

View file

@ -7,7 +7,7 @@ use super::run;
pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
writeln!(
w,
"// WARNING: This is highly experimental output it's intended for stable-mir developers only."
"// WARNING: This is highly experimental output it's intended for rustc_public developers only."
)?;
writeln!(
w,

View file

@ -1,4 +1,4 @@
//! Module containing the translation from stable mir constructs to the rustc counterpart.
//! Module containing the translation from rustc_public constructs to the rustc counterpart.
//!
//! This module will only include a few constructs to allow users to invoke internal rustc APIs
//! due to incomplete stable coverage.
@ -504,7 +504,7 @@ impl RustcInternal for ExistentialProjection {
tables: &mut Tables<'_, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use crate::unstable::internal_cx::SmirExistentialProjection;
use crate::unstable::internal_cx::ExistentialProjectionHelpers;
tcx.new_from_args(
self.def_id.0.internal(tables, tcx),
self.generic_args.internal(tables, tcx),
@ -536,7 +536,7 @@ impl RustcInternal for ExistentialTraitRef {
tables: &mut Tables<'_, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use crate::unstable::internal_cx::SmirExistentialTraitRef;
use crate::unstable::internal_cx::ExistentialTraitRefHelpers;
tcx.new_from_args(
self.def_id.0.internal(tables, tcx),
self.generic_args.internal(tables, tcx),
@ -552,7 +552,7 @@ impl RustcInternal for TraitRef {
tables: &mut Tables<'_, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use crate::unstable::internal_cx::SmirTraitRef;
use crate::unstable::internal_cx::TraitRefHelpers;
tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx))
}
}

View file

@ -1,4 +1,4 @@
//! This module holds the logic to convert rustc internal ADTs into stable mir ADTs.
//! This module holds the logic to convert rustc internal ADTs into rustc_public ADTs.
//!
//! The conversion from stable to internal is not meant to be complete,
//! and it should be added as when needed to be passed as input to rustc_public_bridge functions.
@ -9,7 +9,7 @@
use std::ops::RangeInclusive;
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use super::Stable;
use crate::compiler_interface::BridgeTys;
@ -26,7 +26,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
(*self).stable(tables, cx)
}
@ -41,7 +41,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
self.as_ref().map(|value| value.stable(tables, cx))
}
@ -57,7 +57,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
Ok(val) => Ok(val.stable(tables, cx)),
@ -74,7 +74,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
self.iter().map(|e| e.stable(tables, cx)).collect()
}
@ -89,7 +89,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
(self.0.stable(tables, cx), self.1.stable(tables, cx))
}
@ -103,7 +103,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx))
}

View file

@ -5,7 +5,7 @@
use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
use rustc_middle::ty;
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use rustc_target::callconv;
use crate::abi::{
@ -21,7 +21,7 @@ use crate::{IndexedVal, opaque};
impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
type T = VariantIdx;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
VariantIdx::to_val(self.as_usize())
}
}
@ -29,7 +29,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
type T = crate::target::Endian;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_abi::Endian::Little => crate::target::Endian::Little,
rustc_abi::Endian::Big => crate::target::Endian::Big,
@ -43,7 +43,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) }
}
@ -55,7 +55,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
tables.layout_id(cx.lift(*self).unwrap())
}
@ -67,7 +67,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
LayoutShape {
fields: self.fields.stable(tables, cx),
@ -85,7 +85,7 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
assert!(self.args.len() >= self.fixed_count as usize);
assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
@ -105,7 +105,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
ArgAbi {
ty: self.layout.ty.stable(tables, cx),
@ -118,7 +118,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
impl<'tcx> Stable<'tcx> for CanonAbi {
type T = CallConvention;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
CanonAbi::C => CallConvention::C,
CanonAbi::Rust => CallConvention::Rust,
@ -154,7 +154,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi {
impl<'tcx> Stable<'tcx> for callconv::PassMode {
type T = PassMode;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
callconv::PassMode::Ignore => PassMode::Ignore,
callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
@ -179,7 +179,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
@ -200,7 +200,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::Variants::Single { index } => {
@ -225,7 +225,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
@ -246,7 +246,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match *self {
rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)),
@ -264,7 +264,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
impl<'tcx> Stable<'tcx> for rustc_abi::Size {
type T = Size;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
Size::from_bits(self.bits_usize())
}
}
@ -272,7 +272,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size {
impl<'tcx> Stable<'tcx> for rustc_abi::Align {
type T = Align;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
self.bytes()
}
}
@ -283,7 +283,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
@ -301,7 +301,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::Primitive::Int(length, signed) => {
@ -318,7 +318,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
type T = AddressSpace;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
AddressSpace(self.0)
}
}
@ -326,7 +326,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
type T = IntegerLength;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_abi::Integer::I8 => IntegerLength::I8,
rustc_abi::Integer::I16 => IntegerLength::I16,
@ -340,7 +340,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
impl<'tcx> Stable<'tcx> for rustc_abi::Float {
type T = FloatLength;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_abi::Float::F16 => FloatLength::F16,
rustc_abi::Float::F32 => FloatLength::F32,
@ -353,7 +353,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Float {
impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
type T = WrappingRange;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
WrappingRange { start: self.start, end: self.end }
}
}
@ -364,7 +364,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
fn stable<'cx>(
&self,
_tables: &mut Tables<'cx, BridgeTys>,
_cx: &SmirCtxt<'cx, BridgeTys>,
_cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
ReprFlags {
is_simd: self.intersects(Self::IS_SIMD),
@ -381,7 +381,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
@ -398,7 +398,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
ReprOptions {
int: self.int.map(|int| int.stable(tables, cx)),

View file

@ -2,9 +2,8 @@
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::{bug, mir};
use rustc_public_bridge::Tables;
use rustc_public_bridge::bridge::SmirError;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use rustc_public_bridge::{Tables, bridge};
use crate::compiler_interface::BridgeTys;
use crate::mir::alloc::GlobalAlloc;
@ -19,7 +18,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::mir::Body::new(
self.basic_blocks
@ -54,7 +53,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::mir::VarDebugInfo {
name: self.name.to_string(),
@ -71,7 +70,7 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
Statement {
kind: self.kind.stable(tables, cx),
@ -85,7 +84,7 @@ impl<'tcx> Stable<'tcx> for mir::SourceInfo {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() }
}
@ -96,7 +95,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
VarDebugInfoFragment {
ty: self.ty.stable(tables, cx),
@ -110,7 +109,7 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
mir::VarDebugInfoContents::Place(place) => {
@ -133,7 +132,7 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
mir::StatementKind::Assign(assign) => crate::mir::StatementKind::Assign(
@ -195,7 +194,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::Rvalue::*;
match self {
@ -259,7 +258,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
impl<'tcx> Stable<'tcx> for mir::Mutability {
type T = crate::mir::Mutability;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_hir::Mutability::*;
match *self {
Not => crate::mir::Mutability::Not,
@ -270,7 +269,7 @@ impl<'tcx> Stable<'tcx> for mir::Mutability {
impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
type T = crate::mir::RawPtrKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use mir::RawPtrKind::*;
match *self {
Const => crate::mir::RawPtrKind::Const,
@ -285,7 +284,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::BorrowKind::*;
match *self {
@ -298,7 +297,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind {
impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
type T = crate::mir::MutBorrowKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::MutBorrowKind::*;
match *self {
Default => crate::mir::MutBorrowKind::Default,
@ -310,7 +309,7 @@ impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
type T = crate::mir::FakeBorrowKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::FakeBorrowKind::*;
match *self {
Deep => crate::mir::FakeBorrowKind::Deep,
@ -324,7 +323,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::NullOp::*;
match self {
@ -344,7 +343,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::CastKind::*;
match self {
@ -364,7 +363,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
type T = crate::mir::FakeReadCause;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::FakeReadCause::*;
match self {
ForMatchGuard => crate::mir::FakeReadCause::ForMatchGuard,
@ -383,7 +382,7 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::Operand::*;
match self {
@ -400,7 +399,7 @@ impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::mir::ConstOperand {
span: self.span.stable(tables, cx),
@ -415,7 +414,7 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::mir::Place {
local: self.local.as_usize(),
@ -429,7 +428,7 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::ProjectionElem::*;
match self {
@ -464,21 +463,21 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
type T = crate::mir::UserTypeProjection;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
}
}
impl<'tcx> Stable<'tcx> for mir::Local {
type T = crate::mir::Local;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
self.as_usize()
}
}
impl<'tcx> Stable<'tcx> for mir::RetagKind {
type T = crate::mir::RetagKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::RetagKind;
match self {
RetagKind::FnEntry => crate::mir::RetagKind::FnEntry,
@ -491,7 +490,7 @@ impl<'tcx> Stable<'tcx> for mir::RetagKind {
impl<'tcx> Stable<'tcx> for mir::UnwindAction {
type T = crate::mir::UnwindAction;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::UnwindAction;
match self {
UnwindAction::Continue => crate::mir::UnwindAction::Continue,
@ -508,7 +507,7 @@ impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::NonDivergingIntrinsic;
@ -533,7 +532,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::AssertKind;
match self {
@ -580,7 +579,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
impl<'tcx> Stable<'tcx> for mir::BinOp {
type T = crate::mir::BinOp;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::BinOp;
match self {
BinOp::Add => crate::mir::BinOp::Add,
@ -615,7 +614,7 @@ impl<'tcx> Stable<'tcx> for mir::BinOp {
impl<'tcx> Stable<'tcx> for mir::UnOp {
type T = crate::mir::UnOp;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::mir::UnOp;
match self {
UnOp::Not => crate::mir::UnOp::Not,
@ -630,7 +629,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
mir::AggregateKind::Array(ty) => {
@ -676,7 +675,7 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::mir::InlineAsmOperand;
@ -703,7 +702,7 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::mir::Terminator;
Terminator {
@ -718,7 +717,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::mir::TerminatorKind;
match self {
@ -807,7 +806,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
self.inner().stable(tables, cx)
}
@ -819,9 +818,9 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_public_bridge::context::SmirAllocRange;
use rustc_public_bridge::context::AllocRangeHelpers;
alloc::allocation_filter(
self,
cx.alloc_range(rustc_abi::Size::ZERO, self.size()),
@ -836,7 +835,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
_: &SmirCtxt<'cx, BridgeTys>,
_: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
tables.create_alloc_id(*self)
}
@ -848,7 +847,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
mir::interpret::GlobalAlloc::Function { instance, .. } => {
@ -877,7 +876,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let id = tables.intern_mir_const(cx.lift(*self).unwrap());
match *self {
@ -913,8 +912,8 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
type T = Error;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
Error::new(format!("{self:?}"))
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
bridge::Error::new(format!("{self:?}"))
}
}
@ -924,7 +923,7 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::mir::mono::MonoItem as StableMonoItem;
match self {

View file

@ -2,7 +2,7 @@
use rustc_abi::FieldIdx;
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use super::Stable;
use crate::compiler_interface::BridgeTys;
@ -13,7 +13,7 @@ mod ty;
impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
type T = crate::mir::Safety;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_hir::Safety::Unsafe => crate::mir::Safety::Unsafe,
rustc_hir::Safety::Safe => crate::mir::Safety::Safe,
@ -23,14 +23,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Safety {
impl<'tcx> Stable<'tcx> for FieldIdx {
type T = usize;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
self.as_usize()
}
}
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
type T = crate::mir::CoroutineSource;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_hir::CoroutineSource;
match self {
CoroutineSource::Block => crate::mir::CoroutineSource::Block,
@ -45,7 +45,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_hir::{CoroutineDesugaring, CoroutineKind};
match *self {
@ -77,7 +77,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
impl<'tcx> Stable<'tcx> for rustc_span::Symbol {
type T = crate::Symbol;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
self.to_string()
}
}
@ -88,7 +88,7 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
_: &SmirCtxt<'cx, BridgeTys>,
_: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
tables.create_span(*self)
}

View file

@ -3,7 +3,7 @@
use rustc_middle::ty::Ty;
use rustc_middle::{bug, mir, ty};
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use crate::alloc;
use crate::compiler_interface::BridgeTys;
@ -14,7 +14,7 @@ use crate::unstable::Stable;
impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
type T = crate::ty::AliasKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::Projection => crate::ty::AliasKind::Projection,
ty::Inherent => crate::ty::AliasKind::Inherent,
@ -29,7 +29,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::AliasTy { args, def_id, .. } = self;
crate::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) }
@ -41,7 +41,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::AliasTerm { args, def_id, .. } = self;
crate::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) }
@ -51,7 +51,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> {
impl<'tcx> Stable<'tcx> for ty::DynKind {
type T = crate::ty::DynKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::Dyn => crate::ty::DynKind::Dyn,
}
@ -64,7 +64,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::ExistentialPredicate::*;
match self {
@ -85,7 +85,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::ExistentialTraitRef { def_id, args, .. } = self;
crate::ty::ExistentialTraitRef {
@ -101,7 +101,7 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::TermKind;
match self {
@ -120,7 +120,7 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::ExistentialProjection { def_id, args, term, .. } = self;
crate::ty::ExistentialProjection {
@ -136,7 +136,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::ty::adjustment::PointerCoercion;
match self {
@ -154,7 +154,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
type T = usize;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
self.as_usize()
}
}
@ -162,7 +162,7 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
impl<'tcx> Stable<'tcx> for ty::AdtKind {
type T = AdtKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::AdtKind::Struct => AdtKind::Struct,
ty::AdtKind::Union => AdtKind::Union,
@ -177,7 +177,7 @@ impl<'tcx> Stable<'tcx> for ty::FieldDef {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::ty::FieldDef {
def: tables.create_def_id(self.did),
@ -191,7 +191,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
GenericArgs(self.iter().map(|arg| arg.kind().stable(tables, cx)).collect())
}
@ -203,7 +203,7 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::GenericArgKind;
match self {
@ -225,7 +225,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::Binder;
@ -249,7 +249,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::EarlyBinder;
@ -262,7 +262,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::FnSig;
@ -285,7 +285,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::BoundTyKind;
@ -304,7 +304,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::BoundRegionKind;
@ -326,7 +326,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::BoundVariableKind;
@ -345,7 +345,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
impl<'tcx> Stable<'tcx> for ty::IntTy {
type T = IntTy;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::IntTy::Isize => IntTy::Isize,
ty::IntTy::I8 => IntTy::I8,
@ -360,7 +360,7 @@ impl<'tcx> Stable<'tcx> for ty::IntTy {
impl<'tcx> Stable<'tcx> for ty::UintTy {
type T = UintTy;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::UintTy::Usize => UintTy::Usize,
ty::UintTy::U8 => UintTy::U8,
@ -375,7 +375,7 @@ impl<'tcx> Stable<'tcx> for ty::UintTy {
impl<'tcx> Stable<'tcx> for ty::FloatTy {
type T = FloatTy;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::FloatTy::F16 => FloatTy::F16,
ty::FloatTy::F32 => FloatTy::F32,
@ -390,7 +390,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
tables.intern_ty(cx.lift(*self).unwrap())
}
@ -401,7 +401,7 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match self {
ty::Bool => TyKind::RigidTy(RigidTy::Bool),
@ -487,7 +487,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
match **self {
ty::PatternKind::Range { start, end } => crate::ty::Pattern::Range {
@ -507,7 +507,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ct = cx.lift(*self).unwrap();
let kind = match ct.kind() {
@ -540,7 +540,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
impl<'tcx> Stable<'tcx> for ty::ParamConst {
type T = crate::ty::ParamConst;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use crate::ty::ParamConst;
ParamConst { index: self.index, name: self.name.to_string() }
}
@ -548,7 +548,7 @@ impl<'tcx> Stable<'tcx> for ty::ParamConst {
impl<'tcx> Stable<'tcx> for ty::ParamTy {
type T = crate::ty::ParamTy;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use crate::ty::ParamTy;
ParamTy { index: self.index, name: self.name.to_string() }
}
@ -559,7 +559,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::BoundTy;
BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables, cx) }
@ -568,7 +568,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy {
impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
type T = crate::ty::TraitSpecializationKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use crate::ty::TraitSpecializationKind;
match self {
@ -586,7 +586,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::opaque;
use crate::ty::TraitDecl;
@ -616,7 +616,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::TraitRef;
@ -630,7 +630,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::Generics;
@ -655,7 +655,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics {
impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
type T = crate::ty::GenericParamDefKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use crate::ty::GenericParamDefKind;
match self {
ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
@ -675,7 +675,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
GenericParamDef {
name: self.name.to_string(),
@ -693,7 +693,7 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::ty::PredicateKind;
match self {
@ -731,7 +731,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use rustc_middle::ty::ClauseKind;
match *self {
@ -774,7 +774,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
impl<'tcx> Stable<'tcx> for ty::ClosureKind {
type T = crate::ty::ClosureKind;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::ty::ClosureKind::*;
match self {
Fn => crate::ty::ClosureKind::Fn,
@ -790,7 +790,7 @@ impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
crate::ty::SubtypePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) }
@ -803,7 +803,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::CoercePredicate { a, b } = self;
crate::ty::CoercePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) }
@ -813,7 +813,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
type T = crate::ty::AliasRelationDirection;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::ty::AliasRelationDirection::*;
match self {
Equate => crate::ty::AliasRelationDirection::Equate,
@ -828,7 +828,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::TraitPredicate { trait_ref, polarity } = self;
crate::ty::TraitPredicate {
@ -847,7 +847,7 @@ where
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::OutlivesPredicate(a, b) = self;
crate::ty::OutlivesPredicate(a.stable(tables, cx), b.stable(tables, cx))
@ -860,7 +860,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let ty::ProjectionPredicate { projection_term, term } = self;
crate::ty::ProjectionPredicate {
@ -873,7 +873,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
type T = crate::ty::ImplPolarity;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::ty::ImplPolarity::*;
match self {
Positive => crate::ty::ImplPolarity::Positive,
@ -886,7 +886,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
impl<'tcx> Stable<'tcx> for ty::PredicatePolarity {
type T = crate::ty::PredicatePolarity;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_middle::ty::PredicatePolarity::*;
match self {
Positive => crate::ty::PredicatePolarity::Positive,
@ -901,7 +901,7 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
Region { kind: self.kind().stable(tables, cx) }
}
@ -913,7 +913,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::{BoundRegion, EarlyParamRegion, RegionKind};
match self {
@ -948,7 +948,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
let def = tables.instance_def(cx.lift(*self).unwrap());
let kind = match self.def {
@ -976,7 +976,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
impl<'tcx> Stable<'tcx> for ty::Variance {
type T = crate::mir::Variance;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::Bivariant => crate::mir::Variance::Bivariant,
ty::Contravariant => crate::mir::Variance::Contravariant,
@ -989,7 +989,7 @@ impl<'tcx> Stable<'tcx> for ty::Variance {
impl<'tcx> Stable<'tcx> for ty::Movability {
type T = crate::ty::Movability;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
ty::Movability::Static => crate::ty::Movability::Static,
ty::Movability::Movable => crate::ty::Movability::Movable,
@ -1000,7 +1000,7 @@ impl<'tcx> Stable<'tcx> for ty::Movability {
impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
type T = crate::ty::Abi;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use rustc_abi::ExternAbi;
use crate::ty::Abi;
@ -1042,7 +1042,7 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::ty::ForeignModule {
def_id: tables.foreign_module_def(self.def_id),
@ -1057,7 +1057,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::{AssocKind, AssocTypeData};
match *self {
@ -1080,7 +1080,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
type T = crate::ty::AssocItemContainer;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
use crate::ty::AssocItemContainer;
match self {
ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
@ -1095,7 +1095,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::ty::AssocItem {
def_id: tables.assoc_def(self.def_id),
@ -1112,7 +1112,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
_: &SmirCtxt<'cx, BridgeTys>,
_: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
use crate::ty::ImplTraitInTraitData;
match self {
@ -1135,7 +1135,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> {
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T {
crate::ty::Discr { val: self.val, ty: self.ty.stable(tables, cx) }
}

View file

@ -5,7 +5,7 @@
use rustc_middle::ty;
pub(crate) trait SmirExistentialProjection<'tcx> {
pub(crate) trait ExistentialProjectionHelpers<'tcx> {
fn new_from_args(
&self,
def_id: rustc_span::def_id::DefId,
@ -14,7 +14,7 @@ pub(crate) trait SmirExistentialProjection<'tcx> {
) -> ty::ExistentialProjection<'tcx>;
}
pub(crate) trait SmirExistentialTraitRef<'tcx> {
pub(crate) trait ExistentialTraitRefHelpers<'tcx> {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,
@ -22,7 +22,7 @@ pub(crate) trait SmirExistentialTraitRef<'tcx> {
) -> ty::ExistentialTraitRef<'tcx>;
}
pub(crate) trait SmirTraitRef<'tcx> {
pub(crate) trait TraitRefHelpers<'tcx> {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,

View file

@ -1,14 +1,14 @@
//! Implementation of InternalCx.
pub(crate) use helpers::*;
use rustc_middle::ty::{List, Ty, TyCtxt};
use rustc_middle::{mir, ty};
pub(crate) use traits::*;
use super::InternalCx;
pub(crate) mod traits;
pub(crate) mod helpers;
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
impl<'tcx, T: InternalCx<'tcx>> ExistentialProjectionHelpers<'tcx> for T {
fn new_from_args(
&self,
def_id: rustc_span::def_id::DefId,
@ -19,7 +19,7 @@ impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
}
}
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
impl<'tcx, T: InternalCx<'tcx>> ExistentialTraitRefHelpers<'tcx> for T {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,
@ -29,7 +29,7 @@ impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
}
}
impl<'tcx, T: InternalCx<'tcx>> SmirTraitRef<'tcx> for T {
impl<'tcx, T: InternalCx<'tcx>> TraitRefHelpers<'tcx> for T {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,

View file

@ -1,6 +1,6 @@
//! Module that collects the things that have no stability guarantees.
//!
//! We want to keep StableMIR definitions and logic separate from
//! We want to keep rustc_public's IR definitions and logic separate from
//! any sort of conversion and usage of internal rustc code. So we
//! restrict the usage of internal items to be inside this module.
@ -10,7 +10,7 @@ use rustc_hir::def::DefKind;
use rustc_middle::ty::{List, Ty, TyCtxt};
use rustc_middle::{mir, ty};
use rustc_public_bridge::Tables;
use rustc_public_bridge::context::SmirCtxt;
use rustc_public_bridge::context::CompilerCtxt;
use super::compiler_interface::BridgeTys;
use crate::{CtorKind, ItemKind};
@ -21,7 +21,7 @@ mod internal_cx;
/// Trait that defines the methods that are fine to call from [`RustcInternal`].
///
/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals
/// should go through [`rustc_public_bridge::context::SmirCtxt`].
/// should go through [`rustc_public_bridge::context::CompilerCtxt`].
pub trait InternalCx<'tcx>: Copy + Clone {
fn tcx(self) -> TyCtxt<'tcx>;
@ -53,29 +53,30 @@ pub trait InternalCx<'tcx>: Copy + Clone {
fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx>;
}
/// Trait used to convert between an internal MIR type to a Stable MIR type.
/// Trait used to convert between an internal MIR type to a rustc_public's IR type.
///
/// This trait is currently exposed to users so they can have interoperability between internal MIR
/// and StableMIR constructs. However, they should be used seldom and they have no influence
/// in this crate semver.
/// This trait is currently exposed to users so they can have interoperability
/// between internal MIR and rustc_public's IR constructs.
/// However, they should be used seldom and they have no influence in this crate semver.
#[doc(hidden)]
pub trait Stable<'tcx>: PointeeSized {
/// The stable representation of the type implementing Stable.
type T;
/// Converts an object to the equivalent Stable MIR representation.
/// Converts an object to the equivalent rustc_public's IR representation.
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
cx: &CompilerCtxt<'cx, BridgeTys>,
) -> Self::T;
}
/// Trait used to translate a stable construct to its rustc counterpart.
/// Trait used to translate a rustc_public's IR construct to its rustc counterpart.
///
/// This is basically a mirror of [Stable].
///
/// This trait is currently exposed to users so they can have interoperability between internal MIR
/// and StableMIR constructs. They should be used seldom as they have no stability guarantees.
/// This trait is currently exposed to users so they can have interoperability
/// between internal MIR and rustc_public's IR constructs.
/// They should be used seldom as they have no stability guarantees.
#[doc(hidden)]
pub trait RustcInternal {
type T<'tcx>;

View file

@ -1,4 +1,4 @@
//! Internal memory allocator implementation for StableMIR.
//! Internal memory allocator implementation for rustc_public.
//!
//! This module handles all direct interactions with rustc queries and performs
//! the actual memory allocations. The stable interface in `rustc_public::alloc`
@ -10,22 +10,22 @@ use rustc_middle::mir::interpret::{
};
use rustc_middle::ty::{Ty, layout};
use super::{SmirCtxt, Tables};
use super::{CompilerCtxt, Tables};
use crate::bridge::Allocation as _;
use crate::{Bridge, SmirError};
use crate::{Bridge, Error};
pub fn create_ty_and_layout<'tcx, B: Bridge>(
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
ty: Ty<'tcx>,
) -> Result<TyAndLayout<'tcx, Ty<'tcx>>, &'tcx layout::LayoutError<'tcx>> {
use crate::context::SmirTypingEnv;
use crate::context::TypingEnvHelpers;
cx.tcx.layout_of(cx.fully_monomorphized().as_query_input(ty))
}
pub fn try_new_scalar<'tcx, B: Bridge>(
layout: TyAndLayout<'tcx, Ty<'tcx>>,
scalar: Scalar,
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
) -> Result<Allocation, B::Error> {
let size = scalar.size();
let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ());
@ -40,7 +40,7 @@ pub fn try_new_slice<'tcx, B: Bridge>(
layout: TyAndLayout<'tcx, Ty<'tcx>>,
data: ConstAllocation<'tcx>,
meta: u64,
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
) -> Result<Allocation, B::Error> {
let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data);
let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
@ -60,7 +60,7 @@ pub fn try_new_slice<'tcx, B: Bridge>(
pub fn try_new_indirect<'tcx, B: Bridge>(
alloc_id: AllocId,
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
) -> ConstAllocation<'tcx> {
let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
@ -72,7 +72,7 @@ pub fn allocation_filter<'tcx, B: Bridge>(
alloc: &rustc_middle::mir::interpret::Allocation,
alloc_range: AllocRange,
tables: &mut Tables<'tcx, B>,
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
) -> B::Allocation {
let mut bytes: Vec<Option<u8>> = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(

View file

@ -6,10 +6,10 @@
use std::fmt::Debug;
use super::context::SmirCtxt;
use super::context::CompilerCtxt;
use super::{Bridge, Tables};
pub trait SmirError {
pub trait Error {
fn new(msg: String) -> Self;
fn from_internal<T: Debug>(err: T) -> Self;
}
@ -25,7 +25,7 @@ pub trait Allocation<B: Bridge> {
align: u64,
mutability: rustc_middle::mir::Mutability,
tables: &mut Tables<'tcx, B>,
cx: &SmirCtxt<'tcx, B>,
cx: &CompilerCtxt<'tcx, B>,
) -> Self;
}

View file

@ -1,8 +1,7 @@
//! Logic required to produce a monomorphic stable body.
//! Logic required to produce a monomorphic body.
//!
//! We first retrieve and monomorphize the rustc body representation, i.e., we generate a
//! We retrieve and monomorphize the rustc body representation, i.e., we generate a
//! monomorphic body using internal representation.
//! After that, we convert the internal representation into a stable one.
use rustc_hir::def::DefKind;
use rustc_middle::mir;
@ -25,7 +24,7 @@ impl<'tcx> BodyBuilder<'tcx> {
BodyBuilder { tcx, instance }
}
/// Build a stable monomorphic body for a given instance based on the MIR body.
/// Build a monomorphic body for a given instance based on the MIR body.
///
/// All constants are also evaluated.
pub(crate) fn build(mut self) -> mir::Body<'tcx> {

View file

@ -1,6 +1,6 @@
//! A set of traits that define a stable interface to rustc's internals.
//!
//! These traits abstract rustc's internal APIs, allowing StableMIR to maintain a stable
//! These traits abstract rustc's internal APIs, allowing rustc_public to maintain a stable
//! interface regardless of internal compiler changes.
use rustc_middle::mir::interpret::AllocRange;
@ -8,14 +8,14 @@ use rustc_middle::ty;
use rustc_middle::ty::Ty;
use rustc_span::def_id::DefId;
pub trait SmirTy<'tcx> {
pub trait TyHelpers<'tcx> {
fn new_foreign(&self, def_id: DefId) -> Ty<'tcx>;
}
pub trait SmirTypingEnv<'tcx> {
pub trait TypingEnvHelpers<'tcx> {
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx>;
}
pub trait SmirAllocRange<'tcx> {
pub trait AllocRangeHelpers<'tcx> {
fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange;
}

View file

@ -1,4 +1,4 @@
//! Implementation of StableMIR Context.
//! Implementation of CompilerCtxt.
#![allow(rustc::usage_of_qualified_ty)]
@ -24,23 +24,23 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_span::{FileNameDisplayPreference, Span, Symbol};
use rustc_target::callconv::FnAbi;
use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv};
use super::{AllocRangeHelpers, CompilerCtxt, TyHelpers, TypingEnvHelpers};
use crate::builder::BodyBuilder;
use crate::{Bridge, SmirError, Tables, filter_def_ids};
use crate::{Bridge, Error, Tables, filter_def_ids};
impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> TyHelpers<'tcx> for CompilerCtxt<'tcx, B> {
fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
ty::Ty::new_foreign(self.tcx, def_id)
}
}
impl<'tcx, B: Bridge> SmirTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> TypingEnvHelpers<'tcx> for CompilerCtxt<'tcx, B> {
fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}
impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> AllocRangeHelpers<'tcx> for CompilerCtxt<'tcx, B> {
fn alloc_range(
&self,
offset: rustc_abi::Size,
@ -50,7 +50,7 @@ impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
}
}
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
self.tcx.lift(value)
}
@ -85,7 +85,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
/// Return whether the item has a body defined by the user.
///
/// Note that intrinsics may have a placeholder body that shouldn't be used in practice.
/// In StableMIR, we handle this case as if the body is not available.
/// In rustc_public, we handle this case as if the body is not available.
pub(crate) fn item_has_body(&self, def_id: DefId) -> bool {
let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) {
intrinsic.must_be_overridden
@ -426,7 +426,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
/// Evaluate constant as a target usize.
pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result<u64, B::Error> {
use crate::context::SmirTypingEnv;
use crate::context::TypingEnvHelpers;
cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized())
.ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64")))
}

View file

@ -1,4 +1,4 @@
//! Implementation of StableMIR Context.
//! Implementation of CompilerCtxt.
#![allow(rustc::usage_of_qualified_ty)]
@ -9,30 +9,30 @@ use rustc_middle::ty;
use rustc_middle::ty::layout::{FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOfHelpers};
use rustc_middle::ty::{Ty, TyCtxt};
use crate::{Bridge, SmirError};
use crate::{Bridge, Error};
mod helpers;
mod impls;
mod traits;
pub use traits::*;
pub use helpers::*;
/// Provides direct access to rustc's internal queries.
///
/// `SmirInterface` must go through
/// this context to obtain rustc-level information.
pub struct SmirCtxt<'tcx, B: Bridge> {
/// `CompilerInterface` must go through
/// this context to obtain internal information.
pub struct CompilerCtxt<'tcx, B: Bridge> {
pub tcx: TyCtxt<'tcx>,
_marker: PhantomData<B>,
}
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> CompilerCtxt<'tcx, B> {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
Self { tcx, _marker: Default::default() }
}
}
/// Implement error handling for extracting function ABI information.
impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for CompilerCtxt<'tcx, B> {
type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, B::Error>;
#[inline]
@ -46,7 +46,7 @@ impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
}
}
impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for CompilerCtxt<'tcx, B> {
type LayoutOfResult = Result<ty::layout::TyAndLayout<'tcx>, B::Error>;
#[inline]
@ -60,19 +60,19 @@ impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> {
}
}
impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for CompilerCtxt<'tcx, B> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv::fully_monomorphized()
}
}
impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for CompilerCtxt<'tcx, B> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
}
impl<'tcx, B: Bridge> HasDataLayout for SmirCtxt<'tcx, B> {
impl<'tcx, B: Bridge> HasDataLayout for CompilerCtxt<'tcx, B> {
fn data_layout(&self) -> &rustc_abi::TargetDataLayout {
self.tcx.data_layout()
}

View file

@ -1,6 +1,6 @@
//! Crate that implements what will become the rustc side of Stable MIR.
//! Crate that implements what will become the rustc side of rustc_public.
//!
//! This crate is responsible for building Stable MIR components from internal components.
//! This crate serves as a proxy for making calls to rustc queries.
//!
//! This crate is not intended to be invoked directly by users.
//! This crate is the public API of rustc that will be invoked by the `rustc_public` crate.
@ -29,7 +29,7 @@ use std::hash::Hash;
use std::ops::Index;
use bridge::*;
use context::SmirCtxt;
use context::CompilerCtxt;
use rustc_data_structures::fx::{self, FxIndexMap};
use rustc_middle::mir;
use rustc_middle::mir::interpret::AllocId;
@ -46,9 +46,9 @@ pub mod context;
pub mod rustc_internal {}
/// A container which is used for TLS.
pub struct SmirContainer<'tcx, B: Bridge> {
pub struct Container<'tcx, B: Bridge> {
pub tables: RefCell<Tables<'tcx, B>>,
pub cx: RefCell<SmirCtxt<'tcx, B>>,
pub cx: RefCell<CompilerCtxt<'tcx, B>>,
}
pub struct Tables<'tcx, B: Bridge> {
@ -210,7 +210,7 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> {
}
}
/// A trait defining types that are used to emulate StableMIR components, which is really
/// A trait defining types that are used to emulate rustc_public components, which is really
/// useful when programming in rustc_public-agnostic settings.
pub trait Bridge: Sized {
type DefId: Copy + Debug + PartialEq + IndexedVal;
@ -222,7 +222,7 @@ pub trait Bridge: Sized {
type MirConstId: Copy + Debug + PartialEq + IndexedVal;
type Layout: Copy + Debug + PartialEq + IndexedVal;
type Error: SmirError;
type Error: Error;
type CrateItem: CrateItem<Self>;
type AdtDef: AdtDef<Self>;
type ForeignModuleDef: ForeignModuleDef<Self>;

View file

@ -226,6 +226,13 @@ pub enum CoverageLevel {
Mcdc,
}
// The different settings that the `-Z offload` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum Offload {
/// Enable the llvm offload pipeline
Enable,
}
/// The different settings that the `-Z autodiff` flag can have.
#[derive(Clone, PartialEq, Hash, Debug)]
pub enum AutoDiff {
@ -2706,6 +2713,15 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
)
}
if !nightly_options::is_unstable_enabled(matches)
&& unstable_opts.offload.contains(&Offload::Enable)
{
early_dcx.early_fatal(
"`-Zoffload=Enable` also requires `-Zunstable-options` \
and a nightly compiler",
)
}
let target_triple = parse_target_triple(early_dcx, matches);
// Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
@ -3178,7 +3194,7 @@ pub(crate) mod dep_tracking {
AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OomStrategy, OptLevel, OutFileName,
OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel,
@ -3225,6 +3241,7 @@ pub(crate) mod dep_tracking {
impl_dep_tracking_hash_via_hash!(
(),
AutoDiff,
Offload,
bool,
usize,
NonZero<usize>,

View file

@ -726,6 +726,7 @@ mod desc {
pub(crate) const parse_list_with_polarity: &str =
"a comma-separated list of strings, with elements beginning with + or -";
pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintTAFn`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `PrintPasses`, `NoPostopt`, `LooseTypes`, `Inline`";
pub(crate) const parse_offload: &str = "a comma separated list of settings: `Enable`";
pub(crate) const parse_comma_list: &str = "a comma-separated list of strings";
pub(crate) const parse_opt_comma_list: &str = parse_comma_list;
pub(crate) const parse_number: &str = "a number";
@ -1357,6 +1358,27 @@ pub mod parse {
}
}
pub(crate) fn parse_offload(slot: &mut Vec<Offload>, v: Option<&str>) -> bool {
let Some(v) = v else {
*slot = vec![];
return true;
};
let mut v: Vec<&str> = v.split(",").collect();
v.sort_unstable();
for &val in v.iter() {
let variant = match val {
"Enable" => Offload::Enable,
_ => {
// FIXME(ZuseZ4): print an error saying which value is not recognized
return false;
}
};
slot.push(variant);
}
true
}
pub(crate) fn parse_autodiff(slot: &mut Vec<AutoDiff>, v: Option<&str>) -> bool {
let Some(v) = v else {
*slot = vec![];
@ -2401,6 +2423,11 @@ options! {
"do not use unique names for text and data sections when -Z function-sections is used"),
normalize_docs: bool = (false, parse_bool, [TRACKED],
"normalize associated items in rustdoc when generating documentation"),
offload: Vec<crate::config::Offload> = (Vec::new(), parse_offload, [TRACKED],
"a list of offload flags to enable
Mandatory setting:
`=Enable`
Currently the only option available"),
on_broken_pipe: OnBrokenPipe = (OnBrokenPipe::Default, parse_on_broken_pipe, [TRACKED],
"behavior of std::io::ErrorKind::BrokenPipe (SIGPIPE)"),
oom: OomStrategy = (OomStrategy::Abort, parse_oom_strategy, [TRACKED],

View file

@ -1698,7 +1698,6 @@ symbols! {
ptr_slice_from_raw_parts_mut,
ptr_swap,
ptr_swap_nonoverlapping,
ptr_unique,
ptr_write,
ptr_write_bytes,
ptr_write_unaligned,
@ -1809,6 +1808,8 @@ symbols! {
rust_out,
rustc,
rustc_abi,
// FIXME(#82232, #143834): temporary name to mitigate `#[align]` nameres ambiguity
rustc_align,
rustc_allocator,
rustc_allocator_zeroed,
rustc_allow_const_fn_unstable,

View file

@ -0,0 +1,23 @@
# Perform a subtree sync (pull) using the josh-sync tool once every few days (or on demand).
name: rustc-pull
on:
workflow_dispatch:
schedule:
# Run at 04:00 UTC every Monday and Thursday
- cron: '0 4 * * 1,4'
jobs:
pull:
if: github.repository == 'rust-lang/compiler-builtins'
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
with:
# https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/compiler-builtins.20subtree.20sync.20automation/with/528482375
zulip-stream-id: 219381
zulip-topic: 'compiler-builtins subtree sync automation'
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
pr-base-branch: master
branch-name: rustc-pull
secrets:
zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}

View file

@ -165,3 +165,12 @@ cargo bench --no-default-features \
[`iai-callgrind-runner`]: https://crates.io/crates/iai-callgrind-runner
[Valgrind]: https://valgrind.org/
## Subtree synchronization
`compiler-builtins` is included as a [Josh subtree] in the main compiler
repository (`rust-lang/rust`). You can find a guide on how to create synchronization
(pull and push) PRs at the [`rustc-dev-guide` page].
[Josh subtree]: https://rustc-dev-guide.rust-lang.org/external-repos.html#josh-subtrees
[`rustc-dev-guide` page]: https://rustc-dev-guide.rust-lang.org/external-repos.html#synchronizing-a-josh-subtree

View file

@ -3,7 +3,6 @@ resolver = "2"
members = [
"builtins-shim",
"builtins-test",
"crates/josh-sync",
"crates/libm-macros",
"crates/musl-math-sys",
"crates/panic-handler",

View file

@ -12,9 +12,9 @@ license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)"
# `xoshiro128**` is used for its quality, size, and speed at generating `u32` shift amounts.
rand_xoshiro = "0.7"
# To compare float builtins against
rustc_apfloat = "0.2.2"
rustc_apfloat = "0.2.3"
# Really a dev dependency, but dev dependencies can't be optional
iai-callgrind = { version = "0.14.1", optional = true }
iai-callgrind = { version = "0.15.2", optional = true }
[dependencies.compiler_builtins]
path = "../builtins-shim"

View file

@ -28,7 +28,7 @@ function run_icount_benchmarks() {
iai_args=(
"--home" "$(pwd)/$iai_home"
"--regression=ir=5.0"
"--callgrind-limits=ir=5.0"
"--save-summary"
)

View file

@ -15,6 +15,7 @@
// this use. Of course this is not a guarantee that such use will work, it just means that this
// crate doing wrapping pointer arithmetic with a method that must not wrap won't be the problem if
// something does go wrong at runtime.
use core::ffi::c_int;
use core::intrinsics::likely;
const WORD_SIZE: usize = core::mem::size_of::<usize>();
@ -384,13 +385,13 @@ pub unsafe fn set_bytes(mut s: *mut u8, c: u8, mut n: usize) {
}
#[inline(always)]
pub unsafe fn compare_bytes(s1: *const u8, s2: *const u8, n: usize) -> i32 {
pub unsafe fn compare_bytes(s1: *const u8, s2: *const u8, n: usize) -> c_int {
let mut i = 0;
while i < n {
let a = *s1.wrapping_add(i);
let b = *s2.wrapping_add(i);
if a != b {
return a as i32 - b as i32;
return c_int::from(a) - c_int::from(b);
}
i += 1;
}

View file

@ -3,13 +3,6 @@
// FIXME(e2024): this eventually needs to be removed.
#![allow(unsafe_op_in_unsafe_fn)]
#[allow(warnings)]
#[cfg(target_pointer_width = "16")]
type c_int = i16;
#[allow(warnings)]
#[cfg(not(target_pointer_width = "16"))]
type c_int = i32;
// memcpy/memmove/memset have optimized implementations on some architectures
#[cfg_attr(
all(not(feature = "no-asm"), target_arch = "x86_64"),
@ -38,18 +31,18 @@ intrinsics! {
}
#[mem_builtin]
pub unsafe extern "C" fn memset(s: *mut u8, c: crate::mem::c_int, n: usize) -> *mut u8 {
pub unsafe extern "C" fn memset(s: *mut u8, c: core::ffi::c_int, n: usize) -> *mut u8 {
impls::set_bytes(s, c as u8, n);
s
}
#[mem_builtin]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> core::ffi::c_int {
impls::compare_bytes(s1, s2, n)
}
#[mem_builtin]
pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, n: usize) -> core::ffi::c_int {
memcmp(s1, s2, n)
}

View file

@ -1,8 +0,0 @@
[package]
name = "josh-sync"
edition = "2024"
publish = false
[dependencies]
directories = "6.0.0"
regex-lite = "0.1.6"

View file

@ -1,45 +0,0 @@
use std::io::{Read, Write};
use std::process::exit;
use std::{env, io};
use crate::sync::{GitSync, Josh};
mod sync;
const USAGE: &str = r#"Utility for synchroniing compiler-builtins with rust-lang/rust
Usage:
josh-sync rustc-pull
Pull from rust-lang/rust to compiler-builtins. Creates a commit
updating the version file, followed by a merge commit.
josh-sync rustc-push GITHUB_USERNAME [BRANCH]
Create a branch off of rust-lang/rust updating compiler-builtins.
"#;
fn main() {
let sync = GitSync::from_current_dir();
// Collect args, then recollect as str refs so we can match on them
let args: Vec<_> = env::args().collect();
let args: Vec<&str> = args.iter().map(String::as_str).collect();
match args.as_slice()[1..] {
["rustc-pull"] => sync.rustc_pull(None),
["rustc-push", github_user, branch] => sync.rustc_push(github_user, Some(branch)),
["rustc-push", github_user] => sync.rustc_push(github_user, None),
["start-josh"] => {
let _josh = Josh::start();
println!("press enter to stop");
io::stdout().flush().unwrap();
let _ = io::stdin().read(&mut [0u8]).unwrap();
}
_ => {
println!("{USAGE}");
exit(1);
}
}
}

View file

@ -1,401 +0,0 @@
use std::borrow::Cow;
use std::net::{SocketAddr, TcpStream};
use std::process::{Command, Stdio, exit};
use std::time::Duration;
use std::{env, fs, process, thread};
use regex_lite::Regex;
const JOSH_PORT: u16 = 42042;
const DEFAULT_PR_BRANCH: &str = "update-builtins";
pub struct GitSync {
upstream_repo: String,
upstream_ref: String,
upstream_url: String,
josh_filter: String,
josh_url_base: String,
}
/// This code was adapted from the miri repository, via the rustc-dev-guide
/// (<https://github.com/rust-lang/rustc-dev-guide/tree/c51adbd12d/josh-sync>)
impl GitSync {
pub fn from_current_dir() -> Self {
let upstream_repo =
env::var("UPSTREAM_ORG").unwrap_or_else(|_| "rust-lang".to_owned()) + "/rust";
Self {
upstream_url: format!("https://github.com/{upstream_repo}"),
upstream_repo,
upstream_ref: env::var("UPSTREAM_REF").unwrap_or_else(|_| "HEAD".to_owned()),
josh_filter: ":/library/compiler-builtins".to_owned(),
josh_url_base: format!("http://localhost:{JOSH_PORT}"),
}
}
/// Pull from rust-lang/rust to compiler-builtins.
pub fn rustc_pull(&self, commit: Option<String>) {
let Self {
upstream_ref,
upstream_url,
upstream_repo,
..
} = self;
let new_upstream_base = commit.unwrap_or_else(|| {
let out = check_output(["git", "ls-remote", upstream_url, upstream_ref]);
out.split_whitespace()
.next()
.unwrap_or_else(|| panic!("could not split output: '{out}'"))
.to_owned()
});
ensure_clean();
// Make sure josh is running.
let _josh = Josh::start();
let josh_url_filtered = self.josh_url(
&self.upstream_repo,
Some(&new_upstream_base),
Some(&self.josh_filter),
);
let previous_upstream_base = fs::read_to_string("rust-version")
.expect("failed to read `rust-version`")
.trim()
.to_string();
assert_ne!(previous_upstream_base, new_upstream_base, "nothing to pull");
let orig_head = check_output(["git", "rev-parse", "HEAD"]);
println!("original upstream base: {previous_upstream_base}");
println!("new upstream base: {new_upstream_base}");
println!("original HEAD: {orig_head}");
// Fetch the latest upstream HEAD so we can get a summary. Use the Josh URL for caching.
run([
"git",
"fetch",
&self.josh_url(&self.upstream_repo, Some(&new_upstream_base), Some(":/")),
&new_upstream_base,
"--depth=1",
]);
let new_summary = check_output(["git", "log", "-1", "--format=%h %s", &new_upstream_base]);
let new_summary = replace_references(&new_summary, &self.upstream_repo);
// Update rust-version file. As a separate commit, since making it part of
// the merge has confused the heck out of josh in the past.
// We pass `--no-verify` to avoid running git hooks.
// We do this before the merge so that if there are merge conflicts, we have
// the right rust-version file while resolving them.
fs::write("rust-version", format!("{new_upstream_base}\n"))
.expect("failed to write rust-version");
let prep_message = format!(
"Update the upstream Rust version\n\n\
To prepare for merging from {upstream_repo}, set the version file to:\n\n \
{new_summary}\n\
",
);
run([
"git",
"commit",
"rust-version",
"--no-verify",
"-m",
&prep_message,
]);
// Fetch given rustc commit.
run(["git", "fetch", &josh_url_filtered]);
let incoming_ref = check_output(["git", "rev-parse", "FETCH_HEAD"]);
println!("incoming ref: {incoming_ref}");
let merge_message = format!(
"Merge ref '{upstream_head_short}{filter}' from {upstream_url}\n\n\
Pull recent changes from {upstream_repo} via Josh.\n\n\
Upstream ref: {new_upstream_base}\n\
Filtered ref: {incoming_ref}\n\
",
upstream_head_short = &new_upstream_base[..12],
filter = self.josh_filter
);
// This should not add any new root commits. So count those before and after merging.
let num_roots = || -> u32 {
let out = check_output(["git", "rev-list", "HEAD", "--max-parents=0", "--count"]);
out.trim()
.parse::<u32>()
.unwrap_or_else(|e| panic!("failed to parse `{out}`: {e}"))
};
let num_roots_before = num_roots();
let pre_merge_sha = check_output(["git", "rev-parse", "HEAD"]);
println!("pre-merge HEAD: {pre_merge_sha}");
// Merge the fetched commit.
run([
"git",
"merge",
"FETCH_HEAD",
"--no-verify",
"--no-ff",
"-m",
&merge_message,
]);
let current_sha = check_output(["git", "rev-parse", "HEAD"]);
if current_sha == pre_merge_sha {
run(["git", "reset", "--hard", &orig_head]);
eprintln!(
"No merge was performed, no changes to pull were found. \
Rolled back the preparation commit."
);
exit(1);
}
// Check that the number of roots did not increase.
assert_eq!(
num_roots(),
num_roots_before,
"Josh created a new root commit. This is probably not the history you want."
);
}
/// Construct an update to rust-lang/rust from compiler-builtins.
pub fn rustc_push(&self, github_user: &str, branch: Option<&str>) {
let Self {
josh_filter,
upstream_url,
..
} = self;
let branch = branch.unwrap_or(DEFAULT_PR_BRANCH);
let josh_url = self.josh_url(&format!("{github_user}/rust"), None, Some(josh_filter));
let user_upstream_url = format!("git@github.com:{github_user}/rust.git");
let Ok(rustc_git) = env::var("RUSTC_GIT") else {
panic!("the RUSTC_GIT environment variable must be set to a rust-lang/rust checkout")
};
ensure_clean();
let base = fs::read_to_string("rust-version")
.expect("failed to read `rust-version`")
.trim()
.to_string();
// Make sure josh is running.
let _josh = Josh::start();
// Prepare the branch. Pushing works much better if we use as base exactly
// the commit that we pulled from last time, so we use the `rust-version`
// file to find out which commit that would be.
println!("Preparing {github_user}/rust (base: {base})...");
if Command::new("git")
.args(["-C", &rustc_git, "fetch", &user_upstream_url, branch])
.output() // capture output
.expect("could not run fetch")
.status
.success()
{
panic!(
"The branch '{branch}' seems to already exist in '{user_upstream_url}'. \
Please delete it and try again."
);
}
run(["git", "-C", &rustc_git, "fetch", upstream_url, &base]);
run_cfg("git", |c| {
c.args([
"-C",
&rustc_git,
"push",
&user_upstream_url,
&format!("{base}:refs/heads/{branch}"),
])
.stdout(Stdio::null())
.stderr(Stdio::null()) // silence the "create GitHub PR" message
});
println!("pushed PR branch");
// Do the actual push.
println!("Pushing changes...");
run(["git", "push", &josh_url, &format!("HEAD:{branch}")]);
println!();
// Do a round-trip check to make sure the push worked as expected.
run(["git", "fetch", &josh_url, branch]);
let head = check_output(["git", "rev-parse", "HEAD"]);
let fetch_head = check_output(["git", "rev-parse", "FETCH_HEAD"]);
assert_eq!(
head, fetch_head,
"Josh created a non-roundtrip push! Do NOT merge this into rustc!\n\
Expected {head}, got {fetch_head}."
);
println!(
"Confirmed that the push round-trips back to compiler-builtins properly. Please \
create a rustc PR:"
);
// Open PR with `subtree update` title to silence the `no-merges` triagebot check
println!(
" {upstream_url}/compare/{github_user}:{branch}?quick_pull=1\
&title=Update%20the%20%60compiler-builtins%60%20subtree\
&body=Update%20the%20Josh%20subtree%20to%20https%3A%2F%2Fgithub.com%2Frust-lang%2F\
compiler-builtins%2Fcommit%2F{head_short}.%0A%0Ar%3F%20%40ghost",
head_short = &head[..12],
);
}
/// Construct a url to the local Josh server with (optionally)
fn josh_url(&self, repo: &str, rev: Option<&str>, filter: Option<&str>) -> String {
format!(
"{base}/{repo}.git{at}{rev}{filter}{filt_git}",
base = self.josh_url_base,
at = if rev.is_some() { "@" } else { "" },
rev = rev.unwrap_or_default(),
filter = filter.unwrap_or_default(),
filt_git = if filter.is_some() { ".git" } else { "" }
)
}
}
/// Fail if there are files that need to be checked in.
fn ensure_clean() {
let read = check_output(["git", "status", "--untracked-files=no", "--porcelain"]);
assert!(
read.is_empty(),
"working directory must be clean before performing rustc pull"
);
}
/* Helpers for running commands with logged invocations */
/// Run a command from an array, passing its output through.
fn run<'a, Args: AsRef<[&'a str]>>(l: Args) {
let l = l.as_ref();
run_cfg(l[0], |c| c.args(&l[1..]));
}
/// Run a command from an array, collecting its output.
fn check_output<'a, Args: AsRef<[&'a str]>>(l: Args) -> String {
let l = l.as_ref();
check_output_cfg(l[0], |c| c.args(&l[1..]))
}
/// [`run`] with configuration.
fn run_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) {
// self.read(l.as_ref());
check_output_cfg(prog, |c| f(c.stdout(Stdio::inherit())));
}
/// [`read`] with configuration. All shell helpers print the command and pass stderr.
fn check_output_cfg(prog: &str, f: impl FnOnce(&mut Command) -> &mut Command) -> String {
let mut cmd = Command::new(prog);
cmd.stderr(Stdio::inherit());
f(&mut cmd);
eprintln!("+ {cmd:?}");
let out = cmd.output().expect("command failed");
assert!(out.status.success());
String::from_utf8(out.stdout.trim_ascii().to_vec()).expect("non-UTF8 output")
}
/// Replace `#1234`-style issue/PR references with `repo#1234` to ensure links work across
/// repositories.
fn replace_references<'a>(s: &'a str, repo: &str) -> Cow<'a, str> {
let re = Regex::new(r"\B(?P<id>#\d+)\b").unwrap();
re.replace(s, &format!("{repo}$id"))
}
/// Create a wrapper that stops Josh on drop.
pub struct Josh(process::Child);
impl Josh {
pub fn start() -> Self {
// Determine cache directory.
let user_dirs =
directories::ProjectDirs::from("org", "rust-lang", "rustc-compiler-builtins-josh")
.unwrap();
let local_dir = user_dirs.cache_dir().to_owned();
// Start josh, silencing its output.
#[expect(clippy::zombie_processes, reason = "clippy can't handle the loop")]
let josh = process::Command::new("josh-proxy")
.arg("--local")
.arg(local_dir)
.args([
"--remote=https://github.com",
&format!("--port={JOSH_PORT}"),
"--no-background",
])
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.expect("failed to start josh-proxy, make sure it is installed");
// Wait until the port is open. We try every 10ms until 1s passed.
for _ in 0..100 {
// This will generally fail immediately when the port is still closed.
let addr = SocketAddr::from(([127, 0, 0, 1], JOSH_PORT));
let josh_ready = TcpStream::connect_timeout(&addr, Duration::from_millis(1));
if josh_ready.is_ok() {
println!("josh up and running");
return Josh(josh);
}
// Not ready yet.
thread::sleep(Duration::from_millis(10));
}
panic!("Even after waiting for 1s, josh-proxy is still not available.")
}
}
impl Drop for Josh {
fn drop(&mut self) {
if cfg!(unix) {
// Try to gracefully shut it down.
Command::new("kill")
.args(["-s", "INT", &self.0.id().to_string()])
.output()
.expect("failed to SIGINT josh-proxy");
// Sadly there is no "wait with timeout"... so we just give it some time to finish.
thread::sleep(Duration::from_millis(100));
// Now hopefully it is gone.
if self
.0
.try_wait()
.expect("failed to wait for josh-proxy")
.is_some()
{
return;
}
}
// If that didn't work (or we're not on Unix), kill it hard.
eprintln!(
"I have to kill josh-proxy the hard way, let's hope this does not \
break anything."
);
self.0.kill().expect("failed to SIGKILL josh-proxy");
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_replace() {
assert_eq!(replace_references("#1234", "r-l/rust"), "r-l/rust#1234");
assert_eq!(replace_references("#1234x", "r-l/rust"), "#1234x");
assert_eq!(
replace_references("merge #1234", "r-l/rust"),
"merge r-l/rust#1234"
);
assert_eq!(
replace_references("foo/bar#1234", "r-l/rust"),
"foo/bar#1234"
);
}
}

View file

@ -12,7 +12,7 @@ proc-macro = true
heck = "0.5.0"
proc-macro2 = "1.0.95"
quote = "1.0.40"
syn = { version = "2.0.101", features = ["full", "extra-traits", "visit-mut"] }
syn = { version = "2.0.104", features = ["full", "extra-traits", "visit-mut"] }
[lints.rust]
# Values used during testing

View file

@ -11,4 +11,4 @@ license = "MIT OR Apache-2.0"
libm = { path = "../../libm" }
[build-dependencies]
cc = "1.2.25"
cc = "1.2.29"

View file

@ -0,0 +1,3 @@
org = "rust-lang"
repo = "compiler-builtins"
path = "library/compiler-builtins"

View file

@ -31,8 +31,8 @@ short-benchmarks = []
anyhow = "1.0.98"
# This is not directly used but is required so we can enable `gmp-mpfr-sys/force-cross`.
gmp-mpfr-sys = { version = "1.6.5", optional = true, default-features = false }
iai-callgrind = { version = "0.14.1", optional = true }
indicatif = { version = "0.17.11", default-features = false }
iai-callgrind = { version = "0.15.2", optional = true }
indicatif = { version = "0.18.0", default-features = false }
libm = { path = "../libm", features = ["unstable-public-internals"] }
libm-macros = { path = "../crates/libm-macros" }
musl-math-sys = { path = "../crates/musl-math-sys", optional = true }

View file

@ -363,6 +363,7 @@ pub const fn f32_from_bits(bits: u32) -> f32 {
}
/// `f32::to_bits`
#[allow(dead_code)] // workaround for false positive RUST-144060
#[allow(unnecessary_transmutes)] // lint appears in newer versions of Rust
pub const fn f32_to_bits(x: f32) -> u32 {
// SAFETY: POD cast with no preconditions
@ -377,6 +378,7 @@ pub const fn f64_from_bits(bits: u64) -> f64 {
}
/// `f64::to_bits`
#[allow(dead_code)] // workaround for false positive RUST-144060
#[allow(unnecessary_transmutes)] // lint appears in newer versions of Rust
pub const fn f64_to_bits(x: f64) -> u64 {
// SAFETY: POD cast with no preconditions

View file

@ -1 +1 @@
d087f112b7d1323446c7b39a8b616aee7fa56b3d
82310651b93a594a3fd69015e1562186a080d94c

View file

@ -4,7 +4,7 @@
# Warns when a PR contains merge commits
# Documentation at: https://forge.rust-lang.org/triagebot/no-merge.html
[no-merges]
exclude_titles = ["Update from"]
exclude_titles = ["Rustc pull update"]
# Canonicalize issue numbers to avoid closing the wrong issue
# when commits are included in subtrees, as well as warning links in commits.
@ -19,3 +19,6 @@ check-commits = false
# Enable issue transfers within the org
# Documentation at: https://forge.rust-lang.org/triagebot/transfer.html
[transfer]
# Automatically close and reopen PRs made by bots to run CI on them
[bot-pull-requests]

View file

@ -198,7 +198,8 @@ impl Error for TryFromSliceError {
}
#[stable(feature = "try_from_slice_error", since = "1.36.0")]
impl From<Infallible> for TryFromSliceError {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Infallible> for TryFromSliceError {
fn from(x: Infallible) -> TryFromSliceError {
match x {}
}

View file

@ -546,7 +546,8 @@ macro_rules! into_int_impl {
($($ty:ty)*) => {
$(
#[unstable(feature = "ascii_char", issue = "110998")]
impl From<AsciiChar> for $ty {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<AsciiChar> for $ty {
#[inline]
fn from(chr: AsciiChar) -> $ty {
chr as u8 as $ty

View file

@ -36,7 +36,8 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
}
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<char> for u32 {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<char> for u32 {
/// Converts a [`char`] into a [`u32`].
///
/// # Examples
@ -53,7 +54,8 @@ impl From<char> for u32 {
}
#[stable(feature = "more_char_conversions", since = "1.51.0")]
impl From<char> for u64 {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<char> for u64 {
/// Converts a [`char`] into a [`u64`].
///
/// # Examples
@ -72,7 +74,8 @@ impl From<char> for u64 {
}
#[stable(feature = "more_char_conversions", since = "1.51.0")]
impl From<char> for u128 {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<char> for u128 {
/// Converts a [`char`] into a [`u128`].
///
/// # Examples
@ -157,7 +160,8 @@ impl TryFrom<char> for u16 {
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
/// C0 and C1 control codes.
#[stable(feature = "char_convert", since = "1.13.0")]
impl From<u8> for char {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<u8> for char {
/// Converts a [`u8`] into a [`char`].
///
/// # Examples
@ -247,7 +251,8 @@ const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
}
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<u32> for char {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<u32> for char {
type Error = CharTryFromError;
#[inline]

View file

@ -216,6 +216,8 @@ pub const fn identity<T>(x: T) -> T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "AsRef"]
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait AsRef<T: PointeeSized>: PointeeSized {
/// Converts this type into a shared reference of the (usually inferred) input type.
#[stable(feature = "rust1", since = "1.0.0")]
@ -367,6 +369,8 @@ pub trait AsRef<T: PointeeSized>: PointeeSized {
/// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then).
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "AsMut"]
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait AsMut<T: PointeeSized>: PointeeSized {
/// Converts this type into a mutable reference of the (usually inferred) input type.
#[stable(feature = "rust1", since = "1.0.0")]
@ -710,9 +714,10 @@ pub trait TryFrom<T>: Sized {
// As lifts over &
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &T
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T: PointeeSized, U: PointeeSized> const AsRef<U> for &T
where
T: AsRef<U>,
T: ~const AsRef<U>,
{
#[inline]
fn as_ref(&self) -> &U {
@ -722,9 +727,10 @@ where
// As lifts over &mut
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &mut T
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T: PointeeSized, U: PointeeSized> const AsRef<U> for &mut T
where
T: AsRef<U>,
T: ~const AsRef<U>,
{
#[inline]
fn as_ref(&self) -> &U {
@ -742,9 +748,10 @@ where
// AsMut lifts over &mut
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PointeeSized, U: PointeeSized> AsMut<U> for &mut T
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T: PointeeSized, U: PointeeSized> const AsMut<U> for &mut T
where
T: AsMut<U>,
T: ~const AsMut<U>,
{
#[inline]
fn as_mut(&mut self) -> &mut U {
@ -840,7 +847,8 @@ where
////////////////////////////////////////////////////////////////////////////////
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<[T]> for [T] {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const AsRef<[T]> for [T] {
#[inline(always)]
fn as_ref(&self) -> &[T] {
self
@ -848,7 +856,8 @@ impl<T> AsRef<[T]> for [T] {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsMut<[T]> for [T] {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const AsMut<[T]> for [T] {
#[inline(always)]
fn as_mut(&mut self) -> &mut [T] {
self
@ -856,7 +865,8 @@ impl<T> AsMut<[T]> for [T] {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<str> for str {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const AsRef<str> for str {
#[inline(always)]
fn as_ref(&self) -> &str {
self
@ -864,7 +874,8 @@ impl AsRef<str> for str {
}
#[stable(feature = "as_mut_str_for_str", since = "1.51.0")]
impl AsMut<str> for str {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const AsMut<str> for str {
#[inline(always)]
fn as_mut(&mut self) -> &mut str {
self
@ -925,7 +936,8 @@ impl AsMut<str> for str {
pub enum Infallible {}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Clone for Infallible {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const Clone for Infallible {
fn clone(&self) -> Infallible {
match *self {}
}
@ -953,7 +965,8 @@ impl Error for Infallible {
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl PartialEq for Infallible {
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl const PartialEq for Infallible {
fn eq(&self, _: &Infallible) -> bool {
match *self {}
}
@ -977,7 +990,8 @@ impl Ord for Infallible {
}
#[stable(feature = "convert_infallible", since = "1.34.0")]
impl From<!> for Infallible {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<!> for Infallible {
#[inline]
fn from(x: !) -> Self {
x

View file

@ -69,7 +69,8 @@ macro_rules! impl_from {
};
($Small:ty => $Large:ty, #[$attr:meta], $doc:expr $(,)?) => {
#[$attr]
impl From<$Small> for $Large {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<$Small> for $Large {
// Rustdocs on the impl block show a "[+] show undocumented items" toggle.
// Rustdocs on functions do not.
#[doc = $doc]
@ -200,7 +201,8 @@ macro_rules! impl_float_from_bool {
)?
) => {
#[stable(feature = "float_from_bool", since = "1.68.0")]
impl From<bool> for $float {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<bool> for $float {
#[doc = concat!("Converts a [`bool`] to [`", stringify!($float),"`] losslessly.")]
/// The resulting value is positive `0.0` for `false` and `1.0` for `true` values.
///
@ -250,7 +252,8 @@ impl_float_from_bool!(
macro_rules! impl_try_from_unbounded {
($source:ty => $($target:ty),+) => {$(
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Tries to create the target number type from a source
@ -268,7 +271,8 @@ macro_rules! impl_try_from_unbounded {
macro_rules! impl_try_from_lower_bounded {
($source:ty => $($target:ty),+) => {$(
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Tries to create the target number type from a source
@ -290,7 +294,8 @@ macro_rules! impl_try_from_lower_bounded {
macro_rules! impl_try_from_upper_bounded {
($source:ty => $($target:ty),+) => {$(
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Tries to create the target number type from a source
@ -312,7 +317,8 @@ macro_rules! impl_try_from_upper_bounded {
macro_rules! impl_try_from_both_bounded {
($source:ty => $($target:ty),+) => {$(
#[stable(feature = "try_from", since = "1.34.0")]
impl TryFrom<$source> for $target {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<$source> for $target {
type Error = TryFromIntError;
/// Tries to create the target number type from a source
@ -450,7 +456,8 @@ use crate::num::NonZero;
macro_rules! impl_nonzero_int_from_nonzero_int {
($Small:ty => $Large:ty) => {
#[stable(feature = "nz_int_conv", since = "1.41.0")]
impl From<NonZero<$Small>> for NonZero<$Large> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<NonZero<$Small>> for NonZero<$Large> {
// Rustdocs on the impl block show a "[+] show undocumented items" toggle.
// Rustdocs on functions do not.
#[doc = concat!("Converts <code>[NonZero]\\<[", stringify!($Small), "]></code> ")]
@ -540,7 +547,8 @@ impl_nonzero_int_try_from_int!(isize);
macro_rules! impl_nonzero_int_try_from_nonzero_int {
($source:ty => $($target:ty),+) => {$(
#[stable(feature = "nzint_try_from_nzint_conv", since = "1.49.0")]
impl TryFrom<NonZero<$source>> for NonZero<$target> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const TryFrom<NonZero<$source>> for NonZero<$target> {
type Error = TryFromIntError;
// Rustdocs on the impl block show a "[+] show undocumented items" toggle.

View file

@ -20,6 +20,25 @@ impl<T> Rev<T> {
pub(in crate::iter) fn new(iter: T) -> Rev<T> {
Rev { iter }
}
/// Consumes the `Rev`, returning the inner iterator.
///
/// # Examples
///
/// ```rust
/// #![feature(rev_into_inner)]
///
/// let s = "foobar";
/// let mut rev = s.chars().rev();
/// assert_eq!(rev.next(), Some('r'));
/// assert_eq!(rev.next(), Some('a'));
/// assert_eq!(rev.next(), Some('b'));
/// assert_eq!(rev.into_inner().collect::<String>(), "foo");
/// ```
#[unstable(feature = "rev_into_inner", issue = "144277")]
pub fn into_inner(self) -> T {
self.iter
}
}
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -1088,7 +1088,8 @@ impl fmt::Debug for IpAddr {
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<Ipv4Addr> for IpAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Ipv4Addr> for IpAddr {
/// Copies this address to a new `IpAddr::V4`.
///
/// # Examples
@ -1110,7 +1111,8 @@ impl From<Ipv4Addr> for IpAddr {
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<Ipv6Addr> for IpAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Ipv6Addr> for IpAddr {
/// Copies this address to a new `IpAddr::V6`.
///
/// # Examples
@ -1220,7 +1222,8 @@ impl Ord for Ipv4Addr {
}
#[stable(feature = "ip_u32", since = "1.1.0")]
impl From<Ipv4Addr> for u32 {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Ipv4Addr> for u32 {
/// Uses [`Ipv4Addr::to_bits`] to convert an IPv4 address to a host byte order `u32`.
#[inline]
fn from(ip: Ipv4Addr) -> u32 {
@ -1229,7 +1232,8 @@ impl From<Ipv4Addr> for u32 {
}
#[stable(feature = "ip_u32", since = "1.1.0")]
impl From<u32> for Ipv4Addr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<u32> for Ipv4Addr {
/// Uses [`Ipv4Addr::from_bits`] to convert a host byte order `u32` into an IPv4 address.
#[inline]
fn from(ip: u32) -> Ipv4Addr {
@ -1238,7 +1242,8 @@ impl From<u32> for Ipv4Addr {
}
#[stable(feature = "from_slice_v4", since = "1.9.0")]
impl From<[u8; 4]> for Ipv4Addr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u8; 4]> for Ipv4Addr {
/// Creates an `Ipv4Addr` from a four element byte array.
///
/// # Examples
@ -1256,7 +1261,8 @@ impl From<[u8; 4]> for Ipv4Addr {
}
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u8; 4]> for IpAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u8; 4]> for IpAddr {
/// Creates an `IpAddr::V4` from a four element byte array.
///
/// # Examples
@ -2210,7 +2216,8 @@ impl Ord for Ipv6Addr {
}
#[stable(feature = "i128", since = "1.26.0")]
impl From<Ipv6Addr> for u128 {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Ipv6Addr> for u128 {
/// Uses [`Ipv6Addr::to_bits`] to convert an IPv6 address to a host byte order `u128`.
#[inline]
fn from(ip: Ipv6Addr) -> u128 {
@ -2218,7 +2225,8 @@ impl From<Ipv6Addr> for u128 {
}
}
#[stable(feature = "i128", since = "1.26.0")]
impl From<u128> for Ipv6Addr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<u128> for Ipv6Addr {
/// Uses [`Ipv6Addr::from_bits`] to convert a host byte order `u128` to an IPv6 address.
#[inline]
fn from(ip: u128) -> Ipv6Addr {
@ -2227,7 +2235,8 @@ impl From<u128> for Ipv6Addr {
}
#[stable(feature = "ipv6_from_octets", since = "1.9.0")]
impl From<[u8; 16]> for Ipv6Addr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u8; 16]> for Ipv6Addr {
/// Creates an `Ipv6Addr` from a sixteen element byte array.
///
/// # Examples
@ -2254,7 +2263,8 @@ impl From<[u8; 16]> for Ipv6Addr {
}
#[stable(feature = "ipv6_from_segments", since = "1.16.0")]
impl From<[u16; 8]> for Ipv6Addr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u16; 8]> for Ipv6Addr {
/// Creates an `Ipv6Addr` from an eight element 16-bit array.
///
/// # Examples
@ -2282,7 +2292,8 @@ impl From<[u16; 8]> for Ipv6Addr {
}
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u8; 16]> for IpAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u8; 16]> for IpAddr {
/// Creates an `IpAddr::V6` from a sixteen element byte array.
///
/// # Examples
@ -2309,7 +2320,8 @@ impl From<[u8; 16]> for IpAddr {
}
#[stable(feature = "ip_from_slice", since = "1.17.0")]
impl From<[u16; 8]> for IpAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<[u16; 8]> for IpAddr {
/// Creates an `IpAddr::V6` from an eight element 16-bit array.
///
/// # Examples

View file

@ -592,7 +592,8 @@ impl SocketAddrV6 {
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<SocketAddrV4> for SocketAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<SocketAddrV4> for SocketAddr {
/// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
#[inline]
fn from(sock4: SocketAddrV4) -> SocketAddr {
@ -601,7 +602,8 @@ impl From<SocketAddrV4> for SocketAddr {
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<SocketAddrV6> for SocketAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<SocketAddrV6> for SocketAddr {
/// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
#[inline]
fn from(sock6: SocketAddrV6) -> SocketAddr {
@ -610,7 +612,8 @@ impl From<SocketAddrV6> for SocketAddr {
}
#[stable(feature = "addr_from_into_ip", since = "1.17.0")]
impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<I: ~const Into<IpAddr>> const From<(I, u16)> for SocketAddr {
/// Converts a tuple struct (Into<[`IpAddr`]>, `u16`) into a [`SocketAddr`].
///
/// This conversion creates a [`SocketAddr::V4`] for an [`IpAddr::V4`]

View file

@ -26,14 +26,16 @@ impl Error for TryFromIntError {
}
#[stable(feature = "try_from", since = "1.34.0")]
impl From<Infallible> for TryFromIntError {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Infallible> for TryFromIntError {
fn from(x: Infallible) -> TryFromIntError {
match x {}
}
}
#[unstable(feature = "never_type", issue = "35121")]
impl From<!> for TryFromIntError {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<!> for TryFromIntError {
#[inline]
fn from(never: !) -> TryFromIntError {
// Match rather than coerce to make sure that code like

View file

@ -1378,7 +1378,8 @@ const fn from_ascii_radix_panic(radix: u32) -> ! {
macro_rules! from_str_int_impl {
($signedness:ident $($int_ty:ty)+) => {$(
#[stable(feature = "rust1", since = "1.0.0")]
impl FromStr for $int_ty {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const FromStr for $int_ty {
type Err = ParseIntError;
/// Parses an integer from a string slice with decimal digits.

View file

@ -297,7 +297,8 @@ where
}
#[stable(feature = "from_nonzero", since = "1.31.0")]
impl<T> From<NonZero<T>> for T
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const From<NonZero<T>> for T
where
T: ZeroablePrimitive,
{

View file

@ -128,7 +128,9 @@ use crate::ops::ControlFlow;
)]
#[doc(alias = "?")]
#[lang = "Try"]
pub trait Try: FromResidual {
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait Try: ~const FromResidual {
/// The type of the value produced by `?` when *not* short-circuiting.
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
type Output;
@ -304,6 +306,8 @@ pub trait Try: FromResidual {
)]
#[rustc_diagnostic_item = "FromResidual"]
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait FromResidual<R = <Self as Try>::Residual> {
/// Constructs the type from a compatible `Residual` type.
///
@ -357,6 +361,8 @@ where
/// and in the other direction,
/// `<Result<Infallible, E> as Residual<T>>::TryType = Result<T, E>`.
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait Residual<O> {
/// The "return" type of this meta-function.
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]

View file

@ -842,7 +842,7 @@ impl<T> Option<T> {
// just needs to be aligned, which it is because `&self` is aligned and
// the offset used is a multiple of alignment.
//
// In the new version, the intrinsic always returns a pointer to an
// Here we assume that `offset_of!` always returns an offset to an
// in-bounds and correctly aligned position for a `T` (even if in the
// `None` case it's just padding).
unsafe {
@ -2144,9 +2144,12 @@ const fn expect_failed(msg: &str) -> ! {
/////////////////////////////////////////////////////////////////////////////
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Option<T>
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const Clone for Option<T>
where
T: Clone,
// FIXME(const_hack): the T: ~const Destruct should be inferred from the Self: ~const Destruct in clone_from.
// See https://github.com/rust-lang/rust/issues/144207
T: ~const Clone + ~const Destruct,
{
#[inline]
fn clone(&self) -> Self {
@ -2230,7 +2233,8 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
}
#[stable(since = "1.12.0", feature = "option_from")]
impl<T> From<T> for Option<T> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const From<T> for Option<T> {
/// Moves `val` into a new [`Some`].
///
/// # Examples
@ -2246,7 +2250,8 @@ impl<T> From<T> for Option<T> {
}
#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<'a, T> const From<&'a Option<T>> for Option<&'a T> {
/// Converts from `&Option<T>` to `Option<&T>`.
///
/// # Examples
@ -2273,7 +2278,8 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
}
#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<'a, T> const From<&'a mut Option<T>> for Option<&'a mut T> {
/// Converts from `&mut Option<T>` to `Option<&mut T>`
///
/// # Examples
@ -2593,7 +2599,8 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
}
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
impl<T> ops::Try for Option<T> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const ops::Try for Option<T> {
type Output = T;
type Residual = Option<convert::Infallible>;
@ -2612,9 +2619,10 @@ impl<T> ops::Try for Option<T> {
}
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
// Note: manually specifying the residual type instead of using the default to work around
// https://github.com/rust-lang/rust/issues/99940
impl<T> ops::FromResidual<Option<convert::Infallible>> for Option<T> {
impl<T> const ops::FromResidual<Option<convert::Infallible>> for Option<T> {
#[inline]
fn from_residual(residual: Option<convert::Infallible>) -> Self {
match residual {
@ -2625,7 +2633,8 @@ impl<T> ops::FromResidual<Option<convert::Infallible>> for Option<T> {
#[diagnostic::do_not_recommend]
#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const ops::FromResidual<ops::Yeet<()>> for Option<T> {
#[inline]
fn from_residual(ops::Yeet(()): ops::Yeet<()>) -> Self {
None
@ -2633,7 +2642,8 @@ impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> {
}
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
impl<T> ops::Residual<T> for Option<convert::Infallible> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T> const ops::Residual<T> for Option<convert::Infallible> {
type TryType = Option<T>;
}

View file

@ -189,7 +189,8 @@ impl TryFrom<usize> for Alignment {
}
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl From<Alignment> for NonZero<usize> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Alignment> for NonZero<usize> {
#[inline]
fn from(align: Alignment) -> NonZero<usize> {
align.as_nonzero()
@ -197,7 +198,8 @@ impl From<Alignment> for NonZero<usize> {
}
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl From<Alignment> for usize {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<Alignment> for usize {
#[inline]
fn from(align: Alignment) -> usize {
align.as_usize()

View file

@ -32,8 +32,6 @@ use crate::ptr::NonNull;
)]
#[doc(hidden)]
#[repr(transparent)]
// Lang item used experimentally by Miri to define the semantics of `Unique`.
#[lang = "ptr_unique"]
pub struct Unique<T: PointeeSized> {
pointer: NonNull<T>,
// NOTE: this marker has no consequences for variance, but is necessary

View file

@ -1288,9 +1288,11 @@ impl<T, E> Result<T, E> {
/// ```
#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
#[inline]
pub fn into_ok(self) -> T
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub const fn into_ok(self) -> T
where
E: Into<!>,
E: ~const Into<!>,
{
match self {
Ok(x) => x,
@ -1323,9 +1325,11 @@ impl<T, E> Result<T, E> {
/// ```
#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
#[inline]
pub fn into_err(self) -> E
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub const fn into_err(self) -> E
where
T: Into<!>,
T: ~const Into<!>,
{
match self {
Ok(x) => x.into(),
@ -2052,7 +2056,8 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
}
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
impl<T, E> ops::Try for Result<T, E> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T, E> const ops::Try for Result<T, E> {
type Output = T;
type Residual = Result<convert::Infallible, E>;
@ -2071,7 +2076,10 @@ impl<T, E> ops::Try for Result<T, E> {
}
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Result<T, F> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T, E, F: ~const From<E>> const ops::FromResidual<Result<convert::Infallible, E>>
for Result<T, F>
{
#[inline]
#[track_caller]
fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
@ -2082,7 +2090,8 @@ impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Res
}
#[diagnostic::do_not_recommend]
#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
impl<T, E, F: From<E>> ops::FromResidual<ops::Yeet<E>> for Result<T, F> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T, E, F: ~const From<E>> const ops::FromResidual<ops::Yeet<E>> for Result<T, F> {
#[inline]
fn from_residual(ops::Yeet(e): ops::Yeet<E>) -> Self {
Err(From::from(e))
@ -2090,6 +2099,7 @@ impl<T, E, F: From<E>> ops::FromResidual<ops::Yeet<E>> for Result<T, F> {
}
#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
impl<T, E> ops::Residual<T> for Result<convert::Infallible, E> {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl<T, E> const ops::Residual<T> for Result<convert::Infallible, E> {
type TryType = Result<T, E>;
}

View file

@ -825,6 +825,8 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> {
/// assert!(Point::from_str("(1 2)").is_err());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
pub trait FromStr: Sized {
/// The associated error which can be returned from parsing.
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -2518,7 +2518,8 @@ impl<T> AtomicPtr<T> {
#[cfg(target_has_atomic_load_store = "8")]
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
impl From<bool> for AtomicBool {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<bool> for AtomicBool {
/// Converts a `bool` into an `AtomicBool`.
///
/// # Examples
@ -2615,7 +2616,8 @@ macro_rules! atomic_int {
}
#[$stable_from]
impl From<$int_type> for $atomic_type {
#[rustc_const_unstable(feature = "const_try", issue = "74935")]
impl const From<$int_type> for $atomic_type {
#[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
#[inline]
fn from(v: $int_type) -> Self { Self::new(v) }

View file

@ -1,2 +1,19 @@
# 6 hours timeout for CI builds
timeout = 21600
# Do not allow approving PRs with certain labels
labels_blocking_approval = [
# Waiting for an FCP to finish
"final-comment-period",
"proposed-final-comment-period",
# PRs that were closed or postponed by an FCP
"disposition-close",
"disposition-postpone",
# Waiting for library ACP
"S-waiting-on-ACP",
"S-waiting-on-concerns",
"S-waiting-on-crater",
"S-waiting-on-fcp",
"S-waiting-on-MCP",
"S-waiting-on-team"
]

View file

@ -370,132 +370,18 @@ impl Step for CodegenBackend {
}
}
/// Checks Rust analyzer that links to .rmetas from a checked rustc.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RustAnalyzer {
pub build_compiler: Compiler,
pub target: TargetSelection,
}
impl Step for RustAnalyzer {
type Output = ();
const ONLY_HOSTS: bool = true;
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
run.path("src/tools/rust-analyzer").default_condition(
builder
.config
.tools
.as_ref()
.is_none_or(|tools| tools.iter().any(|tool| tool == "rust-analyzer")),
)
}
fn make_run(run: RunConfig<'_>) {
let build_compiler = prepare_compiler_for_check(run.builder, run.target, Mode::ToolRustc);
run.builder.ensure(RustAnalyzer { build_compiler, target: run.target });
}
fn run(self, builder: &Builder<'_>) {
let build_compiler = self.build_compiler;
let target = self.target;
let mut cargo = prepare_tool_cargo(
builder,
build_compiler,
Mode::ToolRustc,
target,
builder.kind,
"src/tools/rust-analyzer",
SourceType::InTree,
&["in-rust-tree".to_owned()],
);
cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES);
cargo.arg("--bins");
cargo.arg("--tests");
cargo.arg("--benches");
// Cargo's output path in a given stage, compiled by a particular
// compiler for the specified target.
let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::ToolRustc, target))
.with_prefix("rust-analyzer-check");
let _guard = builder.msg_check("rust-analyzer artifacts", target, None);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
fn metadata(&self) -> Option<StepMetadata> {
Some(StepMetadata::check("rust-analyzer", self.target).built_by(self.build_compiler))
}
}
/// Compiletest is implicitly "checked" when it gets built in order to run tests,
/// so this is mainly for people working on compiletest to run locally.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Compiletest {
pub target: TargetSelection,
}
impl Step for Compiletest {
type Output = ();
const ONLY_HOSTS: bool = true;
const DEFAULT: bool = false;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/tools/compiletest")
}
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Compiletest { target: run.target });
}
fn run(self, builder: &Builder<'_>) {
let mode = if builder.config.compiletest_use_stage0_libtest {
Mode::ToolBootstrap
} else {
Mode::ToolStd
};
let build_compiler = prepare_compiler_for_check(builder, self.target, mode);
let mut cargo = prepare_tool_cargo(
builder,
build_compiler,
mode,
self.target,
builder.kind,
"src/tools/compiletest",
SourceType::InTree,
&[],
);
cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
cargo.arg("--all-targets");
let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, self.target))
.with_prefix("compiletest-check");
let _guard = builder.msg_check("compiletest artifacts", self.target, None);
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
}
fn metadata(&self) -> Option<StepMetadata> {
Some(StepMetadata::check("compiletest", self.target))
}
}
macro_rules! tool_check_step {
(
$name:ident {
// The part of this path after the final '/' is also used as a display name.
path: $path:literal
$(, alt_path: $alt_path:literal )*
, mode: $mode:path
// Closure that returns `Mode` based on the passed `&Builder<'_>`
, mode: $mode:expr
// Subset of nightly features that are allowed to be used when checking
$(, allow_features: $allow_features:expr )?
// Features that should be enabled when checking
$(, enable_features: [$($enable_features:expr),*] )?
$(, default: $default:literal )?
$( , )?
}
@ -518,10 +404,13 @@ macro_rules! tool_check_step {
fn make_run(run: RunConfig<'_>) {
let target = run.target;
let build_compiler = prepare_compiler_for_check(run.builder, target, $mode);
let builder = run.builder;
let mode = $mode(builder);
let build_compiler = prepare_compiler_for_check(run.builder, target, mode);
// It doesn't make sense to cross-check bootstrap tools
if $mode == Mode::ToolBootstrap && target != run.builder.host_target {
if mode == Mode::ToolBootstrap && target != run.builder.host_target {
println!("WARNING: not checking bootstrap tool {} for target {target} as it is a bootstrap (host-only) tool", stringify!($path));
return;
};
@ -536,7 +425,9 @@ macro_rules! tool_check_step {
$( _value = $allow_features; )?
_value
};
run_tool_check_step(builder, build_compiler, target, $path, $mode, allow_features);
let extra_features: &[&str] = &[$($($enable_features),*)?];
let mode = $mode(builder);
run_tool_check_step(builder, build_compiler, target, $path, mode, allow_features, extra_features);
}
fn metadata(&self) -> Option<StepMetadata> {
@ -554,9 +445,11 @@ fn run_tool_check_step(
path: &str,
mode: Mode,
allow_features: &str,
extra_features: &[&str],
) {
let display_name = path.rsplit('/').next().unwrap();
let extra_features = extra_features.iter().map(|f| f.to_string()).collect::<Vec<String>>();
let mut cargo = prepare_tool_cargo(
builder,
build_compiler,
@ -569,12 +462,19 @@ fn run_tool_check_step(
// steps should probably be marked non-default so that the default
// checks aren't affected by toolstate being broken.
SourceType::InTree,
&[],
&extra_features,
);
cargo.allow_features(allow_features);
// FIXME: check bootstrap doesn't currently work with --all-targets
cargo.arg("--all-targets");
// FIXME: check bootstrap doesn't currently work when multiple targets are checked
// FIXME: rust-analyzer does not work with --all-targets
if display_name == "rust-analyzer" {
cargo.arg("--bins");
cargo.arg("--tests");
cargo.arg("--benches");
} else {
cargo.arg("--all-targets");
}
let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target))
.with_prefix(&format!("{display_name}-check"));
@ -593,43 +493,66 @@ fn run_tool_check_step(
tool_check_step!(Rustdoc {
path: "src/tools/rustdoc",
alt_path: "src/librustdoc",
mode: Mode::ToolRustc
mode: |_builder| Mode::ToolRustc
});
// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
// of a submodule. Since the SourceType only drives the deny-warnings
// behavior, treat it as in-tree so that any new warnings in clippy will be
// rejected.
tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustc });
tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustc });
tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustc });
tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustc });
tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustc });
tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustc });
tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: |_builder| Mode::ToolRustc });
tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustc });
tool_check_step!(RustAnalyzer {
path: "src/tools/rust-analyzer",
mode: |_builder| Mode::ToolRustc,
allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
enable_features: ["in-rust-tree"],
});
tool_check_step!(MiroptTestTools {
path: "src/tools/miropt-test-tools",
mode: Mode::ToolBootstrap
mode: |_builder| Mode::ToolBootstrap
});
// We want to test the local std
tool_check_step!(TestFloatParse {
path: "src/tools/test-float-parse",
mode: Mode::ToolStd,
mode: |_builder| Mode::ToolStd,
allow_features: tool::TestFloatParse::ALLOW_FEATURES
});
tool_check_step!(FeaturesStatusDump {
path: "src/tools/features-status-dump",
mode: Mode::ToolBootstrap
mode: |_builder| Mode::ToolBootstrap
});
tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
tool_check_step!(Bootstrap {
path: "src/bootstrap",
mode: |_builder| Mode::ToolBootstrap,
default: false
});
// `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
// check to make it easier to work on.
tool_check_step!(RunMakeSupport {
path: "src/tools/run-make-support",
mode: Mode::ToolBootstrap,
mode: |_builder| Mode::ToolBootstrap,
default: false
});
tool_check_step!(CoverageDump {
path: "src/tools/coverage-dump",
mode: Mode::ToolBootstrap,
mode: |_builder| Mode::ToolBootstrap,
default: false
});
// Compiletest is implicitly "checked" when it gets built in order to run tests,
// so this is mainly for people working on compiletest to run locally.
tool_check_step!(Compiletest {
path: "src/tools/compiletest",
mode: |builder: &Builder<'_>| if builder.config.compiletest_use_stage0_libtest {
Mode::ToolBootstrap
} else {
Mode::ToolStd
},
allow_features: COMPILETEST_ALLOW_FEATURES,
default: false,
});

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