Auto merge of #144269 - jieyouxu:rollup-137ysl2, r=jieyouxu
Rollup of 14 pull requests Successful merges: - rust-lang/rust#142097 (gpu offload host code generation) - rust-lang/rust#143430 (Lower extra lifetimes before normal generic params.) - rust-lang/rust#143768 (Constify Try, From, TryFrom and relevant traits) - rust-lang/rust#143816 (Implement `check` for compiletest and RA using tool macro) - rust-lang/rust#143985 (rustc_public: de-StableMIR-ize) - rust-lang/rust#144027 (clippy: make tests work in stage 1) - rust-lang/rust#144080 (Mitigate `#[align]` name resolution ambiguity regression with a rename) - rust-lang/rust#144176 (Add approval blocking labels for new bors) - rust-lang/rust#144187 (fix handling of base address for TypeId allocations) - rust-lang/rust#144212 (Remove the ptr_unique lang item) - rust-lang/rust#144243 (Subtree update of `rust-analyzer`) - rust-lang/rust#144246 (Don't use another main test file as auxiliary) - rust-lang/rust#144251 (rustc-dev-guide subtree update) - rust-lang/rust#144254 (opt-dist: make `artifact-dir` an absolute path for `opt-dist local`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9748d87dc7
185 changed files with 2120 additions and 1166 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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]`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
439
compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs
Normal file
439
compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs
Normal 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)
|
||||
}
|
||||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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()) }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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![]),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:?}")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! # The Stable MIR Visitor
|
||||
//! # The rustc_public's IR Visitor
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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>,
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -739,7 +739,6 @@ impl Step for CompiletestTest {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Clippy {
|
||||
stage: u32,
|
||||
host: TargetSelection,
|
||||
}
|
||||
|
||||
|
|
@ -753,33 +752,23 @@ impl Step for Clippy {
|
|||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
// If stage is explicitly set or not lower than 2, keep it. Otherwise, make sure it's at least 2
|
||||
// as tests for this step don't work with a lower stage.
|
||||
let stage = if run.builder.config.is_explicit_stage() || run.builder.top_stage >= 2 {
|
||||
run.builder.top_stage
|
||||
} else {
|
||||
2
|
||||
};
|
||||
|
||||
run.builder.ensure(Clippy { stage, host: run.target });
|
||||
run.builder.ensure(Clippy { host: run.target });
|
||||
}
|
||||
|
||||
/// Runs `cargo test` for clippy.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
let stage = self.stage;
|
||||
let stage = builder.top_stage;
|
||||
let host = self.host;
|
||||
let compiler = builder.compiler(stage, host);
|
||||
// We need to carefully distinguish the compiler that builds clippy, and the compiler
|
||||
// that is linked into the clippy being tested. `target_compiler` is the latter,
|
||||
// and it must also be used by clippy's test runner to build tests and their dependencies.
|
||||
let target_compiler = builder.compiler(stage, host);
|
||||
|
||||
if stage < 2 {
|
||||
eprintln!("WARNING: clippy tests on stage {stage} may not behave well.");
|
||||
eprintln!("HELP: consider using stage 2");
|
||||
}
|
||||
|
||||
let tool_result = builder.ensure(tool::Clippy { compiler, target: self.host });
|
||||
let compiler = tool_result.build_compiler;
|
||||
let tool_result = builder.ensure(tool::Clippy { compiler: target_compiler, target: host });
|
||||
let tool_compiler = tool_result.build_compiler;
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
tool_compiler,
|
||||
Mode::ToolRustc,
|
||||
host,
|
||||
Kind::Test,
|
||||
|
|
@ -788,11 +777,17 @@ impl Step for Clippy {
|
|||
&[],
|
||||
);
|
||||
|
||||
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
|
||||
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
|
||||
let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
|
||||
cargo.env("RUSTC_TEST_SUITE", builder.rustc(tool_compiler));
|
||||
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(tool_compiler));
|
||||
let host_libs = builder.stage_out(tool_compiler, Mode::ToolRustc).join(builder.cargo_dir());
|
||||
cargo.env("HOST_LIBS", host_libs);
|
||||
|
||||
// Build the standard library that the tests can use.
|
||||
builder.std(target_compiler, host);
|
||||
cargo.env("TEST_SYSROOT", builder.sysroot(target_compiler));
|
||||
cargo.env("TEST_RUSTC", builder.rustc(target_compiler));
|
||||
cargo.env("TEST_RUSTC_LIB", builder.rustc_libdir(target_compiler));
|
||||
|
||||
// Collect paths of tests to run
|
||||
'partially_test: {
|
||||
let paths = &builder.config.paths[..];
|
||||
|
|
@ -813,7 +808,8 @@ impl Step for Clippy {
|
|||
cargo.add_rustc_lib_path(builder);
|
||||
let cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
|
||||
|
||||
let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host);
|
||||
let _guard =
|
||||
builder.msg_sysroot_tool(Kind::Test, tool_compiler.stage, "clippy", host, host);
|
||||
|
||||
// Clippy reports errors if it blessed the outputs
|
||||
if cargo.allow_failure().run(builder) {
|
||||
|
|
|
|||
|
|
@ -1382,7 +1382,7 @@ mod snapshot {
|
|||
[check] rustc 1 <host> -> Miri 2 <target1>
|
||||
[check] rustc 1 <host> -> CargoMiri 2 <target1>
|
||||
[check] rustc 1 <host> -> Rustfmt 2 <target1>
|
||||
[check] rustc 1 <host> -> rust-analyzer 2 <target1>
|
||||
[check] rustc 1 <host> -> RustAnalyzer 2 <target1>
|
||||
[check] rustc 1 <host> -> TestFloatParse 2 <target1>
|
||||
[check] rustc 1 <host> -> std 1 <target1>
|
||||
");
|
||||
|
|
@ -1530,7 +1530,7 @@ mod snapshot {
|
|||
insta::assert_snapshot!(
|
||||
ctx.config("check")
|
||||
.path("compiletest")
|
||||
.render_steps(), @"[check] compiletest <host>");
|
||||
.render_steps(), @"[check] rustc 0 <host> -> Compiletest 1 <host>");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -1544,7 +1544,7 @@ mod snapshot {
|
|||
[build] llvm <host>
|
||||
[build] rustc 0 <host> -> rustc 1 <host>
|
||||
[build] rustc 1 <host> -> std 1 <host>
|
||||
[check] compiletest <host>
|
||||
[check] rustc 1 <host> -> Compiletest 2 <host>
|
||||
");
|
||||
}
|
||||
|
||||
|
|
@ -1569,7 +1569,7 @@ mod snapshot {
|
|||
.path("rust-analyzer")
|
||||
.render_steps(), @r"
|
||||
[check] rustc 0 <host> -> rustc 1 <host>
|
||||
[check] rustc 0 <host> -> rust-analyzer 1 <host>
|
||||
[check] rustc 0 <host> -> RustAnalyzer 1 <host>
|
||||
");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
fd2eb391d032181459773f3498c17b198513e0d0
|
||||
460259d14de0274b97b8801e08cb2fe5f16fdac5
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ create a `.vim/coc-settings.json`. The settings can be edited with
|
|||
[`src/etc/rust_analyzer_settings.json`].
|
||||
|
||||
Another way is without a plugin, and creating your own logic in your
|
||||
configuration. The following code will work for any checkout of rust-lang/rust (newer than Febuary 2025):
|
||||
configuration. The following code will work for any checkout of rust-lang/rust (newer than February 2025):
|
||||
|
||||
```lua
|
||||
local function expand_config_variables(option)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ Note that places 3 and 4 would never actually be possible to encounter as we alw
|
|||
This has a few failure modes:
|
||||
- People may write visitors which check for `GenericArg::Infer` but forget to check for `hir::TyKind/ConstArgKind::Infer`, only handling infers in ambig positions by accident.
|
||||
- People may write visitors which check for `hir::TyKind/ConstArgKind::Infer` but forget to check for `GenericArg::Infer`, only handling infers in unambig positions by accident.
|
||||
- People may write visitors which check for `GenerArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenerigArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`.
|
||||
- People may write visitors which check for `GenericArg::Type/Const(TyKind/ConstArgKind::Infer)` and `GenericArg::Infer`, not realising that we never represent inferred types/consts in ambig positions as a `GenericArg::Type/Const`.
|
||||
- People may write visitors which check for *only* `TyKind::Infer` and not `ConstArgKind::Infer` forgetting that there are also inferred const arguments (and vice versa).
|
||||
|
||||
To make writing HIR visitors less error prone when caring about inferred types/consts we have a relatively complex system:
|
||||
|
|
@ -60,4 +60,4 @@ This has a number of benefits:
|
|||
[ambig_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/enum.AmbigArg.html
|
||||
[visit_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_ty
|
||||
[visit_const_arg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_const_arg
|
||||
[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer
|
||||
[visit_infer]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/intravisit/trait.Visitor.html#method.visit_infer
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ Internally, [`compiletest`] invokes the supplementary checker script [`htmldocck
|
|||
|
||||
Directives to HtmlDocCk are assertions that place constraints on the generated HTML.
|
||||
They look similar to those given to `compiletest` in that they take the form of `//@` comments
|
||||
but ultimately, they are completey distinct and processed by different programs.
|
||||
but ultimately, they are completely distinct and processed by different programs.
|
||||
|
||||
[XPath] is used to query parts of the HTML document tree.
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ impl<D: Decoder> Decodable<D> for MyStruct {
|
|||
|
||||
rustc has a lot of [arena allocated types].
|
||||
Deserializing these types isn't possible without access to the arena that they need to be allocated on.
|
||||
The [`TyDecoder`] and [`TyEncoder`] traits are supertraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`].
|
||||
The [`TyDecoder`] and [`TyEncoder`] traits are subtraits of [`Decoder`] and [`Encoder`] that allow access to a [`TyCtxt`].
|
||||
|
||||
Types which contain `arena` allocated types can then bound the type parameter of their
|
||||
[`Encodable`] and [`Decodable`] implementations with these traits.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ on if or how to run the test, what behavior to expect, and more. See
|
|||
[directives](directives.md) and the test suite documentation below for more details
|
||||
on these annotations.
|
||||
|
||||
See the [Adding new tests](adding.md) and [Best practies](best-practices.md)
|
||||
See the [Adding new tests](adding.md) and [Best practices](best-practices.md)
|
||||
chapters for a tutorial on creating a new test and advice on writing a good
|
||||
test, and the [Running tests](running.md) chapter on how to run the test suite.
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ This end result is incorrect as we had two separate binders introducing their ow
|
|||
|
||||
While in theory we could make this work it would be quite involved and more complex than the current setup, we would have to:
|
||||
- "rewrite" bound variables to have a higher `DebruijnIndex` whenever instantiating a `Binder`/`EarlyBinder` with a `Bound` ty/const/region
|
||||
- When inferring an inference variable to a bound var, if that bound var is from a binder enterred after creating the infer var, we would have to lower the `DebruijnIndex` of the var.
|
||||
- When inferring an inference variable to a bound var, if that bound var is from a binder entered after creating the infer var, we would have to lower the `DebruijnIndex` of the var.
|
||||
- Separately track what binder an inference variable was created inside of, also what the innermost binder it can name parameters from (currently we only have to track the latter)
|
||||
- When resolving inference variables rewrite any bound variables according to the current binder depth of the infcx
|
||||
- Maybe more (while writing this list items kept getting added so it seems naive to think this is exhaustive)
|
||||
|
|
|
|||
8
src/doc/unstable-book/src/compiler-flags/offload.md
Normal file
8
src/doc/unstable-book/src/compiler-flags/offload.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# `offload`
|
||||
|
||||
The tracking issue for this feature is: [#131513](https://github.com/rust-lang/rust/issues/131513).
|
||||
|
||||
------------------------
|
||||
|
||||
This feature will later allow you to run functions on GPUs. It is work in progress.
|
||||
Set the `-Zoffload=Enable` compiler flag to experiment with it.
|
||||
|
|
@ -72,6 +72,7 @@ dependencies = [
|
|||
"futures",
|
||||
"if_chain",
|
||||
"itertools",
|
||||
"libc",
|
||||
"parking_lot",
|
||||
"quote",
|
||||
"regex",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
|||
# Add dependencies here to make them available in ui tests.
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
regex = "1.5.5"
|
||||
serde = { version = "1.0.145", features = ["derive"] }
|
||||
if_chain = "1.0"
|
||||
|
|
|
|||
|
|
@ -151,7 +151,31 @@ impl TestContext {
|
|||
defaults.set_custom(
|
||||
"dependencies",
|
||||
DependencyBuilder {
|
||||
program: CommandBuilder::cargo(),
|
||||
program: {
|
||||
let mut p = CommandBuilder::cargo();
|
||||
// If we run in bootstrap, we need to use the right compiler for building the
|
||||
// tests -- not the compiler that built clippy, but the compiler that got linked
|
||||
// into clippy. Just invoking TEST_RUSTC does not work because LD_LIBRARY_PATH
|
||||
// is set in a way that makes it pick the wrong sysroot. Sadly due to
|
||||
// <https://github.com/rust-lang/cargo/issues/4423> we cannot use RUSTFLAGS to
|
||||
// set `--sysroot`, so we need to use bootstrap's rustc wrapper. That wrapper
|
||||
// however has some staging logic that is hurting us here, so to work around
|
||||
// that we set both the "real" and "staging" rustc to TEST_RUSTC, including the
|
||||
// associated library paths.
|
||||
if let Some(rustc) = option_env!("TEST_RUSTC") {
|
||||
let libdir = option_env!("TEST_RUSTC_LIB").unwrap();
|
||||
let sysroot = option_env!("TEST_SYSROOT").unwrap();
|
||||
p.envs.push(("RUSTC_REAL".into(), Some(rustc.into())));
|
||||
p.envs.push(("RUSTC_REAL_LIBDIR".into(), Some(libdir.into())));
|
||||
p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into())));
|
||||
p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into())));
|
||||
p.envs.push((
|
||||
"RUSTC_SYSROOT".into(),
|
||||
Some(sysroot.into()),
|
||||
));
|
||||
}
|
||||
p
|
||||
},
|
||||
crate_manifest_path: Path::new("clippy_test_deps").join("Cargo.toml"),
|
||||
build_std: None,
|
||||
bless_lockfile: self.args.bless,
|
||||
|
|
@ -192,6 +216,9 @@ impl TestContext {
|
|||
let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
|
||||
config.program.args.push(dep.into());
|
||||
}
|
||||
if let Some(sysroot) = option_env!("TEST_SYSROOT") {
|
||||
config.program.args.push(format!("--sysroot={sysroot}").into());
|
||||
}
|
||||
|
||||
config.program.program = profile_path.join(if cfg!(windows) {
|
||||
"clippy-driver.exe"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub fn derive(_: TokenStream) -> TokenStream {
|
|||
let output = quote! {
|
||||
// Should not trigger `useless_attribute`
|
||||
#[allow(dead_code)]
|
||||
extern crate rustc_middle;
|
||||
extern crate core;
|
||||
};
|
||||
output
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! Test casts for alignment issues
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![warn(clippy::cast_ptr_alignment)]
|
||||
#![allow(
|
||||
|
|
@ -10,8 +9,6 @@
|
|||
clippy::borrow_as_ptr
|
||||
)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
fn main() {
|
||||
/* These should be warned against */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
|
||||
--> tests/ui/cast_alignment.rs:19:5
|
||||
--> tests/ui/cast_alignment.rs:16:5
|
||||
|
|
||||
LL | (&1u8 as *const u8) as *const u16;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -8,19 +8,19 @@ LL | (&1u8 as *const u8) as *const u16;
|
|||
= help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]`
|
||||
|
||||
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
|
||||
--> tests/ui/cast_alignment.rs:22:5
|
||||
--> tests/ui/cast_alignment.rs:19:5
|
||||
|
|
||||
LL | (&mut 1u8 as *mut u8) as *mut u16;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
|
||||
--> tests/ui/cast_alignment.rs:26:5
|
||||
--> tests/ui/cast_alignment.rs:23:5
|
||||
|
|
||||
LL | (&1u8 as *const u8).cast::<u16>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
|
||||
--> tests/ui/cast_alignment.rs:29:5
|
||||
--> tests/ui/cast_alignment.rs:26:5
|
||||
|
|
||||
LL | (&mut 1u8 as *mut u8).cast::<u16>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -3,15 +3,18 @@
|
|||
#![warn(clippy::iter_over_hash_type)]
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
extern crate proc_macros;
|
||||
|
||||
// Ensure it also works via type aliases (this isn't really the Fx hasher but that does not matter).
|
||||
type FxBuildHasher = std::collections::hash_map::RandomState;
|
||||
type FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;
|
||||
type FxHashSet<K> = HashSet<K, FxBuildHasher>;
|
||||
|
||||
fn main() {
|
||||
let mut hash_set = HashSet::<i32>::new();
|
||||
let mut hash_map = HashMap::<i32, i32>::new();
|
||||
let mut fx_hash_map = rustc_data_structures::fx::FxHashMap::<i32, i32>::default();
|
||||
let mut fx_hash_set = rustc_data_structures::fx::FxHashMap::<i32, i32>::default();
|
||||
let mut fx_hash_map = FxHashMap::<i32, i32>::default();
|
||||
let mut fx_hash_set = FxHashSet::<i32>::default();
|
||||
let vec = Vec::<i32>::new();
|
||||
|
||||
// test hashset
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:18:5
|
||||
--> tests/ui/iter_over_hash_type.rs:21:5
|
||||
|
|
||||
LL | / for x in &hash_set {
|
||||
LL | |
|
||||
|
|
@ -11,7 +11,7 @@ LL | | }
|
|||
= help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]`
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:22:5
|
||||
--> tests/ui/iter_over_hash_type.rs:25:5
|
||||
|
|
||||
LL | / for x in hash_set.iter() {
|
||||
LL | |
|
||||
|
|
@ -20,7 +20,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:26:5
|
||||
--> tests/ui/iter_over_hash_type.rs:29:5
|
||||
|
|
||||
LL | / for x in hash_set.clone() {
|
||||
LL | |
|
||||
|
|
@ -29,7 +29,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:30:5
|
||||
--> tests/ui/iter_over_hash_type.rs:33:5
|
||||
|
|
||||
LL | / for x in hash_set.drain() {
|
||||
LL | |
|
||||
|
|
@ -38,7 +38,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:36:5
|
||||
--> tests/ui/iter_over_hash_type.rs:39:5
|
||||
|
|
||||
LL | / for (x, y) in &hash_map {
|
||||
LL | |
|
||||
|
|
@ -47,7 +47,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:40:5
|
||||
--> tests/ui/iter_over_hash_type.rs:43:5
|
||||
|
|
||||
LL | / for x in hash_map.keys() {
|
||||
LL | |
|
||||
|
|
@ -56,7 +56,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:44:5
|
||||
--> tests/ui/iter_over_hash_type.rs:47:5
|
||||
|
|
||||
LL | / for x in hash_map.values() {
|
||||
LL | |
|
||||
|
|
@ -65,7 +65,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:48:5
|
||||
--> tests/ui/iter_over_hash_type.rs:51:5
|
||||
|
|
||||
LL | / for x in hash_map.values_mut() {
|
||||
LL | |
|
||||
|
|
@ -74,7 +74,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:52:5
|
||||
--> tests/ui/iter_over_hash_type.rs:55:5
|
||||
|
|
||||
LL | / for x in hash_map.iter() {
|
||||
LL | |
|
||||
|
|
@ -83,7 +83,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:56:5
|
||||
--> tests/ui/iter_over_hash_type.rs:59:5
|
||||
|
|
||||
LL | / for x in hash_map.clone() {
|
||||
LL | |
|
||||
|
|
@ -92,7 +92,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:60:5
|
||||
--> tests/ui/iter_over_hash_type.rs:63:5
|
||||
|
|
||||
LL | / for x in hash_map.drain() {
|
||||
LL | |
|
||||
|
|
@ -101,7 +101,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:66:5
|
||||
--> tests/ui/iter_over_hash_type.rs:69:5
|
||||
|
|
||||
LL | / for x in fx_hash_set {
|
||||
LL | |
|
||||
|
|
@ -110,7 +110,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: iteration over unordered hash-based type
|
||||
--> tests/ui/iter_over_hash_type.rs:70:5
|
||||
--> tests/ui/iter_over_hash_type.rs:73:5
|
||||
|
|
||||
LL | / for x in fx_hash_map {
|
||||
LL | |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#![warn(clippy::strlen_on_c_strings)]
|
||||
#![allow(dead_code, clippy::manual_c_str_literals)]
|
||||
#![feature(rustc_private)]
|
||||
extern crate libc;
|
||||
|
||||
#[allow(unused)]
|
||||
use libc::strlen;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#![warn(clippy::strlen_on_c_strings)]
|
||||
#![allow(dead_code, clippy::manual_c_str_literals)]
|
||||
#![feature(rustc_private)]
|
||||
extern crate libc;
|
||||
|
||||
#[allow(unused)]
|
||||
use libc::strlen;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:13:13
|
||||
--> tests/ui/strlen_on_c_strings.rs:11:13
|
||||
|
|
||||
LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstring.as_bytes().len()`
|
||||
|
|
@ -8,37 +8,37 @@ LL | let _ = unsafe { libc::strlen(cstring.as_ptr()) };
|
|||
= help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:18:13
|
||||
--> tests/ui/strlen_on_c_strings.rs:16:13
|
||||
|
|
||||
LL | let _ = unsafe { libc::strlen(cstr.as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:21:13
|
||||
--> tests/ui/strlen_on_c_strings.rs:19:13
|
||||
|
|
||||
LL | let _ = unsafe { strlen(cstr.as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cstr.to_bytes().len()`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:25:22
|
||||
--> tests/ui/strlen_on_c_strings.rs:23:22
|
||||
|
|
||||
LL | let _ = unsafe { strlen((*pcstr).as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*pcstr).to_bytes().len()`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:31:22
|
||||
--> tests/ui/strlen_on_c_strings.rs:29:22
|
||||
|
|
||||
LL | let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe_identity(cstr).to_bytes().len()`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:33:13
|
||||
--> tests/ui/strlen_on_c_strings.rs:31:13
|
||||
|
|
||||
LL | let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe { unsafe_identity(cstr) }.to_bytes().len()`
|
||||
|
||||
error: using `libc::strlen` on a `CString` or `CStr` value
|
||||
--> tests/ui/strlen_on_c_strings.rs:37:22
|
||||
--> tests/ui/strlen_on_c_strings.rs:35:22
|
||||
|
|
||||
LL | let _ = unsafe { strlen(f(cstr).as_ptr()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `f(cstr).to_bytes().len()`
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#[allow(unused_imports)]
|
||||
#[allow(unused_extern_crates)]
|
||||
#[macro_use]
|
||||
extern crate rustc_middle;
|
||||
extern crate regex as regex_crate;
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_derive;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#[allow(unused_imports)]
|
||||
#[allow(unused_extern_crates)]
|
||||
#[macro_use]
|
||||
extern crate rustc_middle;
|
||||
extern crate regex as regex_crate;
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_derive;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit b5098d515d5e1bd0f5470553bc0d18da9794ca8b
|
||||
Subproject commit 2cccfba93c1650f26f1cf8be8aa875a7c1d23fb3
|
||||
|
|
@ -116,14 +116,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let this = self.eval_context_ref();
|
||||
let info = this.get_alloc_info(alloc_id);
|
||||
|
||||
// Miri's address assignment leaks state across thread boundaries, which is incompatible
|
||||
// with GenMC execution. So we instead let GenMC assign addresses to allocations.
|
||||
if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
|
||||
let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
|
||||
return interp_ok(addr);
|
||||
}
|
||||
|
||||
let mut rng = this.machine.rng.borrow_mut();
|
||||
// This is either called immediately after allocation (and then cached), or when
|
||||
// adjusting `tcx` pointers (which never get freed). So assert that we are looking
|
||||
// at a live allocation. This also ensures that we never re-assign an address to an
|
||||
|
|
@ -131,6 +123,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// information was removed.
|
||||
assert!(!matches!(info.kind, AllocKind::Dead));
|
||||
|
||||
// TypeId allocations always have a "base address" of 0 (i.e., the relative offset is the
|
||||
// hash fragment and therefore equal to the actual integer value).
|
||||
if matches!(info.kind, AllocKind::TypeId) {
|
||||
return interp_ok(0);
|
||||
}
|
||||
|
||||
// Miri's address assignment leaks state across thread boundaries, which is incompatible
|
||||
// with GenMC execution. So we instead let GenMC assign addresses to allocations.
|
||||
if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
|
||||
let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
|
||||
return interp_ok(addr);
|
||||
}
|
||||
|
||||
// This allocation does not have a base address yet, pick or reuse one.
|
||||
if !this.machine.native_lib.is_empty() {
|
||||
// In native lib mode, we use the "real" address of the bytes for this allocation.
|
||||
|
|
@ -157,7 +162,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.get_alloc_bytes_unchecked_raw(alloc_id)?
|
||||
}
|
||||
}
|
||||
AllocKind::Function | AllocKind::Virtual => {
|
||||
AllocKind::Function | AllocKind::VTable => {
|
||||
// Allocate some dummy memory to get a unique address for this function/vtable.
|
||||
let alloc_bytes = MiriAllocBytes::from_bytes(
|
||||
&[0u8; 1],
|
||||
|
|
@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
std::mem::forget(alloc_bytes);
|
||||
ptr
|
||||
}
|
||||
AllocKind::Dead => unreachable!(),
|
||||
AllocKind::TypeId | AllocKind::Dead => unreachable!(),
|
||||
};
|
||||
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
|
||||
return interp_ok(base_ptr.addr().to_u64());
|
||||
}
|
||||
// We are not in native lib mode, so we control the addresses ourselves.
|
||||
let mut rng = this.machine.rng.borrow_mut();
|
||||
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
|
||||
&mut *rng,
|
||||
info.size,
|
||||
|
|
@ -295,21 +301,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Store address in cache.
|
||||
global_state.base_addr.try_insert(alloc_id, base_addr).unwrap();
|
||||
|
||||
// Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it sorted.
|
||||
// We have a fast-path for the common case that this address is bigger than all previous ones.
|
||||
let pos = if global_state
|
||||
.int_to_ptr_map
|
||||
.last()
|
||||
.is_some_and(|(last_addr, _)| *last_addr < base_addr)
|
||||
{
|
||||
global_state.int_to_ptr_map.len()
|
||||
} else {
|
||||
global_state
|
||||
// Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it
|
||||
// sorted. We have a fast-path for the common case that this address is bigger than
|
||||
// all previous ones. We skip this for allocations at address 0; those can't be
|
||||
// real, they must be TypeId "fake allocations".
|
||||
if base_addr != 0 {
|
||||
let pos = if global_state
|
||||
.int_to_ptr_map
|
||||
.binary_search_by_key(&base_addr, |(addr, _)| *addr)
|
||||
.unwrap_err()
|
||||
};
|
||||
global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
|
||||
.last()
|
||||
.is_some_and(|(last_addr, _)| *last_addr < base_addr)
|
||||
{
|
||||
global_state.int_to_ptr_map.len()
|
||||
} else {
|
||||
global_state
|
||||
.int_to_ptr_map
|
||||
.binary_search_by_key(&base_addr, |(addr, _)| *addr)
|
||||
.unwrap_err()
|
||||
};
|
||||
global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
|
||||
}
|
||||
|
||||
interp_ok(base_addr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
|||
dcx.log_protector();
|
||||
}
|
||||
},
|
||||
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
|
||||
AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
|
||||
// No stacked borrows on these allocations.
|
||||
}
|
||||
}
|
||||
|
|
@ -1021,7 +1021,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
|
||||
alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
|
||||
}
|
||||
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
|
||||
AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
|
||||
// No stacked borrows on these allocations.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue